Hi, When passing the attacked file (libidn-oob-stack-read-main) to the idn command line tool this will cause an out of bounds stack access. This can be seen with either valgrind or by recompiling idn with address sanitizer. The input consists of a random character, a newline and a zero byte.
The error happens in the function main in this code if (readbuf[strlen (readbuf) - 1] == '\n') readbuf[strlen (readbuf) - 1] = '\0'; If readbuf is a zero byte string this won't work. I have attached a patch how to prevent this. Not sure if this is the best way, but it prevents the oob access. This issue was found with the help of american fuzzy lop. It affects latest libidn 1.31. Here's the Address Sanitizer trace of the issue: ==24667==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffefa5df75f at pc 0x402757 bp 0x7ffefa5df430 sp 0x7ffefa5df420 READ of size 1 at 0x7ffefa5df75f thread T0 #0 0x402756 in main /mnt/ram/libidn-1.31-vanilla/src/idn.c:205 #1 0x7f44d334af9f in __libc_start_main (/lib64/libc.so.6+0x1ff9f) #2 0x401c78 (/mnt/ram/libidn-1.31-vanilla/src/idn+0x401c78) Address 0x7ffefa5df75f is located in stack of thread T0 at offset 671 in frame #0 0x40209a in main /mnt/ram/libidn-1.31-vanilla/src/idn.c:127 This frame has 7 object(s): [32, 40) 'p' [96, 104) 'r' [160, 168) 'q' [224, 232) 'len' [288, 296) 'errpos' [352, 640) 'args_info' [672, 8864) 'readbuf' <== Memory access at offset 671 underflows this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow /mnt/ram/libidn-1.31-vanilla/src/idn.c:205 main Shadow bytes around the buggy address: 0x10005f4b3e90: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 f4 f4 f4 0x10005f4b3ea0: f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2 00 f4 f4 f4 0x10005f4b3eb0: f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2 00 f4 f4 f4 0x10005f4b3ec0: f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 0x10005f4b3ed0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x10005f4b3ee0: 00 00 00 00 00 00 00 00 f2 f2 f2[f2]00 00 00 00 0x10005f4b3ef0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10005f4b3f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10005f4b3f10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10005f4b3f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10005f4b3f30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Contiguous container OOB:fc ASan internal: fe ==24667==ABORTING -- Hanno Böck http://hboeck.de/ mail/jabber: ha...@hboeck.de GPG: BBB51E42
libidn-oob-stack-read-main
Description: Binary data
--- libidn-1.31-vanilla/src/idn.c 2015-07-07 22:59:35.000000000 +0200 +++ libidn-1.31/src/idn.c 2015-07-09 09:47:36.239549144 +0200 @@ -202,8 +202,9 @@ error (EXIT_FAILURE, errno, _("input error")); } - if (readbuf[strlen (readbuf) - 1] == '\n') - readbuf[strlen (readbuf) - 1] = '\0'; + if (strlen (readbuf) > 0) + if (readbuf[strlen (readbuf) - 1] == '\n') + readbuf[strlen (readbuf) - 1] = '\0'; if (args_info.stringprep_given) {
pgpMX2sjY9MTz.pgp
Description: OpenPGP digital signature
_______________________________________________ Help-libidn mailing list Help-libidn@gnu.org https://lists.gnu.org/mailman/listinfo/help-libidn