emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: building/using address-sanitizer-enabled emacs?


From: Philipp Stephani
Subject: Re: building/using address-sanitizer-enabled emacs?
Date: Wed, 10 May 2017 22:24:49 +0000



Eli Zaretskii <address@hidden> schrieb am Mi., 10. Mai 2017 um 04:43 Uhr:
> From: Philipp Stephani <address@hidden>
> Date: Tue, 09 May 2017 23:15:26 +0000
>
> There's one actual bug: the sockaddr_in in line 3538 of process.c needs to be sockaddr_storage, otherwise
> it's too small for IPv6. (And conv_sockaddr_to_lisp should probably check that the address is of the expected
> length and not blindly overwrite the len argument.)

Please show the detailed analysis, as I looked into that once and
concluded that the code is correct.

The full report is

=================================================================
==31024==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff5fbfa690 at pc 0x0001003e6baf bp 0x7fff5fbfa4f0 sp 0x7fff5fbfa4e8
READ of size 2 at 0x7fff5fbfa690 thread T0
    #0 0x1003e6bae in conv_sockaddr_to_lisp src/process.c:2497:34
    #1 0x1003eb9f8 in connect_network_socket src/process.c:3542:7
    #2 0x1003e9864 in Fmake_network_process src/process.c:4154:5
    #3 0x10035e417 in eval_sub src/eval.c:2191:10
    #4 0x10035f1a7 in Fsetq src/eval.c:511:10
    #5 0x10035dfd1 in eval_sub src/eval.c:2173:8
    #6 0x10035efbf in Fprogn src/eval.c:449:13
    #7 0x10035dfd1 in eval_sub src/eval.c:2173:8
    #8 0x100361df4 in internal_lisp_condition_case src/eval.c:1297:24
    #9 0x100361a85 in Fcondition_case src/eval.c:1221:10
    #10 0x10035dfd1 in eval_sub src/eval.c:2173:8
    #11 0x10035e02f in eval_sub src/eval.c:2208:21
    #12 0x10035ef16 in Fand src/eval.c:384:13
    #13 0x10035dfd1 in eval_sub src/eval.c:2173:8
    #14 0x100360e44 in Fwhile src/eval.c:979:17
    #15 0x10035dfd1 in eval_sub src/eval.c:2173:8
    #16 0x10035efbf in Fprogn src/eval.c:449:13
    #17 0x10035dfd1 in eval_sub src/eval.c:2173:8
    #18 0x100361a28 in Funwind_protect src/eval.c:1185:9
    #19 0x10035dfd1 in eval_sub src/eval.c:2173:8
    #20 0x10035efbf in Fprogn src/eval.c:449:13
    #21 0x100360d2c in Flet src/eval.c:963:9
    #22 0x10035dfd1 in eval_sub src/eval.c:2173:8
    #23 0x10035efbf in Fprogn src/eval.c:449:13
    #24 0x10036766f in funcall_lambda src/eval.c:3015:11
    #25 0x100364efb in Ffuncall src/eval.c:2746:11
    #26 0x1003dd245 in exec_byte_code src/bytecode.c:641:12
    #27 0x1003673de in funcall_lambda src/eval.c:2944:11
    #28 0x100364efb in Ffuncall src/eval.c:2746:11
    #29 0x1003dd245 in exec_byte_code src/bytecode.c:641:12
    #30 0x1003673de in funcall_lambda src/eval.c:2944:11
    #31 0x100364efb in Ffuncall src/eval.c:2746:11
    #32 0x1003dd245 in exec_byte_code src/bytecode.c:641:12
    #33 0x1003673de in funcall_lambda src/eval.c:2944:11
    #34 0x100364efb in Ffuncall src/eval.c:2746:11
    #35 0x1003dd245 in exec_byte_code src/bytecode.c:641:12
    #36 0x1003673de in funcall_lambda src/eval.c:2944:11
    #37 0x100364efb in Ffuncall src/eval.c:2746:11
    #38 0x1003dd245 in exec_byte_code src/bytecode.c:641:12
    #39 0x1003673de in funcall_lambda src/eval.c:2944:11
    #40 0x100364efb in Ffuncall src/eval.c:2746:11
    #41 0x1003dd245 in exec_byte_code src/bytecode.c:641:12
    #42 0x1003673de in funcall_lambda src/eval.c:2944:11
    #43 0x1003643df in apply_lambda src/eval.c:2881:9
    #44 0x10035df97 in eval_sub src/eval.c:2265:12
    #45 0x100363d85 in Feval src/eval.c:2042:28
    #46 0x100366af0 in funcall_subr src/eval.c:2821:19
    #47 0x100364f15 in Ffuncall src/eval.c:2744:11
    #48 0x1003dd245 in exec_byte_code src/bytecode.c:641:12
    #49 0x1003673de in funcall_lambda src/eval.c:2944:11
    #50 0x100364efb in Ffuncall src/eval.c:2746:11
    #51 0x1003dd245 in exec_byte_code src/bytecode.c:641:12
    #52 0x1003673de in funcall_lambda src/eval.c:2944:11
    #53 0x100364efb in Ffuncall src/eval.c:2746:11
    #54 0x1003dd245 in exec_byte_code src/bytecode.c:641:12
    #55 0x1003673de in funcall_lambda src/eval.c:2944:11
    #56 0x1003643df in apply_lambda src/eval.c:2881:9
    #57 0x10035df97 in eval_sub src/eval.c:2265:12
    #58 0x100363d85 in Feval src/eval.c:2042:28
    #59 0x10035e680 in eval_sub src/eval.c:2223:15
    #60 0x1003a6944 in readevalloop src/lread.c:1947:15
    #61 0x1003a410c in Fload src/lread.c:1359:7
    #62 0x10035e917 in eval_sub src/eval.c:2234:15
    #63 0x100363d85 in Feval src/eval.c:2042:28
    #64 0x10026f0b2 in top_level_2 src/keyboard.c:1121:10
    #65 0x1003621f4 in internal_condition_case src/eval.c:1326:25
    #66 0x10026eaa4 in top_level_1 src/keyboard.c:1129:5
    #67 0x100361411 in internal_catch src/eval.c:1091:25
    #68 0x100249135 in command_loop src/keyboard.c:1090:2
    #69 0x100248f21 in recursive_edit_1 src/keyboard.c:697:9
    #70 0x100249480 in Frecursive_edit src/keyboard.c:768:3
    #71 0x1002453a1 in main src/emacs.c:1687:3
    #72 0x7fffae305234 in start (/usr/lib/system/libdyld.dylib:x86_64+0x5234)

Address 0x7fff5fbfa690 is located in stack of thread T0 at offset 336 in frame
    #0 0x1003eabbf in connect_network_socket src/process.c:3307

  This frame has 10 object(s):
    [32, 36) 'xerrno'
    [48, 52) 'family'
    [64, 68) 'optval'
    [80, 96) 'sa1'
    [112, 116) 'len1'
    [128, 132) 'len'
    [144, 272) 'fdset'
    [304, 308) 'rfamily'
    [320, 336) 'sa1261' <== Memory access at offset 336 overflows this variable
    [352, 356) 'len1262'
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 src/process.c:2497:34 in conv_sockaddr_to_lisp
Shadow bytes around the buggy address:
  0x1fffebf7f480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1fffebf7f490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1fffebf7f4a0: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 04 f2 04 f2
  0x1fffebf7f4b0: 04 f2 00 00 f2 f2 04 f2 04 f2 00 00 00 00 00 00
  0x1fffebf7f4c0: 00 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2 04 f2
=>0x1fffebf7f4d0: 00 00[f2]f2 04 f3 f3 f3 00 00 00 00 00 00 00 00
  0x1fffebf7f4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1fffebf7f4f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1fffebf7f500: 00 00 00 00 f1 f1 f1 f1 00 00 05 f2 f2 f2 f2 f2
  0x1fffebf7f510: 04 f2 00 f2 f2 f2 00 00 00 00 00 00 f2 f2 f2 f2
  0x1fffebf7f520: 00 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00 00 f3 f3
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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==31024==ABORTING

The problem is here:

 struct sockaddr_in sa1;
 socklen_t len1 = sizeof (sa1);
 if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0)
   contact = Fplist_put (contact, QClocal,
 conv_sockaddr_to_lisp ((struct sockaddr *)&sa1, len1));

sockaddr_in is too small for IPv6 addresses, so getsockname doesn't fill it out completely. But conv_sockaddr_to_lisp only looks at the address family and attempts to read out the entire IPv6 address, reading past the sa1 variable memory. Thus this needs to be sockaddr_storage, which is guaranteed to be large enough for all supported addresses.
Probably there should also be an eassert(len1 <= sizeof sa1) after the call to getsockname, just to make sure. 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]