Date: Sun, 22 May 2005 21:02:17 GMT From: Shaun Colley <scolleyuk@gmail.com> To: freebsd-gnats-submit@FreeBSD.org Subject: ports/81372: gpasm is vulnerable to a buffer overflow Message-ID: <200505222102.j4ML2H6e082024@www.freebsd.org> Resent-Message-ID: <200505222110.j4MLA2U5055602@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 81372 >Category: ports >Synopsis: gpasm is vulnerable to a buffer overflow >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun May 22 21:10:02 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Shaun Colley >Release: FreeBSD 5.3-RELEASE >Organization: >Environment: bash-3.00# uname -a FreeBSD my.host.name 5.3-RELEASE FreeBSD 5.3-RELEASE #6: Thu Mar 10 21:08:45 GMT 2005 my.host.name:/usr/src/sys/i386/compile/GENERIC i386 >Description: gpasm, part of the devel/gputils port, is vulnerable to a stack overflow when parsing assembly code. gpasm will segmentation fault when given a long directive in a source file. If a user were tricked into assembling a source file, attacker-controlled code could be executed, giving rise to a security risk. I *suspect* that the problem exists in gp_cod_strncpy, 'libgputils' strncpy wrapper. gp_cod_strncpy's code is as follows: --- /* copy a string to a cod block using the pascal convention, i.e. the string length occupies the first string location */ void gp_cod_strncpy(char *dest, char *src, int max_len) { *(dest-1) = ( (max_len>strlen(src)) ? strlen(src) : max_len ); strncpy(dest, src, *(dest-1)); } --- Although the routine's use of strncpy() may make it look secure, it may not be, because it uses the length of the source as the maximum length. I can not be *absolutely* sure where the overflow is caused, but the above is my suspicion. >How-To-Repeat: Simply feed gpasm a malformed file with a long 'directive'. Here's my test file: --- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa END --- Upon being fed to gpasm, a seg fault should occur: --- bash-3.00# ./gpasm a Warning [226] Must use inhx8m format for EEPROM8 Segmentation fault (core dumped) bash-3.00# --- It seems evident that a stack overflow *is* actually occuring by observing execution in GDB. --- bash-3.00# ./gpasm a Warning [226] Must use inhx8m format for EEPROM8 Segmentation fault (core dumped) bash-3.00# gdb -q -c gpasm.core Core was generated by `gpasm'. Program terminated with signal 11, Segmentation fault. #0 0x2812bbb4 in ?? () (gdb) bt #0 0x2812bbb4 in ?? () #1 0x0809c200 in ?? () #2 0xbfbfe788 in ?? () #33 0x00000001 in ?? () #34 0x00000004 in ?? () [...] #37 0x61616161 in ?? () #38 0x61616161 in ?? () #39 0x61616161 in ?? () #40 0x61616161 in ?? () #41 0x61616161 in ?? () #42 0x61616161 in ?? () #43 0x61616161 in ?? () #44 0x61616161 in ?? () #45 0x61616161 in ?? () ---Type <return> to continue, or q <return> to quit---Q [...] --- And here's another log: --- bash-3.00# gdb -q ./gpasm (no debugging symbols found)...(gdb) run a Starting program: /usr/ports/devel/gputils/work/gputils-0.12.0/gpasm/gpasm a (no debugging symbols found)...(no debugging symbols found)...Warning [226] Must use inhx8m format for EEPROM8 Program received signal SIGSEGV, Segmentation fault. 0x2812bbb4 in strncpy () from /lib/libc.so.5 (gdb) [...] (gdb) bt full #0 0x2812bbb4 in strncpy () from /lib/libc.so.5 No symbol table info available. #1 0x08057989 in gp_cod_strncpy () No symbol table info available. #2 0x08050a52 in cod_write_symbols () No symbol table info available. #3 0x0804da77 in lst_symbol_table () No symbol table info available. #4 0x080499a4 in assemble () No symbol table info available. #5 0x080490cc in main () No symbol table info available. --- Though I could be wrong on the whole thing together, this seems like a stack overflow, triggered by a malformed source file, due to lack of proper bounds checking in gp_cod_strncpy(). I'm not sure how exploitable this would be, since there seem to be quite a few frames that need to be popped before the overwritten return address finally gets jumped to - and by the looks of it, gpasm seg faults before that, else the return address upon crash would probably be 0x61616161. I haven't look at how exploitable it might be yet - any thoughts on that? >Fix: Further proof that a call to gp_cod_strncpy() is the culprit is the fact that this patch fixes it: --- gpcod.orig.c Sun May 22 21:55:08 2005 +++ gpcod.c Sun May 22 21:55:30 2005 @@ -29,8 +29,8 @@ gp_cod_strncpy(char *dest, char *src, int max_len) { - *(dest-1) = ( (max_len>strlen(src)) ? strlen(src) : max_len ); - strncpy(dest, src, *(dest-1)); + /**(dest-1) = ( (max_len>strlen(src)) ? strlen(src) : max_len )*/; + strncpy(dest, src, 80); } If the patch is applied to /usr/ports/devel/gputils/work/gputils-0.12.0/libgputils/gpcod.c, the overflow no longer exists: --- bash-3.00# ./gpasm a Warning [226] Must use inhx8m format for EEPROM8 bash-3.00# --- I haven't given my opinion on which call to gp_cod_strncpy() is responsible, because fixing the actual wrapper function is probably a more reliable way. The above patch is rough. I have no idea as to the actual requirements of string lengths - 80 might be too short, or too long. I'm sorry if this was too brief, or too many copy-and-pastes were done. I did this in a hurry because I've got revision to be doing. :) >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200505222102.j4ML2H6e082024>