* Re: [PATCH 5/5] types: Add standard __ob_trap and __ob_wrap scalar types
From: Kees Cook @ 2026-03-31 18:32 UTC (permalink / raw)
To: Linus Torvalds
Cc: Miguel Ojeda, Peter Zijlstra, Justin Stitt, Miguel Ojeda,
Nathan Chancellor, Andrew Morton, Andy Shevchenko, Arnd Bergmann,
Mark Rutland, Matthew Wilcox (Oracle), Suren Baghdasaryan,
Thomas Gleixner, Finn Thain, Geert Uytterhoeven,
Thomas Weißschuh, llvm, Marco Elver, Jonathan Corbet,
Nicolas Schier, Greg Kroah-Hartman, linux-kernel, kasan-dev,
linux-hardening, linux-doc, linux-kbuild
In-Reply-To: <CAHk-=whjwHjmB0_2yXsOjDa7Mi_yFSx3AMd3vGk5r70WocvZZg@mail.gmail.com>
On Tue, Mar 31, 2026 at 11:02:03AM -0700, Linus Torvalds wrote:
> On Tue, 31 Mar 2026 at 10:48, Miguel Ojeda
> <miguel.ojeda.sandonis@gmail.com> wrote:
> >
> > In the Rust side, even if those "explicit" types like the
> > `wrapping_u32` you suggest exist, we generally use the methods on the
> > normal integers instead, e.g.
>
> In that case the types in question should always be very much opaque,
> and not usable as-is by existing compilers that don't have attributes.
>
> My feeling is that that will discourage use enormously for when people
> want to just say "yes, I know this wraps, and it's ok".
>
> That said, for the *trapping* types, I do think that we likely need an
> opaque type, because I really feel like using
>
> trapping_u32 x;
> ...
> x++;
>
> is a complete and utter mis-design. It makes the "x++' have random behavior that
>
> (a) cannot be recovered from (maybe we're holding random locks)
>
> (b) is completely invisible in the context of the code, because the
> type may be somewhere very different
>
> and I think both of those are fundamental design mistakes.
This design is specifically what Peter was requesting, and what actually
integrates with C. I agree with you that the core problem is "cannot be
recovered from", but that misses the point of these types. The point is
that all of their uses are _supposed_ to have been written in a way that
no overflow is possible (just like all the other types). But this is
the problem: bugs keep happening, no matter what people try to do. And
in fact, to support these kinds of in-code overflow checking, there are
even idiom exclusions for these types (based on what you pointed out in
the original RFC) to allow for things like:
if (var + offset < var) { ... }
If the code was written perfectly, then there's no problem. If there was
a bug that allows for overflow then you get a crash instead of totally
insane behavior that is almost always exploitable in a way that the
system gets compromised. That is a net benefit, even if crashes are
still bad.
The point is to make a type that still works with C and all the associated
APIs (e.g. format strings, native arithmetic, etc) without creating the
mess that Jakub, Peter, and others (correctly) balked at around accessors
for doing function based math.
> So I think wrapping and trapping are fundamentally very different. The
> words may look the same. The semantics may often be discussed
> together. But one is explicitly marking something as "overflow is safe
> and expected", and that's the actual real SAFE case.
Right. Mixing the term "safe" between these is certainly a mistake in
the documentation. We can fix all of that.
> The other is saying "overflow needs special handling". And the key
> here is that we need to have some way to *state* what said special
> handling is, and we need to do it at the point where that special
> handling is needed. Not some generic exception handler that has to
> figure things out from some unknown context.
The generic exception handler, right now, is the distant back-stop to
catch exceptional cases that nothing else was written to catch. Like
uncorrectable RAM errors. Using a trapping type isn't there for people
to _intend_ to crash the system. :)
But, yes, I agree that having a way to require in-place overflow
management would be the perfect solution, but no one seems to be able to
agree on it. The trouble with C arithmetic is that the overflow state is
"hidden". It's like the remainder from division: math statements need an
overflow case built in, almost like a ?:, but from a syntax perspective,
there's not been anything that stuck. The state of the art in C is
"make sure you test for overflow manually first", and these types allow
for that.
-Kees
--
Kees Cook
^ permalink raw reply
* Re: [PATCH 5/5] types: Add standard __ob_trap and __ob_wrap scalar types
From: Kees Cook @ 2026-03-31 18:16 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Linus Torvalds, Peter Zijlstra, Justin Stitt, Miguel Ojeda,
Nathan Chancellor, Andrew Morton, Andy Shevchenko, Arnd Bergmann,
Mark Rutland, Matthew Wilcox (Oracle), Suren Baghdasaryan,
Thomas Gleixner, Finn Thain, Geert Uytterhoeven,
Thomas Weißschuh, llvm, Marco Elver, Jonathan Corbet,
Nicolas Schier, Greg Kroah-Hartman, linux-kernel, kasan-dev,
linux-hardening, linux-doc, linux-kbuild
In-Reply-To: <CANiq72kL3rTKyDNYmD7wXiKCVJSfa1bnp2L8NShXU7OPmWjJ4w@mail.gmail.com>
On Tue, Mar 31, 2026 at 07:47:44PM +0200, Miguel Ojeda wrote:
> In the Rust side, even if those "explicit" types like the
> `wrapping_u32` you suggest exist, we generally use the methods on the
> normal integers instead, e.g.
>
> i.wrapping_add(1)
>
> micros.saturating_mul(NSEC_PER_USEC)
>
> self.index.checked_mul(page::PAGE_SIZE)?
>
> etc.
>
> The advantage is precisely that it is more explicit and avoids
> confusing the operators when copy-pasting code and so on.
>
> So that could perhaps be an option? Kees et al. have been thinking
> about this for a long time as far as I recall.
I went through 7 revisions of creating helpers/accessors[1] (and
function-level annotations) and it ultimately went unused. From memory,
this was specifically from Jakub Kicinski (found breaking up readable
math statements into a series of helpers too bulky), Peter Zijlstra and
Mark Rutland (wanted strictly type-based system)[2].
Link: https://lore.kernel.org/lkml/?q=%22overflow%3A+Introduce+wrapping+helpers%22 [1]
Link: https://lore.kernel.org/lkml/20240424191740.3088894-4-keescook@chromium.org/ [2]
I view accessors as a non-starter given the near universal pushback
against them in C.
--
Kees Cook
^ permalink raw reply
* Re: [PATCH 5/5] types: Add standard __ob_trap and __ob_wrap scalar types
From: Linus Torvalds @ 2026-03-31 18:02 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Kees Cook, Peter Zijlstra, Justin Stitt, Miguel Ojeda,
Nathan Chancellor, Andrew Morton, Andy Shevchenko, Arnd Bergmann,
Mark Rutland, Matthew Wilcox (Oracle), Suren Baghdasaryan,
Thomas Gleixner, Finn Thain, Geert Uytterhoeven,
Thomas Weißschuh, llvm, Marco Elver, Jonathan Corbet,
Nicolas Schier, Greg Kroah-Hartman, linux-kernel, kasan-dev,
linux-hardening, linux-doc, linux-kbuild
In-Reply-To: <CANiq72kL3rTKyDNYmD7wXiKCVJSfa1bnp2L8NShXU7OPmWjJ4w@mail.gmail.com>
On Tue, 31 Mar 2026 at 10:48, Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> In the Rust side, even if those "explicit" types like the
> `wrapping_u32` you suggest exist, we generally use the methods on the
> normal integers instead, e.g.
In that case the types in question should always be very much opaque,
and not usable as-is by existing compilers that don't have attributes.
My feeling is that that will discourage use enormously for when people
want to just say "yes, I know this wraps, and it's ok".
That said, for the *trapping* types, I do think that we likely need an
opaque type, because I really feel like using
trapping_u32 x;
...
x++;
is a complete and utter mis-design. It makes the "x++' have random behavior that
(a) cannot be recovered from (maybe we're holding random locks)
(b) is completely invisible in the context of the code, because the
type may be somewhere very different
and I think both of those are fundamental design mistakes.
And no, "dead machine" is *still* not an acceptable form of "that's
not random behavior".
So I think wrapping and trapping are fundamentally very different. The
words may look the same. The semantics may often be discussed
together. But one is explicitly marking something as "overflow is safe
and expected", and that's the actual real SAFE case.
The other is saying "overflow needs special handling". And the key
here is that we need to have some way to *state* what said special
handling is, and we need to do it at the point where that special
handling is needed. Not some generic exception handler that has to
figure things out from some unknown context.
Very very different things, and they need very very different
interfaces and very very different infrastructure.
Anything that says "these are two faces of the same coin and are just
different attributes on the type" is simply broken by design.
Linus
^ permalink raw reply
* Re: [PATCH v8 04/10] x86/vmscape: Rename x86_ibpb_exit_to_user to x86_predictor_flush_exit_to_user
From: Sean Christopherson @ 2026-03-31 17:50 UTC (permalink / raw)
To: Pawan Gupta
Cc: x86, Jon Kohler, Nikolay Borisov, H. Peter Anvin, Josh Poimboeuf,
David Kaplan, Borislav Petkov, Dave Hansen, Peter Zijlstra,
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, KP Singh,
Jiri Olsa, David S. Miller, David Laight, Andy Lutomirski,
Thomas Gleixner, Ingo Molnar, David Ahern, Martin KaFai Lau,
Eduard Zingerman, Song Liu, Yonghong Song, John Fastabend,
Stanislav Fomichev, Hao Luo, Paolo Bonzini, Jonathan Corbet,
linux-kernel, kvm, Asit Mallick, Tao Zhang, bpf, netdev,
linux-doc
In-Reply-To: <20260324-vmscape-bhb-v8-4-68bb524b3ab9@linux.intel.com>
On Tue, Mar 24, 2026, Pawan Gupta wrote:
> With the upcoming changes x86_ibpb_exit_to_user will also be used when BHB
> clearing sequence is used. Rename it cover both the cases.
>
> No functional change.
>
> Suggested-by: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
> ---
Acked-by: Sean Christopherson <seanjc@google.com>
^ permalink raw reply
* Re: [PATCH 5/5] types: Add standard __ob_trap and __ob_wrap scalar types
From: Miguel Ojeda @ 2026-03-31 17:47 UTC (permalink / raw)
To: Linus Torvalds
Cc: Kees Cook, Peter Zijlstra, Justin Stitt, Miguel Ojeda,
Nathan Chancellor, Andrew Morton, Andy Shevchenko, Arnd Bergmann,
Mark Rutland, Matthew Wilcox (Oracle), Suren Baghdasaryan,
Thomas Gleixner, Finn Thain, Geert Uytterhoeven,
Thomas Weißschuh, llvm, Marco Elver, Jonathan Corbet,
Nicolas Schier, Greg Kroah-Hartman, linux-kernel, kasan-dev,
linux-hardening, linux-doc, linux-kbuild
In-Reply-To: <CAHk-=wiJ6Q_qMHSe-hs+QvqKVZphvDZjvFP_gQLw1eaWimv8+w@mail.gmail.com>
On Tue, Mar 31, 2026 at 7:11 PM Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> No stupid one-character things. If we go down this path it would need
> to be "wrapping_u32" or whatever.
That sounds close to similar types provided by Rust, i.e. if something
like these types are used, then it would be nice to match names if
possible (assuming they are similar enough, i.e. no surprises).
e.g. with generics they do `Wrapping<u32>` or, in other cases, without
generics they name them something like e.g. `NonZeroU32`.
Having said that...
> This needs to look _very_different_.
I think there is an actual risk of someone e.g. copying an expression
from one place to another, with the operators behaving differently,
yeah.
In the Rust side, even if those "explicit" types like the
`wrapping_u32` you suggest exist, we generally use the methods on the
normal integers instead, e.g.
i.wrapping_add(1)
micros.saturating_mul(NSEC_PER_USEC)
self.index.checked_mul(page::PAGE_SIZE)?
etc.
The advantage is precisely that it is more explicit and avoids
confusing the operators when copy-pasting code and so on.
So that could perhaps be an option? Kees et al. have been thinking
about this for a long time as far as I recall.
[ And for the usual operators on integer primitives, we panic by
default (configurable via Kconfig), but at least that applies to all
Rust code, which is all new, and kernel developers get accustomed to
think about what they actually want for a particular operation and
whether they need one of the explicit behaviors above, so it has been
good so far, but it remains to be seen what happens when we have way
more code around etc. It does mean someone copying a simple math
expression from C to Rust could forget about it, though... ]
Cheers,
Miguel
^ permalink raw reply
* Re: [PATCH v3 02/24] PCI: Add API to track PCI devices preserved across Live Update
From: Samiullah Khawaja @ 2026-03-31 17:33 UTC (permalink / raw)
To: David Matlack
Cc: Alex Williamson, Bjorn Helgaas, Adithya Jayachandran,
Alexander Graf, Alex Mastro, Andrew Morton, Ankit Agrawal,
Arnd Bergmann, Askar Safin, Borislav Petkov (AMD), Chris Li,
Dapeng Mi, David Rientjes, Feng Tang, Jacob Pan, Jason Gunthorpe,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Kees Cook,
Kevin Tian, kexec, kvm, Leon Romanovsky, Leon Romanovsky,
linux-doc, linux-kernel, linux-kselftest, linux-mm, linux-pci,
Li RongQing, Lukas Wunner, Marco Elver, Michał Winiarski,
Mike Rapoport, Parav Pandit, Pasha Tatashin, Paul E. McKenney,
Pawan Gupta, Peter Zijlstra (Intel), Pranjal Shrivastava,
Pratyush Yadav, Raghavendra Rao Ananta, Randy Dunlap,
Rodrigo Vivi, Saeed Mahameed, Shuah Khan, Vipin Sharma,
Vivek Kasireddy, William Tu, Yi Liu, Zhu Yanjun
In-Reply-To: <20260323235817.1960573-3-dmatlack@google.com>
On Mon, Mar 23, 2026 at 11:57:54PM +0000, David Matlack wrote:
>Add an API to enable the PCI subsystem to participate in a Live Update
>and track all devices that are being preserved by drivers. Since this
>support is still under development, hide it behind a new Kconfig
>PCI_LIVEUPDATE that is marked experimental.
>
>This API will be used in subsequent commits by the vfio-pci driver to
>preserve VFIO devices across Live Update.
>
>Signed-off-by: David Matlack <dmatlack@google.com>
>---
> drivers/pci/Kconfig | 11 ++
> drivers/pci/Makefile | 1 +
> drivers/pci/liveupdate.c | 380 ++++++++++++++++++++++++++++++++++++
> drivers/pci/pci.h | 14 ++
> drivers/pci/probe.c | 2 +
> include/linux/kho/abi/pci.h | 62 ++++++
> include/linux/pci.h | 41 ++++
> 7 files changed, 511 insertions(+)
> create mode 100644 drivers/pci/liveupdate.c
> create mode 100644 include/linux/kho/abi/pci.h
>
>diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
>index e3f848ffb52a..05307d89c3f4 100644
>--- a/drivers/pci/Kconfig
>+++ b/drivers/pci/Kconfig
>@@ -334,6 +334,17 @@ config VGA_ARB_MAX_GPUS
> Reserves space in the kernel to maintain resource locking for
> multiple GPUS. The overhead for each GPU is very small.
>
>+config PCI_LIVEUPDATE
>+ bool "PCI Live Update Support (EXPERIMENTAL)"
>+ depends on PCI && LIVEUPDATE
>+ help
>+ Support for preserving PCI devices across a Live Update. This option
>+ should only be enabled by developers working on implementing this
>+ support. Once enough support as landed in the kernel, this option
>+ will no longer be marked EXPERIMENTAL.
>+
>+ If unsure, say N.
>+
> source "drivers/pci/hotplug/Kconfig"
> source "drivers/pci/controller/Kconfig"
> source "drivers/pci/endpoint/Kconfig"
>diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
>index 41ebc3b9a518..e8d003cb6757 100644
>--- a/drivers/pci/Makefile
>+++ b/drivers/pci/Makefile
>@@ -16,6 +16,7 @@ obj-$(CONFIG_PROC_FS) += proc.o
> obj-$(CONFIG_SYSFS) += pci-sysfs.o slot.o
> obj-$(CONFIG_ACPI) += pci-acpi.o
> obj-$(CONFIG_GENERIC_PCI_IOMAP) += iomap.o
>+obj-$(CONFIG_PCI_LIVEUPDATE) += liveupdate.o
> endif
>
> obj-$(CONFIG_OF) += of.o
>diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
>new file mode 100644
>index 000000000000..bec7b3500057
>--- /dev/null
>+++ b/drivers/pci/liveupdate.c
>@@ -0,0 +1,380 @@
>+// SPDX-License-Identifier: GPL-2.0
>+
>+/*
>+ * Copyright (c) 2026, Google LLC.
>+ * David Matlack <dmatlack@google.com>
>+ */
>+
>+/**
>+ * DOC: PCI Live Update
>+ *
>+ * The PCI subsystem participates in the Live Update process to enable drivers
>+ * to preserve their PCI devices across kexec.
>+ *
>+ * Device preservation across Live Update is built on top of the Live Update
>+ * Orchestrator (LUO) support for file preservation across kexec. Userspace
>+ * indicates that a device should be preserved by preserving the file associated
>+ * with the device with ``ioctl(LIVEUPDATE_SESSION_PRESERVE_FD)``.
>+ *
>+ * .. note::
>+ * The support for preserving PCI devices across Live Update is currently
>+ * *partial* and should be considered *experimental*. It should only be
>+ * used by developers working on the implementation for the time being.
>+ *
>+ * To enable the support, enable ``CONFIG_PCI_LIVEUPDATE``.
>+ *
>+ * Driver API
>+ * ==========
>+ *
>+ * Drivers that support file-based device preservation must register their
>+ * ``liveupdate_file_handler`` with the PCI subsystem by calling
>+ * ``pci_liveupdate_register_flb()``. This ensures the PCI subsystem will be
>+ * notified whenever a device file is preserved so that ``struct pci_ser``
>+ * can be allocated to track all preserved devices. This struct is an ABI
>+ * and is eventually handed off to the next kernel via Kexec-Handover (KHO).
>+ *
>+ * In the "outgoing" kernel (before kexec), drivers should then notify the PCI
>+ * subsystem directly whenever the preservation status for a device changes:
>+ *
>+ * * ``pci_liveupdate_preserve(pci_dev)``: The device is being preserved.
>+ *
>+ * * ``pci_liveupdate_unpreserve(pci_dev)``: The device is no longer being
>+ * preserved (preservation is cancelled).
>+ *
>+ * In the "incoming" kernel (after kexec), drivers should notify the PCI
>+ * subsystem with the following calls:
>+ *
>+ * * ``pci_liveupdate_retrieve(pci_dev)``: The device file is being retrieved
>+ * by userspace.
>+ *
>+ * * ``pci_liveupdate_finish(pci_dev)``: The device is done participating in
>+ * Live Update. After this point the device may no longer be even associated
>+ * with the same driver.
>+ *
>+ * Incoming/Outgoing
>+ * =================
>+ *
>+ * The state of each device's participation in Live Update is stored in
>+ * ``struct pci_dev``:
>+ *
>+ * * ``liveupdate_outgoing``: True if the device is being preserved in the
>+ * outgoing kernel. Set in ``pci_liveupdate_preserve()`` and cleared in
>+ * ``pci_liveupdate_unpreserve()``.
>+ *
>+ * * ``liveupdate_incoming``: True if the device is preserved in the incoming
>+ * kernel. Set during probing when the device is first created and cleared
>+ * in ``pci_liveupdate_finish()``.
>+ *
>+ * Restrictions
>+ * ============
>+ *
>+ * Preserved devices currently have the following restrictions. Each of these
>+ * may be relaxed in the future.
>+ *
>+ * * The device must not be a Virtual Function (VF).
>+ *
>+ * * The device must not be a Physical Function (PF).
>+ *
>+ * Preservation Behavior
>+ * =====================
>+ *
>+ * The kernel preserves the following state for devices preserved across a Live
>+ * Update:
>+ *
>+ * * The PCI Segment, Bus, Device, and Function numbers assigned to the device
>+ * are guaranteed to remain the same across Live Update.
>+ *
>+ * This list will be extended in the future as new support is added.
>+ *
>+ * Driver Binding
>+ * ==============
>+ *
>+ * It is the driver's responsibility for ensuring that preserved devices are not
>+ * released or bound to a different driver for as long as they are preserved. In
>+ * practice, this is enforced by LUO taking an extra referenced to the preserved
>+ * device file for as long as it is preserved.
>+ *
>+ * However, there is a window of time in the incoming kernel when a device is
>+ * first probed and when userspace retrieves the device file with
>+ * ``LIVEUPDATE_SESSION_RETRIEVE_FD`` when the device could be bound to any
>+ * driver.
>+ *
>+ * It is currently userspace's responsibility to ensure that the device is bound
>+ * to the correct driver in this window.
>+ */
>+
>+#include <linux/bsearch.h>
>+#include <linux/io.h>
>+#include <linux/kexec_handover.h>
>+#include <linux/kho/abi/pci.h>
>+#include <linux/liveupdate.h>
>+#include <linux/mutex.h>
>+#include <linux/mm.h>
>+#include <linux/pci.h>
>+#include <linux/sort.h>
>+
>+#include "pci.h"
>+
>+static DEFINE_MUTEX(pci_flb_outgoing_lock);
>+
>+static int pci_flb_preserve(struct liveupdate_flb_op_args *args)
>+{
>+ struct pci_dev *dev = NULL;
>+ int max_nr_devices = 0;
>+ struct pci_ser *ser;
>+ unsigned long size;
>+
>+ /*
>+ * Don't both accounting for VFs that could be created after this
>+ * since preserving VFs is not supported yet. Also don't account
>+ * for devices that could be hot-plugged after this since preserving
>+ * hot-plugged devices across Live Update is not yet an expected
>+ * use-case.
>+ */
>+ for_each_pci_dev(dev)
>+ max_nr_devices++;
>+
>+ size = struct_size_t(struct pci_ser, devices, max_nr_devices);
>+
>+ ser = kho_alloc_preserve(size);
>+ if (IS_ERR(ser))
>+ return PTR_ERR(ser);
>+
>+ ser->max_nr_devices = max_nr_devices;
>+
>+ args->obj = ser;
>+ args->data = virt_to_phys(ser);
>+ return 0;
>+}
>+
>+static void pci_flb_unpreserve(struct liveupdate_flb_op_args *args)
>+{
>+ struct pci_ser *ser = args->obj;
>+
>+ WARN_ON_ONCE(ser->nr_devices);
>+ kho_unpreserve_free(ser);
>+}
>+
>+static int pci_flb_retrieve(struct liveupdate_flb_op_args *args)
>+{
>+ args->obj = phys_to_virt(args->data);
>+ return 0;
>+}
>+
>+static void pci_flb_finish(struct liveupdate_flb_op_args *args)
>+{
>+ kho_restore_free(args->obj);
>+}
>+
>+static struct liveupdate_flb_ops pci_liveupdate_flb_ops = {
>+ .preserve = pci_flb_preserve,
>+ .unpreserve = pci_flb_unpreserve,
>+ .retrieve = pci_flb_retrieve,
>+ .finish = pci_flb_finish,
>+ .owner = THIS_MODULE,
>+};
>+
>+static struct liveupdate_flb pci_liveupdate_flb = {
>+ .ops = &pci_liveupdate_flb_ops,
>+ .compatible = PCI_LUO_FLB_COMPATIBLE,
>+};
>+
>+#define INIT_PCI_DEV_SER(_dev) { \
>+ .domain = pci_domain_nr((_dev)->bus), \
>+ .bdf = pci_dev_id(_dev), \
>+}
>+
>+static int pci_dev_ser_cmp(const void *__a, const void *__b)
>+{
>+ const struct pci_dev_ser *a = __a, *b = __b;
>+
>+ return cmp_int((u64)a->domain << 16 | a->bdf,
>+ (u64)b->domain << 16 | b->bdf);
>+}
>+
>+static struct pci_dev_ser *pci_ser_find(struct pci_ser *ser,
>+ struct pci_dev *dev)
>+{
>+ const struct pci_dev_ser key = INIT_PCI_DEV_SER(dev);
>+
>+ return bsearch(&key, ser->devices, ser->nr_devices,
>+ sizeof(key), pci_dev_ser_cmp);
>+}
>+
>+static void pci_ser_delete(struct pci_ser *ser, struct pci_dev *dev)
>+{
>+ struct pci_dev_ser *dev_ser;
>+ int i;
>+
>+ dev_ser = pci_ser_find(ser, dev);
>+
>+ /*
>+ * This should never happen unless there is a kernel bug or
>+ * corruption that causes the state in struct pci_ser to get
>+ * out of sync with struct pci_dev.
>+ */
>+ if (pci_WARN_ONCE(dev, !dev_ser, "Cannot find preserved device!"))
>+ return;
>+
>+ for (i = dev_ser - ser->devices; i < ser->nr_devices - 1; i++)
>+ ser->devices[i] = ser->devices[i + 1];
>+
>+ ser->nr_devices--;
>+}
>+
>+int pci_liveupdate_preserve(struct pci_dev *dev)
>+{
>+ struct pci_dev_ser new = INIT_PCI_DEV_SER(dev);
>+ struct pci_ser *ser;
>+ int i, ret;
>+
>+ /* SR-IOV is not supported yet. */
>+ if (dev->is_virtfn || dev->is_physfn)
>+ return -EINVAL;
This check for "is_physfn" is new in this version of the series,
previously it was only checking for is_virtfn. If I understand
correctly, this means a PF device that has SRIOV capability will not be
presereved. Shouldn't we be able to preserve such PFs without preserving
the underlying VFs and SRIOV bits?
>+
>+ guard(mutex)(&pci_flb_outgoing_lock);
>+
>+ if (dev->liveupdate_outgoing)
>+ return -EBUSY;
>+
>+ ret = liveupdate_flb_get_outgoing(&pci_liveupdate_flb, (void **)&ser);
>+ if (ret)
>+ return ret;
>+
>+ if (ser->nr_devices == ser->max_nr_devices)
>+ return -E2BIG;
>+
>+ for (i = ser->nr_devices; i > 0; i--) {
>+ struct pci_dev_ser *prev = &ser->devices[i - 1];
>+ int cmp = pci_dev_ser_cmp(&new, prev);
>+
>+ /*
>+ * This should never happen unless there is a kernel bug or
>+ * corruption that causes the state in struct pci_ser to get out
>+ * of sync with struct pci_dev.
>+ */
>+ if (WARN_ON_ONCE(!cmp))
>+ return -EBUSY;
>+
>+ if (cmp > 0)
>+ break;
>+
>+ ser->devices[i] = *prev;
>+ }
>+
>+ ser->devices[i] = new;
>+ ser->nr_devices++;
>+ dev->liveupdate_outgoing = true;
>+ return 0;
>+}
>+EXPORT_SYMBOL_GPL(pci_liveupdate_preserve);
>+
>+void pci_liveupdate_unpreserve(struct pci_dev *dev)
>+{
>+ struct pci_ser *ser;
>+ int ret;
>+
>+ /* This should never happen unless the caller (driver) is buggy */
>+ if (WARN_ON_ONCE(!dev->liveupdate_outgoing))
>+ return;
>+
>+ guard(mutex)(&pci_flb_outgoing_lock);
>+
>+ ret = liveupdate_flb_get_outgoing(&pci_liveupdate_flb, (void **)&ser);
>+
>+ /* This should never happen unless there is a bug in LUO */
>+ if (WARN_ON_ONCE(ret))
>+ return;
>+
>+ pci_ser_delete(ser, dev);
>+ dev->liveupdate_outgoing = false;
>+}
>+EXPORT_SYMBOL_GPL(pci_liveupdate_unpreserve);
>+
>+static int pci_liveupdate_flb_get_incoming(struct pci_ser **serp)
>+{
>+ int ret;
>+
>+ ret = liveupdate_flb_get_incoming(&pci_liveupdate_flb, (void **)serp);
>+
>+ /* Live Update is not enabled. */
>+ if (ret == -EOPNOTSUPP)
>+ return ret;
>+
>+ /* Live Update is enabled, but there is no incoming FLB data. */
>+ if (ret == -ENODATA)
>+ return ret;
>+
>+ /*
>+ * Live Update is enabled and there is incoming FLB data, but none of it
>+ * matches pci_liveupdate_flb.compatible.
>+ *
>+ * This could mean that no PCI FLB data was passed by the previous
>+ * kernel, but it could also mean the previous kernel used a different
>+ * compatibility string (i.e.a different ABI). The latter deserves at
>+ * least a WARN_ON_ONCE() but it cannot be distinguished from the
>+ * former.
>+ */
>+ if (ret == -ENOENT) {
>+ pr_info_once("PCI: No incoming FLB data detected during Live Update");
>+ return ret;
>+ }
>+
>+ /*
>+ * There is incoming FLB data that matches pci_liveupdate_flb.compatible
>+ * but it cannot be retrieved. Proceed with standard initialization as
>+ * if there was not incoming PCI FLB data.
>+ */
>+ WARN_ONCE(ret, "PCI: Failed to retrieve incoming FLB data during Live Update");
>+ return ret;
>+}
>+
>+u32 pci_liveupdate_incoming_nr_devices(void)
>+{
>+ struct pci_ser *ser;
>+
>+ if (pci_liveupdate_flb_get_incoming(&ser))
>+ return 0;
>+
>+ return ser->nr_devices;
>+}
>+
>+void pci_liveupdate_setup_device(struct pci_dev *dev)
>+{
>+ struct pci_ser *ser;
>+
>+ if (pci_liveupdate_flb_get_incoming(&ser))
>+ return;
>+
>+ if (!pci_ser_find(ser, dev))
>+ return;
>+
>+ dev->liveupdate_incoming = true;
>+}
>+
>+int pci_liveupdate_retrieve(struct pci_dev *dev)
>+{
>+ if (!dev->liveupdate_incoming)
>+ return -EINVAL;
>+
>+ return 0;
>+}
>+EXPORT_SYMBOL_GPL(pci_liveupdate_retrieve);
>+
>+void pci_liveupdate_finish(struct pci_dev *dev)
>+{
>+ dev->liveupdate_incoming = false;
>+}
>+EXPORT_SYMBOL_GPL(pci_liveupdate_finish);
>+
>+int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh)
>+{
>+ return liveupdate_register_flb(fh, &pci_liveupdate_flb);
>+}
>+EXPORT_SYMBOL_GPL(pci_liveupdate_register_flb);
>+
>+void pci_liveupdate_unregister_flb(struct liveupdate_file_handler *fh)
>+{
>+ liveupdate_unregister_flb(fh, &pci_liveupdate_flb);
>+}
>+EXPORT_SYMBOL_GPL(pci_liveupdate_unregister_flb);
>diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
>index 13d998fbacce..979cb9921340 100644
>--- a/drivers/pci/pci.h
>+++ b/drivers/pci/pci.h
>@@ -1434,4 +1434,18 @@ static inline int pci_msix_write_tph_tag(struct pci_dev *pdev, unsigned int inde
> (PCI_CONF1_ADDRESS(bus, dev, func, reg) | \
> PCI_CONF1_EXT_REG(reg))
>
>+#ifdef CONFIG_PCI_LIVEUPDATE
>+void pci_liveupdate_setup_device(struct pci_dev *dev);
>+u32 pci_liveupdate_incoming_nr_devices(void);
>+#else
>+static inline void pci_liveupdate_setup_device(struct pci_dev *dev)
>+{
>+}
>+
>+static inline u32 pci_liveupdate_incoming_nr_devices(void)
>+{
>+ return 0;
>+}
>+#endif
>+
> #endif /* DRIVERS_PCI_H */
>diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>index bccc7a4bdd79..c60222d45659 100644
>--- a/drivers/pci/probe.c
>+++ b/drivers/pci/probe.c
>@@ -2064,6 +2064,8 @@ int pci_setup_device(struct pci_dev *dev)
> if (pci_early_dump)
> early_dump_pci_device(dev);
>
>+ pci_liveupdate_setup_device(dev);
>+
> /* Need to have dev->class ready */
> dev->cfg_size = pci_cfg_space_size(dev);
>
>diff --git a/include/linux/kho/abi/pci.h b/include/linux/kho/abi/pci.h
>new file mode 100644
>index 000000000000..7764795f6818
>--- /dev/null
>+++ b/include/linux/kho/abi/pci.h
>@@ -0,0 +1,62 @@
>+/* SPDX-License-Identifier: GPL-2.0 */
>+
>+/*
>+ * Copyright (c) 2025, Google LLC.
>+ * David Matlack <dmatlack@google.com>
>+ */
>+
>+#ifndef _LINUX_KHO_ABI_PCI_H
>+#define _LINUX_KHO_ABI_PCI_H
>+
>+#include <linux/bug.h>
>+#include <linux/compiler.h>
>+#include <linux/types.h>
>+
>+/**
>+ * DOC: PCI File-Lifecycle Bound (FLB) Live Update ABI
>+ *
>+ * This header defines the ABI for preserving core PCI state across kexec using
>+ * Live Update File-Lifecycle Bound (FLB) data.
>+ *
>+ * This interface is a contract. Any modification to any of the serialization
>+ * structs defined here constitutes a breaking change. Such changes require
>+ * incrementing the version number in the PCI_LUO_FLB_COMPATIBLE string.
>+ */
>+
>+#define PCI_LUO_FLB_COMPATIBLE "pci-v1"
>+
>+/**
>+ * struct pci_dev_ser - Serialized state about a single PCI device.
>+ *
>+ * @domain: The device's PCI domain number (segment).
>+ * @bdf: The device's PCI bus, device, and function number.
>+ * @reserved: Reserved (to naturally align struct pci_dev_ser).
>+ */
>+struct pci_dev_ser {
>+ u32 domain;
>+ u16 bdf;
>+ u16 reserved;
>+} __packed;
>+
>+/**
>+ * struct pci_ser - PCI Subsystem Live Update State
>+ *
>+ * This struct tracks state about all devices that are being preserved across
>+ * a Live Update for the next kernel.
>+ *
>+ * @max_nr_devices: The length of the devices[] flexible array.
>+ * @nr_devices: The number of devices that were preserved.
>+ * @devices: Flexible array of pci_dev_ser structs for each device. Guaranteed
>+ * to be sorted ascending by domain and bdf.
>+ */
>+struct pci_ser {
>+ u64 max_nr_devices;
>+ u64 nr_devices;
>+ struct pci_dev_ser devices[];
>+} __packed;
>+
>+/* Ensure all elements of devices[] are naturally aligned. */
>+static_assert(offsetof(struct pci_ser, devices) % sizeof(unsigned long) == 0);
>+static_assert(sizeof(struct pci_dev_ser) % sizeof(unsigned long) == 0);
>+
>+#endif /* _LINUX_KHO_ABI_PCI_H */
>diff --git a/include/linux/pci.h b/include/linux/pci.h
>index 1c270f1d5123..27ee9846a2fd 100644
>--- a/include/linux/pci.h
>+++ b/include/linux/pci.h
>@@ -40,6 +40,7 @@
> #include <linux/resource_ext.h>
> #include <linux/msi_api.h>
> #include <uapi/linux/pci.h>
>+#include <linux/liveupdate.h>
>
> #include <linux/pci_ids.h>
>
>@@ -591,6 +592,10 @@ struct pci_dev {
> u8 tph_mode; /* TPH mode */
> u8 tph_req_type; /* TPH requester type */
> #endif
>+#ifdef CONFIG_PCI_LIVEUPDATE
>+ unsigned int liveupdate_incoming:1; /* Preserved by previous kernel */
>+ unsigned int liveupdate_outgoing:1; /* Preserved for next kernel */
>+#endif
> };
>
> static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
>@@ -2871,4 +2876,40 @@ void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type);
> WARN_ONCE(condition, "%s %s: " fmt, \
> dev_driver_string(&(pdev)->dev), pci_name(pdev), ##arg)
>
>+#ifdef CONFIG_PCI_LIVEUPDATE
>+int pci_liveupdate_preserve(struct pci_dev *dev);
>+void pci_liveupdate_unpreserve(struct pci_dev *dev);
>+int pci_liveupdate_retrieve(struct pci_dev *dev);
>+void pci_liveupdate_finish(struct pci_dev *dev);
>+int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh);
>+void pci_liveupdate_unregister_flb(struct liveupdate_file_handler *fh);
>+#else
>+static inline int pci_liveupdate_preserve(struct pci_dev *dev)
>+{
>+ return -EOPNOTSUPP;
>+}
>+
>+static inline void pci_liveupdate_unpreserve(struct pci_dev *dev)
>+{
>+}
>+
>+static inline int pci_liveupdate_retrieve(struct pci_dev *dev)
>+{
>+ return -EOPNOTSUPP;
>+}
>+
>+static inline void pci_liveupdate_finish(struct pci_dev *dev)
>+{
>+}
>+
>+static inline int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh)
>+{
>+ return -EOPNOTSUPP;
>+}
>+
>+static inline void pci_liveupdate_unregister_flb(struct liveupdate_file_handler *fh)
>+{
>+}
>+#endif
>+
> #endif /* LINUX_PCI_H */
>--
>2.53.0.983.g0bb29b3bc5-goog
>
^ permalink raw reply
* Re: [PATCH v10 0/8] ACPI: Unify CPU UID interface and fix ARM64 TPH steer-tag issue
From: Catalin Marinas @ 2026-03-31 17:31 UTC (permalink / raw)
To: Chengwen Feng
Cc: Bjorn Helgaas, Will Deacon, Rafael J . Wysocki, Jonathan Corbet,
Palmer Dabbelt, Borislav Petkov, H . Peter Anvin, Juergen Gross,
Boris Ostrovsky, Len Brown, Sunil V L, Mark Rutland,
Jonathan Cameron, Kees Cook, Yanteng Si, Sean Christopherson,
Kai Huang, Tom Lendacky, Thomas Huth, Thorsten Blum,
Kevin Loughlin, Zheyun Shen, Peter Zijlstra, Pawan Gupta, Xin Li,
Ahmed S . Darwish, Sohil Mehta, Ilkka Koskinen, Robin Murphy,
James Clark, Besar Wicaksono, Ma Ke, Wei Huang, Andy Gospodarek,
Somnath Kotur, punit.agrawal, guohanjun, suzuki.poulose,
ryan.roberts, chenl311, masahiroy, wangyuquan1236,
anshuman.khandual, heinrich.schuchardt, Eric.VanTassell,
wangzhou1, wanghuiqiang, liuyonglong, linux-pci, linux-doc,
linux-kernel, linux-arm-kernel, loongarch, linux-riscv, xen-devel,
linux-acpi, linux-perf-users, stable
In-Reply-To: <20260320031737.35048-1-fengchengwen@huawei.com>
On Fri, Mar 20, 2026 at 11:17:29AM +0800, Chengwen Feng wrote:
> This patchset unifies ACPI Processor UID retrieval across
> arm64/loongarch/riscv/x86 via acpi_get_cpu_uid() (with input validation)
> and fixes ARM64 CPU steer-tag retrieval failure in PCI/TPH:
>
> 1-4: Add acpi_get_cpu_uid() for arm64/loongarch/riscv/x86 (update
> respective users)
> 5: Centralize acpi_get_cpu_uid() declaration in include/linux/acpi.h
> 6: Clean up perf/arm_cspmu
> 7: Clean up ACPI/PPTT and remove unused get_acpi_id_for_cpu()
> 8: Pass ACPI Processor UID to Cache Locality _DSM
>
> The interface refactor ensures consistent CPU UID retrieval across
> architectures (no functional changes for valid inputs) and provides the
> unified interface required for the ARM64 TPH fix.
>
> ---
> Changes in v10:
> - Refine commit header&log according to Punit's and Bjorn's review
> - Split perf/arm_cspmu as a separate commit which address Punit's
> review
>
> Changes in v9:
> - Address Bjorn's review: split commits to each platform so that make
> them easy to review
>
> Changes in v8:
> - Moving arm64's get_cpu_for_acpi_id() to kernel/acpi.c which address
> Jeremy's review
>
> Chengwen Feng (8):
> arm64: acpi: Add acpi_get_cpu_uid() for unified ACPI CPU UID retrieval
> LoongArch: Add acpi_get_cpu_uid() for unified ACPI CPU UID retrieval
> RISC-V: ACPI: Add acpi_get_cpu_uid() for unified ACPI CPU UID
> retrieval
> x86/acpi: Add acpi_get_cpu_uid() for unified ACPI CPU UID retrieval
> ACPI: Centralize acpi_get_cpu_uid() declaration in
> include/linux/acpi.h
> perf: arm_cspmu: Switch to acpi_get_cpu_uid() from
> get_acpi_id_for_cpu()
> ACPI: PPTT: Use acpi_get_cpu_uid() and remove get_acpi_id_for_cpu()
> PCI/TPH: Pass ACPI Processor UID to Cache Locality _DSM
>
> Documentation/PCI/tph.rst | 4 +--
> arch/arm64/include/asm/acpi.h | 17 +---------
> arch/arm64/kernel/acpi.c | 30 ++++++++++++++++++
For the arm64 bits:
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* Re: [PATCH 3/5] compiler_attributes: Add overflow_behavior macros __ob_trap and __ob_wrap
From: Linus Torvalds @ 2026-03-31 17:18 UTC (permalink / raw)
To: Kees Cook
Cc: Peter Zijlstra, Justin Stitt, Marco Elver, Andrey Konovalov,
Andrey Ryabinin, Jonathan Corbet, Shuah Khan, Miguel Ojeda,
Nathan Chancellor, kasan-dev, linux-doc, llvm, Nicolas Schier,
Arnd Bergmann, Greg Kroah-Hartman, Andrew Morton, linux-kernel,
linux-hardening, linux-kbuild
In-Reply-To: <CAHk-=wg=q7ptcMyUAqPGDbX_DKHivJVppc8bP0zpQqzOky_avA@mail.gmail.com>
On Tue, 31 Mar 2026 at 10:16, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> The only safe trapping behavior is something that has a clear an
> unambiguous and simple to use way to *HANDLE* it. Not just "mark it
> trapping".
Side note: this is the same kind of complete and utter idiocy that
made Rust people have allocators that abort when running out of
memory, because it's "safer" than returning NULL.
THAT KIND OF THINKING IS NOT ACCEPTABLE IN THE KERNEL.
I don't know why people keep doing this. Stop it.
Linus
^ permalink raw reply
* Re: [PATCH 3/5] compiler_attributes: Add overflow_behavior macros __ob_trap and __ob_wrap
From: Justin Stitt @ 2026-03-31 17:17 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Kees Cook, Peter Zijlstra, Marco Elver, Andrey Konovalov,
Andrey Ryabinin, Jonathan Corbet, Shuah Khan, Miguel Ojeda,
Nathan Chancellor, kasan-dev, linux-doc, llvm, Linus Torvalds,
Nicolas Schier, Arnd Bergmann, Greg Kroah-Hartman, Andrew Morton,
linux-kernel, linux-hardening, linux-kbuild
In-Reply-To: <CANiq72mQPU2Uyz27mBtfT6UF4Zgoq_osodALs21kJ4qOFLVhUQ@mail.gmail.com>
Hi,
On Tue, Mar 31, 2026 at 10:14 AM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> On Tue, Mar 31, 2026 at 7:09 PM Justin Stitt <justinstitt@google.com> wrote:
> >
> > __ob_trap and __ob_wrap are defined by the compiler.
> >
> > There are some examples within the documentation additions of this patch.
> >
> > Kees, is it possible to make it more clear about what we expect of
> > kernel developers in terms of style? Should they use keyword
> > spellings? attribute spellings? only use custom types?
>
> Yeah, I noticed that right after sending the email, sorry.
>
> So I tried to use a macro even if happens to have the same name as the
> keyword, since that form is a bit more flexible, but it is fine either
> way.
>
> What I would suggest is adding to the comment that these were decided
> to be used as keywords, and thus we only need to define them as empty
> in the disabled case.
Agreed.
>
> Thanks!
>
> Cheers,
> Miguel
Justin
^ permalink raw reply
* Re: [PATCH 3/5] compiler_attributes: Add overflow_behavior macros __ob_trap and __ob_wrap
From: Linus Torvalds @ 2026-03-31 17:16 UTC (permalink / raw)
To: Kees Cook
Cc: Peter Zijlstra, Justin Stitt, Marco Elver, Andrey Konovalov,
Andrey Ryabinin, Jonathan Corbet, Shuah Khan, Miguel Ojeda,
Nathan Chancellor, kasan-dev, linux-doc, llvm, Nicolas Schier,
Arnd Bergmann, Greg Kroah-Hartman, Andrew Morton, linux-kernel,
linux-hardening, linux-kbuild
In-Reply-To: <20260331163725.2765789-3-kees@kernel.org>
On Tue, 31 Mar 2026 at 09:37, Kees Cook <kees@kernel.org> wrote:
>> +
> + typedef unsigned int __attribute__((overflow_behavior(trap))) safe_uint;
> + typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint;
This is fundamentally broken sh*t.
Stop thinking that trapping is "safe".
It damn well isn't. A dead machine is not a safe machine.
Any patches that call trapping behavior safe will ne NAK'ed by me.,
We have decades of peoiple using BUG_ON() as a safety measure, and it
has been a HUGE PROBLEM.
There is no way in hell that we are ever adding implicit BUG_ON()
things that are this hidden, this easy to use, and then mislabeled as
being "safe".
Guys, that's the same logic as having a airbag in your car that just
shoots you in the head. You're certainly "safe" from the vagaries of
bad healthcare. But dammit, if anybody thinks that a "bullet to the
head" should be called "safe", then that person damn well shouldn't be
involved with kernel development.
So NAK NAK NAK NAK.
The only safe trapping behavior is something that has a clear an
unambiguous and simple to use way to *HANDLE* it. Not just "mark it
trapping".
Linus
^ permalink raw reply
* Re: [PATCH 4/5] lkdtm/bugs: Add basic Overflow Behavior Types test
From: Justin Stitt @ 2026-03-31 17:16 UTC (permalink / raw)
To: Kees Cook
Cc: Peter Zijlstra, Arnd Bergmann, Greg Kroah-Hartman, Shuah Khan,
linux-kselftest, Linus Torvalds, Marco Elver, Jonathan Corbet,
Nathan Chancellor, Nicolas Schier, Miguel Ojeda, Andrew Morton,
linux-kernel, kasan-dev, linux-hardening, linux-doc, linux-kbuild,
llvm
In-Reply-To: <20260331163725.2765789-4-kees@kernel.org>
Hi,
On Tue, Mar 31, 2026 at 9:37 AM Kees Cook <kees@kernel.org> wrote:
>
> Exercise the end-to-end build and trap infrastructure in the kernel for
> __ob_trap, __ob_wrap, and associated sanitizer ignore patterns (i.e. idiom
> exclusions). Add a test for each of the basic overflow conditions under
> CONFIG_OVERFLOW_BEHAVIOR_TYPES=y, as well as the corner cases associated
> with promotion, casting, etc.
>
> For example, executing this test with CONFIG_OVERFLOW_BEHAVIOR_TYPES_WARN=y
> (instead of CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP=y), will show:
>
> $ echo OBT_ASSIGN_TRUNCATE_TO | cat >/sys/kernel/debug/provoke-crash/DIRECT
> $ dmesg
> ...
> lkdtm: Performing direct entry OBT_ASSIGN_TRUNCATE_TO
> UBSAN: implicit-conversion in ../drivers/misc/lkdtm/bugs.c:825:10
> cannot represent 'int' value 2147483647 during reference binding to 'u8t' (aka '__ob_trap u8'), truncated to 255
>
> Signed-off-by: Kees Cook <kees@kernel.org>
> ---
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Shuah Khan <shuah@kernel.org>
> Cc: <linux-kselftest@vger.kernel.org>
> ---
> drivers/misc/lkdtm/bugs.c | 253 ++++++++++++++++++++++++
> tools/testing/selftests/lkdtm/tests.txt | 10 +
> 2 files changed, 263 insertions(+)
>
> diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c
> index e0098f314570..f00c9099957e 100644
> --- a/drivers/misc/lkdtm/bugs.c
> +++ b/drivers/misc/lkdtm/bugs.c
> @@ -817,6 +817,249 @@ static noinline void lkdtm_CORRUPT_PAC(void)
> #endif
> }
>
> +static void lkdtm_OBT_ASSIGN_TRUNCATE_TO(void)
> +{
> + volatile int big = INT_MAX;
> + volatile int wide_low_value = 5;
> + u8 __ob_trap narrow_low_value = 0;
> + s32 __ob_trap same = 0;
> + u8 __ob_trap small = 0;
> +
> + pr_info("Performing same-width assignment to OBT\n");
> + same = big;
> +
> + pr_info("Performing small-value assignment to OBT\n");
> + narrow_low_value = wide_low_value;
> +
> + pr_info("Expecting trap on truncated assignment to OBT\n");
> + small = big;
> +
> + pr_err("FAIL: survived overflowing truncated assignment to OBT: %d -> %u (ok: %d -> %u)\n",
> + same, small, wide_low_value, narrow_low_value);
> + pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
> +}
> +
> +static void lkdtm_OBT_ASSIGN_TRUNCATE_FROM(void)
> +{
> + volatile s32 __ob_trap big = INT_MAX;
> + volatile s32 __ob_trap wide_low_value = 5;
> + u8 narrow_low_value = 0;
> + s32 same = 0;
> + u8 small = 0;
> +
> + pr_info("Performing same-width assignment from OBT\n");
> + same = big;
> +
> + pr_info("Performing small-value assignment from OBT\n");
> + narrow_low_value = wide_low_value;
> +
> + pr_info("Expecting trap on truncated assignment from OBT\n");
> + small = big;
> +
> + pr_err("FAIL: survived overflowing truncated assignment from OBT: %d -> %u (ok: %d -> %u)\n",
> + same, small, wide_low_value, narrow_low_value);
> + pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
> +}
> +
> +static void lkdtm_OBT_CAST_TRUNCATE(void)
> +{
> + volatile u32 __ob_trap big = INT_MAX;
> + u32 trunc = 0;
> + u32 small = 0;
> +
> + pr_info("Performing wrapping too-small cast\n");
> + trunc = (u16 __ob_wrap)big;
> +
> + pr_info("Expecting trap on too-small cast\n");
> + small = (s16)big;
> +
> + pr_err("FAIL: survived truncated casting: %u -> %u (ok: %u -> %u)\n",
> + big, small, big, trunc);
> + pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
> +}
> +
> +static void lkdtm_OBT_CAST_SIGNED(void)
> +{
> + volatile u32 __ob_trap big = UINT_MAX;
> + s32 neg = 0;
> + s32 small = 0;
> +
> + pr_info("Performing explicit sign-changing cast\n");
> + neg = (s32 __ob_wrap)big;
> +
> + pr_info("Expecting trap on unexpected sign-changing cast\n");
> + small = (s32)big;
> +
> + pr_err("FAIL: survived lossy sign conversion: %u -> %d (forced: %u -> %d)\n",
> + big, small, big, neg);
> + pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
> +}
Note to travelers and testers, we still have a compiler patch in
flight [1] that fixes a bug with sign-change instrumentation
concerning OBTs.
> +
> +static void lkdtm_OBT_MUL(void)
> +{
> + /* Promotion means no overflow checking can happen. */
> + volatile u8 __ob_trap a8 = 100;
<snip>
[1]: https://github.com/llvm/llvm-project/pull/188340
Justin
^ permalink raw reply
* Re: [PATCH 3/5] compiler_attributes: Add overflow_behavior macros __ob_trap and __ob_wrap
From: Miguel Ojeda @ 2026-03-31 17:14 UTC (permalink / raw)
To: Justin Stitt
Cc: Kees Cook, Peter Zijlstra, Marco Elver, Andrey Konovalov,
Andrey Ryabinin, Jonathan Corbet, Shuah Khan, Miguel Ojeda,
Nathan Chancellor, kasan-dev, linux-doc, llvm, Linus Torvalds,
Nicolas Schier, Arnd Bergmann, Greg Kroah-Hartman, Andrew Morton,
linux-kernel, linux-hardening, linux-kbuild
In-Reply-To: <CAFhGd8paijFboDVr8rJDjScob047q+zgYAs038WuVozOG0aYaQ@mail.gmail.com>
On Tue, Mar 31, 2026 at 7:09 PM Justin Stitt <justinstitt@google.com> wrote:
>
> __ob_trap and __ob_wrap are defined by the compiler.
>
> There are some examples within the documentation additions of this patch.
>
> Kees, is it possible to make it more clear about what we expect of
> kernel developers in terms of style? Should they use keyword
> spellings? attribute spellings? only use custom types?
Yeah, I noticed that right after sending the email, sorry.
So I tried to use a macro even if happens to have the same name as the
keyword, since that form is a bit more flexible, but it is fine either
way.
What I would suggest is adding to the comment that these were decided
to be used as keywords, and thus we only need to define them as empty
in the disabled case.
Thanks!
Cheers,
Miguel
^ permalink raw reply
* Re: [PATCH 5/5] types: Add standard __ob_trap and __ob_wrap scalar types
From: Linus Torvalds @ 2026-03-31 17:10 UTC (permalink / raw)
To: Kees Cook
Cc: Peter Zijlstra, Justin Stitt, Miguel Ojeda, Nathan Chancellor,
Andrew Morton, Andy Shevchenko, Arnd Bergmann, Mark Rutland,
Matthew Wilcox (Oracle), Suren Baghdasaryan, Thomas Gleixner,
Finn Thain, Geert Uytterhoeven, Thomas Weißschuh, llvm,
Marco Elver, Jonathan Corbet, Nicolas Schier, Greg Kroah-Hartman,
linux-kernel, kasan-dev, linux-hardening, linux-doc, linux-kbuild
In-Reply-To: <20260331163725.2765789-5-kees@kernel.org>
On Tue, 31 Mar 2026 at 09:37, Kees Cook <kees@kernel.org> wrote:
>
> Current straw-man proposal is single letter suffix because it vaguely
> felt like the least bad of all choices, and they should be short or
> everyone will just continue to type "int". :)
Violently disagree.
I'd rather have people continue to use other types than have somethign
that isn't visually obvious for *VERY* subtle semantic changes.
If somebody starts using explicitly trapping types, they need to say
so. Not just *say* so, but scream it at the top of their lungs. No
hidden subtle behavior changes. This needs to look _very_different_.
No stupid one-character things. If we go down this path it would need
to be "wrapping_u32" or whatever.
That said, I think the trapping behavior is unacceptable unless
there's some way to recover from it. An dno, that "some way" is not
the broken C++ style exception handling. That thing is pure and utter
shit, and fragile as hell. Anything that requires trying to unwind the
stack is just a complete no-go because it's going to be buggy and
untestable (sure, you can have test-cases and the unwinding will work
for *those*, but...)
I don't actually see any sane interface. The "unsafe_get_user()" thing
with actual labels and exception tables works very well, but it would
require wrapping all trapping operations in a macro.
Which is maybe not a bad idea - it's almost certainly better than the
overflow builtins - but might also be disgusting. Hard to tell.
Linus
^ permalink raw reply
* Re: [PATCH 3/5] compiler_attributes: Add overflow_behavior macros __ob_trap and __ob_wrap
From: Justin Stitt @ 2026-03-31 17:09 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Kees Cook, Peter Zijlstra, Marco Elver, Andrey Konovalov,
Andrey Ryabinin, Jonathan Corbet, Shuah Khan, Miguel Ojeda,
Nathan Chancellor, kasan-dev, linux-doc, llvm, Linus Torvalds,
Nicolas Schier, Arnd Bergmann, Greg Kroah-Hartman, Andrew Morton,
linux-kernel, linux-hardening, linux-kbuild
In-Reply-To: <CANiq72mK9fz6Spmgt4js3hScqhqvZb2YP2T7tDfR0fHPDFWJ7g@mail.gmail.com>
Hi,
On Tue, Mar 31, 2026 at 10:02 AM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> On Tue, Mar 31, 2026 at 6:37 PM Kees Cook <kees@kernel.org> wrote:
> >
> > +/*
> > + * Optional: only supported by Clang with -Xclang -experimental-foverflow-behavior-types
> > + * passed via CONFIG_OVERFLOW_BEHAVIOR_TYPES. When not available, define empty macros for
> > + * the trap/wrap annotations.
> > + *
> > + * clang: https://clang.llvm.org/docs/OverflowBehaviorTypes.html
> > + */
> > +#if !__has_attribute(overflow_behavior) || !defined(OVERFLOW_BEHAVIOR_TYPES)
> > +# define __ob_trap
> > +# define __ob_wrap
> > +#endif
>
> Should that have `CONFIG_*`? i.e.
>
> !defined(CONFIG_OVERFLOW_BEHAVIOR_TYPES)
>
> In addition, since this depends on a `CONFIG_`, with the current setup
> we would put them elsewhere instead of `compiler_attributes.h` until
> they are promoted to be "unconditional" (i.e. without the compiler
> flag):
>
> * Any other "attributes" (i.e. those that depend on a configuration option,
> * on a compiler, on an architecture, on plugins, on other attributes...)
> * should be defined elsewhere (e.g. compiler_types.h or compiler-*.h).
> * The intention is to keep this file as simple as possible, as well as
> * compiler- and version-agnostic (e.g. avoiding GCC_VERSION checks).
>
> However, thinking about it, why is the config needed?
>
> i.e. if the compiler is not passed that flag, shouldn't the
> `__has_attribute` simply return false?
>
> Also, I am a bit confused -- does the compiler flag automatically
> recognize the names like `__ob_trap`? i.e. I see the docs mention
> using the attribute,
>
> typedef unsigned int __attribute__((overflow_behavior(trap))) safe_uint;
> typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint;
>
> But then we don't actually use it?
__ob_trap and __ob_wrap are defined by the compiler.
There are some examples within the documentation additions of this patch.
Kees, is it possible to make it more clear about what we expect of
kernel developers in terms of style? Should they use keyword
spellings? attribute spellings? only use custom types?
>
> Or should this just be like the rest of the attributes, i.e. we
> actually define them here?
>
> Thanks!
>
> Cheers,
> Miguel
Justin
^ permalink raw reply
* Re: [PATCH 3/5] compiler_attributes: Add overflow_behavior macros __ob_trap and __ob_wrap
From: Miguel Ojeda @ 2026-03-31 17:09 UTC (permalink / raw)
To: Kees Cook
Cc: Peter Zijlstra, Justin Stitt, Marco Elver, Andrey Konovalov,
Andrey Ryabinin, Jonathan Corbet, Shuah Khan, Miguel Ojeda,
Nathan Chancellor, kasan-dev, linux-doc, llvm, Linus Torvalds,
Nicolas Schier, Arnd Bergmann, Greg Kroah-Hartman, Andrew Morton,
linux-kernel, linux-hardening, linux-kbuild
In-Reply-To: <CANiq72mK9fz6Spmgt4js3hScqhqvZb2YP2T7tDfR0fHPDFWJ7g@mail.gmail.com>
On Tue, Mar 31, 2026 at 7:01 PM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> Also, I am a bit confused -- does the compiler flag automatically
> recognize the names like `__ob_trap`? i.e. I see the docs mention
> using the attribute,
>
> typedef unsigned int __attribute__((overflow_behavior(trap))) safe_uint;
> typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint;
>
> But then we don't actually use it?
Ah, it does, it is a keyword, and I should have read the docs better.
From a quick test in Compiler Explorer it seems to be fine to define a
macro like the keyword:
#define __ob_trap __attribute__((overflow_behavior(trap)))
#define __ob_wrap __attribute__((overflow_behavior(wrap)))
That could be a bit more flexible in the name we pick on our side and
more like the rest of the attributes, but if the intention is to
eventually use that keyword in standard C or similar, I guess it is
fine.
Cheers,
Miguel
^ permalink raw reply
* RE: [PATCH v5 2/4] iio: adc: ad4691: add initial driver for AD4691 family
From: Sabau, Radu bogdan @ 2026-03-31 17:05 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Andy Shevchenko, Lars-Peter Clausen, Hennerich, Michael,
Jonathan Cameron, David Lechner, Sa, Nuno, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Uwe Kleine-König, Liam Girdwood, Mark Brown, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Jonathan Corbet, Shuah Khan,
linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org,
linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org
In-Reply-To: <acuMxjX_rsfsJvMp@ashevche-desk.local>
> -----Original Message-----
> From: Andy Shevchenko <andriy.shevchenko@intel.com>
> Sent: Tuesday, March 31, 2026 11:59 AM
> To: Sabau, Radu bogdan <Radu.Sabau@analog.com>
> Cc: Andy Shevchenko <andy.shevchenko@gmail.com>; Lars-Peter Clausen
> <lars@metafoo.de>; Hennerich, Michael <Michael.Hennerich@analog.com>;
> Jonathan Cameron <jic23@kernel.org>; David Lechner
> <dlechner@baylibre.com>; Sa, Nuno <Nuno.Sa@analog.com>; Andy
> Shevchenko <andy@kernel.org>; Rob Herring <robh@kernel.org>; Krzysztof
> Kozlowski <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Uwe
> Kleine-König <ukleinek@kernel.org>; Liam Girdwood <lgirdwood@gmail.com>;
> Mark Brown <broonie@kernel.org>; Linus Walleij <linusw@kernel.org>;
> Bartosz Golaszewski <brgl@kernel.org>; Philipp Zabel
> <p.zabel@pengutronix.de>; Jonathan Corbet <corbet@lwn.net>; Shuah Khan
> <skhan@linuxfoundation.org>; linux-iio@vger.kernel.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
> pwm@vger.kernel.org; linux-gpio@vger.kernel.org; linux-doc@vger.kernel.org
> Subject: Re: [PATCH v5 2/4] iio: adc: ad4691: add initial driver for AD4691
> family
>
> [External]
>
> On Tue, Mar 31, 2026 at 08:36:42AM +0000, Sabau, Radu bogdan wrote:
> > > -----Original Message-----
> > > From: Andy Shevchenko <andy.shevchenko@gmail.com>
> > > Sent: Monday, March 30, 2026 8:24 PM
>
> ...
>
> > > > > > +#include <linux/bitfield.h>
> > > > > > +#include <linux/bitops.h>
> > > > > > +#include <linux/cleanup.h>
> > > > > > +#include <linux/delay.h>
> > > > > > +#include <linux/device.h>
> > > > >
> > > > > Hmm... Is it used? Or perhaps you need only
> > > > > dev_printk.h
> > > > > device/devres.h
> > > > > ?
> > >
> > > > I have checked this out and it seems device.h doesn't actually need
> > > > to be included anyway since spi.h directly includes device.h, and since
> > > > this is a SPI driver that's never going away, it's covered. Will drop it!
> > >
> > > No, this is the wrong justification. IWYU principle is about exact
> > > match between what is used and included in a file (module). spi.h is
> > > not dev_*() provider and may not be considered for that.
> > >
> >
> > You are right, my justification was incorrect. Under IWYU, relying on
> > spi.h's transitive pull of device.h is not valid. However, I think device.h
> > is still needed in this case since struct device is used directly in the code
> > both as local variables and in the regmap callbacks.
>
> Really? I can't see that.
> (Hint: use of the data type and use of its pointer is a huge difference.)
>
> > Also dev_err_probe() is called directly and lives in device.h.
>
> No, as I started with my replies. The proper header that provides it is
> dev_printk.h.
>
Yep, my bad... device.h can be removed and devres and dev_printk be
used instead. Sorry for the confusion from my end, I thought I was
looking at device.h, but was instead looking at dev_printk.h.
^ permalink raw reply
* Re: [PATCH 3/5] compiler_attributes: Add overflow_behavior macros __ob_trap and __ob_wrap
From: Miguel Ojeda @ 2026-03-31 17:01 UTC (permalink / raw)
To: Kees Cook
Cc: Peter Zijlstra, Justin Stitt, Marco Elver, Andrey Konovalov,
Andrey Ryabinin, Jonathan Corbet, Shuah Khan, Miguel Ojeda,
Nathan Chancellor, kasan-dev, linux-doc, llvm, Linus Torvalds,
Nicolas Schier, Arnd Bergmann, Greg Kroah-Hartman, Andrew Morton,
linux-kernel, linux-hardening, linux-kbuild
In-Reply-To: <20260331163725.2765789-3-kees@kernel.org>
On Tue, Mar 31, 2026 at 6:37 PM Kees Cook <kees@kernel.org> wrote:
>
> +/*
> + * Optional: only supported by Clang with -Xclang -experimental-foverflow-behavior-types
> + * passed via CONFIG_OVERFLOW_BEHAVIOR_TYPES. When not available, define empty macros for
> + * the trap/wrap annotations.
> + *
> + * clang: https://clang.llvm.org/docs/OverflowBehaviorTypes.html
> + */
> +#if !__has_attribute(overflow_behavior) || !defined(OVERFLOW_BEHAVIOR_TYPES)
> +# define __ob_trap
> +# define __ob_wrap
> +#endif
Should that have `CONFIG_*`? i.e.
!defined(CONFIG_OVERFLOW_BEHAVIOR_TYPES)
In addition, since this depends on a `CONFIG_`, with the current setup
we would put them elsewhere instead of `compiler_attributes.h` until
they are promoted to be "unconditional" (i.e. without the compiler
flag):
* Any other "attributes" (i.e. those that depend on a configuration option,
* on a compiler, on an architecture, on plugins, on other attributes...)
* should be defined elsewhere (e.g. compiler_types.h or compiler-*.h).
* The intention is to keep this file as simple as possible, as well as
* compiler- and version-agnostic (e.g. avoiding GCC_VERSION checks).
However, thinking about it, why is the config needed?
i.e. if the compiler is not passed that flag, shouldn't the
`__has_attribute` simply return false?
Also, I am a bit confused -- does the compiler flag automatically
recognize the names like `__ob_trap`? i.e. I see the docs mention
using the attribute,
typedef unsigned int __attribute__((overflow_behavior(trap))) safe_uint;
typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint;
But then we don't actually use it?
Or should this just be like the rest of the attributes, i.e. we
actually define them here?
Thanks!
Cheers,
Miguel
^ permalink raw reply
* Re: [PATCH net-next V9 11/14] net/mlx5: qos: Remove qos domains and use shd lock
From: Cosmin Ratiu @ 2026-03-31 16:37 UTC (permalink / raw)
To: Tariq Toukan, kuba@kernel.org
Cc: allison.henderson@oracle.com, jiri@resnulli.us, Moshe Shemesh,
davem@davemloft.net, daniel.zahka@gmail.com,
donald.hunter@gmail.com, netdev@vger.kernel.org,
matttbe@kernel.org, pabeni@redhat.com, horms@kernel.org,
Parav Pandit, corbet@lwn.net, razor@blackwall.org, Dragos Tatulea,
linux-kernel@vger.kernel.org, willemb@google.com, Jiri Pirko,
Adithya Jayachandran, Dan Jurgens, leon@kernel.org,
kees@kernel.org, vadim.fedorenko@linux.dev, Saeed Mahameed,
shuah@kernel.org, andrew+netdev@lunn.ch, Mark Bloch,
Shahar Shitrit, Carolina Jubran, Nimrod Oren,
daniel@iogearbox.net, minhquangbui99@gmail.com, dw@davidwei.uk,
jacob.e.keller@intel.com, skhan@linuxfoundation.org, Petr Machata,
edumazet@google.com, antonio@openvpn.net, mst@redhat.com,
linux-kselftest@vger.kernel.org, linux-rdma@vger.kernel.org,
Shay Drori, sdf@fomichev.me, chuck.lever@oracle.com, Gal Pressman,
joe@dama.to, linux-doc@vger.kernel.org
In-Reply-To: <3bd3caead46d1965d3a7a151d0ef0a54ac78332a.camel@nvidia.com>
On Tue, 2026-03-31 at 12:53 +0000, Cosmin Ratiu wrote:
> On Mon, 2026-03-30 at 19:08 -0700, Jakub Kicinski wrote:
> > This is an AI-generated review of your patch. The human sending
> > this
> > email has considered the AI review valid, or at least plausible.
> > ---
> > net/mlx5: qos: Remove qos domains and use shd lock
> >
> > This commit removes QoS domains and switches to using the shd lock
> > to
> > protect against concurrent QoS modifications. It also enables the
> > supported_cross_device_rate_nodes devlink ops attribute.
> >
> > Link:
> > https://lore.kernel.org/netdev/20250213180134.323929-1-tariqt@nvidia.com/
> >
> > > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
> > > b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
> > > index 6698ac55a4bfa..c051605fecd23 100644
> > > --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
> > > +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
> > > @@ -385,6 +385,7 @@ static const struct devlink_ops
> > > mlx5_devlink_ops = {
> > > .rate_node_del = mlx5_esw_devlink_rate_node_del,
> > > .rate_leaf_parent_set =
> > > mlx5_esw_devlink_rate_leaf_parent_set,
> > > .rate_node_parent_set =
> > > mlx5_esw_devlink_rate_node_parent_set,
> > > + .supported_cross_device_rate_nodes = true,
> >
> > The commit message states that enabling
> > supported_cross_device_rate_nodes
> > now is safe because mlx5_esw_qos_vport_update_parent rejects cross-
> > esw
> > parent updates.
> >
> > When a user provides a DEVLINK_ATTR_PARENT_DEV belonging to an
> > unrelated
> > device, the devlink core (devlink_nl_rate_parent_node_set) drops
> > the
> > lock on
> > the parent devlink and calls devlink_rate_node_get_by_name(). This
> > function
> > traverses the rate_list of the unlocked parent devlink instance.
> >
> > Does this leave the devlink core exposed to data races and
> > potential
> > use-after-free vulnerabilities, since the driver's rejection
> > callback
> > executes only after this lockless list traversal has occurred?
>
> I will address this by adding common ancestor validation in devlink
> rate core, which was missing.
>
> >
> > > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
> > > b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
> > > index 0be516003bcde..f67f99428959f 100644
> > > --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
> > > +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
> > > @@ -1110,7 +1068,7 @@ void mlx5_esw_qos_vport_disable(struct
> > > mlx5_vport *vport)
> > > struct mlx5_esw_sched_node *parent;
> > >
> > > lockdep_assert_held(&esw->state_lock);
> > > - esw_qos_lock(esw);
> > > + devl_lock(esw->dev->shd);
> >
> > Could esw->dev->shd be NULL here?
> >
> > In mlx5_shd_init(), initialization is explicitly skipped for non-PF
> > devices,
> > meaning Sub-Functions (SFs) acting as E-Switch managers will have a
> > NULL
> > shd pointer. If the device lacks VPD data, pci_vpd_alloc() returns
> > -
> > ENODEV,
> > causing mlx5_shd_init() to return 0 but leaving dev->shd as NULL.
> >
> > When QoS operations are attempted on these devices, calling
> > devl_lock()
> > dereferences the pointer, which could cause an immediate NULL
> > pointer
> > dereference and kernel panic.
>
> Right. This is a race with Jiri's fix ([1]), which changed the
> assumption this code was architected with that dev->shd is always
> initialized. That is no longer the case, and the consequence is that
> this needs to 1) not unconditionally use dev->shd and 2) use a
> fallback
> lock when it isn't available.
Forgot:
[1]
https://lore.kernel.org/netdev/20260325152801.236343-1-jiri@resnulli.us/
^ permalink raw reply
* [PATCH 5/5] types: Add standard __ob_trap and __ob_wrap scalar types
From: Kees Cook @ 2026-03-31 16:37 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Kees Cook, Justin Stitt, Linus Torvalds, Miguel Ojeda,
Nathan Chancellor, Andrew Morton, Andy Shevchenko, Arnd Bergmann,
Mark Rutland, Matthew Wilcox (Oracle), Suren Baghdasaryan,
Thomas Gleixner, Finn Thain, Geert Uytterhoeven,
Thomas Weißschuh, llvm, Marco Elver, Jonathan Corbet,
Nicolas Schier, Greg Kroah-Hartman, linux-kernel, kasan-dev,
linux-hardening, linux-doc, linux-kbuild
In-Reply-To: <20260331163716.work.696-kees@kernel.org>
While Linux's use of -fno-strict-overflow means that all arithmetic
operations have a defined behavior (2's-complement wrapping), there
isn't a way to unambiguously specify if a given variable was designed
or intended to wrap around by the author.
Introduce explicit trapping and wrapping types for all bit widths
including architecture word length (i.e. "long"), signed and unsigned,
for use going forward for unambiguous arithmetic, now available via
Clang 23+'s Overflow Behavior Types[1] (CONFIG_OVERFLOW_BEHAVIOR_TYPES=y).
Bike shedding time! How should these be named? We already have the short
bit width types, named as: {u,s}{8,16,32,64}. We need to construct new
type names that also indicate their overflow behavior: "trapping" or
"wrapping". And we need to capture the "architectural word" length type
too (i.e. what "unsigned long" or "size_t" captures).
Whole word addition:
- Pro: Unambiguous
- Con: Long. E.g. suffixed "u16_trap", or prefixed "wrap_u16"
Single letter addition, "t" for "trap" and "w" for "wrap":
- At the end: but "u8t" looks like the "t" is "type", like "uint8_t".
- At the front: but "wu8" looks like the "w" is "wide", like "wchar_t".
Current straw-man proposal is single letter suffix because it vaguely
felt like the least bad of all choices, and they should be short or
everyone will just continue to type "int". :)
Link: https://clang.llvm.org/docs/OverflowBehaviorTypes.html [1]
Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: Justin Stitt <justinstitt@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Miguel Ojeda <ojeda@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Finn Thain <fthain@linux-m68k.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: "Thomas Weißschuh" <thomas.weissschuh@linutronix.de>
Cc: <llvm@lists.linux.dev>
---
include/linux/types.h | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/include/linux/types.h b/include/linux/types.h
index 7e71d260763c..786eb2c9775f 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -94,6 +94,30 @@ typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned long long ullong;
+/* Trapping types. */
+typedef u8 __ob_trap u8t;
+typedef u16 __ob_trap u16t;
+typedef u32 __ob_trap u32t;
+typedef u64 __ob_trap u64t;
+typedef unsigned long __ob_trap ulongt;
+typedef s8 __ob_trap s8t;
+typedef s16 __ob_trap s16t;
+typedef s32 __ob_trap s32t;
+typedef s64 __ob_trap s64t;
+typedef signed long __ob_trap slongt;
+
+/* Wrapping types. */
+typedef u8 __ob_wrap u8w;
+typedef u16 __ob_wrap u16w;
+typedef u32 __ob_wrap u32w;
+typedef u64 __ob_wrap u64w;
+typedef unsigned long __ob_wrap ulongw;
+typedef s8 __ob_wrap s8w;
+typedef s16 __ob_wrap s16w;
+typedef s32 __ob_wrap s32w;
+typedef s64 __ob_wrap s64w;
+typedef signed long __ob_wrap slongw;
+
#ifndef __BIT_TYPES_DEFINED__
#define __BIT_TYPES_DEFINED__
--
2.34.1
^ permalink raw reply related
* [PATCH 4/5] lkdtm/bugs: Add basic Overflow Behavior Types test
From: Kees Cook @ 2026-03-31 16:37 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Kees Cook, Arnd Bergmann, Greg Kroah-Hartman, Shuah Khan,
linux-kselftest, Justin Stitt, Linus Torvalds, Marco Elver,
Jonathan Corbet, Nathan Chancellor, Nicolas Schier, Miguel Ojeda,
Andrew Morton, linux-kernel, kasan-dev, linux-hardening,
linux-doc, linux-kbuild, llvm
In-Reply-To: <20260331163716.work.696-kees@kernel.org>
Exercise the end-to-end build and trap infrastructure in the kernel for
__ob_trap, __ob_wrap, and associated sanitizer ignore patterns (i.e. idiom
exclusions). Add a test for each of the basic overflow conditions under
CONFIG_OVERFLOW_BEHAVIOR_TYPES=y, as well as the corner cases associated
with promotion, casting, etc.
For example, executing this test with CONFIG_OVERFLOW_BEHAVIOR_TYPES_WARN=y
(instead of CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP=y), will show:
$ echo OBT_ASSIGN_TRUNCATE_TO | cat >/sys/kernel/debug/provoke-crash/DIRECT
$ dmesg
...
lkdtm: Performing direct entry OBT_ASSIGN_TRUNCATE_TO
UBSAN: implicit-conversion in ../drivers/misc/lkdtm/bugs.c:825:10
cannot represent 'int' value 2147483647 during reference binding to 'u8t' (aka '__ob_trap u8'), truncated to 255
Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: <linux-kselftest@vger.kernel.org>
---
drivers/misc/lkdtm/bugs.c | 253 ++++++++++++++++++++++++
tools/testing/selftests/lkdtm/tests.txt | 10 +
2 files changed, 263 insertions(+)
diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c
index e0098f314570..f00c9099957e 100644
--- a/drivers/misc/lkdtm/bugs.c
+++ b/drivers/misc/lkdtm/bugs.c
@@ -817,6 +817,249 @@ static noinline void lkdtm_CORRUPT_PAC(void)
#endif
}
+static void lkdtm_OBT_ASSIGN_TRUNCATE_TO(void)
+{
+ volatile int big = INT_MAX;
+ volatile int wide_low_value = 5;
+ u8 __ob_trap narrow_low_value = 0;
+ s32 __ob_trap same = 0;
+ u8 __ob_trap small = 0;
+
+ pr_info("Performing same-width assignment to OBT\n");
+ same = big;
+
+ pr_info("Performing small-value assignment to OBT\n");
+ narrow_low_value = wide_low_value;
+
+ pr_info("Expecting trap on truncated assignment to OBT\n");
+ small = big;
+
+ pr_err("FAIL: survived overflowing truncated assignment to OBT: %d -> %u (ok: %d -> %u)\n",
+ same, small, wide_low_value, narrow_low_value);
+ pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
+}
+
+static void lkdtm_OBT_ASSIGN_TRUNCATE_FROM(void)
+{
+ volatile s32 __ob_trap big = INT_MAX;
+ volatile s32 __ob_trap wide_low_value = 5;
+ u8 narrow_low_value = 0;
+ s32 same = 0;
+ u8 small = 0;
+
+ pr_info("Performing same-width assignment from OBT\n");
+ same = big;
+
+ pr_info("Performing small-value assignment from OBT\n");
+ narrow_low_value = wide_low_value;
+
+ pr_info("Expecting trap on truncated assignment from OBT\n");
+ small = big;
+
+ pr_err("FAIL: survived overflowing truncated assignment from OBT: %d -> %u (ok: %d -> %u)\n",
+ same, small, wide_low_value, narrow_low_value);
+ pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
+}
+
+static void lkdtm_OBT_CAST_TRUNCATE(void)
+{
+ volatile u32 __ob_trap big = INT_MAX;
+ u32 trunc = 0;
+ u32 small = 0;
+
+ pr_info("Performing wrapping too-small cast\n");
+ trunc = (u16 __ob_wrap)big;
+
+ pr_info("Expecting trap on too-small cast\n");
+ small = (s16)big;
+
+ pr_err("FAIL: survived truncated casting: %u -> %u (ok: %u -> %u)\n",
+ big, small, big, trunc);
+ pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
+}
+
+static void lkdtm_OBT_CAST_SIGNED(void)
+{
+ volatile u32 __ob_trap big = UINT_MAX;
+ s32 neg = 0;
+ s32 small = 0;
+
+ pr_info("Performing explicit sign-changing cast\n");
+ neg = (s32 __ob_wrap)big;
+
+ pr_info("Expecting trap on unexpected sign-changing cast\n");
+ small = (s32)big;
+
+ pr_err("FAIL: survived lossy sign conversion: %u -> %d (forced: %u -> %d)\n",
+ big, small, big, neg);
+ pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
+}
+
+static void lkdtm_OBT_MUL(void)
+{
+ /* Promotion means no overflow checking can happen. */
+ volatile u8 __ob_trap a8 = 100;
+ volatile u8 __ob_trap b8 = 3;
+ unsigned int promoted;
+ /* 32-bit or larger, however, get checked. */
+ volatile u32 __ob_trap a = UINT_MAX - 1;
+ volatile u32 __ob_trap b = 2;
+ unsigned long long happy;
+ unsigned long long outcome;
+
+ /* Promotion means a * b happens as "int __ob_trap", so no trap. */
+ pr_info("Performing promoted overflowing unsigned multiplication\n");
+ promoted = a8 * b8;
+
+ pr_info("Performing non-overflowing unsigned multiplication\n");
+ happy = b * b;
+
+ pr_info("Expecting trap on overflowing unsigned multiplication\n");
+ outcome = a * b;
+
+ pr_err("FAIL: survived unsigned multiplication overflow: %u * %u -> %llu (ok: %u * %u -> %llu, %u)\n",
+ a, b, outcome, b, b, happy, promoted);
+ pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
+}
+
+static void lkdtm_OBT_MUL_SIGNED(void)
+{
+ /* Promotion means no overflow checking can happen. */
+ volatile s8 __ob_trap a8 = 100;
+ volatile s8 __ob_trap b8 = 3;
+ int promoted;
+ /* 32-bit or larger, however, get checked. */
+ volatile s32 __ob_trap a = INT_MAX - 1;
+ volatile s32 __ob_trap b = 2;
+ signed long long happy;
+ signed long long outcome;
+
+ /* Promotion means a8 * b8 happens as "int __ob_trap", so no trap. */
+ pr_info("Performing promoted overflowing signed multiplication\n");
+ promoted = a8 * b8;
+
+ pr_info("Performing non-overflowing signed multiplication\n");
+ happy = b * b;
+
+ pr_info("Expecting trap on overflowing signed multiplication\n");
+ outcome = a * b;
+
+ pr_err("FAIL: survived signed multiplication overflow: %d * %d -> %lld (ok: %d * %d -> %lld, %d)\n",
+ a, b, outcome, b, b, happy, promoted);
+ pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
+}
+
+static void lkdtm_OBT_ADD(void)
+{
+ /* Promotion means no overflow checking can happen. */
+ volatile u8 __ob_trap a8 = 250;
+ volatile u8 __ob_trap b8 = 30;
+ unsigned int promoted;
+ /* 32-bit or larger, however, get checked. */
+ volatile u32 __ob_trap a = UINT_MAX - 1;
+ volatile u32 __ob_trap b = 2;
+ unsigned long long happy;
+ unsigned long long outcome;
+
+ /* Promotion means a8 + b8 happens as "int __ob_trap", so no trap. */
+ pr_info("Performing promoted overflowing unsigned addition\n");
+ promoted = a8 + b8;
+
+ pr_info("Performing idiomatic unsigned overflow addition test\n");
+ if (a + b < a) {
+ /* Report status so test isn't elided by compiler. */
+ pr_info("ok: overflow contained by conditional\n");
+ }
+
+ pr_info("Performing non-overflowing unsigned addition\n");
+ happy = b + b;
+
+ pr_info("Expecting trap on overflowing unsigned addition\n");
+ outcome = a + b;
+
+ pr_err("FAIL: survived unsigned addition overflow: %u + %u -> %llu (ok: %u + %u -> %llu)\n",
+ a, b, outcome, b, b, happy);
+ pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
+}
+
+static void lkdtm_OBT_ADD_SIGNED(void)
+{
+ /* Promotion means no overflow checking can happen. */
+ volatile s8 __ob_trap a8 = 120;
+ volatile s8 __ob_trap b8 = 30;
+ int promoted;
+ /* 32-bit or larger, however, get checked. */
+ volatile s32 __ob_trap a = INT_MAX - 1;
+ volatile s32 __ob_trap b = 2;
+ signed long long happy;
+ signed long long outcome;
+
+ /* Promotion means a8 + b8 happens as "int __ob_trap", so no trap. */
+ pr_info("Performing promoted overflowing signed addition\n");
+ promoted = a8 + b8;
+
+ pr_info("Performing idiomatic signed overflow addition test\n");
+ if (a + b < a) {
+ /* Report status so test isn't elided by compiler. */
+ pr_info("ok: overflow contained by conditional\n");
+ }
+
+ pr_info("Performing non-overflowing signed addition\n");
+ happy = b + b;
+
+ pr_info("Expecting trap on overflowing signed addition\n");
+ outcome = a + b;
+
+ pr_err("FAIL: survived signed addition overflow: %u + %u -> %llu (ok: %u + %u -> %llu)\n",
+ a, b, outcome, b, b, happy);
+ pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
+}
+
+static void lkdtm_OBT_NEGATED_UNSIGNED(void)
+{
+ volatile unsigned long __ob_trap value = 256;
+ size_t outcome;
+
+ pr_info("Expecting trap on overflowing unsigned negation\n");
+ outcome = value & -value;
+
+ pr_err("FAIL: survived negated unsigned value: %lu -> %zu\n",
+ value, outcome);
+ pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
+}
+
+static void lkdtm_OBT_POSTFIX_OPERATORS(void)
+{
+ volatile int target = 300;
+ volatile int flag = 0;
+ int i;
+ u8 __ob_wrap wrapper = 0; /* Explicitly wrapping. */
+ u8 __ob_trap counter = 0;
+
+ pr_info("Performing u8 __ob_wrap post-increment past 255\n");
+ for (i = 0; i < target; i++)
+ wrapper++;
+ if (wrapper != 44)
+ pr_err("FAIL: wrapped incorrecty: %u\n", wrapper);
+
+ pr_info("Performing idiomatic post-decrement zero test\n");
+ counter = target / 2;
+ while (counter--)
+ if (flag)
+ break;
+ if (counter != 255)
+ pr_err("FAIL: u8 __ob_trap post-decrement zero-test did not wrap: %u\n",
+ counter);
+
+ pr_info("Expecting trap on u8 __ob_trap post-increment past 255\n");
+ counter = 0;
+ for (i = 0; i < target; i++)
+ counter++;
+
+ pr_err("FAIL: survived overflowed post-increment: %u\n", counter);
+ pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
+}
+
static struct crashtype crashtypes[] = {
CRASHTYPE(PANIC),
CRASHTYPE(PANIC_STOP_IRQOFF),
@@ -850,6 +1093,16 @@ static struct crashtype crashtypes[] = {
CRASHTYPE(UNSET_SMEP),
CRASHTYPE(DOUBLE_FAULT),
CRASHTYPE(CORRUPT_PAC),
+ CRASHTYPE(OBT_ASSIGN_TRUNCATE_TO),
+ CRASHTYPE(OBT_ASSIGN_TRUNCATE_FROM),
+ CRASHTYPE(OBT_CAST_TRUNCATE),
+ CRASHTYPE(OBT_CAST_SIGNED),
+ CRASHTYPE(OBT_MUL),
+ CRASHTYPE(OBT_MUL_SIGNED),
+ CRASHTYPE(OBT_ADD),
+ CRASHTYPE(OBT_ADD_SIGNED),
+ CRASHTYPE(OBT_NEGATED_UNSIGNED),
+ CRASHTYPE(OBT_POSTFIX_OPERATORS),
};
struct crashtype_category bugs_crashtypes = {
diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt
index e62b85b591be..231299ba3959 100644
--- a/tools/testing/selftests/lkdtm/tests.txt
+++ b/tools/testing/selftests/lkdtm/tests.txt
@@ -87,3 +87,13 @@ FORTIFY_STR_MEMBER detected buffer overflow
FORTIFY_MEM_OBJECT detected buffer overflow
FORTIFY_MEM_MEMBER detected field-spanning write
PPC_SLB_MULTIHIT Recovered
+OBT_ASSIGN_TRUNCATE_TO traps: UBSAN: integer truncation
+OBT_ASSIGN_TRUNCATE_FROM traps: UBSAN: integer truncation
+OBT_CAST_TRUNCATE traps: UBSAN: integer truncation
+OBT_CAST_SIGNED traps: UBSAN: integer truncation
+OBT_MUL traps: UBSAN: integer multiplication overflow
+OBT_MUL_SIGNED traps: UBSAN: integer multiplication overflow
+OBT_ADD traps: UBSAN: integer addition overflow
+OBT_ADD_SIGNED traps: UBSAN: integer addition overflow
+OBT_NEGATED_UNSIGNED traps: UBSAN: negation overflow
+OBT_POSTFIX_OPERATORS traps: UBSAN: integer truncation
--
2.34.1
^ permalink raw reply related
* [PATCH 2/5] hardening: Introduce Overflow Behavior Types support
From: Kees Cook @ 2026-03-31 16:37 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Kees Cook, Justin Stitt, Nathan Chancellor, Nicolas Schier,
linux-kbuild, kasan-dev, Linus Torvalds, Marco Elver,
Jonathan Corbet, Arnd Bergmann, Greg Kroah-Hartman, Miguel Ojeda,
Andrew Morton, linux-kernel, linux-hardening, linux-doc, llvm
In-Reply-To: <20260331163716.work.696-kees@kernel.org>
From: Justin Stitt <justinstitt@google.com>
Replace CONFIG_UBSAN_INTEGER_WRAP with CONFIG_OVERFLOW_BEHAVIOR_TYPES,
which a more distinct implementation of the integer wrapping logic,
with the introduction of the Overflow Behavior Types in Clang 23+. While
this uses sanitizers, it isn't really part of the "undefined behavior"
sanitizer collection (there is nothing "undefined" going on, but the
warn/trap infrastructure is still used for common instrumentation).
As OBTs will be annotated in code, we no longer need type annotation in
the sanitizer SCL file. A build with CONFIG_OVERFLOW_BEHAVIOR_TYPES=y
will result in no new instrumentation being added (as there are no users
of the coming __ob_trap and __ob_wrap annotations yet).
Signed-off-by: Justin Stitt <justinstitt@google.com>
Co-developed-by: Kees Cook <kees@kernel.org>
Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nsc@kernel.org>
Cc: <linux-kbuild@vger.kernel.org>
Cc: <kasan-dev@googlegroups.com>
---
lib/Kconfig.ubsan | 18 ------------
security/Kconfig.hardening | 50 +++++++++++++++++++++++++++++++-
Makefile | 1 +
scripts/basic/Makefile | 2 +-
scripts/Makefile.lib | 7 +++--
scripts/Makefile.obt | 28 ++++++++++++++++++
scripts/Makefile.ubsan | 10 -------
scripts/Makefile.warn | 7 +++++
scripts/integer-wrap-ignore.scl | 3 +-
include/linux/compiler-version.h | 2 +-
include/linux/sched.h | 3 +-
include/linux/ubsan.h | 12 +++++++-
lib/ubsan.c | 17 ++++++-----
MAINTAINERS | 9 ++++++
kernel/configs/hardening.config | 1 -
15 files changed, 125 insertions(+), 45 deletions(-)
create mode 100644 scripts/Makefile.obt
diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
index 1ecaae7064d2..666286e0d294 100644
--- a/lib/Kconfig.ubsan
+++ b/lib/Kconfig.ubsan
@@ -116,24 +116,6 @@ config UBSAN_UNREACHABLE
This option enables -fsanitize=unreachable which checks for control
flow reaching an expected-to-be-unreachable position.
-config UBSAN_INTEGER_WRAP
- bool "Perform checking for integer arithmetic wrap-around"
- # This is very experimental so drop the next line if you really want it
- depends on BROKEN
- depends on !COMPILE_TEST
- depends on $(cc-option,-fsanitize-undefined-ignore-overflow-pattern=all)
- depends on $(cc-option,-fsanitize=signed-integer-overflow)
- depends on $(cc-option,-fsanitize=unsigned-integer-overflow)
- depends on $(cc-option,-fsanitize=implicit-signed-integer-truncation)
- depends on $(cc-option,-fsanitize=implicit-unsigned-integer-truncation)
- depends on $(cc-option,-fsanitize-ignorelist=/dev/null)
- help
- This option enables all of the sanitizers involved in integer overflow
- (wrap-around) mitigation: signed-integer-overflow, unsigned-integer-overflow,
- implicit-signed-integer-truncation, and implicit-unsigned-integer-truncation.
- This is currently limited only to the size_t type while testing and
- compiler development continues.
-
config UBSAN_BOOL
bool "Perform checking for non-boolean values used as boolean"
default UBSAN
diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
index 86f8768c63d4..0c9e03c8a5a7 100644
--- a/security/Kconfig.hardening
+++ b/security/Kconfig.hardening
@@ -211,7 +211,55 @@ config ZERO_CALL_USED_REGS
endmenu
-menu "Bounds checking"
+menu "Bounds safety"
+
+config CC_HAS_OVERFLOW_BEHAVIOR_TYPES
+ # Clang 23+
+ depends on CC_IS_CLANG
+ def_bool $(cc-option,-Xclang -fexperimental-overflow-behavior-types)
+
+config OVERFLOW_BEHAVIOR_TYPES
+ bool
+ help
+ Selected if either OVERFLOW_BEHAVIOR_TYPES_TRAP or
+ OVERFLOW_BEHAVIOR_TYPES_WARN is chosen.
+
+choice
+ prompt "Perform checking for integer arithmetic wrap-around"
+ default OVERFLOW_BEHAVIOR_TYPES_TRAP if CC_HAS_OVERFLOW_BEHAVIOR_TYPES
+ default OVERFLOW_BEHAVIOR_TYPES_WARN if COMPILE_TEST && CC_HAS_OVERFLOW_BEHAVIOR_TYPES
+ default OVERFLOW_BEHAVIOR_TYPES_NONE
+ help
+ This option enables Overflow Behavior Types and all of the
+ sanitizers involved in integer overflow (wrap-around) mitigation:
+ signed-integer-overflow, unsigned-integer-overflow,
+ implicit-signed-integer-truncation, implicit-unsigned-integer-truncation,
+ and implicit-integer-sign-change. Only types (and variables)
+ annotated with __ob_wrap or __ob_trap will be instrumented by the
+ compiler.
+
+ config OVERFLOW_BEHAVIOR_TYPES_TRAP
+ bool "Trap when __ob_trap types overflow (mitigate)"
+ depends on CC_HAS_OVERFLOW_BEHAVIOR_TYPES
+ select OVERFLOW_BEHAVIOR_TYPES
+ help
+ Enables Overflow Behavior Types and traps when __ob_trap
+ annotated variables overflow or underflow.
+
+ config OVERFLOW_BEHAVIOR_TYPES_WARN
+ bool "Warn when __ob_trap types overflow (informational)"
+ depends on CC_HAS_OVERFLOW_BEHAVIOR_TYPES
+ select OVERFLOW_BEHAVIOR_TYPES
+ help
+ Enables Overflow Behavior Types and warns when __ob_trap
+ annotated variables overflow or underflow.
+
+ config OVERFLOW_BEHAVIOR_TYPES_NONE
+ bool "Disable any handling of __ob_trap types (disabled)"
+ help
+ No special handling of __ob_trap annotated types.
+
+endchoice
config FORTIFY_SOURCE
bool "Harden common str/mem functions against buffer overflows"
diff --git a/Makefile b/Makefile
index 2446085983f7..8e7336d22488 100644
--- a/Makefile
+++ b/Makefile
@@ -1123,6 +1123,7 @@ include-$(CONFIG_KASAN) += scripts/Makefile.kasan
include-$(CONFIG_KCSAN) += scripts/Makefile.kcsan
include-$(CONFIG_KMSAN) += scripts/Makefile.kmsan
include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan
+include-$(CONFIG_OVERFLOW_BEHAVIOR_TYPES) += scripts/Makefile.obt
include-$(CONFIG_KCOV) += scripts/Makefile.kcov
include-$(CONFIG_RANDSTRUCT) += scripts/Makefile.randstruct
include-$(CONFIG_KSTACK_ERASE) += scripts/Makefile.kstack_erase
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index fb8e2c38fbc7..098760fc403a 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -18,4 +18,4 @@ always-$(CONFIG_RANDSTRUCT) += randstruct.seed
# integer-wrap: if the .scl file changes, we need to do a full rebuild.
$(obj)/../../include/generated/integer-wrap.h: $(srctree)/scripts/integer-wrap-ignore.scl FORCE
$(call if_changed,touch)
-always-$(CONFIG_UBSAN_INTEGER_WRAP) += ../../include/generated/integer-wrap.h
+always-$(CONFIG_OVERFLOW_BEHAVIOR_TYPES) += ../../include/generated/integer-wrap.h
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0718e39cedda..d0e5cf2b0e3f 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -76,9 +76,12 @@ ifeq ($(CONFIG_UBSAN),y)
_c_flags += $(if $(patsubst n%,, \
$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SANITIZE)$(is-kernel-object)), \
$(CFLAGS_UBSAN))
+endif
+
+ifeq ($(CONFIG_OVERFLOW_BEHAVIOR_TYPES),y)
_c_flags += $(if $(patsubst n%,, \
- $(UBSAN_INTEGER_WRAP_$(target-stem).o)$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_INTEGER_WRAP)$(UBSAN_SANITIZE)$(is-kernel-object)), \
- $(CFLAGS_UBSAN_INTEGER_WRAP))
+ $(OVERFLOW_BEHAVIOR_TYPES_$(target-stem).o)$(OVERFLOW_BEHAVIOR_TYPES)$(is-kernel-object)), \
+ $(CFLAGS_OVERFLOW_BEHAVIOR_TYPES))
endif
ifeq ($(CONFIG_KCOV),y)
diff --git a/scripts/Makefile.obt b/scripts/Makefile.obt
new file mode 100644
index 000000000000..f87f87e148f9
--- /dev/null
+++ b/scripts/Makefile.obt
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Instead of specifying `all`, let's pick our patterns piecemeal so we aren't
+# blindsided by compiler upgrades.
+OVERFLOW_BEHAVIOR_TYPES_IGNORE_PATTERNS := negated-unsigned-const,$\
+ unsigned-post-decr-while,$\
+ add-signed-overflow-test,$\
+ add-unsigned-overflow-test
+
+OVERFLOW_BEHAVIOR_TYPES_SANITIZERS := signed-integer-overflow,$\
+ unsigned-integer-overflow,$\
+ implicit-signed-integer-truncation,$\
+ implicit-unsigned-integer-truncation,$\
+ implicit-integer-sign-change
+
+overflow-behavior-types-cflags-$(CONFIG_OVERFLOW_BEHAVIOR_TYPES) += \
+ -DOVERFLOW_BEHAVIOR_TYPES \
+ -Xclang -fexperimental-overflow-behavior-types \
+ -fsanitize=$(OVERFLOW_BEHAVIOR_TYPES_SANITIZERS) \
+ -fsanitize-undefined-ignore-overflow-pattern=$(OVERFLOW_BEHAVIOR_TYPES_IGNORE_PATTERNS) \
+ -fsanitize-ignorelist=$(srctree)/scripts/integer-wrap-ignore.scl \
+ -Wno-incompatible-pointer-types-discards-overflow-behavior
+overflow-behavior-types-cflags-$(CONFIG_OVERFLOW_BEHAVIOR_TYPES_WARN) += \
+ -fno-sanitize-trap=$(OVERFLOW_BEHAVIOR_TYPES_SANITIZERS)
+overflow-behavior-types-cflags-$(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP) += \
+ -fsanitize-trap=$(OVERFLOW_BEHAVIOR_TYPES_SANITIZERS)
+
+export CFLAGS_OVERFLOW_BEHAVIOR_TYPES := $(overflow-behavior-types-cflags-y)
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
index 734a102e6b56..fb49302078e5 100644
--- a/scripts/Makefile.ubsan
+++ b/scripts/Makefile.ubsan
@@ -16,13 +16,3 @@ ubsan-cflags-$(CONFIG_UBSAN_ENUM) += -fsanitize=enum
ubsan-cflags-$(CONFIG_UBSAN_TRAP) += $(CFLAGS_UBSAN_TRAP)
export CFLAGS_UBSAN := $(ubsan-cflags-y)
-
-ubsan-integer-wrap-cflags-$(CONFIG_UBSAN_INTEGER_WRAP) += \
- -DINTEGER_WRAP \
- -fsanitize-undefined-ignore-overflow-pattern=all \
- -fsanitize=signed-integer-overflow \
- -fsanitize=unsigned-integer-overflow \
- -fsanitize=implicit-signed-integer-truncation \
- -fsanitize=implicit-unsigned-integer-truncation \
- -fsanitize-ignorelist=$(srctree)/scripts/integer-wrap-ignore.scl
-export CFLAGS_UBSAN_INTEGER_WRAP := $(ubsan-integer-wrap-cflags-y)
diff --git a/scripts/Makefile.warn b/scripts/Makefile.warn
index 5567da6c7dfe..eae0ecb88da4 100644
--- a/scripts/Makefile.warn
+++ b/scripts/Makefile.warn
@@ -49,6 +49,13 @@ KBUILD_CFLAGS += $(call cc-option, -Wno-format-truncation-non-kprintf)
# because -Wuninitialized will still flag when an uninitialized const variable
# is used.
KBUILD_CFLAGS += $(call cc-option, -Wno-default-const-init-unsafe)
+
+# Clang with Overflow Behavior Types support but building a kernel without
+# CONFIG_OVERFLOW_BEHAVIOR_TYPES needs to explicitly ignore the attribute.
+ifndef CONFIG_OVERFLOW_BEHAVIOR_TYPES
+KBUILD_CFLAGS += $(call cc-option, -Wno-overflow-behavior-attribute-ignored)
+endif
+
else
# gcc inanely warns about local variables called 'main'
diff --git a/scripts/integer-wrap-ignore.scl b/scripts/integer-wrap-ignore.scl
index 431c3053a4a2..8168d376ffff 100644
--- a/scripts/integer-wrap-ignore.scl
+++ b/scripts/integer-wrap-ignore.scl
@@ -1,3 +1,2 @@
-[{unsigned-integer-overflow,signed-integer-overflow,implicit-signed-integer-truncation,implicit-unsigned-integer-truncation}]
+[{unsigned-integer-overflow,signed-integer-overflow,implicit-signed-integer-truncation,implicit-unsigned-integer-truncation,implicit-integer-sign-change}]
type:*
-type:size_t=sanitize
diff --git a/include/linux/compiler-version.h b/include/linux/compiler-version.h
index ac1665a98a15..20033781ff15 100644
--- a/include/linux/compiler-version.h
+++ b/include/linux/compiler-version.h
@@ -39,6 +39,6 @@
* may have changed, which may impact the expected behaviors that should
* not differ between compilation units.
*/
-#ifdef INTEGER_WRAP
+#ifdef OVERFLOW_BEHAVIOR_TYPES
#include <generated/integer-wrap.h>
#endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index a7b4a980eb2f..d3e2ae0e2fe4 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -48,6 +48,7 @@
#include <linux/uidgid_types.h>
#include <linux/tracepoint-defs.h>
#include <linux/unwind_deferred_types.h>
+#include <linux/ubsan.h>
#include <asm/kmap_size.h>
#include <linux/time64.h>
#ifndef COMPILE_OFFSETS
@@ -1271,7 +1272,7 @@ struct task_struct {
struct held_lock held_locks[MAX_LOCK_DEPTH];
#endif
-#if defined(CONFIG_UBSAN) && !defined(CONFIG_UBSAN_TRAP)
+#ifdef NEED_SANITIZER_WARN_HANDLER
unsigned int in_ubsan;
#endif
diff --git a/include/linux/ubsan.h b/include/linux/ubsan.h
index 3ab8d38aedb8..7fedff0cdf8e 100644
--- a/include/linux/ubsan.h
+++ b/include/linux/ubsan.h
@@ -2,7 +2,17 @@
#ifndef _LINUX_UBSAN_H
#define _LINUX_UBSAN_H
-#if defined(CONFIG_UBSAN_TRAP) || defined(CONFIG_UBSAN_KVM_EL2)
+#if defined(CONFIG_UBSAN_TRAP) || defined(CONFIG_UBSAN_KVM_EL2) || \
+ defined(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP)
+# define NEED_SANITIZER_TRAP_HANDLER
+#endif
+
+#if (defined(CONFIG_UBSAN) && !defined(CONFIG_UBSAN_TRAP)) || \
+ defined(CONFIG_OVERFLOW_BEHAVIOR_TYPES_WARN)
+# define NEED_SANITIZER_WARN_HANDLER
+#endif
+
+#ifdef NEED_SANITIZER_TRAP_HANDLER
const char *report_ubsan_failure(u32 check_type);
#else
static inline const char *report_ubsan_failure(u32 check_type)
diff --git a/lib/ubsan.c b/lib/ubsan.c
index 456e3dd8f4ea..19edb5cedb5a 100644
--- a/lib/ubsan.c
+++ b/lib/ubsan.c
@@ -19,7 +19,7 @@
#include "ubsan.h"
-#if defined(CONFIG_UBSAN_TRAP) || defined(CONFIG_UBSAN_KVM_EL2)
+#ifdef NEED_SANITIZER_TRAP_HANDLER
/*
* Only include matches for UBSAN checks that are actually compiled in.
* The mappings of struct SanitizerKind (the -fsanitize=xxx args) to
@@ -44,7 +44,7 @@ const char *report_ubsan_failure(u32 check_type)
case ubsan_shift_out_of_bounds:
return "UBSAN: shift out of bounds";
#endif
-#if defined(CONFIG_UBSAN_DIV_ZERO) || defined(CONFIG_UBSAN_INTEGER_WRAP)
+#if defined(CONFIG_UBSAN_DIV_ZERO) || defined(CONFIG_OVERFLOW_BEHAVIOR_TYPES)
/*
* SanitizerKind::IntegerDivideByZero and
* SanitizerKind::SignedIntegerOverflow emit
@@ -79,7 +79,7 @@ const char *report_ubsan_failure(u32 check_type)
case ubsan_type_mismatch:
return "UBSAN: type mismatch";
#endif
-#ifdef CONFIG_UBSAN_INTEGER_WRAP
+#ifdef CONFIG_OVERFLOW_BEHAVIOR_TYPES
/*
* SanitizerKind::SignedIntegerOverflow emits
* SanitizerHandler::AddOverflow, SanitizerHandler::SubOverflow,
@@ -91,15 +91,18 @@ const char *report_ubsan_failure(u32 check_type)
return "UBSAN: integer subtraction overflow";
case ubsan_mul_overflow:
return "UBSAN: integer multiplication overflow";
+ case ubsan_implicit_conversion:
+ return "UBSAN: integer truncation";
+ case ubsan_negate_overflow:
+ return "UBSAN: negation overflow";
#endif
default:
return "UBSAN: unrecognized failure code";
}
}
+#endif /* NEED_SANITIZER_TRAP_HANDLER */
-#endif
-
-#ifndef CONFIG_UBSAN_TRAP
+#ifdef NEED_SANITIZER_WARN_HANDLER
static const char * const type_check_kinds[] = {
"load of",
"store to",
@@ -558,4 +561,4 @@ void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr,
}
EXPORT_SYMBOL(__ubsan_handle_alignment_assumption);
-#endif /* !CONFIG_UBSAN_TRAP */
+#endif /* NEED_SANITIZER_WARN_HANDLER */
diff --git a/MAINTAINERS b/MAINTAINERS
index 61bf550fd37c..a9f067164203 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19919,6 +19919,15 @@ F: Documentation/devicetree/bindings/media/i2c/ovti,ov2659.txt
F: drivers/media/i2c/ov2659.c
F: include/media/i2c/ov2659.h
+OVERFLOW BEHAVIOR TYPES
+M: Kees Cook <kees@kernel.org>
+M: Justin Stitt <justinstitt@google.com>
+L: linux-hardening@vger.kernel.org
+S: Supported
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
+F: scripts/integer-wrap-ignore.scl
+F: scripts/Makefile.obt
+
OVERLAY FILESYSTEM
M: Miklos Szeredi <miklos@szeredi.hu>
M: Amir Goldstein <amir73il@gmail.com>
diff --git a/kernel/configs/hardening.config b/kernel/configs/hardening.config
index 7c3924614e01..aabe28005a3d 100644
--- a/kernel/configs/hardening.config
+++ b/kernel/configs/hardening.config
@@ -46,7 +46,6 @@ CONFIG_UBSAN_BOUNDS=y
# CONFIG_UBSAN_SHIFT is not set
# CONFIG_UBSAN_DIV_ZERO is not set
# CONFIG_UBSAN_UNREACHABLE is not set
-# CONFIG_UBSAN_INTEGER_WRAP is not set
# CONFIG_UBSAN_BOOL is not set
# CONFIG_UBSAN_ENUM is not set
# CONFIG_UBSAN_ALIGNMENT is not set
--
2.34.1
^ permalink raw reply related
* [PATCH 0/5] Introduce Overflow Behavior Types
From: Kees Cook @ 2026-03-31 16:37 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Kees Cook, Justin Stitt, Linus Torvalds, Marco Elver,
Jonathan Corbet, Nathan Chancellor, Nicolas Schier, Arnd Bergmann,
Greg Kroah-Hartman, Miguel Ojeda, Andrew Morton, linux-kernel,
kasan-dev, linux-hardening, linux-doc, linux-kbuild, llvm
Hi,
This is the spiritual successor to the "Mitigating unexpected arithmetic
overflow" thread from 2024[1]. After a long discussion there, and
subsequent discussions with Peter at Linux Plumbers, Justin went off to
build a type-based solution. After more than a year of RFCs and feedback
from compiler folks and with an eye toward potentially making this part
of the C Standard in the future, what has evolved is Overflow Behavior
Types[2], which are first-class native types that mirror the existing
native scalar types in C. They are created using a type qualifier
("__ob_trap" and "__ob_wrap"), but they are their own distinct
types. e.g. "int" and "int __ob_trap" are different types, though
they are mostly interchangable (e.g. format strings, implicit casts,
etc), with some specific instrumentation in cases where wrap-around or
truncation is possible.
This series provides support for building with them enabled, adds
documentation, adds tests, and proposes the new typedefs (see the last
patch in the series) for the corresponding kernel scalar types. With this,
we can start converting variables (and types) that are never supposed
to overflow/underflow to these new types[3]. (Or types that are always
supposed to overflow/underflow.)
Enjoy! :)
-Kees
Link: https://lore.kernel.org/lkml/202404291502.612E0A10@keescook/ [1]
Link: https://clang.llvm.org/docs/OverflowBehaviorTypes.html [2]
Justin Stitt (2):
hardening: Introduce Overflow Behavior Types support
compiler_attributes: Add overflow_behavior macros __ob_trap and
__ob_wrap
Kees Cook (3):
refcount: Remove unused __signed_wrap function annotations
lkdtm/bugs: Add basic Overflow Behavior Types test
types: Add standard __ob_trap and __ob_wrap scalar types
lib/Kconfig.ubsan | 18 -
security/Kconfig.hardening | 50 ++-
Makefile | 1 +
scripts/basic/Makefile | 2 +-
scripts/Makefile.lib | 7 +-
scripts/Makefile.obt | 28 ++
scripts/Makefile.ubsan | 10 -
scripts/Makefile.warn | 7 +
scripts/integer-wrap-ignore.scl | 3 +-
Documentation/dev-tools/ubsan.rst | 13 +
Documentation/process/arithmetic-overflow.rst | 323 ++++++++++++++++++
Documentation/process/deprecated.rst | 39 +++
Documentation/process/index.rst | 1 +
include/linux/compiler-version.h | 2 +-
include/linux/compiler_attributes.h | 12 +
include/linux/compiler_types.h | 9 +-
include/linux/refcount.h | 10 +-
include/linux/sched.h | 3 +-
include/linux/types.h | 24 ++
include/linux/ubsan.h | 12 +-
drivers/misc/lkdtm/bugs.c | 253 ++++++++++++++
lib/ubsan.c | 17 +-
MAINTAINERS | 10 +
kernel/configs/hardening.config | 1 -
tools/testing/selftests/lkdtm/tests.txt | 10 +
25 files changed, 807 insertions(+), 58 deletions(-)
create mode 100644 scripts/Makefile.obt
create mode 100644 Documentation/process/arithmetic-overflow.rst
--
2.34.1
^ permalink raw reply
* [PATCH 3/5] compiler_attributes: Add overflow_behavior macros __ob_trap and __ob_wrap
From: Kees Cook @ 2026-03-31 16:37 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Kees Cook, Justin Stitt, Marco Elver, Andrey Konovalov,
Andrey Ryabinin, Jonathan Corbet, Shuah Khan, Miguel Ojeda,
Nathan Chancellor, kasan-dev, linux-doc, llvm, Linus Torvalds,
Nicolas Schier, Arnd Bergmann, Greg Kroah-Hartman, Andrew Morton,
linux-kernel, linux-hardening, linux-kbuild
In-Reply-To: <20260331163716.work.696-kees@kernel.org>
From: Justin Stitt <justinstitt@google.com>
When CONFIG_OVERFLOW_BEHAVIOR_TYPES=y, Clang 23+'s Overflow Behavior
Type[1] annotations are available (i.e. __ob_trap, __ob_wrap). When not
enabled, these need to be empty macros. Document the new annotation and
add links from sanitizer docs pointing to the arithmetic-overflow docs.
Link: https://clang.llvm.org/docs/OverflowBehaviorTypes.html [1]
Signed-off-by: Justin Stitt <justinstitt@google.com>
Co-developed-by: Kees Cook <kees@kernel.org>
Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: Marco Elver <elver@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: Miguel Ojeda <ojeda@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: <kasan-dev@googlegroups.com>
Cc: <linux-doc@vger.kernel.org>
Cc: <llvm@lists.linux.dev>
---
Documentation/dev-tools/ubsan.rst | 13 +
Documentation/process/arithmetic-overflow.rst | 323 ++++++++++++++++++
Documentation/process/deprecated.rst | 39 +++
Documentation/process/index.rst | 1 +
include/linux/compiler_attributes.h | 12 +
MAINTAINERS | 1 +
6 files changed, 389 insertions(+)
create mode 100644 Documentation/process/arithmetic-overflow.rst
diff --git a/Documentation/dev-tools/ubsan.rst b/Documentation/dev-tools/ubsan.rst
index e3591f8e9d5b..9e0c0f048eef 100644
--- a/Documentation/dev-tools/ubsan.rst
+++ b/Documentation/dev-tools/ubsan.rst
@@ -71,6 +71,19 @@ unaligned accesses (CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y). One could
still enable it in config, just note that it will produce a lot of UBSAN
reports.
+Additional sanitizer options include::
+
+ CONFIG_OVERFLOW_BEHAVIOR_TYPES=y
+
+This enables checking for integer arithmetic wrap-around (overflow/underflow).
+It instruments signed and unsigned integer overflow, as well as implicit
+truncation operations. This option is currently limited to specific types
+via the ``__ob_trap`` and ``__ob_wrap`` annotations.
+
+For detailed information about arithmetic overflow handling, overflow behavior
+annotations, and best practices, see:
+Documentation/process/arithmetic-overflow.rst
+
References
----------
diff --git a/Documentation/process/arithmetic-overflow.rst b/Documentation/process/arithmetic-overflow.rst
new file mode 100644
index 000000000000..2f19990f189b
--- /dev/null
+++ b/Documentation/process/arithmetic-overflow.rst
@@ -0,0 +1,323 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _arithmetic_overflow:
+
+Arithmetic Overflow Resolutions for Linux
+=========================================
+
+Background
+----------
+
+When a calculation's result exceeds the involved storage ranges, several
+strategies can be followed to handle such an overflow (or underflow),
+including:
+
+ - Undefined (i.e. pretend it's impossible and the result depends on hardware)
+ - Wrap around (this is what 2s-complement representation does by default)
+ - Trap (create an exception so the problem can be handled in another way)
+ - Saturate (explicitly hold the maximum or minimum representable value)
+
+In the C standard, three basic types can be involved in arithmetic, and each
+has a default strategy for solving the overflow problem:
+
+ - Signed overflow is undefined
+ - Unsigned overflow explicitly wraps around
+ - Pointer overflow is undefined
+
+The Linux kernel uses ``-fno-strict-overflow`` which implies ``-fwrapv``
+and ``-fwrapv-pointer`` which treats signed integer overflow and pointer
+overflow respectively as being consistent with two's complement. This flag
+allows for consistency within the codebase about the expectations of
+overflowing arithmetic as well as prevents eager compiler optimizations.
+Note that :ref:`open-coded intentional arithmetic wrap-around is deprecated <open_coded_wrap_around>`.
+
+From here on, arithmetic overflow concerning signed, unsigned, or
+pointer types will be referred to as "wrap-around" since it is the
+default strategy for the kernel. There is no such thing as "undefined
+behavior" for arithmetic in Linux: it always wraps.
+
+Overflow Behavior Types
+-----------------------
+
+The newly available ``__ob_trap`` and ``__ob_wrap`` annotations provide
+fine-grained control over overflow behavior. These can be applied to
+integer types to unambiguously specify how arithmetic operations are
+expected to behave upon overflow. Currently, only Clang supports these
+annotations. The annotation defines two possible overflow behaviors:
+
+* ``wrap``: Ensures arithmetic operations wrap on overflow, providing
+ well-defined two's complement semantics according to the bitwidth of the
+ underlying type, regardless of any associated ``-fwrapv`` options or
+ sanitizers (integer overflow and truncation checks are suppressed)
+* ``trap``: Enables overflow and truncation checking for the type, even when
+ associated ``-fwrapv`` options are enabled. Without the sanitizer enabled
+ the compiler emits a trap instruction, otherwise the integer overflow
+ and truncation warnings are emitted but execution continues.
+
+Note that the sanitizer infrastructure is used for instrumentation shows
+up in logs as the "Undefined Behavior" sanitizer (UBSan), which may be
+confusing. Instead this should be thought of as the "Unexpected Behavior"
+sanitizer. Its infrastructure is used to report on unexpected wrapping
+behaviors: none of integer operations are "undefined" any more, as per
+the use of ``-fno-strict-overflow``, but instead UBSan will kick in when
+a type is explicitly marked as non-wrapping (i.e. trapping).
+
+
+Enablement
+~~~~~~~~~~
+
+When supported by the compiler, kernels can build with either
+``CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP=y`` for trapping mode (i.e.
+mitigation enabled), or ``CONFIG_OVERFLOW_BEHAVIOR_TYPES_WARN=y`` which
+enables warn-only mode, which logs the overflows but will continue as
+if the type was not marked with ``__ob_trap``.
+
+Compiler Options
+^^^^^^^^^^^^^^^^
+
+Usage of the ``overflow_behavior`` attribute is gated behind the
+``-fexperimental-overflow-behavior-types`` compiler flag which
+is a ``-cc1`` flag, meaning the kernel passes it as ``-Xclang
+-fexperimental-overflow-behavior-types``.
+
+Sanitizer Case Lists
+^^^^^^^^^^^^^^^^^^^^
+
+Linux uses a Sanitizer Case List file to selectively enable certain
+sanitizers for specific types. Specifically, the overflow and truncation
+sanitizers have had their standard instrumentation disabled for all
+types. To "allowlist" specific types for instrumentation the kernel
+makes use of the in-source ``__ob_trap`` annotations to gain reporting
+by the sanitizers.
+
+Currently, type-based entries within a sanitizer case list are only
+supported by Clang. For more information on the syntax for SCL files
+refer to the Clang docs:
+https://clang.llvm.org/docs/SanitizerSpecialCaseList.html
+
+Syntax
+~~~~~~
+
+Creating Overflow Behavior Types is possible via two syntactic forms;
+
+**Attribute syntax:**
+
+.. code-block:: c
+
+ typedef unsigned int __attribute__((overflow_behavior(trap))) safe_uint;
+ typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint;
+
+**Keyword syntax:**
+
+.. code-block:: c
+
+ typedef unsigned int __ob_trap safe_uint;
+ typedef unsigned int __ob_wrap wrapping_uint;
+
+Both forms are semantically identical. The keyword syntax is shorter and can
+appear in the same positions as ``const`` or ``volatile``. The attribute syntax
+is more self-documenting, so Linux uses this form.
+
+When ``-fexperimental-overflow-behavior-types`` is not enabled, both the
+keywords (``__ob_wrap``, ``__ob_trap``) and the attribute are ignored with a
+warning.
+
+The feature can be queried with either
+``__has_extension(overflow_behavior_types)`` or
+``__has_attribute(overflow_behavior)``.
+
+Basic Usage
+^^^^^^^^^^^
+
+.. code-block:: c
+
+ typedef unsigned int __ob_wrap counter_t;
+ typedef unsigned long __ob_trap safe_size_type;
+
+ counter_t increment_counter(counter_t count) {
+ return count + 1;
+ }
+
+ safe_size_type calculate_buffer_size(safe_size_type base,
+ safe_size_type extra) {
+ return base + extra;
+ }
+
+In the first function, arithmetic on ``counter_t`` is well-defined
+wrapping. Its overflow will never be reported and unlike an plain
+``unsigned int`` its purpose is unambiguous: it is expected to wrap
+around. In the second function, arithmetic on ``safe_size_type`` is
+checked -- overflow will result in a trap or sanitizer report depending
+on the build configuration.
+
+Variables can be annotated directly:
+
+.. code-block:: c
+
+ void foo(int num) {
+ int __ob_trap a = num;
+ a += 42;
+
+ unsigned char __ob_wrap b = 255;
+ b += 10;
+ }
+
+
+Interaction with Compiler Options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Overflow behavior annotations override many global compiler flags and
+sanitizer configurations:
+
+* ``wrap`` types suppress UBSan's integer overflow checks
+ (``signed-integer-overflow``, ``unsigned-integer-overflow``) and implicit
+ truncation checks (``implicit-signed-integer-truncation``,
+ ``implicit-unsigned-integer-truncation``). They also suppress ``-ftrapv``
+ for the annotated type.
+* ``trap`` types enable overflow checking even when ``-fwrapv``
+ is globally enabled. When no sanitizer runtime is available, the compiler
+ emits a trap instruction directly.
+* Both forms override Sanitizer Special Case List (SSCL) entries.
+
+Common overflow idioms are excluded from instrumentation via
+``-fsanitize-undefined-ignore-overflow-pattern=``. These overflow idioms have
+their instrumentation withheld even under the presence of overflow behavior
+annotations. For more details see:
+https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#disabling-instrumentation-for-common-overflow-patterns
+
+Truncation Semantics
+^^^^^^^^^^^^^^^^^^^^
+
+Truncation and overflow are related -- both are often desirable in some
+contexts and undesirable in others. Overflow behavior types control truncation
+instrumentation at the type level as well:
+
+* If a ``trap`` type is involved as source or destination of a truncation, the
+ compiler inserts truncation checks. These will either trap or report via
+ sanitizer depending on the build configuration.
+* If a ``wrap`` type is involved as source or destination, truncation checks
+ are suppressed regardless of compiler flags.
+* If both ``trap`` and ``wrap`` are involved in the same truncation, ``wrap``
+ takes precedence (truncation checks are suppressed) since the explicit
+ wrapping intent covers truncation as well.
+
+.. code-block:: c
+
+ void checked(char a, int __ob_trap b) {
+ a = b;
+ }
+
+ void wrapping(char a, int __ob_wrap b) {
+ a = b;
+ }
+
+
+Promotion Rules
+^^^^^^^^^^^^^^^
+
+Overflow behavior types follow standard C integer promotion rules while
+preserving the overflow behavior annotation through expressions:
+
+* When an overflow behavior type is mixed with a standard integer type, the
+ result carries the overflow behavior annotation. Standard C conversion rules
+ determine the resulting width and signedness.
+* When two overflow behavior types of the same kind (both ``wrap`` or both
+ ``trap``) are mixed, the result follows standard C arithmetic conversion
+ rules with that behavior applied.
+* When ``wrap`` and ``trap`` are mixed, ``trap`` dominates. The result follows
+ standard C conversions with ``trap`` behavior.
+
+.. code-block:: c
+
+ typedef int __ob_wrap wrap_int;
+ typedef int __ob_trap trap_int;
+
+ wrap_int a = 1;
+ trap_int b = 2;
+ /* a + b results in __ob_trap int (trap dominates) */
+
+
+Type Compatibility
+^^^^^^^^^^^^^^^^^^
+
+Overflow behavior types are distinct from their underlying types for type
+checking purposes. Assigning between types with different overflow behaviors
+(``wrap`` vs ``trap``) is an error:
+
+.. code-block:: c
+
+ int __ob_wrap w;
+ int __ob_trap t;
+ w = t; /* error: incompatible overflow behavior types */
+
+Assigning from an overflow behavior type to a plain integer type discards the
+overflow behavior. The compiler can warn about this with
+``-Wimplicit-overflow-behavior-conversion`` (implied by ``-Wconversion``).
+
+Intentionally discarding the overflow behavior should use an explicit
+cast:
+
+.. code-block:: c
+
+ unsigned long __ob_trap checked_size;
+ unsigned long regular_size;
+
+ regular_size = checked_size; /* warning: discards overflow behavior */
+ regular_size = (unsigned long)checked_size; /* OK, explicit cast */
+
+If truncation should be allowed for a cast away from ``trap``, an
+explicit ``wrap`` cast is needed to suppress run-time instrumentation:
+
+.. code-block:: c
+
+ unsigned long __ob_trap checked_size;
+ unsigned char small_size;
+
+ small_size = checked_size; /* may trap at run-time on truncation */
+ small_size = (unsigned long __ob_wrap)checked_size; /* OK, explicit cast */
+
+
+Pointer Semantics
+^^^^^^^^^^^^^^^^^
+
+Pointers to overflow behavior types are treated as distinct from pointers to
+their underlying types. Converting between them produces a warning controlled
+by ``-Wincompatible-pointer-types-discards-overflow-behavior``:
+
+.. code-block:: c
+
+ unsigned long *px;
+ unsigned long __ob_trap *py;
+
+ px = py; /* warning: discards overflow behavior */
+ py = px; /* warning: discards overflow behavior */
+
+
+Best Practices
+^^^^^^^^^^^^^^
+
+1. **Use ``__ob_trap`` for sizes and counts** where overflow indicates bugs:
+
+ .. code-block:: c
+
+ typedef unsigned long long __ob_trap no_wrap_u64;
+ no_wrap_u64 buffer_len = kmalloc_size + header_size;
+
+2. **Use ``__ob_wrap`` for arithmetic that intentionally overflows**:
+
+ .. code-block:: c
+
+ typedef u32 __ob_wrap hash_t;
+ hash_t hash = (hash * 31) + byte;
+
+3. **Don't mix different overflow behavior types**:
+
+ .. code-block:: c
+
+ int __ob_wrap a;
+ int __ob_trap b;
+
+ a = b; /* error: incompatible overflow behavior types */
+
+ a = (int __ob_wrap)b; /* OK, explicit cast */
+ a = (int)b; /* OK, cast to underlying type */
diff --git a/Documentation/process/deprecated.rst b/Documentation/process/deprecated.rst
index fed56864d036..1c20f7ff0798 100644
--- a/Documentation/process/deprecated.rst
+++ b/Documentation/process/deprecated.rst
@@ -109,6 +109,45 @@ For more details, also see array3_size() and flex_array_size(),
as well as the related check_mul_overflow(), check_add_overflow(),
check_sub_overflow(), and check_shl_overflow() family of functions.
+.. _open_coded_wrap_around:
+
+open-coded intentional arithmetic wrap-around
+---------------------------------------------
+Depending on arithmetic wrap-around without annotations means the
+kernel cannot distinguish between intentional wrap-around and accidental
+wrap-around (when using things like the overflow sanitizers).
+
+For example, where an addition is intended to wrap around::
+
+ magic = counter + rotation;
+
+please use the wrapping_add() helper::
+
+ magic = wrapping_add(int, counter, rotation);
+
+To help minimize needless code churn, the kernel uses overflow idiom exclusions
+(currently only supported by Clang). Some commonly used overflow-dependent code
+patterns will not be instrumented by overflow sanitizers. The currently
+supported patterns are::
+
+ /* wrap-around test */
+ if (var + offset < var) ...
+
+ /* standalone unsigned decrement used in while loop */
+ while(size--)
+
+ /* negated unsigned constants */
+ -1UL;
+ -5U;
+
+In rare cases where helpers aren't available (e.g. in early boot code, etc) but
+overflow instrumentation still needs to be avoided, utilize wrap-around tests
+to check wrap-around outcomes before performing calculations::
+
+ if (var + offset < var) {
+ /* wrap-around has occurred */
+ }
+
simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
----------------------------------------------------------------------
The simple_strtol(), simple_strtoll(),
diff --git a/Documentation/process/index.rst b/Documentation/process/index.rst
index dbd6ea16aca7..620257eca00e 100644
--- a/Documentation/process/index.rst
+++ b/Documentation/process/index.rst
@@ -111,3 +111,4 @@ developers:
kernel-docs
deprecated
+ arithmetic-overflow
diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h
index c16d4199bf92..65f57ff378bb 100644
--- a/include/linux/compiler_attributes.h
+++ b/include/linux/compiler_attributes.h
@@ -396,6 +396,18 @@
# define __disable_sanitizer_instrumentation
#endif
+/*
+ * Optional: only supported by Clang with -Xclang -experimental-foverflow-behavior-types
+ * passed via CONFIG_OVERFLOW_BEHAVIOR_TYPES. When not available, define empty macros for
+ * the trap/wrap annotations.
+ *
+ * clang: https://clang.llvm.org/docs/OverflowBehaviorTypes.html
+ */
+#if !__has_attribute(overflow_behavior) || !defined(OVERFLOW_BEHAVIOR_TYPES)
+# define __ob_trap
+# define __ob_wrap
+#endif
+
/*
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-weak-function-attribute
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-weak-variable-attribute
diff --git a/MAINTAINERS b/MAINTAINERS
index a9f067164203..342a550c25b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19925,6 +19925,7 @@ M: Justin Stitt <justinstitt@google.com>
L: linux-hardening@vger.kernel.org
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
+F: Documentation/process/arithmetic-overflow.rst
F: scripts/integer-wrap-ignore.scl
F: scripts/Makefile.obt
--
2.34.1
^ permalink raw reply related
* [PATCH 1/5] refcount: Remove unused __signed_wrap function annotations
From: Kees Cook @ 2026-03-31 16:37 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Kees Cook, Will Deacon, Boqun Feng, Mark Rutland, Gary Guo,
Nathan Chancellor, Marco Elver, Miguel Ojeda, Przemek Kitszel,
Justin Stitt, Linus Torvalds, Jonathan Corbet, Nicolas Schier,
Arnd Bergmann, Greg Kroah-Hartman, Andrew Morton, linux-kernel,
kasan-dev, linux-hardening, linux-doc, linux-kbuild, llvm
In-Reply-To: <20260331163716.work.696-kees@kernel.org>
With CONFIG_UBSAN_INTEGER_WRAP being replaced by Overflow Behavior
Types, remove the __signed_wrap function annotation as it is already
unused, and any future work here will use OBT annotations instead.
Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: Will Deacon <will@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Boqun Feng <boqun@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Gary Guo <gary@garyguo.net>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Marco Elver <elver@google.com>
Cc: Miguel Ojeda <ojeda@kernel.org>
Cc: Przemek Kitszel <przemyslaw.kitszel@intel.com>
---
include/linux/compiler_types.h | 9 +--------
include/linux/refcount.h | 10 +++++-----
2 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 890076d0974b..e8fd77593b68 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -432,18 +432,11 @@ struct ftrace_likely_data {
#define at_least
#endif
-/* Do not trap wrapping arithmetic within an annotated function. */
-#ifdef CONFIG_UBSAN_INTEGER_WRAP
-# define __signed_wrap __attribute__((no_sanitize("signed-integer-overflow")))
-#else
-# define __signed_wrap
-#endif
-
/* Section for code which can't be instrumented at all */
#define __noinstr_section(section) \
noinline notrace __attribute((__section__(section))) \
__no_kcsan __no_sanitize_address __no_profile __no_sanitize_coverage \
- __no_sanitize_memory __signed_wrap
+ __no_sanitize_memory
#define noinstr __noinstr_section(".noinstr.text")
diff --git a/include/linux/refcount.h b/include/linux/refcount.h
index 3da377ffb0c2..ba7657ced281 100644
--- a/include/linux/refcount.h
+++ b/include/linux/refcount.h
@@ -170,7 +170,7 @@ static inline unsigned int refcount_read(const refcount_t *r)
return atomic_read(&r->refs);
}
-static inline __must_check __signed_wrap
+static inline __must_check
bool __refcount_add_not_zero(int i, refcount_t *r, int *oldp)
{
int old = refcount_read(r);
@@ -212,7 +212,7 @@ static inline __must_check bool refcount_add_not_zero(int i, refcount_t *r)
return __refcount_add_not_zero(i, r, NULL);
}
-static inline __must_check __signed_wrap
+static inline __must_check
bool __refcount_add_not_zero_limited_acquire(int i, refcount_t *r, int *oldp,
int limit)
{
@@ -244,7 +244,7 @@ __refcount_inc_not_zero_limited_acquire(refcount_t *r, int *oldp, int limit)
return __refcount_add_not_zero_limited_acquire(1, r, oldp, limit);
}
-static inline __must_check __signed_wrap
+static inline __must_check
bool __refcount_add_not_zero_acquire(int i, refcount_t *r, int *oldp)
{
return __refcount_add_not_zero_limited_acquire(i, r, oldp, INT_MAX);
@@ -277,7 +277,7 @@ static inline __must_check bool refcount_add_not_zero_acquire(int i, refcount_t
return __refcount_add_not_zero_acquire(i, r, NULL);
}
-static inline __signed_wrap
+static inline
void __refcount_add(int i, refcount_t *r, int *oldp)
{
int old = atomic_fetch_add_relaxed(i, &r->refs);
@@ -383,7 +383,7 @@ static inline void refcount_inc(refcount_t *r)
__refcount_inc(r, NULL);
}
-static inline __must_check __signed_wrap
+static inline __must_check
bool __refcount_sub_and_test(int i, refcount_t *r, int *oldp)
{
int old = atomic_fetch_sub_release(i, &r->refs);
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] docs/ja_JP: submitting-patches: Amend "Describe your changes"
From: weibu @ 2026-03-31 15:45 UTC (permalink / raw)
To: Akira Yokosawa; +Cc: Jonathan Corbet, Shuah Khan, linux-doc, linux-kernel
In-Reply-To: <20260326114637.144601-1-akiyks@gmail.com>
Looks good to me.
Acked-by: Akiyoshi Kurita <weibu@redadmin.org>
2026-03-26 20:46 に Akira Yokosawa さんは書きました:
> To make the translation of "Describe your changes" (into
> "変更内容を記述する") easier to follow, do some rewording and
> rephrasing, as well as fixing a couple of mistranslations.
>
> Signed-off-by: Akira Yokosawa <akiyks@gmail.com>
> ---
> .../ja_JP/process/submitting-patches.rst | 107 +++++++++---------
> 1 file changed, 53 insertions(+), 54 deletions(-)
>
> diff --git
> a/Documentation/translations/ja_JP/process/submitting-patches.rst
> b/Documentation/translations/ja_JP/process/submitting-patches.rst
> index 3bb2383871e1..9d63220abd15 100644
> --- a/Documentation/translations/ja_JP/process/submitting-patches.rst
> +++ b/Documentation/translations/ja_JP/process/submitting-patches.rst
> @@ -55,67 +55,66 @@ Documentation/process/maintainer-handbooks.rst.
> 変更内容を記述する
> ------------------
>
> -問題を記述してください。あなたのパッチが 1 行のバグ修正であっても、
> +まず問題点を記べてください。あなたのパッチが 1 行のバグ修正であっても、
> 5000 行の新機能であっても、それを行う動機となった根本的な問題が
> -必ずあるはずです。修正すべき価値のある問題が存在し、レビューアが
> -最初の段落以降を読む意味があることを納得させてください。
> +必ずあるはずです。レビューアが、修正すべき問題がたしかに存在し、冒頭の
> +段落の続きを読むべきだと納得できるように書いてください。
>
> -ユーザーから見える影響を記述してください。クラッシュやロックアップは
> +次にユーザーから見える影響を記述してください。クラッシュやロックアップは
> 分かりやすいですが、すべてのバグがそこまで露骨とは限りません。
> たとえコードレビュー中に見つかった問題であっても、ユーザーに
> どのような影響があり得るかを記述してください。
> Linux の多くの環境は、上流から特定のパッチだけを取り込む二次的な
> 安定版ツリーや、ベンダー/製品固有のツリーのカーネルで動いています。
> -したがって、変更を下流へ適切に流す助けになる情報(発生条件、dmesg
> +したがって、変更を適切に下流へ流す助けになる情報(発生条件、dmesg
> の抜粋、クラッシュ内容、性能劣化、レイテンシのスパイク、
> ロックアップ等)があれば記載してください。
>
> -最適化とトレードオフを定量的に示してください。パフォーマンス、
> +次に最適化とトレードオフを定量的に示してください。パフォーマンス、
> メモリ消費量、スタックフットプリント、バイナリサイズの改善を主張する
> 場合は、それを裏付ける数値を記載してください。
> -また、目に見えないコストについても記述してください。最適化は通常
> -無料ではなく、CPU・メモリ・可読性の間でのトレードオフになります。
> -ヒューリスティクスの場合は、異なるワークロード間でのトレードオフに
> +また、目に見えないコストについても記述してください。多くの場合、
> +最適化は CPU・メモリ・可読性の間でのトレードオフとなります。
> +ヒューリスティクスの場合は、異なるワークロード間でのトレードオフと
> なります。レビューアがコストとメリットを比較検討できるよう、
> -最適化によって予想されるデメリットも記述してください。
> +最適化に伴って想定されるデメリットも記述してください。
>
> -問題を明確にできたら、実際にどのような対策を講じているかを技術的に
> -詳しく記述してください。レビューアがコードが意図したとおりに動作して
> -いるかを確認できるよう、変更内容を平易な言葉で書き下すことが重要です。
> +問題点の明確化が済んだら、実際にどのような対策を講じているかを技術的に
> +詳しく説明してください。コードが意図したとおりに動作していることを
> +レビューアが確認できるよう、変更内容を平易な言葉で書き下すことが重要です。
>
> -パッチ説明を Linux のソースコード管理システム ``git`` の
> -「コミットログ」としてそのまま取り込める形で書けば、メンテナは
> -助かります。詳細は原文の該当節を参照してください。
> +パッチの説明が Linux のソースコード管理システム ``git`` の「コミットログ」
> +としてそのまま取り込める形で書かれていれば、メンテナは助かります。
> +詳細は原文の該当節 ("The canonical patch format") を参照してください。
>
> .. TODO: Convert to file-local cross-reference when the destination is
> translated.
>
> 1 つのパッチでは 1 つの問題だけを解決してください。記述が長くなり
> -始めたら、パッチを分割すべきサインです。詳細は原文の該当節を参照
> -してください。
> +始めたら、それはパッチを分割すべきサインです。
> +詳細は原文の該当節 ("Separate your changes") を参照してください。
>
> .. TODO: Convert to file-local cross-reference when the destination is
> translated.
>
> パッチまたはパッチシリーズを投稿/再投稿する際は、その完全な
> -説明と、それを正当化する理由を含めてください。単に、これが
> -パッチ(シリーズ)のバージョン N であるとだけ書かないでください。
> -サブシステムメンテナが以前のパッチ版や参照先 URL をさかのぼって
> -パッチ説明を探し、それをパッチに補うことを期待してはいけません。
> +説明と、それを正当化する理由を含めてください。単に「これはパッチ
> +(シリーズ)のバージョン N です」とだけ書くのは避けてください。
> +サブシステムメンテナが以前のパッチバージョンや参照先 URL をさかのぼって
> +パッチ記述を探し、それをパッチに補うことを期待してはいけません。
> つまり、パッチ(シリーズ)とその説明は、それだけで完結しているべき
> です。これはメンテナとレビューアの双方に有益です。レビューアの
> -中には、以前のパッチ版を受け取っていない人もいるでしょう。
> +中には、以前のパッチバージョンを受け取っていない人もいるでしょう。
>
> -変更内容は命令形で記述してください。たとえば、
> -「make xyzzy do frotz」とし、
> -「[This patch] makes xyzzy do frotz」や
> -「[I] changed xyzzy to do frotz」
> -のようには書かないでください。あたかもコードベースに対して、
> -その振る舞いを変えるよう命令しているかのように書いてください。
> +変更内容は、あたかもコードベースに対してその振る舞いを変えるように
> +命令するかの如く、(訳補: 英語の)命令形で記述してください。たとえば、
> +"[This patch] makes xyzzy do frotz" や
> +"[I] changed xyzzy to do frotz" のような言い回しを避け、
> +"make xyzzy do frotz" のように書いてください。
>
> -特定のコミットに言及したい場合は、コミットの SHA-1 ID だけを
> -書かないでください。レビューアがそれが何についてのものかを
> -把握しやすくなるよう、コミットの 1 行要約も含めてください。例::
> +特定のコミットに言及したい場合に、コミットの SHA-1 ID だけを
> +書くのは避けてください。レビューアがそれが何についてのものかを
> +把握しやすいよう、コミットの 1 行要約も含めてください。例::
>
> Commit e21d2170f36602ae2708 ("video: remove unnecessary
> platform_set_drvdata()") removed the unnecessary
> @@ -123,28 +122,29 @@ Linux の多くの環境は、上流から特定のパッチだけを取り込
> delete it.
>
> また、SHA-1 ID は少なくとも先頭 12 文字を使うようにしてください。
> -カーネルのリポジトリには非常に多くのオブジェクトがあるため、
> -それより短い ID では衝突が現実に起こり得ます。いま 6 文字の ID に
> -衝突がなくても、5 年後もそうだとは限らないことに注意してください。
> +カーネルのリポジトリには\ **非常に多くの**\ オブジェクトがあるため、
> +それより短い ID では衝突が現実問題となります。6 文字の ID が今現在
> +衝突しないからといって、5 年後もそうであるとは限らないことを念頭に
> +置いてください。
>
> 変更に関連する議論や、その背景情報が Web 上で参照できる場合は、
> -それを指す ``Link:`` タグを追加してください。パッチが過去の
> -メーリングリストでの議論や、Web に記録された何かの結果であるなら、
> +それを指す 'Link:' タグを追加してください。過去のメーリングリスト
> +での議論や、Web に記録された何かに由来するパッチならば、
> それを示してください。
>
> -メーリングリストのアーカイブへリンクする場合は、できれば
> -lore.kernel.org のメッセージアーカイブサービスを使ってください。
> -リンク URL を作るには、そのメッセージの ``Message-ID`` ヘッダの内容
> -から、前後の山括弧を取り除いたものを使います。例::
> +メーリングリストのアーカイブへリンクする場合は、できれば lore.kernel.org
> +のメッセージアーカイブサービスを使ってください。リンク URL を作るには、
> +そのメッセージの ``Message-ID`` ヘッダの内容から、前後の山括弧を取り除いた
> +ものを使います。例::
>
> Link:
> https://lore.kernel.org/30th.anniversary.repost@klaava.Helsinki.FI
>
> 実際にリンクが機能し、該当するメッセージを指していることを
> -確認してください。ただし、外部リソースを見なくても説明が理解できる
> -ようにするよう努めてください。
> +確認してください。
>
> +ただし、外部リソースを見なくても説明が理解できるようにするよう努めてください。
> メーリングリストのアーカイブやバグへの URL を示すだけでなく、
> -投稿されたパッチに至った議論の要点も要約してください。
> +投稿されたパッチに至った議論のポイントも要約してください。
>
> パッチがバグを修正するものであれば、メーリングリストのアーカイブや
> 公開バグトラッカー上の報告を指す URL を付けて、``Closes:`` タグを
> @@ -153,23 +153,22 @@ lore.kernel.org のメッセージアーカイブサービスを使ってくだ
> Closes: https://example.com/issues/1234
>
> このようなタグ付きのコミットが適用されたとき、自動的に issue を
> -閉じられるバグトラッカーもあります。メーリングリストを監視している
> +閉じるバグトラッカーもあります。メーリングリストを監視している
> ボットの中には、そのようなタグを追跡して一定の動作を行うものも
> -あります。非公開のバグトラッカーや無効な URL は禁止です。
> +あります。ただし、非公開バグトラッカーの(訳補: 部外者が)閲覧できない
> +URL は禁止です。
>
> -パッチが特定のコミットに含まれるバグを修正するものであれば、
> -たとえば ``git bisect`` で問題を見つけた場合には、SHA-1 ID の
> -先頭少なくとも 12 文字と 1 行要約を含めて、``Fixes:`` タグを
> +パッチが特定のコミットに含まれるバグを修正するもの、たとえば
> +``git bisect`` で問題を見つけたものの場合には、SHA-1 ID の
> +先頭少なくとも 12 文字と 1 行要約を含めて 'Fixes:' タグを
> 使ってください。タグを複数行に分割してはいけません。タグは
> 解析スクリプトを単純にするため、「75 桁で折り返す」規則の
> -例外です。
> -
> -例::
> +例外です。例::
>
> Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the
> number of pages it actually freed")
>
> -上の形式を ``git log`` や ``git show`` で出力しやすくするために、
> -次の ``git config`` 設定を使えます::
> +``git log`` や ``git show`` の出力を上の形式で整形させるには、
> +次の ``git config`` 設定が使えます::
>
> [core]
> abbrev = 12
>
> base-commit: 0a4f3ef9880e505d41817419b0255d6552776143
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox