Patchwork libsanitizer merge from upstream r173241

login
register
mail settings
Submitter Jakub Jelinek
Date Feb. 12, 2013, 1:46 p.m.
Message ID <20130212134618.GC4385@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/219858/
State New
Headers show

Comments

Jakub Jelinek - Feb. 12, 2013, 1:46 p.m.
On Tue, Feb 12, 2013 at 05:28:53PM +0400, Evgeniy Stepanov wrote:
> Hey,
> 
> seems like that last of the scanf changes are in.
> We're intercepting __isoc99_*scanf irrespective of the glibc version,
> because (a) it does not hurt (and with the static runtime, even
> interceptor itself is thrown out by the linker), and (b) user program
> and tool's runtime can be built with different libc versions.
> 
> Thanks for the help with scanf testing, we've got much more confidence
> in our implementation now.

Thanks.  Perhaps (completely untested) you could still disallow the GNU
%as/%aS/%a[ compatibility for __isoc99_*, that way you can acurately verify
even
#define _XOPEN_SOURCE 700
...
float flt;
int i;
sscanf ("0.1234[x6]", "%a[x%d]", &flt, &i);



	Jakub
Evgeniy Stepanov - Feb. 12, 2013, 4:01 p.m.
Yes, this looks good. I've added some tests and committed to
compiler-rt. Thanks!

On Tue, Feb 12, 2013 at 5:46 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Tue, Feb 12, 2013 at 05:28:53PM +0400, Evgeniy Stepanov wrote:
>> Hey,
>>
>> seems like that last of the scanf changes are in.
>> We're intercepting __isoc99_*scanf irrespective of the glibc version,
>> because (a) it does not hurt (and with the static runtime, even
>> interceptor itself is thrown out by the linker), and (b) user program
>> and tool's runtime can be built with different libc versions.
>>
>> Thanks for the help with scanf testing, we've got much more confidence
>> in our implementation now.
>
> Thanks.  Perhaps (completely untested) you could still disallow the GNU
> %as/%aS/%a[ compatibility for __isoc99_*, that way you can acurately verify
> even
> #define _XOPEN_SOURCE 700
> ...
> float flt;
> int i;
> sscanf ("0.1234[x6]", "%a[x%d]", &flt, &i);
>
> --- sanitizer_common/sanitizer_common_interceptors.inc.jj       2013-02-12 14:34:06.000000000 +0100
> +++ sanitizer_common/sanitizer_common_interceptors.inc  2013-02-12 14:40:05.486968072 +0100
> @@ -150,7 +150,7 @@ INTERCEPTOR(int, prctl, int option, unsi
>
>  #include "sanitizer_common_interceptors_scanf.inc"
>
> -#define VSCANF_INTERCEPTOR_IMPL(vname, ...)                                    \
> +#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
>    {                                                                            \
>      void *ctx;                                                                 \
>      COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
> @@ -158,29 +158,29 @@ INTERCEPTOR(int, prctl, int option, unsi
>      va_copy(aq, ap);                                                           \
>      int res = REAL(vname)(__VA_ARGS__);                                        \
>      if (res > 0)                                                               \
> -      scanf_common(ctx, res, format, aq);                                      \
> +      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
>      va_end(aq);                                                                \
>      return res;                                                                \
>    }
>
>  INTERCEPTOR(int, vscanf, const char *format, va_list ap)
> -VSCANF_INTERCEPTOR_IMPL(vscanf, format, ap)
> +VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
>
>  INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
> -VSCANF_INTERCEPTOR_IMPL(vsscanf, str, format, ap)
> +VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
>
>  INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
> -VSCANF_INTERCEPTOR_IMPL(vfscanf, stream, format, ap)
> +VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
>
>  INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
> -VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, format, ap)
> +VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
>
>  INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
>              va_list ap)
> -VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, str, format, ap)
> +VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
>
>  INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
> -VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, stream, format, ap)
> +VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
>
>  #define SCANF_INTERCEPTOR_IMPL(name, vname, ...)                               \
>    {                                                                            \
> --- sanitizer_common/sanitizer_common_interceptors_scanf.inc.jj 2013-02-11 16:56:09.000000000 +0100
> +++ sanitizer_common/sanitizer_common_interceptors_scanf.inc    2013-02-12 14:37:46.948784135 +0100
> @@ -39,7 +39,8 @@ static bool char_is_one_of(char c, const
>  // returned in dir. This function returns the pointer to the first
>  // unprocessed character, or 0 in case of error.
>  // In case of the end-of-string, a pointer to the closing \0 is returned.
> -static const char *scanf_parse_next(const char *p, ScanfDirective *dir) {
> +static const char *scanf_parse_next(const char *p, bool allowGnuMalloc,
> +                                   ScanfDirective *dir) {
>    internal_memset(dir, 0, sizeof(*dir));
>    dir->argIdx = -1;
>
> @@ -121,7 +122,8 @@ static const char *scanf_parse_next(cons
>      // This is unfortunately ambiguous between old GNU extension
>      // of %as, %aS and %a[...] and newer POSIX %a followed by
>      // letters s, S or [.
> -    if (dir->convSpecifier == 'a' && !dir->lengthModifier[0]) {
> +    if (dir->convSpecifier == 'a' && !dir->lengthModifier[0]
> +       && allowGnuMalloc) {
>        if (*p == 's' || *p == 'S') {
>          dir->maybeGnuMalloc = true;
>          ++p;
> @@ -271,14 +273,14 @@ static int scanf_get_store_size(ScanfDir
>  // Common part of *scanf interceptors.
>  // Process format string and va_list, and report all store ranges.
>  // Stops when "consuming" n_inputs input items.
> -static void scanf_common(void *ctx, int n_inputs, const char *format,
> -                         va_list aq) {
> +static void scanf_common(void *ctx, int n_inputs, bool allowGnuMalloc,
> +                        const char *format, va_list aq) {
>    CHECK_GT(n_inputs, 0);
>    const char *p = format;
>
>    while (*p && n_inputs) {
>      ScanfDirective dir;
> -    p = scanf_parse_next(p, &dir);
> +    p = scanf_parse_next(p, allowGnuMalloc, &dir);
>      if (!p)
>        break;
>      if (dir.convSpecifier == 0) {
>
>
>         Jakub

Patch

--- sanitizer_common/sanitizer_common_interceptors.inc.jj	2013-02-12 14:34:06.000000000 +0100
+++ sanitizer_common/sanitizer_common_interceptors.inc	2013-02-12 14:40:05.486968072 +0100
@@ -150,7 +150,7 @@  INTERCEPTOR(int, prctl, int option, unsi
 
 #include "sanitizer_common_interceptors_scanf.inc"
 
-#define VSCANF_INTERCEPTOR_IMPL(vname, ...)                                    \
+#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
   {                                                                            \
     void *ctx;                                                                 \
     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
@@ -158,29 +158,29 @@  INTERCEPTOR(int, prctl, int option, unsi
     va_copy(aq, ap);                                                           \
     int res = REAL(vname)(__VA_ARGS__);                                        \
     if (res > 0)                                                               \
-      scanf_common(ctx, res, format, aq);                                      \
+      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
     va_end(aq);                                                                \
     return res;                                                                \
   }
 
 INTERCEPTOR(int, vscanf, const char *format, va_list ap)
-VSCANF_INTERCEPTOR_IMPL(vscanf, format, ap)
+VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
 
 INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
-VSCANF_INTERCEPTOR_IMPL(vsscanf, str, format, ap)
+VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
 
 INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
-VSCANF_INTERCEPTOR_IMPL(vfscanf, stream, format, ap)
+VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
 
 INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
-VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, format, ap)
+VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
 
 INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
             va_list ap)
-VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, str, format, ap)
+VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
 
 INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
-VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, stream, format, ap)
+VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
 
 #define SCANF_INTERCEPTOR_IMPL(name, vname, ...)                               \
   {                                                                            \
--- sanitizer_common/sanitizer_common_interceptors_scanf.inc.jj	2013-02-11 16:56:09.000000000 +0100
+++ sanitizer_common/sanitizer_common_interceptors_scanf.inc	2013-02-12 14:37:46.948784135 +0100
@@ -39,7 +39,8 @@  static bool char_is_one_of(char c, const
 // returned in dir. This function returns the pointer to the first
 // unprocessed character, or 0 in case of error.
 // In case of the end-of-string, a pointer to the closing \0 is returned.
-static const char *scanf_parse_next(const char *p, ScanfDirective *dir) {
+static const char *scanf_parse_next(const char *p, bool allowGnuMalloc,
+				    ScanfDirective *dir) {
   internal_memset(dir, 0, sizeof(*dir));
   dir->argIdx = -1;
 
@@ -121,7 +122,8 @@  static const char *scanf_parse_next(cons
     // This is unfortunately ambiguous between old GNU extension
     // of %as, %aS and %a[...] and newer POSIX %a followed by
     // letters s, S or [.
-    if (dir->convSpecifier == 'a' && !dir->lengthModifier[0]) {
+    if (dir->convSpecifier == 'a' && !dir->lengthModifier[0]
+	&& allowGnuMalloc) {
       if (*p == 's' || *p == 'S') {
         dir->maybeGnuMalloc = true;
         ++p;
@@ -271,14 +273,14 @@  static int scanf_get_store_size(ScanfDir
 // Common part of *scanf interceptors.
 // Process format string and va_list, and report all store ranges.
 // Stops when "consuming" n_inputs input items.
-static void scanf_common(void *ctx, int n_inputs, const char *format,
-                         va_list aq) {
+static void scanf_common(void *ctx, int n_inputs, bool allowGnuMalloc,
+			 const char *format, va_list aq) {
   CHECK_GT(n_inputs, 0);
   const char *p = format;
 
   while (*p && n_inputs) {
     ScanfDirective dir;
-    p = scanf_parse_next(p, &dir);
+    p = scanf_parse_next(p, allowGnuMalloc, &dir);
     if (!p)
       break;
     if (dir.convSpecifier == 0) {