public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: Konstantin Serebryany <konstantin.s.serebryany@gmail.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>,
	Dodji Seketeli <dodji@redhat.com>,
	       Dmitry Vyukov <dvyukov@google.com>
Subject: Re: libsanitizer merge from upstream r173241
Date: Wed, 23 Jan 2013 11:14:00 -0000	[thread overview]
Message-ID: <20130123111352.GD7269@tucnak.redhat.com> (raw)
In-Reply-To: <CAGQ9bdxqQ=4A1Yhhhwppp5QsukVO5UzDm7YBcy1U0QJa9MYgDQ@mail.gmail.com>

On Wed, Jan 23, 2013 at 02:31:57PM +0400, Konstantin Serebryany wrote:
> The attached patch is the libsanitizer merge from upstream r173241.
> 
> Lots of changes. Among other things:
>   - slow CFI-based unwinder is on by default for fatal errors
> (fast_unwind_on_fatal=0, Linux-only)
>   - more interceptors in asan/tsan
>   - new asan allocator on Linux (faster and uses less memory than the old one)
>   - Dropped dependency on CoreFoundation (Mac OS)
> 
> Patch for libsanitizer is automatically generated by libsanitizer/merge.sh
> Tested with
> rm -rf */{*/,}libsanitizer \
>   && make -j 50 \
>   && make -C gcc check-g{cc,++}
> RUNTESTFLAGS='--target_board=unix\{-m32,-m64\} asan.exp'
> 
> Our internal LLVM bots (Linux, Mac and Android) are green.
> 
> Ok to commit?

Please mention
	PR sanitizer/55989
in the ChangeLog entry, as this should fix that issue.

If you want to commit now, I'd prefer if you could for now change
# define SANITIZER_INTERCEPT_SCANF SI_NOT_WINDOWS
to
# define SANITIZER_INTERCEPT_SCANF 0
(see comments below).  Ok with those changes.

No changes for the ppc64 address space issue?  Do you think that can be done
say before end of month for yet another merge?  Also, I'd appreciate the
(optional) libtsan shadow mapping change to allow tracing non-PIEs (that
would really be a big usability plus for libtsan).

I think we should stop doing the full libsanitizer merges at the beginning
of February, we can backport strict severe bugfixes then, but otherwise it
should be frozen and ABI stable.

+static void scanf_common(void *ctx, const char *format, va_list ap_const) {
+  va_list aq;
+  va_copy(aq, ap_const);
+
+  const char *p = format;
+  unsigned size;
+
+  while (*p) {
+    if (*p != '%') {
+      ++p;
+      continue;
+    }
+    ++p;
+    if (*p == '*' || *p == '%' || *p == 0) {
+      ++p;
+      continue;
+    }
+    if (*p == '0' || (*p >= '1' && *p <= '9')) {
+      size = internal_atoll(p);
+      // +1 for the \0 at the end
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, va_arg(aq, void *), size + 1);
+      ++p;
+      continue;
+    }
+
+    if (*p == 'L' || *p == 'q') {
+      ++p;
+      size = match_spec(scanf_llspecs, scanf_llspecs_cnt, *p);
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, va_arg(aq, void *), size);
+      continue;
+    }
+
+    if (*p == 'l') {
+      ++p;
+      if (*p == 'l') {
+        ++p;
+        size = match_spec(scanf_llspecs, scanf_llspecs_cnt, *p);
+        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, va_arg(aq, void *), size);
+        continue;
+      } else {
+        size = match_spec(scanf_lspecs, scanf_lspecs_cnt, *p);
+        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, va_arg(aq, void *), size);
+        continue;
+      }
+    }
+
+    if (*p == 'h' && *(p + 1) == 'h') {
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, va_arg(aq, void *), sizeof(char));
+      p += 2;
+      continue;
+    }
+
+    size = match_spec(scanf_specs, scanf_specs_cnt, *p);
+    if (size) {
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, va_arg(aq, void *), size);
+      ++p;
+      continue;
+    }
+  }
+  va_end(aq);
+}

I think this isn't safe.  It should always parse completely the whole %
spec, and whenever it discovers one that it doesn't fully understand, it
should just give up completely, because it has no idea how much it needs to
read from the va_arg.  E.g. it doesn't handle %5$d syntax (generally not a
problem), but it has to give up if it sees it.  So, e.g. whenever match_spec
returns 0, it should break out of the loop, rather than continue.
And for %hh it doesn't check following letters, no match_spec at all.
%[, %s, %c, %n, %ls, %lc, %p, %A and many others aren't handled FYI (again, not
a problem if the implementation is conservative).  Handling %c, %s and
%[0123456789] style would be worthwhile though, I bet most of the buffer
overflows are from the use of those scanf specifiers.

BTW, %as, %aS and %a[ should always result in giving up, as there is an
ambiguity between GNU extensions and C99/POSIX and libasan can't know how
glibc resolves that ambiguity.

What if glibc adds a scanf hook (like it has already printf hooks), apps
could then register their own stuff and the above would then break.  It
really should be very conservative, and should be checked e.g. with all
glibc's *scanf tests (e.g. stdio-common/scanf[0-9]*.c,
stdio-common/tst-sscanf.c).

	Jakub

  parent reply	other threads:[~2013-01-23 11:14 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-23 10:32 Konstantin Serebryany
2013-01-23 10:45 ` Dmitry Vyukov
2013-01-23 11:14 ` Jakub Jelinek [this message]
2013-01-23 11:29   ` Konstantin Serebryany
2013-01-23 12:24     ` Evgeniy Stepanov
2013-01-23 12:39       ` Jakub Jelinek
2013-01-23 12:49         ` Evgeniy Stepanov
2013-01-23 13:52           ` Jakub Jelinek
2013-02-11 11:38       ` Jakub Jelinek
2013-02-11 12:00         ` Evgeniy Stepanov
2013-02-11 12:12           ` Jakub Jelinek
2013-02-11 13:55         ` Jack Howarth
2013-02-12 13:29           ` Evgeniy Stepanov
2013-02-12 13:46             ` Jakub Jelinek
2013-02-12 16:01               ` Evgeniy Stepanov

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=20130123111352.GD7269@tucnak.redhat.com \
    --to=jakub@redhat.com \
    --cc=dodji@redhat.com \
    --cc=dvyukov@google.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=konstantin.s.serebryany@gmail.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.
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 read-only IMAP folder(s) and NNTP newsgroup(s).