lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAHk-=wjERv03yFU7-RUuqX1y89DYHcpdsuu++ako2nR41-EjYg@mail.gmail.com>
Date: Sun, 12 May 2024 09:09:08 -0700
From: Linus Torvalds <torvalds@...ux-foundation.org>
To: Martin Uecker <uecker@...raz.at>
Cc: Kees Cook <keescook@...omium.org>, Justin Stitt <justinstitt@...gle.com>, 
	Peter Zijlstra <peterz@...radead.org>, Mark Rutland <mark.rutland@....com>, 
	linux-hardening@...r.kernel.org, linux-kernel@...r.kernel.org, 
	llvm@...ts.linux.dev
Subject: Re: [RFC] Mitigating unexpected arithmetic overflow

On Sun, 12 May 2024 at 01:03, Martin Uecker <uecker@...raz.at> wrote:
>
> But I guess it still could be smarter. Or does it have to be a
> sanitizer because compile-time will always have too many false
> positives?

Yes, there will be way too many false positives.

I'm pretty sure there will be a ton of "intentional positives" too,
where we do drop bits, but it's very much intentional. I think
somebody already mentioned the "store little endian" kind of things
where code like

        unsigned chat *p;
        u32 val;

        p[0] = val;
        p[1] = val >> 8;
        p[2] = val >> 16;
        p[3] = val >> 24;

kind of code is both traditional and correct, but obviously drops bits
very much intentionally on each of those assignments.

Now, obviously, in a perfect world the compiler would see the above as
"not really dropping bits", but that's not the world we live in.

So the whole "cast drops bits" is not easy to deal with.

In the case of the above kind of byte-wise behavior, I do think that
we could easily make the byte masking explicit, and so in *some* cases
it might actually be a good thing to just make these things more
explicit, and write it as

        p[0] = val & 0xff;
        p[1] = (val >> 8) & 0xff;
        ...

and the above doesn't make the source code worse: it arguably just
makes things more explicit both for humans and for the compiler, with
that explicit bitwise 'and' operation making it very clear that we're
just picking a particular set of bits out of the value.

But I do suspect the "implicit cast truncates value" is _so_ common
that it might be very very painful. Even with a run-time sanitizer
check.

And statically I think it's entirely a lost cause - it's literally
impossible to avoid in C. Why? Because there are no bitfield
variables, only fields in structures/unions, so if you pass a value
around as an argument, and then end up finally assigning it to a
bitfield, there was literally no way to pass that value around as the
"right type" originally. The final assignment *will* drop bits from a
static compiler standpoint.

                Linus

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ