Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

_vsnprintf reads past the format parameter value #139

Closed
aptly-io opened this issue Jul 20, 2022 · 6 comments
Closed

_vsnprintf reads past the format parameter value #139

aptly-io opened this issue Jul 20, 2022 · 6 comments

Comments

@aptly-io
Copy link

This code snippet illustrates the issue (the issue does not manifest when using libc's printf):
(it can likely be abused by a hacker for malicious purposes)

/* enable one of these 2 lines to use printf()*/
#include "printf.h"  // enable this and see wrong print
//#include <stdio.h>  // enable this and printf works correctly

#include <unistd.h>

void _putchar(char character) {
    int dummy = write(1, &character, 1);
}

int main(int argc, char *argv[]) {
    return printf("Reads past this string%.\x00\nShould not see this: it's beyond the NUL terminator!%.");
}

Compile like this:

gcc -fsanitize=address -o main main.c printf.c

The output:

./main
Reads past this string
Should not see this: it's beyond the NUL terminator!=================================================================
==71716==ERROR: AddressSanitizer: global-buffer-overflow on address 0x561c9bbae091 at pc 0x561c9bbac9e1 bp 0x7ffe9610e970 sp 0x7ffe9610e960
READ of size 1 at 0x561c9bbae091 thread T0
    #0 0x561c9bbac9e0 in _vsnprintf (/home/francis/dev/git/printf/tst+0x59e0)
    #1 0x561c9bbacbda in printf_ (/home/francis/dev/git/printf/tst+0x5bda)
    #2 0x561c9bba83f8 in main (/home/francis/dev/git/printf/tst+0x13f8)
    #3 0x7f4594eadd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #4 0x7f4594eade3f in __libc_start_main_impl ../csu/libc-start.c:392
    #5 0x561c9bba8204 in _start (/home/francis/dev/git/printf/tst+0x1204)

0x561c9bbae091 is located 0 bytes to the right of global variable '*.LC1' defined in 'main.c' (0x561c9bbae040) of size 81
SUMMARY: AddressSanitizer: global-buffer-overflow (/home/francis/dev/git/printf/tst+0x59e0) in _vsnprintf
Shadow bytes around the buggy address:
  0x0ac41376dbc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac41376dbd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac41376dbe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac41376dbf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac41376dc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0ac41376dc10: 00 00[01]f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
  0x0ac41376dc20: 00 00 00 00 04 f9 f9 f9 f9 f9 f9 f9 05 f9 f9 f9
  0x0ac41376dc30: f9 f9 f9 f9 05 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
  0x0ac41376dc40: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac41376dc50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac41376dc60: 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
  Shadow gap:              cc
==71716==ABORTING

@eyalroz
Copy link

eyalroz commented Jul 20, 2022

@aptly-io : This library is unmaintained and has a large number of unresolved bugs. The maintained for is mine. Could you please test with my fork to see whether you see the bug there as well?

@ledvinap
Copy link

Fixing this needs sanitizing width/precision parsing, adding code that is used only in malformed program.
Passing invalid format string is probably in 'undefined behavior' category, so it may be better to ignore it.
There are tons of other things you can do with malformed format string that can't be sanitized (%n etc.)

@aptly-io
Copy link
Author

aptly-io commented Jul 20, 2022

@ledvinap I agree with you all input needs to be sanitized by the caller of printf().
I dont agree with leaving security holes. If %. cannot be supported correctly, it is better to remove it from this code base.
@eyalroz I see it also in that fork. I will make an issue there as well.
Thanks all for looking into it.

@ledvinap
Copy link

It's not '%.'. '%\0' will behave the same, putting '\0' into output stream and continuing format expansion.

Special-casing '\0' in format character switch is possible, but see above.

@aptly-io
Copy link
Author

aptly-io commented Jul 20, 2022

@ledvinap I will try that case as well. Thanks! It also fails in the fork.

eyalroz added a commit to eyalroz/printf that referenced this issue Jul 20, 2022
…hen a format specifier does not end before the string does.
@eyalroz
Copy link

eyalroz commented Jul 20, 2022

So, this is not a bug, as incomplete format specifier at string end cause undefined behavior. I am considering an opt-in "sanitization" via a CMake option - please have a look at eyalroz#140. But - this issue needs to be closed. @aptly-io : Please close this...

eyalroz added a commit to eyalroz/printf that referenced this issue Jul 20, 2022
…hen a format specifier does not end before the string does.
eyalroz added a commit to eyalroz/printf that referenced this issue Jul 22, 2022
…hen a format specifier does not end before the string does.
eyalroz added a commit to eyalroz/printf that referenced this issue Aug 19, 2022
…hen a format specifier does not end before the string does.
eyalroz added a commit to eyalroz/printf that referenced this issue Aug 19, 2022
…hen a format specifier does not end before the string does.
eyalroz added a commit to eyalroz/printf that referenced this issue Aug 19, 2022
…hen a format specifier does not end before the string does.
eyalroz added a commit to eyalroz/printf that referenced this issue Aug 21, 2022
…hen a format specifier does not end before the string does.
eyalroz added a commit to eyalroz/printf that referenced this issue Oct 17, 2022
…hen a format specifier does not end before the string does.
HEYAHONG pushed a commit to HEYAHONG/printf that referenced this issue Jan 1, 2024
…option of Craig Scott's `FetchContent`-friendliness approach
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants