diff options
author | Uri Lublin <uril@redhat.com> | 2013-11-05 18:43:42 +0200 |
---|---|---|
committer | Uri Lublin <uril@redhat.com> | 2013-11-13 10:39:57 +0200 |
commit | 4335b0d43a420784e753bd85bf4cecfbda3d991b (patch) | |
tree | 60d61f14834815b7eb420f5bdf6fc61672c53f02 /vdagent/file_xfer.cpp | |
parent | 066f614cee28609176cb24c594e034e7a1237220 (diff) |
vdagent: file_xfer: make g_key_get_string safer
By providing the size of the destination string buffer.
Diffstat (limited to 'vdagent/file_xfer.cpp')
-rw-r--r-- | vdagent/file_xfer.cpp | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/vdagent/file_xfer.cpp b/vdagent/file_xfer.cpp index eb2119a..e402eb2 100644 --- a/vdagent/file_xfer.cpp +++ b/vdagent/file_xfer.cpp @@ -49,7 +49,7 @@ void FileXfer::handle_start(VDAgentFileXferStartMessage* start, status->id = start->id; status->result = VD_AGENT_FILE_XFER_STATUS_ERROR; - if (!g_key_get_string(file_meta, "vdagent-file-xfer", "name", file_name) || + if (!g_key_get_string(file_meta, "vdagent-file-xfer", "name", file_name, sizeof(file_name)) || !g_key_get_uint64(file_meta, "vdagent-file-xfer", "size", &file_size)) { vd_printf("file id %u meta parsing failed", start->id); return; @@ -181,10 +181,12 @@ bool FileXfer::dispatch(VDAgentMessage* msg, VDAgentFileXferStatusMessage* statu //minimal parsers for GKeyFile, supporting only key=value with no spaces. #define G_KEY_MAX_LEN 256 -bool FileXfer::g_key_get_string(char* data, const char* group, const char* key, char* value) +bool FileXfer::g_key_get_string(char* data, const char* group, const char* key, char* value, + unsigned vsize) { char group_pfx[G_KEY_MAX_LEN], key_pfx[G_KEY_MAX_LEN]; - char *group_pos, *key_pos, *next_group_pos; + char *group_pos, *key_pos, *next_group_pos, *start, *end; + unsigned len; snprintf(group_pfx, sizeof(group_pfx), "[%s]", group); if (!(group_pos = strstr((char*)data, group_pfx))) return false; @@ -193,15 +195,26 @@ bool FileXfer::g_key_get_string(char* data, const char* group, const char* key, if (!(key_pos = strstr(group_pos, key_pfx))) return false; next_group_pos = strstr(group_pos + strlen(group_pfx), "["); - if (next_group_pos && key_pos > next_group_pos) return false; + if (next_group_pos && key_pos > next_group_pos) return false; - return !!sscanf(key_pos + strlen(key_pfx), "%s\n", value); + start = key_pos + strlen(key_pfx); + end = strchr(start, '\n'); + if (!end) return false; + + len = end - start; + if (len >= vsize) return false; + + memcpy(value, start, len); + value[len] = '\0'; + + return true; } bool FileXfer::g_key_get_uint64(char* data, const char* group, const char* key, uint64_t* value) { char str[G_KEY_MAX_LEN]; - if (!g_key_get_string(data, group, key, str)) return false; + if (!g_key_get_string(data, group, key, str, sizeof(str))) + return false; return !!sscanf(str, "%" PRIu64, value); } |