Message ID | ZcIInrbI0w2ZW2HI@tucnak |
---|---|
State | New |
Headers | show |
Series | asan: Don't fold some strlens with -fsanitize=address [PR110676] | expand |
On Tue, 6 Feb 2024, Jakub Jelinek wrote: > Hi! > > The UB on the following testcase isn't diagnosed by -fsanitize=address, > because we see that the array has a single element and optimize the > strlen to 0. I think it is fine to assume e.g. for range purposes the > lower bound for the strlen as long as we don't try to optimize > strlen (str) > where we know that it returns [26, 42] to > 26 + strlen (str + 26), but for the upper bound we really want to punt > on optimizing that for -fsanitize=address to read all the bytes of the > string and diagnose if we run to object end etc. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? OK > 2024-02-06 Jakub Jelinek <jakub@redhat.com> > > PR sanitizer/110676 > * gimple-fold.cc (gimple_fold_builtin_strlen): For -fsanitize=address > reset maxlen to sizetype maximum. > > * gcc.dg/asan/pr110676.c: New test. > > --- gcc/gimple-fold.cc.jj 2024-01-31 12:24:51.714239628 +0100 > +++ gcc/gimple-fold.cc 2024-02-05 21:38:03.829964904 +0100 > @@ -4019,6 +4019,11 @@ gimple_fold_builtin_strlen (gimple_stmt_ > maxlen = wi::to_wide (max_object_size (), prec) - 2; > } > > + /* For -fsanitize=address, don't optimize the upper bound of the > + length to be able to diagnose UB on non-zero terminated arrays. */ > + if (sanitize_flags_p (SANITIZE_ADDRESS)) > + maxlen = wi::max_value (TYPE_PRECISION (sizetype), UNSIGNED); > + > if (minlen == maxlen) > { > /* Fold the strlen call to a constant. */ > --- gcc/testsuite/gcc.dg/asan/pr110676.c.jj 2024-02-05 21:42:43.657104536 +0100 > +++ gcc/testsuite/gcc.dg/asan/pr110676.c 2024-02-05 21:42:39.091167524 +0100 > @@ -0,0 +1,14 @@ > +/* PR sanitizer/110676 */ > +/* { dg-do run } */ > +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ > +/* { dg-shouldfail "asan" } */ > + > +int > +main () > +{ > + char s[1] = "A"; > + return __builtin_strlen (s); > +} > + > +/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow on address.*(\n|\r\n|\r)" } */ > +/* { dg-output "READ of size.*" } */ > > Jakub > >
--- gcc/gimple-fold.cc.jj 2024-01-31 12:24:51.714239628 +0100 +++ gcc/gimple-fold.cc 2024-02-05 21:38:03.829964904 +0100 @@ -4019,6 +4019,11 @@ gimple_fold_builtin_strlen (gimple_stmt_ maxlen = wi::to_wide (max_object_size (), prec) - 2; } + /* For -fsanitize=address, don't optimize the upper bound of the + length to be able to diagnose UB on non-zero terminated arrays. */ + if (sanitize_flags_p (SANITIZE_ADDRESS)) + maxlen = wi::max_value (TYPE_PRECISION (sizetype), UNSIGNED); + if (minlen == maxlen) { /* Fold the strlen call to a constant. */ --- gcc/testsuite/gcc.dg/asan/pr110676.c.jj 2024-02-05 21:42:43.657104536 +0100 +++ gcc/testsuite/gcc.dg/asan/pr110676.c 2024-02-05 21:42:39.091167524 +0100 @@ -0,0 +1,14 @@ +/* PR sanitizer/110676 */ +/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ +/* { dg-shouldfail "asan" } */ + +int +main () +{ + char s[1] = "A"; + return __builtin_strlen (s); +} + +/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow on address.*(\n|\r\n|\r)" } */ +/* { dg-output "READ of size.*" } */