All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Martin Uecker <uecker@tugraz.at>,
	Justin Stitt <justinstitt@google.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Mark Rutland <mark.rutland@arm.com>,
	linux-hardening@vger.kernel.org, linux-kernel@vger.kernel.org,
	llvm@lists.linux.dev
Subject: Re: [RFC] Mitigating unexpected arithmetic overflow
Date: Mon, 13 May 2024 11:34:20 -0700	[thread overview]
Message-ID: <202405131047.A3861EC13@keescook> (raw)
In-Reply-To: <CAHk-=wjERv03yFU7-RUuqX1y89DYHcpdsuu++ako2nR41-EjYg@mail.gmail.com>

On Sun, May 12, 2024 at 09:09:08AM -0700, Linus Torvalds wrote:
>         unsigned char *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.

The good news here is that the integer implicit truncation sanitizers
are already split between "signed" and "unsigned". So the 2 cases of
exploitable flaws mentioned earlier:

	u8 num_elems;
	...
	num_elems++;		/* int promotion stored back to u8 */

and

	int size;
	u16 read_size;
	...
	read_size = size;	/* large int stored to u16 */

are both confusions across signed/unsigned types, which the signed
sanitizer would catch. The signed sanitizer would entirely ignore
the quoted example at the top: everything is unsigned and no int
promotion is happening.

So, I think we can start with just the "signed integer implicit
truncation" sanitizer. The compiler will still need to deal with the
issues I outlined in [1], where I think we need some consideration
specifically on how to handle things like this (that have a
smaller-than-int size and trip the sanitizer due to int promotion):

u8 checksum(const u8 *buf)
{
	u8 sum = 0;

	for (int i = 0; i < 4; i++)
		sum += buf[i];		/* int promotion */
	return sum;
}

We want "sum" to wrap. We could avoid the "implicit" truncation by
explicitly truncating with something eye-bleedingly horrible like:

		sum = (u8)(sum + buf[i]);

Adding a wrapper for the calculation could work but repeats "sum", and
needs to be explicitly typed, making it just as unfriendly:

		sum = truncate(u8, sum + buf[i]);

Part of the work I'd done in preparation for all this was making the
verbosely named wrapping_assign_add() helper which handles all the
types by examining the arguments and avoids repeating the destination
argument. So this would become:

		wrapping_assign_add(sum, buf[i]);

Still not as clean as "+=", but at least more readable than the
alternatives and leaves no question about wrapping intent.

-Kees

[1] https://lore.kernel.org/lkml/202405081949.0565810E46@keescook/

-- 
Kees Cook

  parent reply	other threads:[~2024-05-13 18:34 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-07 23:27 [RFC] Mitigating unexpected arithmetic overflow Kees Cook
2024-05-08 12:22 ` David Laight
2024-05-08 23:43   ` Kees Cook
2024-05-08 17:52 ` Linus Torvalds
2024-05-08 19:44   ` Kees Cook
2024-05-08 20:07     ` Linus Torvalds
2024-05-08 22:54       ` Kees Cook
2024-05-08 23:47         ` Linus Torvalds
2024-05-09  0:06           ` Linus Torvalds
2024-05-09  0:23           ` Linus Torvalds
2024-05-09  6:11           ` Kees Cook
2024-05-09 14:08             ` Theodore Ts'o
2024-05-09 15:38               ` Linus Torvalds
2024-05-09 17:54                 ` Al Viro
2024-05-09 18:08                   ` Linus Torvalds
2024-05-09 18:39                     ` Linus Torvalds
2024-05-09 18:48                       ` Al Viro
2024-05-09 19:15                         ` Linus Torvalds
2024-05-09 19:28                           ` Al Viro
2024-05-09 21:06                 ` David Laight
2024-05-18  5:11             ` Matthew Wilcox
2024-05-09 21:23           ` David Laight
2024-05-12  8:03           ` Martin Uecker
2024-05-12 16:09             ` Linus Torvalds
2024-05-12 19:29               ` Martin Uecker
2024-05-13 18:34               ` Kees Cook [this message]
2024-05-15  7:36           ` Peter Zijlstra
2024-05-15 17:12             ` Justin Stitt
2024-05-16  7:45               ` Peter Zijlstra
2024-05-16 13:30             ` Kees Cook
2024-05-16 14:09               ` Peter Zijlstra
2024-05-16 19:48                 ` Justin Stitt
2024-05-16 20:07                   ` Kees Cook
2024-05-16 20:51                   ` Theodore Ts'o
2024-05-17 21:15                     ` Kees Cook
2024-05-18  2:51                       ` Theodore Ts'o
2024-05-17 22:04                   ` Fangrui Song
2024-05-18 13:08               ` David Laight
2024-05-15  7:57           ` Peter Zijlstra
2024-05-17  7:45       ` Jonas Oberhauser
2024-05-11 16:19 ` Dan Carpenter
2024-05-13 19:43   ` Kees Cook
2024-05-14  8:45     ` Dan Carpenter
2024-05-18 15:39       ` David Laight

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=202405131047.A3861EC13@keescook \
    --to=keescook@chromium.org \
    --cc=justinstitt@google.com \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=mark.rutland@arm.com \
    --cc=peterz@infradead.org \
    --cc=torvalds@linux-foundation.org \
    --cc=uecker@tugraz.at \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.