[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2024-02-14 Thread i at maskray dot me via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

Fangrui Song  changed:

   What|Removed |Added

 CC||i at maskray dot me

--- Comment #13 from Fangrui Song  ---
I see a Clang patch that proposes -fsanitize=signed-integer-wrap, which appears
to be the same as signed-integer-overflow, but performs the check in the
-fwrapv mode.

I feel that it's better to make -fsanitize=signed-integer-overflow work with
-fwrapv
https://github.com/llvm/llvm-project/pull/80089#issuecomment-1945202620

--- Copying here for folks prefer not to read github

This is a UI discussion about how command line options should behave.
Some folks prefer simpler rules while some prefer smart rules (guessing user
intention).

A
[-fwrapv](https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fwrapv)
user may either:

* rely on the wraparound behavior
* or prevent certain optimizations that would raise security concerns

Our -fsanitize=signed-integer-overflow design have been assuming that -fwrapv
users don't need the check.
This PR suggests that an important user does want overflow checks and our guess
has failed.
It seems very confusing to have two options doing the same thing.

https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html is clear that not
all checks are undefined behavior in the standards.

> Issues caught by this sanitizer are not undefined behavior, but are often 
> unintentional.

Sure -fwrapv makes wraparound defined, but it doesn't prevent us from making
-fsanitize=signed-integer-overflow useful. "-fwrapv => no
signed-integer-overflow" is not a solid argument.

I think we can try making -fsanitize=signed-integer-overflow effective even
when -fwrapv if specified.
-fsanitize=signed-integer-overflow is rare in the wild, probably rarer when
combined with -fwrapv.

There is a precedent that -fsanitize=undefined enables different checks for
different targets.
We could make -fsanitize=undefined not imply -fsanitize=signed-integer-overflow
when -fwrapv is specified, if we do want to guess the user intention.
Personally I'd prefer moving away from such behaviors and be more orthogonal.

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2023-09-07 Thread qinzhao at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

--- Comment #12 from qinzhao at gcc dot gnu.org ---
(In reply to Kees Cook from comment #11)
> The trouble with "optimize" is that it just doesn't work. The kernel has
> banned its use because it results in all other optimization options being
> forgotten for the function in question.

How about Jacub's another suggestion in comment#10:

"If you don't want to use optimize attribute, there is always the option to
just do the arithmetics in unsigned types in the few selected functions where
you don't want the sanitization"?

is it possible to use "unsigned" integer instead of "signed" integer for the
cases you want the "wrap around" behavior when overflow? 

if not, what's the major issue with this workaround?

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2021-09-23 Thread kees at outflux dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

--- Comment #11 from Kees Cook  ---
The trouble with "optimize" is that it just doesn't work. The kernel has banned
its use because it results in all other optimization options being forgotten
for the function in question.

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2021-09-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

--- Comment #10 from Jakub Jelinek  ---
The optimize attribute is how different options are represented in LTO
compilation, so it grew over years from perhaps initial debugging use to
something that is used everywhere.  And we definitely aren't going to add
further and further attributes that match just a small subset of the optimize
and/or target attributes, especially when they'd need to use the same
infrastructure under the hood anyway.
If you don't want to use optimize attribute, there is always the option to just
do the arithmetics in unsigned types in the few selected functions where you
don't want the sanitization, and if you really want use -fwrapv-pointer
together with -fsanitize=integer-signed-overflow and throw away
-fno-strict-overflow.

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2021-09-14 Thread kees at outflux dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

--- Comment #9 from Kees Cook  ---
(In reply to Jakub Jelinek from comment #8)
> So, instead (when building the kernel with sanitization) build with
> -fsanitize=signed-integer-overflow and no -fno-strict-overflow, and
> the routines where you want wrapv behavior and not runtime traps build with
> optimize ("wrapv", "wrapv-pointer") attribute?

__attribute__((optimize)) is documented as not for production use ("for
debugging purposes only"):
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-optimize-function-attribute
and the kernel has hit multiple problems with it. As such, all use has been
removed, for example:
https://lore.kernel.org/lkml/20201027205723.12514-1-a...@kernel.org/
https://lore.kernel.org/lkml/20201028080433.26799-1-a...@kernel.org/
https://lore.kernel.org/lkml/20210118105557.186614-3-adrian.ra...@collabora.com/

If there were an __attribute__((wrapv)) and __attribute__((wrapv-pointer)), we
could create the wrapping helpers with those and
__attribute__((no_sanitize("signed-integer-overflow")))


FWIW, I've been trying to track this issue in the kernel here:
https://github.com/KSPP/linux/issues/26

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2021-09-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

--- Comment #8 from Jakub Jelinek  ---
So, instead (when building the kernel with sanitization) build with
-fsanitize=signed-integer-overflow and no -fno-strict-overflow, and
the routines where you want wrapv behavior and not runtime traps build with
optimize ("wrapv", "wrapv-pointer") attribute?

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2021-09-14 Thread kees at outflux dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

--- Comment #7 from Kees Cook  ---
The problem the kernel needs to solve is basically having our cake and eating
it too. :)

In _most_ situations, we want signed overflows to trap (i.e. get caught by
"-fsanitize=signed-integer-overflow").

In some limited situations, we want to be able to depend on 2s-complement
wrap-around on overflow -- and we would create a helper function to do this
work, marked with __attribute__((no_sanitize("signed-integer-overflow"))). (We
need this most for our atomic_t/refcount_t code, as well as all the open-coded
bounds checks -- see details below.)

For the latter case (wrap-around), the kernel must depend on the effects of
"-fwrapv-pointer" and "-fwrapv" because otherwise some cases end up being
elided due to being classified as undefined behavior.

(In reply to Jakub Jelinek from comment #6)
> That doesn't make sense.  -fsanitize=signed-integer-overflow also removes
> that undefined behavior by defining what happens on signed integer overflow,
> one can choose whether to get a non-fatal runtime diagnostic + wrapv
> behavior, or fatal runtime diagnostic, or just abort.

There doesn't appear to be a way to remove the UB _and_ the diagnostic on a
case-by-case basis.

The matrix of behaviors:

code generation: UB, no UB (2s-complement wrap-around)

diagnostics: no diagnostic, warn or trap

-fno-strict-overflow provides "no UB", and "no diagnostic". ("warn or trap" are
not available.)

-fsanitize=signed-integer-overflow provides "no UB" and "warn or trap". ("no
diagnostic" is not available; using
__attribute__((no_sanitize("signed-integer-overflow"))) also removes "no UB")

So, on a per-function basis, we need to _either_ catch overflow _or_
deterministically perform 2s-complement wrap-around.


If there's a way to achieve this already, I would be very grateful, as I've not
been able to find the correct combination.


Background on the kernel's use of -fno-strict-overflow:
https://git.kernel.org/linus/a137802ee839ace40079bebde24cfb416f73208a
and (earlier) -fwrapv:
https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594

An example of wanting no-UB without diagnostic:
https://git.kernel.org/linus/adb03115f4590baa280ddc440a8eff08a6be0cb7
which ultimately had to be reverted:
https://git.kernel.org/linus/a6211caa634da39d861a47437ffcda8b38ef421b
and all of UBSAN integer overflow support was removed:
https://git.kernel.org/linus/6aaa31aeb9cf260e1b7155cc11ec864f052db5ec

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2021-09-13 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

--- Comment #6 from Jakub Jelinek  ---
That doesn't make sense.  -fsanitize=signed-integer-overflow also removes that
undefined behavior by defining what happens on signed integer overflow, one can
choose whether to get a non-fatal runtime diagnostic + wrapv behavior, or fatal
runtime diagnostic, or just abort.  So, when you use
-fsanitize=signed-integer-overflow, you don't want -fwrapv or
-fno-strict-overflow, unless you want the former to be basically a nop.

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2021-09-13 Thread qing.zhao at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

--- Comment #5 from Qing Zhao  ---
> On Sep 13, 2021, at 4:45 PM, pinskia at gcc dot gnu.org 
>  wrote:
> 
>> is it possible to make -fsanitize=signed-integer-overflow work with -fwrapv?
> 
> Why would it? they conflict.

This is a feature that is requested by Kees Cook for kernel security usage. 

"the kernel builds with -fno-strict-overflow which removes
possible undefined behavior, but I still want the sanitizer to catch
this case.”

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2021-09-13 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

Jakub Jelinek  changed:

   What|Removed |Added

 Resolution|--- |INVALID
 Status|UNCONFIRMED |RESOLVED

--- Comment #4 from Jakub Jelinek  ---
Well, -fwrapv says that signed integer overflow is well defined, therefore
there is nothing for -fsanitize=signed-integer-overflow to diagnose.  It is
like if you've done all the arithmetics that could overflow in unsigned
types...

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2021-09-13 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

--- Comment #3 from Andrew Pinski  ---
(In reply to qinzhao from comment #2)
> (In reply to Andrew Pinski from comment #1)
> > -fno-strict-overflow maps directly to -fwrapv .
> > 
> > If you want to use -fsanitize=signed-integer-overflow, you can just remove
> > both -fno-strict-overflow -fwrapv.  -fwrapv is implied for code later on.
> 
> is it possible to make -fsanitize=signed-integer-overflow work with -fwrapv?

Why would it? they conflict.

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2021-09-13 Thread qinzhao at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

--- Comment #2 from qinzhao at gcc dot gnu.org ---
(In reply to Andrew Pinski from comment #1)
> -fno-strict-overflow maps directly to -fwrapv .
> 
> If you want to use -fsanitize=signed-integer-overflow, you can just remove
> both -fno-strict-overflow -fwrapv.  -fwrapv is implied for code later on.

is it possible to make -fsanitize=signed-integer-overflow work with -fwrapv?

[Bug sanitizer/102317] signed integer overflow sanitizer cannot work well with -fno-strict-overflow

2021-09-13 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102317

--- Comment #1 from Andrew Pinski  ---
-fno-strict-overflow maps directly to -fwrapv .

If you want to use -fsanitize=signed-integer-overflow, you can just remove both
-fno-strict-overflow -fwrapv.  -fwrapv is implied for code later on.