i3 / i3status

Generates status bar to use with i3bar, dzen2 or xmobar
BSD 3-Clause "New" or "Revised" License
602 stars 254 forks source link

[BUG][FIX] Buffer Overflow caused by long ESSID #525

Closed raefko closed 5 months ago

raefko commented 7 months ago

Buffer Overflow Caused by Long ESSID (>30 chars) and Call to sprintf

Description:

I've encountered a buffer overflow issue in the file output.c. The problem arises when the ESSID length exceeds 30 characters. The code attempts to call sprintf from a buffer of size 32 to a buffer of size 30, which can lead to an overflow if the ESSID is longer than 30 characters.

Steps to reproduce:

  1. Set the ESSID of your network to a string longer than 30 characters.
  2. Run the program.

Expected behavior:

The program should handle ESSIDs of any length without causing a buffer overflow.

Actual behavior:

The program causes a buffer overflow when the ESSID is longer than 30 characters.

==115654==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7efc05d0023e at pc 0x7efc08696fd6 bp 0x7ffc7e17fc60 sp 0x7ffc7e17f3f0
WRITE of size 31 at 0x7efc05d0023e thread T0
    #0 0x7efc08696fd5 in __interceptor_vsnprintf ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1746
    #1 0x7efc0869723e in __interceptor_snprintf ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1817
    #2 0x55d0ae1ffe2e in maybe_escape_markup ../src/output.c:93
    #3 0x55d0ae21ae24 in print_wireless_info ../src/print_wireless_info.c:607
    #4 0x55d0ae1f6c20 in main ../i3status.c:709
    #5 0x7efc08023a8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #6 0x7efc08023b48 in __libc_start_main_impl ../csu/libc-start.c:360
    #7 0x55d0ae1eac94 in _start (/home/raefko/i3status/build/i3status+0x12c94) (BuildId: 672c2796da52236def443eeaefd16a360cbb168f)

Address 0x7efc05d0023e is located in stack of thread T0 at offset 574 in frame
    #0 0x55d0ae218e2a in print_wireless_info ../src/print_wireless_info.c:513

  This frame has 10 object(s):
    [48, 56) 'tmp' (line 604)
    [80, 168) 'info' (line 516)
    [208, 320) 'placeholders' (line 623)
    [352, 382) 'string_quality' (line 569)
    [416, 446) 'string_signal' (line 570)
    [480, 510) 'string_noise' (line 571)
    [544, 574) 'string_essid' (line 572) <== Memory access at offset 574 overflows this variable
    [608, 638) 'string_frequency' (line 573)
    [672, 702) 'string_ip' (line 574)
    [736, 766) 'string_bitrate' (line 575)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1746 in __interceptor_vsnprintf
Shadow bytes around the buggy address:
  0x7efc05cfff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7efc05d00000: f1 f1 f1 f1 f1 f1 00 f2 f2 f2 00 00 00 00 00 00
  0x7efc05d00080: 00 00 00 00 00 f2 f2 f2 f2 f2 00 00 00 00 00 00
  0x7efc05d00100: 00 00 00 00 00 00 00 00 f2 f2 f2 f2 00 00 00 06
  0x7efc05d00180: f2 f2 f2 f2 00 00 00 06 f2 f2 f2 f2 00 00 00 06
=>0x7efc05d00200: f2 f2 f2 f2 00 00 00[06]f2 f2 f2 f2 00 00 00 06
  0x7efc05d00280: f2 f2 f2 f2 00 00 00 06 f2 f2 f2 f2 00 00 00 06
  0x7efc05d00300: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x7efc05d00380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7efc05d00400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7efc05d00480: 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
  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
==115654==ABORTING

Environment:

Ubuntu 23.04 i3status commit : c07b9ca5baee47a85cb745985703080ae8d56fc7

Additional context:

The problematic code is located in https://github.com/i3/i3status/blob/c07b9ca5baee47a85cb745985703080ae8d56fc7/src/output.c#L93

The max essid size is set here

https://github.com/i3/i3status/blob/c07b9ca5baee47a85cb745985703080ae8d56fc7/src/print_wireless_info.c#L18

https://github.com/i3/i3status/blob/c07b9ca5baee47a85cb745985703080ae8d56fc7/src/print_wireless_info.c#L84

But the buffer used in the sprintf function is set and defined here

https://github.com/i3/i3status/blob/c07b9ca5baee47a85cb745985703080ae8d56fc7/src/print_wireless_info.c#L71

https://github.com/i3/i3status/blob/c07b9ca5baee47a85cb745985703080ae8d56fc7/src/print_wireless_info.c#L572

https://github.com/i3/i3status/blob/c07b9ca5baee47a85cb745985703080ae8d56fc7/src/print_wireless_info.c#L604

Fix My fix is to replace sprintf function by snprintf function with STRING_SIZE = 30