fix undefined behavior in scanf core
authorRich Felker <dalias@aerifal.cx>
Fri, 17 Apr 2020 17:46:57 +0000 (13:46 -0400)
committerRich Felker <dalias@aerifal.cx>
Fri, 17 Apr 2020 19:19:05 +0000 (15:19 -0400)
as reported/analyzed by Pascal Cuoq, the shlim and shcnt
macros/functions are called by the scanf core (vfscanf) with f->rpos
potentially null (if the FILE is not yet activated for reading at the
time of the call). in this case, they compute differences between a
null pointer (f->rpos) and a non-null one (f->buf), resulting in
undefined behavior.

it's unlikely that any observably wrong behavior occurred in practice,
at least without LTO, due to limits on what's visible to the compiler
from translation unit boundaries, but this has not been checked.

fix is simply ensuring that the FILE is activated for read mode before
entering the main scanf loop, and erroring out early if it can't be.

src/stdio/vfscanf.c

index 9e030fc4441f0854f95eae1cf31ae3687fd71dd6..b5ebc16ea15a457b17e27a626635f66ceb7c9154 100644 (file)
@@ -76,6 +76,9 @@ int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap)
 
        FLOCK(f);
 
+       if (!f->rpos) __toread(f);
+       if (!f->rpos) goto input_fail;
+
        for (p=(const unsigned char *)fmt; *p; p++) {
 
                alloc = 0;