Improved Buffer overflow for scanf* functions
Yair Lenga
yair.lenga@gmail.com
Tue Jul 12 07:02:38 GMT 2022
Hi,
I posting into libc-alpha, based on feedback that I got from libc-help
members on proposal to improve buffer checks for scanf* functions.
Short summary - scanf* are a constant source for buffer overflow issues.
There is no good mechanizm to address the very common use case:
char foo[FOOSIZE] ;
scanf("%s", foo) ; // How to limit the actual size
All proposed solution do not scale well - especially when the code base is
large. See few of them below:
* Use explicit width - scanf("%20s", foo) - does not work well for FOOSIZE
changes.
* Use dynamic allocation char *foobuff = NULL ;sscanf ("%ms", &value) ;
strcpy(foo, foobuff, sizeof(foo)-1) ; free(foobuff) ;
* Create dynamic format: char fmt[1000] ; sprintf(fmt, "%%ds", FOOSIZE-1) ;
scanf(fmt, foo) ;
One alternative is to allow "dynamic" width, following the '*' style used
by printf, where width field can be replaced by '*', which indicates the
argument list will contain an integer specifying the width. One unfortunate
issue: the '*' is already assigned a meaning of 'avoid assignment' flag.
The final suggestion that came up from the discussion is:
* Use a special character (my favorite: '@') in the scanf. It will be
allowed in the sequences '%@s', '%@[' and '%@S', etc. TThis should indicate
that the width will be picked from the next integer argument, which is
expected to be the sizeof, or the dynamic size (if malloc was used). The
number of characters will be one less the size, to ensure the string is
always null terminated. The implementation will look like:
sscanf("%@s", sizeof(foo), foo) ; // fixed size string: char
foo[FOOSIZE] ;
My question:
* Would like to get community feedback from the glibc maintainer - is there
a reasonable chance that this will be accepted as a GLIBC extension to
scanf. I understand that this is not a light decision - but considering the
security risks associated with the current state - anything is better than
the current alternative.
As far as implementing, I've reviewed the code for glibc scanf (and a few
other implementations) - looks like a very light effort.Since the '@' is
currently not allowed, it's not going to break any existing code.
Looking for feedback, comments, idea,
Yair
More information about the Libc-alpha
mailing list