Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-06-04 Thread Justin Suess
On Mon, May 18, 2026 at 09:33:02AM -0400, Sasha Levin wrote:
> On Sun, May 17, 2026 at 11:37:36PM -0700, Song Liu wrote:
> > On Sun, May 17, 2026 at 6:49 AM Sasha Levin  wrote:
> > > * fail_function (CONFIG_FUNCTION_ERROR_INJECTION) is disabled in
> > >   most production kernels. Even where enabled, it only works on
> > >   functions pre-annotated with ALLOW_ERROR_INJECTION() in source -
> > >   no help for a freshly-disclosed CVE. The debugfs UI is blocked by
> > >   lockdown=integrity and the override is probabilistic.
> > > 
> > > * BPF override (bpf_override_return) honors the same
> > >   ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
> > >   production kernels. Even where on, the operator interface is
> > >   "load a verified BPF program," not a one-line write.
> > 
> > If it is OK for killswitch to attach to any kernel functions, do we still
> > need ALLOW_ERROR_INJECTION() for fail_function and BPF
> > override? Shall we instead also allow fail_function and BPF override
> > to attach to any kernel functions?
> 
> I don't think so. ALLOW_ERROR_INJECTION is not a security mechanism, it's an
> integrity/safety mechanism for both bpf and fault injection.
> 
> It protects against a "developer or CI script doing legitimate fault injection
> accidentally panics the box" scenario, not an "attacker gets in" one.
>
At that point why not just make this entire killswitch mechanism an expanded
version of the bpf_override_return helper that doesn't care about 
ALLOW_ERROR_INJECTION?

Then killswitch mitigations are just BPF programs.

This could be paired with a userspace tool for building and
loading the killswitch programs conveniently.

You can make the helper function only succeed if (CONFIG_KILLSWITCH=y
CONFIG_BPF_KPROBE_OVERRIDE=y etc.) and taint the kernel on the first call.

BPF has the crash_kexec kfunc already that can take down the kernel.
Thus it's not crazy in my opinion to add a helper with a similar intentional
intentional footgun in another kfunc/helper.

We can automatically benefit from BPF signing mechanisms to prevent
unauthorized loading of programs. If killswitch is enabled, users can
restrict unauthorized use of it by restricting the loading of all BPF
programs to those signed w/ the key.

Thanks,
Justin
> -- 
> Thanks,
> Sasha



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-26 Thread Sasha Levin

On Tue, May 26, 2026 at 03:10:45PM +0200, Daniel Borkmann wrote:

On 5/23/26 3:41 PM, Sasha Levin wrote:

On Thu, May 21, 2026 at 11:16:46AM -0700, Song Liu wrote:

On Thu, May 21, 2026 at 8:31 AM Sasha Levin  wrote:

On Thu, May 21, 2026 at 11:11:16AM +0200, Daniel Borkmann wrote:

On 5/19/26 9:57 PM, Sasha Levin wrote:

Sure, this would also work. How do you see this happening? Can we let a certain
user/pid/etc disable the allowlist if they choose to?


I don't think we should, given then we're back to square one where root
or some other user would be able to just override/bypass an LSM.


killswitch already disables itself when lockdown is active. We can easily
disable it too when one of the LSMs that cares about this is active.


[...]

How do you see this working with the allowlist?


We should look at the underlying areas where most of the CVE-like fixes
took place (these days should be more easily doable given Claude and friends)
and based on that either extend ALLOW_ERROR_INJECTION() or (better) create
new hooks which BPF LSM can consume where you can then have a policy to reject
requests and tighten the attack surface. For example, the AF_ALG stuff you


So we could grow the LSM tentacles deeper into the kernel, and we can see where
current CVEs are happening, which I suspect is the darker corners of the kernel
(old unmaintained, rarely used code), but this definitely won't stay the case,
right? Newer and better LLMs will discover issues elsewhere, and once the low
hanging fruits are picked off of the current target subsystems, researchers
will move elsewhere. We will be dooming ourselves to an endless cat and mouse
game where we go add LSM hooks after some big security issue goes public.


Do we really need to add new LSM hooks for recent CVEs?

The LSM hooks are designed to cover all the user-kernel interfaces. Then
with properly designed policies, we should have coverage for potential CVEs.
Existing LSM hooks may not be perfect, but we can improve the hooks,
potentially with the help of smart LLMs, so that these hooks can cover
future security issues. In some cases, we will need new policies, but I don't
think new hooks will be needed for most of these CVEs.


Running a quick LLM evaluation on the last ~70 severe CVEs, it seems that about
40% is doable with the current hooks.



Interesting, do you have some more details in which areas your eval sees new
lsm hooks missing?


The recent ones I saw fall into about 5 buckets:

1. Kernel-thread / workqueue context: LSM hooks fire but current is a worker,
not the actual attacker. Lots of ksmbd, ceph-msgr, and async cleanup races land
here.

2. Driver: pci_driver.probe, notifier_call_chain, ib_* RDMA callbacks, ndo_*,
bus dispatch tables all sit below any LSM hook. Big chunk of mlx5, RDMA, USB,
i3c, DRM bugs.

3. Per-packet softirq RX: security_sock_rcv_skb only fires inside
sk_filter_trim_cap, which UDP encap_rcv bypasses and L2/bridge protocols never
reach. Covers Bluetooth softirq, bond, IPv6 softirq, TCP-MD5/AO timing leaks,
etc.

4. Netfilter: config path is well-gated via security_netlink_send, but
per-match callbacks, set GC, and flowtable cleanup have nothing. That's where
most of the recent netfilter CVEs actually fire.

5. Crypto subsystem + io_uring per-opcode: crypto/ has zero LSM hooks.

--
Thanks,
Sasha



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-26 Thread Daniel Borkmann

On 5/23/26 3:41 PM, Sasha Levin wrote:

On Thu, May 21, 2026 at 11:16:46AM -0700, Song Liu wrote:

On Thu, May 21, 2026 at 8:31 AM Sasha Levin  wrote:

On Thu, May 21, 2026 at 11:11:16AM +0200, Daniel Borkmann wrote:
>On 5/19/26 9:57 PM, Sasha Levin wrote:
>>Sure, this would also work. How do you see this happening? Can we let a 
certain
>>user/pid/etc disable the allowlist if they choose to?
>
>I don't think we should, given then we're back to square one where root
>or some other user would be able to just override/bypass an LSM.

killswitch already disables itself when lockdown is active. We can easily
disable it too when one of the LSMs that cares about this is active.

>[...]
>>How do you see this working with the allowlist?
>
>We should look at the underlying areas where most of the CVE-like fixes
>took place (these days should be more easily doable given Claude and friends)
>and based on that either extend ALLOW_ERROR_INJECTION() or (better) create
>new hooks which BPF LSM can consume where you can then have a policy to reject
>requests and tighten the attack surface. For example, the AF_ALG stuff you

So we could grow the LSM tentacles deeper into the kernel, and we can see where
current CVEs are happening, which I suspect is the darker corners of the kernel
(old unmaintained, rarely used code), but this definitely won't stay the case,
right? Newer and better LLMs will discover issues elsewhere, and once the low
hanging fruits are picked off of the current target subsystems, researchers
will move elsewhere. We will be dooming ourselves to an endless cat and mouse
game where we go add LSM hooks after some big security issue goes public.


Do we really need to add new LSM hooks for recent CVEs?

The LSM hooks are designed to cover all the user-kernel interfaces. Then
with properly designed policies, we should have coverage for potential CVEs.
Existing LSM hooks may not be perfect, but we can improve the hooks,
potentially with the help of smart LLMs, so that these hooks can cover
future security issues. In some cases, we will need new policies, but I don't
think new hooks will be needed for most of these CVEs.


Running a quick LLM evaluation on the last ~70 severe CVEs, it seems that about
40% is doable with the current hooks.



Interesting, do you have some more details in which areas your eval sees new
lsm hooks missing?



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-23 Thread Sasha Levin

On Thu, May 21, 2026 at 11:16:46AM -0700, Song Liu wrote:

On Thu, May 21, 2026 at 8:31 AM Sasha Levin  wrote:


On Thu, May 21, 2026 at 11:11:16AM +0200, Daniel Borkmann wrote:
>On 5/19/26 9:57 PM, Sasha Levin wrote:
>>Sure, this would also work. How do you see this happening? Can we let a 
certain
>>user/pid/etc disable the allowlist if they choose to?
>
>I don't think we should, given then we're back to square one where root
>or some other user would be able to just override/bypass an LSM.

killswitch already disables itself when lockdown is active. We can easily
disable it too when one of the LSMs that cares about this is active.

>[...]
>>How do you see this working with the allowlist?
>
>We should look at the underlying areas where most of the CVE-like fixes
>took place (these days should be more easily doable given Claude and friends)
>and based on that either extend ALLOW_ERROR_INJECTION() or (better) create
>new hooks which BPF LSM can consume where you can then have a policy to reject
>requests and tighten the attack surface. For example, the AF_ALG stuff you

So we could grow the LSM tentacles deeper into the kernel, and we can see where
current CVEs are happening, which I suspect is the darker corners of the kernel
(old unmaintained, rarely used code), but this definitely won't stay the case,
right? Newer and better LLMs will discover issues elsewhere, and once the low
hanging fruits are picked off of the current target subsystems, researchers
will move elsewhere. We will be dooming ourselves to an endless cat and mouse
game where we go add LSM hooks after some big security issue goes public.


Do we really need to add new LSM hooks for recent CVEs?

The LSM hooks are designed to cover all the user-kernel interfaces. Then
with properly designed policies, we should have coverage for potential CVEs.
Existing LSM hooks may not be perfect, but we can improve the hooks,
potentially with the help of smart LLMs, so that these hooks can cover
future security issues. In some cases, we will need new policies, but I don't
think new hooks will be needed for most of these CVEs.


Running a quick LLM evaluation on the last ~70 severe CVEs, it seems that about
40% is doable with the current hooks.

--
Thanks,
Sasha



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-21 Thread Song Liu
On Thu, May 21, 2026 at 8:31 AM Sasha Levin  wrote:
>
> On Thu, May 21, 2026 at 11:11:16AM +0200, Daniel Borkmann wrote:
> >On 5/19/26 9:57 PM, Sasha Levin wrote:
> >>Sure, this would also work. How do you see this happening? Can we let a 
> >>certain
> >>user/pid/etc disable the allowlist if they choose to?
> >
> >I don't think we should, given then we're back to square one where root
> >or some other user would be able to just override/bypass an LSM.
>
> killswitch already disables itself when lockdown is active. We can easily
> disable it too when one of the LSMs that cares about this is active.
>
> >[...]
> >>How do you see this working with the allowlist?
> >
> >We should look at the underlying areas where most of the CVE-like fixes
> >took place (these days should be more easily doable given Claude and friends)
> >and based on that either extend ALLOW_ERROR_INJECTION() or (better) create
> >new hooks which BPF LSM can consume where you can then have a policy to 
> >reject
> >requests and tighten the attack surface. For example, the AF_ALG stuff you
>
> So we could grow the LSM tentacles deeper into the kernel, and we can see 
> where
> current CVEs are happening, which I suspect is the darker corners of the 
> kernel
> (old unmaintained, rarely used code), but this definitely won't stay the case,
> right? Newer and better LLMs will discover issues elsewhere, and once the low
> hanging fruits are picked off of the current target subsystems, researchers
> will move elsewhere. We will be dooming ourselves to an endless cat and mouse
> game where we go add LSM hooks after some big security issue goes public.

Do we really need to add new LSM hooks for recent CVEs?

The LSM hooks are designed to cover all the user-kernel interfaces. Then
with properly designed policies, we should have coverage for potential CVEs.
Existing LSM hooks may not be perfect, but we can improve the hooks,
potentially with the help of smart LLMs, so that these hooks can cover
future security issues. In some cases, we will need new policies, but I don't
think new hooks will be needed for most of these CVEs.

Thanks,
Song



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-21 Thread Song Liu
On Thu, May 21, 2026 at 7:38 AM Sasha Levin  wrote:
>
> On Tue, May 19, 2026 at 03:00:15PM -0700, Song Liu wrote:
> >On Tue, May 19, 2026 at 12:57 PM Sasha Levin  wrote:
> >[...]
> >> >Fully agree with Song here that there is no clear boundary, and that the
> >> >killswitch could lead to arbitrary, hard to debug breakage if applied to
> >> >the wrong function.. introducing worse bugs than the one being mitigated
> >> >or even /short-circuit LSM enforcement/ (engage security_file_open 0,
> >> >engage cap_capable 0, engage apparmor_* etc).
> >>
> >> This is similar to livepatch, right? Do we need guardrails there too?
> >
> >livepatch has the same guardrails as other kernel modules:
> >CONFIG_MODULE_SIG, CONFIG_MODULE_SIG_FORCE, etc.
>
> Which the user can choose to enable or disable. Livepatches will work just 
> fine
> with CONFIG_MODULE_SIG=n, right?
>
> With the whitelist approach, the user has no choice but to accept it.
>
> Would it make sense to allow disabling the whitelist via a kernel config or
> some runtime flag?

I personally think it makes sense to have options to allow bypassing/blocking
more kernel functions than the current allow list. But I don't know whether
we would like to go all the way to allow it for all the ftrace-able functions.
I think we will need some careful analysis on this.

Thanks,
Song



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-21 Thread Sasha Levin

On Tue, May 19, 2026 at 03:00:15PM -0700, Song Liu wrote:

On Tue, May 19, 2026 at 12:57 PM Sasha Levin  wrote:
[...]

>Fully agree with Song here that there is no clear boundary, and that the
>killswitch could lead to arbitrary, hard to debug breakage if applied to
>the wrong function.. introducing worse bugs than the one being mitigated
>or even /short-circuit LSM enforcement/ (engage security_file_open 0,
>engage cap_capable 0, engage apparmor_* etc).

This is similar to livepatch, right? Do we need guardrails there too?


livepatch has the same guardrails as other kernel modules:
CONFIG_MODULE_SIG, CONFIG_MODULE_SIG_FORCE, etc.


Which the user can choose to enable or disable. Livepatches will work just fine
with CONFIG_MODULE_SIG=n, right?

With the whitelist approach, the user has no choice but to accept it.

Would it make sense to allow disabling the whitelist via a kernel config or
some runtime flag?

--
Thanks,
Sasha



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-21 Thread Sasha Levin

On Thu, May 21, 2026 at 11:11:16AM +0200, Daniel Borkmann wrote:

On 5/19/26 9:57 PM, Sasha Levin wrote:

Sure, this would also work. How do you see this happening? Can we let a certain
user/pid/etc disable the allowlist if they choose to?


I don't think we should, given then we're back to square one where root
or some other user would be able to just override/bypass an LSM.


killswitch already disables itself when lockdown is active. We can easily
disable it too when one of the LSMs that cares about this is active.


[...]

How do you see this working with the allowlist?


We should look at the underlying areas where most of the CVE-like fixes
took place (these days should be more easily doable given Claude and friends)
and based on that either extend ALLOW_ERROR_INJECTION() or (better) create
new hooks which BPF LSM can consume where you can then have a policy to reject
requests and tighten the attack surface. For example, the AF_ALG stuff you


So we could grow the LSM tentacles deeper into the kernel, and we can see where
current CVEs are happening, which I suspect is the darker corners of the kernel
(old unmaintained, rarely used code), but this definitely won't stay the case,
right? Newer and better LLMs will discover issues elsewhere, and once the low
hanging fruits are picked off of the current target subsystems, researchers
will move elsewhere. We will be dooming ourselves to an endless cat and mouse
game where we go add LSM hooks after some big security issue goes public.

One question I had here: how would we tackle security issues with BPF itself?


can already easily cover today ...

#include "vmlinux.h"
#include 
#include 

#define AF_ALG  38
#define EPERM   1

char _license[] SEC("license") = "Dual BSD/GPL";

SEC("lsm/socket_create")
int BPF_PROG(block_af_alg, int family, int type, int protocol, int kern)
{
if (family == AF_ALG)
return -EPERM;
return 0;
}

... the problem is that distros enable and pull in all sort of crap which
then non-root could pull in via request_module() as an example; similarly
for netlink we want to have a BPF LSM policy to parse into netlink requests
and then reject based on certain attribute matching (both on our todo list)
which would have helped in case of exotic tc cls/act/qdisc modules to prevent
them to be pulled from userns. I bet there are a ton more examples once we
look further into the data.


I definitely agree that BPF is a much nicer hammer than the simple killswitch
implementation. I've actually been (privately) playing with an out of tree
killswitch that also supports BPF. I've pushed the (hacky) code I have to
https://github.com/sashalevin/killswitch , and you can see an example of a BPF
mitigation similar to the one you have above:

https://github.com/sashalevin/killswitch/blob/master/mitigations/cve-2025-21703.sh

My concern is mostly with the whitelist approach.

--
Thanks,
Sasha



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-21 Thread Daniel Borkmann

On 5/19/26 9:57 PM, Sasha Levin wrote:

On Tue, May 19, 2026 at 02:13:26PM +0200, Daniel Borkmann wrote:

On 5/19/26 1:59 AM, Song Liu wrote:

On Mon, May 18, 2026 at 6:33 AM Sasha Levin  wrote:

On Sun, May 17, 2026 at 11:37:36PM -0700, Song Liu wrote:

On Sun, May 17, 2026 at 6:49 AM Sasha Levin  wrote:

* fail_function (CONFIG_FUNCTION_ERROR_INJECTION) is disabled in
  most production kernels. Even where enabled, it only works on
  functions pre-annotated with ALLOW_ERROR_INJECTION() in source -
  no help for a freshly-disclosed CVE. The debugfs UI is blocked by
  lockdown=integrity and the override is probabilistic.

* BPF override (bpf_override_return) honors the same
  ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
  production kernels. Even where on, the operator interface is
  "load a verified BPF program," not a one-line write.


If it is OK for killswitch to attach to any kernel functions, do we still
need ALLOW_ERROR_INJECTION() for fail_function and BPF
override? Shall we instead also allow fail_function and BPF override
to attach to any kernel functions?


I don't think so. ALLOW_ERROR_INJECTION is not a security mechanism, it's an
integrity/safety mechanism for both bpf and fault injection.

It protects against a "developer or CI script doing legitimate fault injection
accidentally panics the box" scenario, not an "attacker gets in" one.


There really isn't a clear boundary between "security mechanism" and
"non-security mechanism". As we are making killswitch available
everywhere under root, users will soon learn to use it to do fault injection,
and potentially much more scary things. (Think about agents with sudo
access).


Fully agree with Song here that there is no clear boundary, and that the
killswitch could lead to arbitrary, hard to debug breakage if applied to
the wrong function.. introducing worse bugs than the one being mitigated
or even /short-circuit LSM enforcement/ (engage security_file_open 0,
engage cap_capable 0, engage apparmor_* etc).


This is similar to livepatch, right? Do we need guardrails there too?

Or do we just trust root to do the right thing for it's systems without needing
to be it's babysitter?


[See Song's reply.]


The ALLOW_ERROR_INJECTION() provides a curated white-list where you may
return with an error without causing more severe damage (assuming the
error handling code is right). The right thing would be to more widely
apply ALLOW_ERROR_INJECTION() or to figure out a better way to safely
enable the latter without explicit function annotation.


Sure, this would also work. How do you see this happening? Can we let a certain
user/pid/etc disable the allowlist if they choose to?


I don't think we should, given then we're back to square one where root
or some other user would be able to just override/bypass an LSM.

[...]

How do you see this working with the allowlist?


We should look at the underlying areas where most of the CVE-like fixes
took place (these days should be more easily doable given Claude and friends)
and based on that either extend ALLOW_ERROR_INJECTION() or (better) create
new hooks which BPF LSM can consume where you can then have a policy to reject
requests and tighten the attack surface. For example, the AF_ALG stuff you
can already easily cover today ...

#include "vmlinux.h"
#include 
#include 

#define AF_ALG  38
#define EPERM   1

char _license[] SEC("license") = "Dual BSD/GPL";

SEC("lsm/socket_create")
int BPF_PROG(block_af_alg, int family, int type, int protocol, int kern)
{
if (family == AF_ALG)
return -EPERM;
return 0;
}

... the problem is that distros enable and pull in all sort of crap which
then non-root could pull in via request_module() as an example; similarly
for netlink we want to have a BPF LSM policy to parse into netlink requests
and then reject based on certain attribute matching (both on our todo list)
which would have helped in case of exotic tc cls/act/qdisc modules to prevent
them to be pulled from userns. I bet there are a ton more examples once we
look further into the data.

Thanks,
Daniel



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-19 Thread Song Liu
On Tue, May 19, 2026 at 12:57 PM Sasha Levin  wrote:
[...]
> >Fully agree with Song here that there is no clear boundary, and that the
> >killswitch could lead to arbitrary, hard to debug breakage if applied to
> >the wrong function.. introducing worse bugs than the one being mitigated
> >or even /short-circuit LSM enforcement/ (engage security_file_open 0,
> >engage cap_capable 0, engage apparmor_* etc).
>
> This is similar to livepatch, right? Do we need guardrails there too?

livepatch has the same guardrails as other kernel modules:
CONFIG_MODULE_SIG, CONFIG_MODULE_SIG_FORCE, etc.

Thanks,
Song



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-19 Thread Sasha Levin

On Tue, May 19, 2026 at 02:13:26PM +0200, Daniel Borkmann wrote:

On 5/19/26 1:59 AM, Song Liu wrote:

On Mon, May 18, 2026 at 6:33 AM Sasha Levin  wrote:

On Sun, May 17, 2026 at 11:37:36PM -0700, Song Liu wrote:

On Sun, May 17, 2026 at 6:49 AM Sasha Levin  wrote:

* fail_function (CONFIG_FUNCTION_ERROR_INJECTION) is disabled in
  most production kernels. Even where enabled, it only works on
  functions pre-annotated with ALLOW_ERROR_INJECTION() in source -
  no help for a freshly-disclosed CVE. The debugfs UI is blocked by
  lockdown=integrity and the override is probabilistic.

* BPF override (bpf_override_return) honors the same
  ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
  production kernels. Even where on, the operator interface is
  "load a verified BPF program," not a one-line write.


If it is OK for killswitch to attach to any kernel functions, do we still
need ALLOW_ERROR_INJECTION() for fail_function and BPF
override? Shall we instead also allow fail_function and BPF override
to attach to any kernel functions?


I don't think so. ALLOW_ERROR_INJECTION is not a security mechanism, it's an
integrity/safety mechanism for both bpf and fault injection.

It protects against a "developer or CI script doing legitimate fault injection
accidentally panics the box" scenario, not an "attacker gets in" one.


There really isn't a clear boundary between "security mechanism" and
"non-security mechanism". As we are making killswitch available
everywhere under root, users will soon learn to use it to do fault injection,
and potentially much more scary things. (Think about agents with sudo
access).


Fully agree with Song here that there is no clear boundary, and that the
killswitch could lead to arbitrary, hard to debug breakage if applied to
the wrong function.. introducing worse bugs than the one being mitigated
or even /short-circuit LSM enforcement/ (engage security_file_open 0,
engage cap_capable 0, engage apparmor_* etc).


This is similar to livepatch, right? Do we need guardrails there too?

Or do we just trust root to do the right thing for it's systems without needing
to be it's babysitter?


The ALLOW_ERROR_INJECTION() provides a curated white-list where you may
return with an error without causing more severe damage (assuming the
error handling code is right). The right thing would be to more widely
apply ALLOW_ERROR_INJECTION() or to figure out a better way to safely
enable the latter without explicit function annotation.


Sure, this would also work. How do you see this happening? Can we let a certain
user/pid/etc disable the allowlist if they choose to?


Wrt BPF:


* BPF override (bpf_override_return) honors the same
  ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
  production kernels. Even where on, the operator interface is
  "load a verified BPF program," not a one-line write.


The claim that BPF itself is off in many production kernels is not really
true, where did you get that from? All the major distros and cloud providers
have BPF enabled these days, and even systemd ships BPF programs for
custom service firewalling etc.


The world is a bit bigger than home distros and cloud providers, but sure - bpf
is enabled widely enough at this point.

How do you see this working with the allowlist?

--
Thanks,
Sasha



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-19 Thread Daniel Borkmann

On 5/19/26 1:59 AM, Song Liu wrote:

On Mon, May 18, 2026 at 6:33 AM Sasha Levin  wrote:

On Sun, May 17, 2026 at 11:37:36PM -0700, Song Liu wrote:

On Sun, May 17, 2026 at 6:49 AM Sasha Levin  wrote:

* fail_function (CONFIG_FUNCTION_ERROR_INJECTION) is disabled in
   most production kernels. Even where enabled, it only works on
   functions pre-annotated with ALLOW_ERROR_INJECTION() in source -
   no help for a freshly-disclosed CVE. The debugfs UI is blocked by
   lockdown=integrity and the override is probabilistic.

* BPF override (bpf_override_return) honors the same
   ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
   production kernels. Even where on, the operator interface is
   "load a verified BPF program," not a one-line write.


If it is OK for killswitch to attach to any kernel functions, do we still
need ALLOW_ERROR_INJECTION() for fail_function and BPF
override? Shall we instead also allow fail_function and BPF override
to attach to any kernel functions?


I don't think so. ALLOW_ERROR_INJECTION is not a security mechanism, it's an
integrity/safety mechanism for both bpf and fault injection.

It protects against a "developer or CI script doing legitimate fault injection
accidentally panics the box" scenario, not an "attacker gets in" one.


There really isn't a clear boundary between "security mechanism" and
"non-security mechanism". As we are making killswitch available
everywhere under root, users will soon learn to use it to do fault injection,
and potentially much more scary things. (Think about agents with sudo
access).


Fully agree with Song here that there is no clear boundary, and that the
killswitch could lead to arbitrary, hard to debug breakage if applied to
the wrong function.. introducing worse bugs than the one being mitigated
or even /short-circuit LSM enforcement/ (engage security_file_open 0,
engage cap_capable 0, engage apparmor_* etc).

The ALLOW_ERROR_INJECTION() provides a curated white-list where you may
return with an error without causing more severe damage (assuming the
error handling code is right). The right thing would be to more widely
apply ALLOW_ERROR_INJECTION() or to figure out a better way to safely
enable the latter without explicit function annotation.

Wrt BPF:


* BPF override (bpf_override_return) honors the same
   ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
   production kernels. Even where on, the operator interface is
   "load a verified BPF program," not a one-line write.


The claim that BPF itself is off in many production kernels is not really
true, where did you get that from? All the major distros and cloud providers
have BPF enabled these days, and even systemd ships BPF programs for
custom service firewalling etc.

The operator interface is to load a program vs. one-line write.. so we're
disregarding existing infra where you can already achieve the same for a
less safe one-liner convenience? (similarly for the livepatch infra..)

If you need a one-liner: bpftrace -e 'kprobe:FUNC { override(RETVAL); }'
Alternatively, add an extension to systemd where you can just deploy a
list of functions, and it does the necessary work in the background and
persistently.

Also, what about other classes of bugs, like OOB access, UAFs, locking
issues, etc which then could be used as a means for privilege escalations?
It feels like this proposal is a quick'n'dirty prototype via Claude as a
reaction to copy fail bug, but the right solution would be to improve
the user space tooling as mentioned and existing infra we have in kernel.



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-18 Thread Sasha Levin

On Mon, May 18, 2026 at 04:59:08PM -0700, Song Liu wrote:

On Mon, May 18, 2026 at 6:33 AM Sasha Levin  wrote:


On Sun, May 17, 2026 at 11:37:36PM -0700, Song Liu wrote:
>On Sun, May 17, 2026 at 6:49 AM Sasha Levin  wrote:
>> * fail_function (CONFIG_FUNCTION_ERROR_INJECTION) is disabled in
>>   most production kernels. Even where enabled, it only works on
>>   functions pre-annotated with ALLOW_ERROR_INJECTION() in source -
>>   no help for a freshly-disclosed CVE. The debugfs UI is blocked by
>>   lockdown=integrity and the override is probabilistic.
>>
>> * BPF override (bpf_override_return) honors the same
>>   ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
>>   production kernels. Even where on, the operator interface is
>>   "load a verified BPF program," not a one-line write.
>
>If it is OK for killswitch to attach to any kernel functions, do we still
>need ALLOW_ERROR_INJECTION() for fail_function and BPF
>override? Shall we instead also allow fail_function and BPF override
>to attach to any kernel functions?

I don't think so. ALLOW_ERROR_INJECTION is not a security mechanism, it's an
integrity/safety mechanism for both bpf and fault injection.

It protects against a "developer or CI script doing legitimate fault injection
accidentally panics the box" scenario, not an "attacker gets in" one.


There really isn't a clear boundary between "security mechanism" and
"non-security mechanism". As we are making killswitch available
everywhere under root, users will soon learn to use it to do fault injection,
and potentially much more scary things. (Think about agents with sudo
access).


Wouldn't the same argument apply to /dev/mem? If you enable that, and you give
whatever tool/agent/etc access to the interface, you're bound to have a really
bad time unless you know what you're doing?

root can already load a killswitch equivalent module, right? there's nothing
really new with killswitch.

--
Thanks,
Sasha



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-18 Thread Song Liu
On Mon, May 18, 2026 at 6:33 AM Sasha Levin  wrote:
>
> On Sun, May 17, 2026 at 11:37:36PM -0700, Song Liu wrote:
> >On Sun, May 17, 2026 at 6:49 AM Sasha Levin  wrote:
> >> * fail_function (CONFIG_FUNCTION_ERROR_INJECTION) is disabled in
> >>   most production kernels. Even where enabled, it only works on
> >>   functions pre-annotated with ALLOW_ERROR_INJECTION() in source -
> >>   no help for a freshly-disclosed CVE. The debugfs UI is blocked by
> >>   lockdown=integrity and the override is probabilistic.
> >>
> >> * BPF override (bpf_override_return) honors the same
> >>   ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
> >>   production kernels. Even where on, the operator interface is
> >>   "load a verified BPF program," not a one-line write.
> >
> >If it is OK for killswitch to attach to any kernel functions, do we still
> >need ALLOW_ERROR_INJECTION() for fail_function and BPF
> >override? Shall we instead also allow fail_function and BPF override
> >to attach to any kernel functions?
>
> I don't think so. ALLOW_ERROR_INJECTION is not a security mechanism, it's an
> integrity/safety mechanism for both bpf and fault injection.
>
> It protects against a "developer or CI script doing legitimate fault injection
> accidentally panics the box" scenario, not an "attacker gets in" one.

There really isn't a clear boundary between "security mechanism" and
"non-security mechanism". As we are making killswitch available
everywhere under root, users will soon learn to use it to do fault injection,
and potentially much more scary things. (Think about agents with sudo
access).

Thanks,
Song



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-18 Thread Song Liu
On Sun, May 17, 2026 at 6:49 AM Sasha Levin  wrote:
>
> When a kernel (security) issue goes public, fleets stay exposed until a 
> patched
> kernel is built, distributed, and rebooted into.
>
> For many such issues the simplest mitigation is to stop calling the buggy
> function. Killswitch provides that. An admin writes:
>
> echo "engage af_alg_sendmsg -1" \
> > /sys/kernel/security/killswitch/control
>

With v3, we hit this with fentry and killswitch on the same function:

[root@(none) /]# bpftrace -e 'fentry:security_file_open {@count+=1;}' &
[1] 295
Attached 1 probe
[root@(none) /]# echo 'engage security_file_open 0' >
/sys/kernel/security/killswitch/control
[   97.112360] killswitch: engage security_file_open=0 uid=0
auid=4294967295 ses=4294967295 comm=bash
[   97.120766] BUG: unable to handle page fault for address: b5855043
[   97.121212] #PF: supervisor read access in kernel mode
[   97.121517] #PF: error_code(0x) - not-present page
[   97.121710] PGD 4a76067 P4D 4a77067 PUD 4a78063 PMD 0
[   97.121710] Oops: Oops:  [#1] SMP NOPTI
[   97.121710] CPU: 1 UID: 0 PID: 430 Comm: bash Tainted: G
 N H 7.1.0-rc4+ #195 PREEMPT(full)
[   97.121710] Tainted: [N]=TEST, [H]=KILLSWITCH
[   97.121710] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[   97.121710] RIP: 0010:fd_install+0x1c/0x220
[   97.121710] Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f
1e fa 0f 1f 44 00 00 65 48 8b 15 47 a0 a4 04 41 54 55 53 48 8b 9a 70
0a 00 00  46 43 01 0f 85 62 01 00 00 41 89 fc 48 89 f5 65 ff 05 3d
a0 a4
[   97.121710] RSP: 0018:ffa000f2fe70 EFLAGS: 00010286
[   97.121710] RAX: b5855000 RBX: ff11000100911c40 RCX: 
[   97.121710] RDX: ff110001045349c0 RSI: b5855000 RDI: 0003
[   97.121710] RBP: ff11000100be81c0 R08: 0001 R09: 
[   97.121710] R10: 0001 R11: 08c2 R12: 0003
[   97.121710] R13: ff9c R14: 0101 R15: 
[   97.121710] FS:  7fb231d4d740() GS:ff110001b5855000()
knlGS:
[   97.121710] CS:  0010 DS:  ES:  CR0: 80050033
[   97.121710] CR2: b5855043 CR3: 000114513002 CR4: 00771ef0
[   97.121710] PKRU: 
[   97.121710] Call Trace:
[   97.121710]  
[   97.121710]  do_sys_openat2+0x7f/0xe0
[   97.121710]  __x64_sys_openat+0x56/0xa0
[   97.121710]  do_syscall_64+0xc4/0xf20
[   97.121710]  ? srso_alias_return_thunk+0x5/0xfbef5
[   97.121710]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   97.121710] RIP: 0033:0x7fb231e4ee1b
[   97.121710] Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25
18 00 00 00 85 c0 75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00
00 0f 05 <48> 3d 00 f0 ff ff 0f 87 91 00 00 00 48 8b 54 24 28 64 48 2b
14 25
[   97.121710] RSP: 002b:7ffefe160770 EFLAGS: 0246 ORIG_RAX:
0101
[   97.121710] RAX: ffda RBX: 0004 RCX: 7fb231e4ee1b
[   97.121710] RDX:  RSI: 55616f0411d0 RDI: ff9c
[   97.121710] RBP: 55616f0411d0 R08: 55616f046b60 R09: 0064692d656e6968
[   97.121710] R10:  R11: 0246 R12: 
[   97.121710] R13: 55616f03cb20 R14: 55616f039310 R15: 
[   97.121710]  
[   97.121710] Modules linked in:
[   97.121710] CR2: b5855043
[   97.121710] ---[ end trace  ]---
[   97.121710] RIP: 0010:fd_install+0x1c/0x220
[   97.121710] Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f
1e fa 0f 1f 44 00 00 65 48 8b 15 47 a0 a4 04 41 54 55 53 48 8b 9a 70
0a 00 00  46 43 01 0f 85 62 01 00 00 41 89 fc 48 89 f5 65 ff 05 3d
a0 a4
[   97.121710] RSP: 0018:ffa000f2fe70 EFLAGS: 00010286
[   97.121710] RAX: b5855000 RBX: ff11000100911c40 RCX: 
[   97.121710] RDX: ff110001045349c0 RSI: b5855000 RDI: 0003
[   97.121710] RBP: ff11000100be81c0 R08: 0001 R09: 
[   97.121710] R10: 0001 R11: 08c2 R12: 0003
[   97.121710] R13: ff9c R14: 0101 R15: 
[   97.121710] FS:  7fb231d4d740() GS:ff110001b5855000()
knlGS:
[   97.121710] CS:  0010 DS:  ES:  CR0: 80050033
[   97.121710] CR2: b5855043 CR3: 000114513002 CR4: 00771ef0
[   97.121710] PKRU: 
[   97.121710] Kernel panic - not syncing: Fatal exception
[   97.121710] Kernel Offset: disabled



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-18 Thread Sasha Levin

On Sun, May 17, 2026 at 11:37:36PM -0700, Song Liu wrote:

On Sun, May 17, 2026 at 6:49 AM Sasha Levin  wrote:

* fail_function (CONFIG_FUNCTION_ERROR_INJECTION) is disabled in
  most production kernels. Even where enabled, it only works on
  functions pre-annotated with ALLOW_ERROR_INJECTION() in source -
  no help for a freshly-disclosed CVE. The debugfs UI is blocked by
  lockdown=integrity and the override is probabilistic.

* BPF override (bpf_override_return) honors the same
  ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
  production kernels. Even where on, the operator interface is
  "load a verified BPF program," not a one-line write.


If it is OK for killswitch to attach to any kernel functions, do we still
need ALLOW_ERROR_INJECTION() for fail_function and BPF
override? Shall we instead also allow fail_function and BPF override
to attach to any kernel functions?


I don't think so. ALLOW_ERROR_INJECTION is not a security mechanism, it's an
integrity/safety mechanism for both bpf and fault injection.

It protects against a "developer or CI script doing legitimate fault injection
accidentally panics the box" scenario, not an "attacker gets in" one.

--
Thanks,
Sasha



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-17 Thread Song Liu
On Sun, May 17, 2026 at 6:49 AM Sasha Levin  wrote:
>
> When a kernel (security) issue goes public, fleets stay exposed until a 
> patched
> kernel is built, distributed, and rebooted into.
>
> For many such issues the simplest mitigation is to stop calling the buggy
> function. Killswitch provides that. An admin writes:
>
> echo "engage af_alg_sendmsg -1" \
> > /sys/kernel/security/killswitch/control
>
> After this, af_alg_sendmsg() returns -EPERM on every call without
> running its body. The mitigation takes effect immediately, and is dropped on
> the next reboot -- by which point a patched kernel is hopefully in place.
>
> A lot of recent kernel issues sit in code paths most installs only have 
> enabled
> to support a relative minority of users: AF_ALG, ksmbd, nf_tables, vsock, 
> ax25,
> and friends.
>
> For most users, the cost of "this socket family stops working for the day" is
> much smaller than the cost of running a known vulnerable kernel until the fix
> lands.
>
> Why not an existing facility:
>
> * livepatch needs a built, signed, per-kernel-version module per CVE.
>   Under Secure Boot the operator can't sign their own, so they wait
>   for the vendor, and only a minority of vendors actually ship
>   livepatches. Killswitch covers the days before that module shows
>   up.
>
> * fail_function (CONFIG_FUNCTION_ERROR_INJECTION) is disabled in
>   most production kernels. Even where enabled, it only works on
>   functions pre-annotated with ALLOW_ERROR_INJECTION() in source -
>   no help for a freshly-disclosed CVE. The debugfs UI is blocked by
>   lockdown=integrity and the override is probabilistic.
>
> * BPF override (bpf_override_return) honors the same
>   ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
>   production kernels. Even where on, the operator interface is
>   "load a verified BPF program," not a one-line write.

If it is OK for killswitch to attach to any kernel functions, do we still
need ALLOW_ERROR_INJECTION() for fail_function and BPF
override? Shall we instead also allow fail_function and BPF override
to attach to any kernel functions?

Thanks,
Song



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-17 Thread Greg Kroah-Hartman
On Sun, May 17, 2026 at 02:19:35PM -0500, Brandon Taylor wrote:
> Have we learned NOTHING from just over 9 and a half years ago?!
> 
> I do not pretend to be a prophet of Linus, but I cannot for the life of me
> help but get flashbacks from kernel version 4.8 when Linus himself did not
> explain, but EXPLODED, in saying "there is NO F*CKING EXCUSE to knowingly
> kill the kernel."

That's not what this patchset does, sorry.

best of luck!

greg k-h



Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive

2026-05-17 Thread Brandon Taylor

Have we learned NOTHING from just over 9 and a half years ago?!

I do not pretend to be a prophet of Linus, but I cannot for the life of 
me help but get flashbacks from kernel version 4.8 when Linus himself 
did not explain, but EXPLODED, in saying "there is NO F*CKING EXCUSE to 
knowingly kill the kernel."


So for me to hear about THIS from a YouTube video, the fact that we are 
still--STILL!--coming up with new ways to do something which we ought to 
KNOW to be ABSOLUTELY UNACCEPTABLE and DOWNRIGHT INTOLERABLE, BOILS MY 
BLOOD TO NO END.


You ought to consider yourself lucky that it's ME writing this and not 
Linus, because he'd be saying the exact same thing, and making it God 
knows how many times worse. He would break his foot off in somebody's 
BEHIND over this "killswitch" idiocy, and NEVER MIND that it was 
supposedly "designed" to prevent exploits like Fragnesia, Copy Fail, and 
Dirty Frag from creating havoc in Linux distributions, ESPECIALLY his 
go-to in Fedora!


Forgive me (especially you, Master Linus) for blowing my stack over 
this, but we all ought to take a lesson from the past:


Killing the Linux kernel is NOT an acceptable method to mitigate exploits.

I don't care HOW long it takes, but we HAVE TO PATCH THOSE 
VULNERABILITIES, and we HAVE to do it the RIGHT WAY, NOT just introduce 
some kernel-killing "failsafe" just because somebody doesn't know how to 
plug those holes.


I don't care--and neither will Linus--about the so-called "simplest 
mitigation," and neither should you. We should all care that we get the 
code RIGHT.


Brandon

On 5/17/2026 8:48 AM, Sasha Levin wrote:

When a kernel (security) issue goes public, fleets stay exposed until a patched
kernel is built, distributed, and rebooted into.

For many such issues the simplest mitigation is to stop calling the buggy
function. Killswitch provides that. An admin writes:

 echo "engage af_alg_sendmsg -1" \
 > /sys/kernel/security/killswitch/control

After this, af_alg_sendmsg() returns -EPERM on every call without
running its body. The mitigation takes effect immediately, and is dropped on
the next reboot -- by which point a patched kernel is hopefully in place.

A lot of recent kernel issues sit in code paths most installs only have enabled
to support a relative minority of users: AF_ALG, ksmbd, nf_tables, vsock, ax25,
and friends.

For most users, the cost of "this socket family stops working for the day" is
much smaller than the cost of running a known vulnerable kernel until the fix
lands.

Why not an existing facility:

* livepatch needs a built, signed, per-kernel-version module per CVE.
   Under Secure Boot the operator can't sign their own, so they wait
   for the vendor, and only a minority of vendors actually ship
   livepatches. Killswitch covers the days before that module shows
   up.

* fail_function (CONFIG_FUNCTION_ERROR_INJECTION) is disabled in
   most production kernels. Even where enabled, it only works on
   functions pre-annotated with ALLOW_ERROR_INJECTION() in source -
   no help for a freshly-disclosed CVE. The debugfs UI is blocked by
   lockdown=integrity and the override is probabilistic.

* BPF override (bpf_override_return) honors the same
   ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
   production kernels. Even where on, the operator interface is
   "load a verified BPF program," not a one-line write.

* Module blacklist only helps when the bug is in a loadable module.

Killswitch fills the gap: write a symbol to securityfs, function
returns the chosen value until disengage or reboot.

Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Sasha Levin 
---

Changes since v2:
- Fix LLVM=1 build: gate __noipa__ on __has_attribute() (Breno)
- Admin guide: do-not-engage list, pre-soak workflow, relation to
   livepatch/fail_function/BPF (Michal, Mathieu, Joshua)
- Add CVE-2026-43284 (esp_input) worked example + netns selftest
- Drop unused [reason] token from Kconfig help and cmdline comment
- Commit message: spell out why livepatch / fail_function / BPF
   override / module-blacklist don't cover this window.

  Documentation/admin-guide/index.rst   |   1 +
  Documentation/admin-guide/killswitch.rst  | 229 +
  Documentation/admin-guide/tainted-kernels.rst |   8 +
  MAINTAINERS   |  11 +
  include/linux/killswitch.h|  19 +
  include/linux/panic.h |   3 +-
  include/linux/security.h  |   1 +
  init/Kconfig  |   2 +
  kernel/Kconfig.killswitch |  31 +
  kernel/Makefile   |   1 +
  kernel/killswitch.c   | 863 ++
  kernel/panic.c|   1 +
  lib/Kconfig.debug |  13 +
  lib/Makefile  |   1 +
  lib/test_killswitch.c |  85 ++
  securit