Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect pointer math wrap-around (overflow and underflow) #344

Open
6 tasks
Tracked by #345
kees opened this issue Sep 15, 2023 · 1 comment
Open
6 tasks
Tracked by #345

Detect pointer math wrap-around (overflow and underflow) #344

kees opened this issue Sep 15, 2023 · 1 comment

Comments

@kees
Copy link

kees commented Sep 15, 2023

Much like issue #26 and issue #27, we must mitigate pointer arithmetic wrap-around (overflow/underflow). This should be possible via -fsanitize=pointer-overflow but it has similar problems as the other issues, namely -fwrapv-pointer.

  • make sanitizer work with -fwrapv-pointer (and -fno-strict-overflow)
  • fix sanitizer to work at all on Clang: Sanitizer pointer-overflow does not appear to function llvm/llvm-project#66451
  • create "expected pointer overflow" helper inline functions marked with attribute((no_sanitize("pointer-overflow"))).
  • find all true positives and replace with helper calls.
  • add note to "deprecated.rst" with something like "open coded pointer math wrap around without a helper".
  • add pointer overflow as a UBSan Kconfig
@kees kees changed the title Detect pointer overflow Detect pointer overflows Sep 15, 2023
@kees kees changed the title Detect pointer overflows Detect pointer math wrap-around (overflow and underflow) Sep 25, 2023
@JustinStitt
Copy link
Collaborator

JustinStitt commented Sep 29, 2023

As for bullet point 2: fix sanitizer to work at all on Clang: https://github.com/llvm/llvm-project/issues/66451 it looks like this sanitizer DOES work... just not for void* 😕

demo: https://godbolt.org/z/Ef3Kvqq1x

What's going on here?

Update: I triaged and nikic fixed here: llvm/llvm-project#67772

sirlucjan pushed a commit to CachyOS/linux that referenced this issue Jan 23, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP#26 [2]
Link: KSPP#27 [3]
Link: KSPP#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
sirlucjan pushed a commit to CachyOS/linux that referenced this issue Jan 23, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP#26 [2]
Link: KSPP#27 [3]
Link: KSPP#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
sirlucjan pushed a commit to CachyOS/linux that referenced this issue Jan 23, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP#26 [2]
Link: KSPP#27 [3]
Link: KSPP#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
lseman pushed a commit to CachyOS/linux that referenced this issue Feb 8, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP#26 [2]
Link: KSPP#27 [3]
Link: KSPP#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
ptr1337 pushed a commit to CachyOS/linux that referenced this issue Mar 25, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP#26 [2]
Link: KSPP#27 [3]
Link: KSPP#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
sirlucjan pushed a commit to CachyOS/linux that referenced this issue Mar 27, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP#26 [2]
Link: KSPP#27 [3]
Link: KSPP#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
sirlucjan pushed a commit to CachyOS/linux that referenced this issue Mar 27, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP#26 [2]
Link: KSPP#27 [3]
Link: KSPP#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
sirlucjan pushed a commit to CachyOS/linux that referenced this issue Mar 27, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP#26 [2]
Link: KSPP#27 [3]
Link: KSPP#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
nilz3000 pushed a commit to nilz3000/pf-linux that referenced this issue Apr 10, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP/linux#26 [2]
Link: KSPP/linux#27 [3]
Link: KSPP/linux#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
nilz3000 pushed a commit to nilz3000/pf-linux that referenced this issue Apr 14, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP/linux#26 [2]
Link: KSPP/linux#27 [3]
Link: KSPP/linux#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
ptr1337 pushed a commit to CachyOS/linux that referenced this issue May 13, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP#26 [2]
Link: KSPP#27 [3]
Link: KSPP#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
ptr1337 pushed a commit to CachyOS/linux that referenced this issue May 26, 2024
In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: KSPP#26 [2]
Link: KSPP#27 [3]
Link: KSPP#344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants