Bugzilla – Bug 223
CVE-2009-0241: Buffer overflow in gmetad's interactive port
Last modified: 2009-01-24 14:26:26
You need to log in before you can comment on or make changes to this bug.
See http://www.mail-archive.com/ganglia-developers@lists.sourceforge.net/msg04929.html for full details. Quoting from this email: === Buffer overflow It is possible to instantly crash gmetad by crafting a special request to be sent to the interactive port. In process_path() a char element[256] is allocated to contain the pieces of the path as it is processed. If a request is made with a path element longer than that the strncpy call will write to invalid memory location, since there is no length checking performed on the input data to make sure it is less than the size of element.
Created an attachment (id=182) [details] Proposed patch
Correct me if I am wrong, but I think we still have a one-off problem with the patch. len = q-p; /* +1 not needed as q-p is already accounting for that */ element = malloc(len); strncpy(element, p, len); element[len] = '\0'; In the above code suppose "len" is 10 so we malloc() 10 bytes which means that the array indexing for element is 0-9. Then we strncpy() 10 bytes into "element" which is OK. However setting element[len] = "\0", IOW element [10] = "\0" is indexing into the element array 1 byte beyond the actual length of element. So either the code needs to be element = malloc(len+1) or element [len-1] = "\0" correct? I would suggest that maybe rather than allowing the code to malloc() any size buffer to match the incoming element length that instead or in addition we limit the element length as well. Allowing the code to malloc() an unlimited buffer can also lead to security issues. Since the original code defined a 256 byte buffer, 256 seems to be a good limit for elements of the path. It might be a better idea to simply add the limit checking rather than doing a lot of malloc and free calls. If an element is larger than the limit, then produce a mal-formed error message and bail out. Also I don't think that the current patch will work without the multi-path patch that was also submitted, without being reworked. The current patch removes the recursive call to process_path() which means that without the for loop that was provided in the multi-path patch, only one element of the path will be processed and the rest will be ignored. The current patch probably needs to be reworked and separated from the multi-path patch.
Created an attachment (id=187) [details] Consolidates the original patch with some addition fixes Consolidated patch
this bug also affects 3.0 and 2.5.7 (the later no longer in maintenance even if still widely used as it is provided by Debian/Ubuntu and OpenSuSE)
Created an attachment (id=188) [details] avoid a stack buffer overflow by using a dynamically allocated buffer for process_path simplified patch to correct buffer overflow
with the first fix a second buffer overflow was uncovered (before, gmetad crashed so the first overflow was irrelevant) and which will result in the connection to the client not closing after a request with more of 2048 bytes is issued to the interactive port and in errors like : server_thread() 1135602000 unable to write root preamble (DTD, etc) because a "one off" write in readline will write a 0 in the fd used, fix committed for trunk in r1953
Created an attachment (id=189) [details] avoid a stack buffer overflow by using a dynamically allocated buffer for process_path also includes r1953 to avoid off-one buffer overflow when the request on the interactive port is bigger than 2048 bytes
Committed revision 1959 for ganglia-3.1