mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Rich Felker <dalias@libc.org>
To: Pascal Cuoq <cuoq@trust-in-soft.com>
Cc: "musl@lists.openwall.com" <musl@lists.openwall.com>
Subject: Re: [musl] Invalid pointer subtractions in __shlim and __shgetc
Date: Fri, 17 Apr 2020 12:48:07 -0400	[thread overview]
Message-ID: <20200417164807.GI11469@brightrain.aerifal.cx> (raw)
In-Reply-To: <20200417161351.GH11469@brightrain.aerifal.cx>

[-- Attachment #1: Type: text/plain, Size: 2649 bytes --]

On Fri, Apr 17, 2020 at 12:13:51PM -0400, Rich Felker wrote:
> On Fri, Apr 17, 2020 at 03:56:06PM +0000, Pascal Cuoq wrote:
> > ?Hello,
> > 
> > both functions `__shlim` and `__shgetc` subtract the members
> > named `buf` and `rpos` of the struct they manipulate.
> > 
> > In `__shlim`, this happens in the statement `f->shcnt = f->buf - f->rpos;`.
> > And in `__shgetc`, in happens inside the `shcnt` macro:
> > 
> > #define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf))
> > 
> > In our tests, while running `testsuite` in `libc-testsuite`,
> > both the `__shlim` and `__shgetc` functions are reached
> > with `f->buf` non-null and `f->rpos` a null pointer.
> > 
> > This can be made visible on execution platforms other than ours
> > by adding a statement at the beginning of the functions:
> > 
> > +      if (f->buf && !f->rpos) dprintf (2, "XXX Problem in __shlim\n");
> > +      if (f->buf && !f->rpos) dprintf (2, "XXX Problem in __shgetc\n");
> > 
> > Then if, running `libc-testsuite`, you see the following, it means that
> > `f->buf` was non-null and `f->rpos` was null when these points were
> > reached:
> > 
> > $ ./testsuite
> > fdopen test passed
> > fcntl test passed
> > fnmatch test passed
> > XXX Problem in __shlim
> > XXX Problem in __shgetc
> > XXX Problem in __shlim
> > XXX Problem in __shgetc
> > XXX Problem in __shlim
> > XXX Problem in __shgetc
> > XXX Problem in __shlim
> > XXX Problem in __shgetc
> > XXX Problem in __shlim
> > XXX Problem in __shgetc
> > XXX Problem in __shlim
> > XXX Problem in __shgetc
> > fscanf test passed
> > (...)
> > 
> > This has been tested on the (tag: v1.2.0) branch of git://git.musl-libc.org/musl
> > 
> > These pointer subtractions are undefined behavior. This is slightly worse
> > than computing `(char*)0-(char*)0`, which is undefined in C and defined in C++,
> > because compilers for both C and C++ are unlikely to exploit this one
> > for optimization. Subtracting between a non-null pointer and a null pointer
> > on the other hand is undefined behavior in both languages, and it is
> > plausible that doing it may someday have unexpected consequences.
> > 
> > I mention this because similar undefined behaviors that were extremely
> > unlikely to cause harm have been fixed in musl in recent months,
> > so that this looks like something you may want to fix too.
> 
> Absolutely. Do you have an analysis of how this is reached? Neither of
> these should be called when the FILE is not in suitable state for
> reading. It might just be that vfscanf needs to call __toread on the
> FILE before starting and error out if it fails.

Indeed I think the attached fixes it.

Rich

[-- Attachment #2: shgetc_rpos_usage_fix.diff --]
[-- Type: text/plain, Size: 355 bytes --]

diff --git a/src/stdio/vfscanf.c b/src/stdio/vfscanf.c
index 9e030fc4..d990db9f 100644
--- a/src/stdio/vfscanf.c
+++ b/src/stdio/vfscanf.c
@@ -76,6 +76,8 @@ int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap)
 
 	FLOCK(f);
 
+	if (!f->rpos && __toread(f)) goto input_fail;
+
 	for (p=(const unsigned char *)fmt; *p; p++) {
 
 		alloc = 0;

  reply	other threads:[~2020-04-17 16:48 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-17 15:56 Pascal Cuoq
2020-04-17 16:13 ` Rich Felker
2020-04-17 16:48   ` Rich Felker [this message]
2020-04-17 17:56     ` Rich Felker
2020-04-23 11:34       ` Pascal Cuoq
2020-04-23 16:14         ` Rich Felker
2020-04-24  9:40           ` Pascal Cuoq
2020-04-24 14:12             ` Rich Felker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200417164807.GI11469@brightrain.aerifal.cx \
    --to=dalias@libc.org \
    --cc=cuoq@trust-in-soft.com \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).