Invalid pointer subtractions in __shlim and __shgetc

Submitted by Rich Felker on April 23, 2020, 4:14 p.m.

Details

Message ID 20200423161435.GT11469@brightrain.aerifal.cx
State New
Series "Invalid pointer subtractions in __shlim and __shgetc"
Headers show

Commit Message

Rich Felker April 23, 2020, 4:14 p.m.
On Thu, Apr 23, 2020 at 11:34:26AM +0000, Pascal Cuoq wrote:
> Hello again,
> 
> Rich Felker <dalias@libc.org> wrote:
> > I think this patch may result in wrong error behavior on a trivial
> > scanf that doesn't try to read anything. Instead it should be:
> >
> >        if (!f->rpos) __toread(f);
> >        if (!f->rpos) goto input_fail;
> >
> > so that the error path is taken only on failure to enter read mode,
> > not on EOF.
> 
> This has indeed fixed the invalid comparisons that were observed
> from the tests I mentioned earlier, but a different test still has
> the same problem.
> 
> As of commit 33338eb, the function wcstox does:
>         f.rpos = f.rend = 0;
>         f.buf = buf + 4;
> 
> (https://git.musl-libc.org/cgit/musl/tree/src/stdlib/wcstol.c?id=33338ebc853d37c80f0f236cc7a92cb0acc6aace#n38 )
> 
> It then passes the address of this f to shlim (line 45), causing the
> same invalid pointer subtraction f->buf - f->rpos that has already
> been discussed in this thread.

Thanks. The attached should fix it, I think.

Rich

Patch hide | download patch | download mbox

diff --git a/src/stdlib/wcstod.c b/src/stdlib/wcstod.c
index 26fe9af8..0be8c167 100644
--- a/src/stdlib/wcstod.c
+++ b/src/stdlib/wcstod.c
@@ -33,8 +33,7 @@  static long double wcstox(const wchar_t *s, wchar_t **p, int prec)
 	unsigned char buf[64];
 	FILE f = {0};
 	f.flags = 0;
-	f.rpos = f.rend = 0;
-	f.buf = buf + 4;
+	f.rpos = f.rend = buf + 4;
 	f.buf_size = sizeof buf - 4;
 	f.lock = -1;
 	f.read = do_read;
diff --git a/src/stdlib/wcstol.c b/src/stdlib/wcstol.c
index 4443f577..39a51269 100644
--- a/src/stdlib/wcstol.c
+++ b/src/stdlib/wcstol.c
@@ -35,8 +35,7 @@  static unsigned long long wcstox(const wchar_t *s, wchar_t **p, int base, unsign
 	unsigned char buf[64];
 	FILE f = {0};
 	f.flags = 0;
-	f.rpos = f.rend = 0;
-	f.buf = buf + 4;
+	f.rpos = f.rend = buf + 4;
 	f.buf_size = sizeof buf - 4;
 	f.lock = -1;
 	f.read = do_read;