public inbox for io-uring@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] io_uring: fix missing submitter_task ownership check in bpf_io_reg()
@ 2026-04-22 15:53 Ali Raza
  2026-04-22 21:20 ` Gabriel Krisman Bertazi
  0 siblings, 1 reply; 9+ messages in thread
From: Ali Raza @ 2026-04-22 15:53 UTC (permalink / raw)
  To: Jens Axboe; +Cc: io-uring, linux-kernel, bpf, Ali Raza, Pavel Begunkov

bpf_io_reg() installs a BPF struct_ops loop_step on any io_uring ring
the caller holds a file descriptor for.  io_uring_ctx_get_file() only
validates that the fd resolves to an io_uring file; it does not verify
the caller has authority over the ring's submitter_task.

A parallel path in io_uring_register() already enforces this:

    if (ctx->submitter_task && ctx->submitter_task != current)
        return -EEXIST;  /* register.c:733 */

Without the equivalent check in bpf_io_reg(), a local user with
CAP_PERFMON can exploit IORING_SETUP_R_DISABLED -- which defers
submitter_task assignment until IORING_REGISTER_ENABLE_RINGS -- to
install a loop_step on a ring before a more-privileged process becomes
its submitter_task.  The loop_step then executes in the privileged
process's task context and can issue arbitrary io_uring operations
(IORING_OP_WRITE, IORING_OP_READ, IORING_OP_SPLICE) against that
process's open file table.  This provides a cross-privilege io_uring
execution primitive that can serve as a component in a privilege
escalation chain when combined with a vector that induces a privileged
process to adopt an attacker-controlled ring.

Affected: v7.1-rc1+ with CONFIG_IO_URING_BPF_OPS=y.
Requires: IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER.

Add the ownership check in io_install_bpf(), which is called under
uring_lock, matching the locking context of the register.c check.

Signed-off-by: Ali Raza <elirazamumtaz@gmail.com>
Cc: Pavel Begunkov <asml.silence@gmail.com>
---
 io_uring/bpf-ops.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/io_uring/bpf-ops.c b/io_uring/bpf-ops.c
index 937e48bef40b..cac11c929297 100644
--- a/io_uring/bpf-ops.c
+++ b/io_uring/bpf-ops.c
@@ -162,6 +162,8 @@ static int io_install_bpf(struct io_ring_ctx *ctx, struct io_uring_bpf_ops *ops)
 		return -EOPNOTSUPP;
 	if (!(ctx->flags & IORING_SETUP_DEFER_TASKRUN))
 		return -EOPNOTSUPP;
+	if (ctx->submitter_task && ctx->submitter_task != current)
+		return -EPERM;
 
 	if (ctx->bpf_ops)
 		return -EBUSY;

---
base-commit: bea8d77e45a8b77f2beca1affc9aa7ed28f39b17
change-id: 20260422-master-d96fe0e8bb3c

Best regards,
--  
Ali Raza <elirazamumtaz@gmail.com>


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] io_uring: fix missing submitter_task ownership check in bpf_io_reg()
  2026-04-22 15:53 [PATCH] io_uring: fix missing submitter_task ownership check in bpf_io_reg() Ali Raza
@ 2026-04-22 21:20 ` Gabriel Krisman Bertazi
  2026-04-22 21:46   ` Jens Axboe
  2026-04-22 21:58   ` Pavel Begunkov
  0 siblings, 2 replies; 9+ messages in thread
From: Gabriel Krisman Bertazi @ 2026-04-22 21:20 UTC (permalink / raw)
  To: Ali Raza; +Cc: Jens Axboe, io-uring, linux-kernel, bpf, Pavel Begunkov

Ali Raza <elirazamumtaz@gmail.com> writes:

> bpf_io_reg() installs a BPF struct_ops loop_step on any io_uring ring
> the caller holds a file descriptor for.  io_uring_ctx_get_file() only
> validates that the fd resolves to an io_uring file; it does not verify
> the caller has authority over the ring's submitter_task.
>
> A parallel path in io_uring_register() already enforces this:
>
>     if (ctx->submitter_task && ctx->submitter_task != current)
>         return -EEXIST;  /* register.c:733 */

How is this a protection?  I thought ctx->submitter_task is about
IORING_SETUP_SINGLE_ISSUER. there is no permission or capability over
it against other processes.

> Without the equivalent check in bpf_io_reg(), a local user with
> CAP_PERFMON can exploit IORING_SETUP_R_DISABLED -- which defers

I'd argue this is a non-issue.  If you have CAP_PERFMON, you are able to
mess with the process in many ways beyond this.  Otherwise, how a
process would be able to get the fd in the first place?

> submitter_task assignment until IORING_REGISTER_ENABLE_RINGS -- to
> install a loop_step on a ring before a more-privileged process becomes
> its submitter_task.  The loop_step then executes in the privileged
> process's task context and can issue arbitrary io_uring operations
> (IORING_OP_WRITE, IORING_OP_READ, IORING_OP_SPLICE) against that
> process's open file table.  This provides a cross-privilege io_uring
> execution primitive that can serve as a component in a privilege
> escalation chain when combined with a vector that induces a privileged
> process to adopt an attacker-controlled ring.
>
> Affected: v7.1-rc1+ with CONFIG_IO_URING_BPF_OPS=y.
> Requires: IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER.
>
> Add the ownership check in io_install_bpf(), which is called under
> uring_lock, matching the locking context of the register.c check.
>
> Signed-off-by: Ali Raza <elirazamumtaz@gmail.com>
> Cc: Pavel Begunkov <asml.silence@gmail.com>
> ---
>  io_uring/bpf-ops.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/io_uring/bpf-ops.c b/io_uring/bpf-ops.c
> index 937e48bef40b..cac11c929297 100644
> --- a/io_uring/bpf-ops.c
> +++ b/io_uring/bpf-ops.c
> @@ -162,6 +162,8 @@ static int io_install_bpf(struct io_ring_ctx *ctx, struct io_uring_bpf_ops *ops)
>  		return -EOPNOTSUPP;
>  	if (!(ctx->flags & IORING_SETUP_DEFER_TASKRUN))
>  		return -EOPNOTSUPP;
> +	if (ctx->submitter_task && ctx->submitter_task != current)
> +		return -EPERM;
>  
>  	if (ctx->bpf_ops)
>  		return -EBUSY;
>
> ---
> base-commit: bea8d77e45a8b77f2beca1affc9aa7ed28f39b17
> change-id: 20260422-master-d96fe0e8bb3c
>
> Best regards,
> --  
>
> Ali Raza <elirazamumtaz@gmail.com>
>

-- 
Gabriel Krisman Bertazi

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] io_uring: fix missing submitter_task ownership check in bpf_io_reg()
  2026-04-22 21:20 ` Gabriel Krisman Bertazi
@ 2026-04-22 21:46   ` Jens Axboe
  2026-04-22 21:58   ` Pavel Begunkov
  1 sibling, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2026-04-22 21:46 UTC (permalink / raw)
  To: Gabriel Krisman Bertazi, Ali Raza
  Cc: io-uring, linux-kernel, bpf, Pavel Begunkov

On 4/22/26 3:20 PM, Gabriel Krisman Bertazi wrote:
> Ali Raza <elirazamumtaz@gmail.com> writes:
> 
>> bpf_io_reg() installs a BPF struct_ops loop_step on any io_uring ring
>> the caller holds a file descriptor for.  io_uring_ctx_get_file() only
>> validates that the fd resolves to an io_uring file; it does not verify
>> the caller has authority over the ring's submitter_task.
>>
>> A parallel path in io_uring_register() already enforces this:
>>
>>     if (ctx->submitter_task && ctx->submitter_task != current)
>>         return -EEXIST;  /* register.c:733 */
> 
> How is this a protection?  I thought ctx->submitter_task is about
> IORING_SETUP_SINGLE_ISSUER. there is no permission or capability over
> it against other processes.
> 
>> Without the equivalent check in bpf_io_reg(), a local user with
>> CAP_PERFMON can exploit IORING_SETUP_R_DISABLED -- which defers
> 
> I'd argue this is a non-issue.  If you have CAP_PERFMON, you are able to
> mess with the process in many ways beyond this.  Otherwise, how a
> process would be able to get the fd in the first place?

It is a non-issue. It relies entirely on an unrealistic scenarior. Yes
if you have a privileged task that can take over a non-privileged ring
fd, yes than you can do bad things. News at 11...

-- 
Jens Axboe

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] io_uring: fix missing submitter_task ownership check in bpf_io_reg()
  2026-04-22 21:20 ` Gabriel Krisman Bertazi
  2026-04-22 21:46   ` Jens Axboe
@ 2026-04-22 21:58   ` Pavel Begunkov
  2026-04-23  8:40     ` Ali Raza
  1 sibling, 1 reply; 9+ messages in thread
From: Pavel Begunkov @ 2026-04-22 21:58 UTC (permalink / raw)
  To: Gabriel Krisman Bertazi, Ali Raza; +Cc: Jens Axboe, io-uring, linux-kernel, bpf

On 4/22/26 22:20, Gabriel Krisman Bertazi wrote:
> Ali Raza <elirazamumtaz@gmail.com> writes:
> 
>> bpf_io_reg() installs a BPF struct_ops loop_step on any io_uring ring
>> the caller holds a file descriptor for.  io_uring_ctx_get_file() only
>> validates that the fd resolves to an io_uring file; it does not verify
>> the caller has authority over the ring's submitter_task.
>>
>> A parallel path in io_uring_register() already enforces this:
>>
>>      if (ctx->submitter_task && ctx->submitter_task != current)
>>          return -EEXIST;  /* register.c:733 */
> 
> How is this a protection?  I thought ctx->submitter_task is about
> IORING_SETUP_SINGLE_ISSUER. there is no permission or capability over
> it against other processes.
> 
>> Without the equivalent check in bpf_io_reg(), a local user with
>> CAP_PERFMON can exploit IORING_SETUP_R_DISABLED -- which defers
> 
> I'd argue this is a non-issue.

Right, it involves receiving a ring from an untrusted source and
then using it. Any application doing that is extremely broken,
even without any bpf you can use that to do some pretty nasty things

   If you have CAP_PERFMON, you are able to
> mess with the process in many ways beyond this.  Otherwise, how a
> process would be able to get the fd in the first place?



-- 
Pavel Begunkov


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] io_uring: fix missing submitter_task ownership check in bpf_io_reg()
  2026-04-22 21:58   ` Pavel Begunkov
@ 2026-04-23  8:40     ` Ali Raza
  2026-04-27  8:55       ` Pavel Begunkov
  0 siblings, 1 reply; 9+ messages in thread
From: Ali Raza @ 2026-04-23  8:40 UTC (permalink / raw)
  To: asml.silence; +Cc: axboe, bpf, elirazamumtaz, io-uring, krisman, linux-kernel

On 4/22/26 10:20 PM, Gabriel Krisman Bertazi wrote:
> How is this a protection?  I thought ctx->submitter_task is about
> IORING_SETUP_SINGLE_ISSUER. there is no permission or capability over
> it against other processes.

You are correct.  submitter_task is a SINGLE_ISSUER mechanism, not a
cross-process security boundary.  The "parallel path" framing in the
commit message was inaccurate.

The code confirms it - submitter_task is only assigned under
IORING_SETUP_SINGLE_ISSUER, either at ring creation [1]:

    if (ctx->flags & IORING_SETUP_SINGLE_ISSUER
        && !(ctx->flags & IORING_SETUP_R_DISABLED))
        ctx->submitter_task = get_task_struct(current);

or deferred to IORING_REGISTER_ENABLE_RINGS [2]:

    if (ctx->flags & IORING_SETUP_SINGLE_ISSUER) {
        ctx->submitter_task = get_task_struct(current);

The check at [3] I cited returns -EEXIST to prevent a second process from
registering on a SINGLE_ISSUER ring - it has the effect of blocking
cross-process access but that is not its purpose.

The commit message's Requires: line was also incomplete:
IORING_SETUP_R_DISABLED is a prerequisite but was omitted.  Without
R_DISABLED, submitter_task is assigned to the ring creator immediately
at [1], so the attacker who creates the ring already satisfies
submitter_task == current - no timing window exists and the attack is
impossible regardless of whether the check is present.

> I'd argue this is a non-issue.  If you have CAP_PERFMON, you are able to
> mess with the process in many ways beyond this.  Otherwise, how a
> process would be able to get the fd in the first place?

On CAP_PERFMON I'd push back slightly: it is narrow (BPF program loading,
perf monitoring) and does not grant ptrace, arbitrary file write, or
process control.  The BPF struct_ops path is specifically what
CAP_PERFMON enables here, not a general process manipulation capability.

But the fd acquisition question is the real barrier, and on that point
you, Jens, and Pavel are all correct.  As Pavel noted, any application
that accepts a ring fd from an untrusted source and calls ENABLE_RINGS on
it is already catastrophically broken - the BPF vector is just one of
many things an attacker could do in that scenario.  There is no realistic
path to get a privileged process into that state without it already being
compromised by other means.

The fix itself closes a genuine asymmetry - bpf_io_reg() is the only
registration path without this guard. I can resubmit with an elaborated 
commit message, if Pavel thinks it's worth applying.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/io_uring/io_uring.c?id=bea8d77e45a8b77f2beca1affc9aa7ed28f39b17#n3053
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/io_uring/register.c?id=bea8d77e45a8b77f2beca1affc9aa7ed28f39b17#n282
[3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/io_uring/register.c?id=bea8d77e45a8b77f2beca1affc9aa7ed28f39b17#n733

Ali Raza

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] io_uring: fix missing submitter_task ownership check in bpf_io_reg()
  2026-04-23  8:40     ` Ali Raza
@ 2026-04-27  8:55       ` Pavel Begunkov
  2026-04-27 19:24         ` [PATCH v2] io_uring: add submitter_task consistency check to io_install_bpf() Ali Raza
  2026-04-28 12:27         ` [PATCH v3] " Ali Raza
  0 siblings, 2 replies; 9+ messages in thread
From: Pavel Begunkov @ 2026-04-27  8:55 UTC (permalink / raw)
  To: Ali Raza; +Cc: axboe, bpf, io-uring, krisman, linux-kernel

On 4/23/26 09:40, Ali Raza wrote:
> On 4/22/26 10:20 PM, Gabriel Krisman Bertazi wrote:
>> How is this a protection?  I thought ctx->submitter_task is about
>> IORING_SETUP_SINGLE_ISSUER. there is no permission or capability over
>> it against other processes.
> 
> You are correct.  submitter_task is a SINGLE_ISSUER mechanism, not a
> cross-process security boundary.  The "parallel path" framing in the
> commit message was inaccurate.
> 
> The code confirms it - submitter_task is only assigned under
> IORING_SETUP_SINGLE_ISSUER, either at ring creation [1]:
> 
>      if (ctx->flags & IORING_SETUP_SINGLE_ISSUER
>          && !(ctx->flags & IORING_SETUP_R_DISABLED))
>          ctx->submitter_task = get_task_struct(current);
> 
> or deferred to IORING_REGISTER_ENABLE_RINGS [2]:
> 
>      if (ctx->flags & IORING_SETUP_SINGLE_ISSUER) {
>          ctx->submitter_task = get_task_struct(current);
> 
> The check at [3] I cited returns -EEXIST to prevent a second process from
> registering on a SINGLE_ISSUER ring - it has the effect of blocking
> cross-process access but that is not its purpose.
> 
> The commit message's Requires: line was also incomplete:
> IORING_SETUP_R_DISABLED is a prerequisite but was omitted.  Without
> R_DISABLED, submitter_task is assigned to the ring creator immediately
> at [1], so the attacker who creates the ring already satisfies
> submitter_task == current - no timing window exists and the attack is
> impossible regardless of whether the check is present.
> 
>> I'd argue this is a non-issue.  If you have CAP_PERFMON, you are able to
>> mess with the process in many ways beyond this.  Otherwise, how a
>> process would be able to get the fd in the first place?
> 
> On CAP_PERFMON I'd push back slightly: it is narrow (BPF program loading,
> perf monitoring) and does not grant ptrace, arbitrary file write, or
> process control.  The BPF struct_ops path is specifically what
> CAP_PERFMON enables here, not a general process manipulation capability.
> 
> But the fd acquisition question is the real barrier, and on that point
> you, Jens, and Pavel are all correct.  As Pavel noted, any application
> that accepts a ring fd from an untrusted source and calls ENABLE_RINGS on
> it is already catastrophically broken - the BPF vector is just one of
> many things an attacker could do in that scenario.  There is no realistic
> path to get a privileged process into that state without it already being
> compromised by other means.
> 
> The fix itself closes a genuine asymmetry - bpf_io_reg() is the only

Not a fix, submitter_task was not made to be a security mechanism in
the first place.

> registration path without this guard. I can resubmit with an elaborated
> commit message, if Pavel thinks it's worth applying.

That might be fine to add. I omitted it because it happens off the bpf
syscall path and not through the io_uring registration syscall, i.e. it'll
break if bpf folks decide to defer registration to a worker thread
for some reason. It's of low probability to be a problem, so it might
be okay.

If you're rebasing, don't forget to use the latest branch and look
up how it checks ctx->flags around submitter task.

-- 
Pavel Begunkov


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] io_uring: add submitter_task consistency check to io_install_bpf()
  2026-04-27  8:55       ` Pavel Begunkov
@ 2026-04-27 19:24         ` Ali Raza
  2026-04-27 21:47           ` Gabriel Krisman Bertazi
  2026-04-28 12:27         ` [PATCH v3] " Ali Raza
  1 sibling, 1 reply; 9+ messages in thread
From: Ali Raza @ 2026-04-27 19:24 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, Pavel Begunkov, Ali Raza

io_uring_register() already guards against a different task touching
a SINGLE_ISSUER ring (register.c:733):

    if (ctx->submitter_task && ctx->submitter_task != current)
        return -EEXIST;

bpf_io_reg() calls io_install_bpf() without an equivalent guard.  Add
the same check for consistency.  The check is gated on
IORING_SETUP_SINGLE_ISSUER since submitter_task is only assigned for
that flag combination (io_uring.c:3053 and register.c:282).

Note: io_install_bpf() is called directly from the BPF syscall path,
so `current` is the task invoking BPF_LINK_CREATE.  If BPF link
registration were ever deferred to a worker thread, this check would
need revisiting.

Signed-off-by: Ali Raza <elirazamumtaz@gmail.com>
---
v2: Added IORING_SETUP_SINGLE_ISSUER gate; changed -EPERM to -EEXIST to
    match register.c:733; removed security/exploit framing from commit
    message; acknowledged that `current` may not be valid if BPF link
    creation is ever deferred to a worker thread.

 io_uring/bpf-ops.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/io_uring/bpf-ops.c b/io_uring/bpf-ops.c
index 937e48bef40b..84578614cc0b 100644
--- a/io_uring/bpf-ops.c
+++ b/io_uring/bpf-ops.c
@@ -162,6 +162,9 @@ static int io_install_bpf(struct io_ring_ctx *ctx, struct io_uring_bpf_ops *ops)
 		return -EOPNOTSUPP;
 	if (!(ctx->flags & IORING_SETUP_DEFER_TASKRUN))
 		return -EOPNOTSUPP;
+	if ((ctx->flags & IORING_SETUP_SINGLE_ISSUER) &&
+	    ctx->submitter_task && ctx->submitter_task != current)
+		return -EEXIST;

 	if (ctx->bpf_ops)
 		return -EBUSY;
--
2.43.0

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] io_uring: add submitter_task consistency check to io_install_bpf()
  2026-04-27 19:24         ` [PATCH v2] io_uring: add submitter_task consistency check to io_install_bpf() Ali Raza
@ 2026-04-27 21:47           ` Gabriel Krisman Bertazi
  0 siblings, 0 replies; 9+ messages in thread
From: Gabriel Krisman Bertazi @ 2026-04-27 21:47 UTC (permalink / raw)
  To: Ali Raza; +Cc: io-uring, Jens Axboe, Pavel Begunkov

Ali Raza <elirazamumtaz@gmail.com> writes:

> io_uring_register() already guards against a different task touching
> a SINGLE_ISSUER ring (register.c:733):
>
>     if (ctx->submitter_task && ctx->submitter_task != current)
>         return -EEXIST;
>
> bpf_io_reg() calls io_install_bpf() without an equivalent guard.  Add
> the same check for consistency.  The check is gated on
> IORING_SETUP_SINGLE_ISSUER since submitter_task is only assigned for
> that flag combination (io_uring.c:3053 and register.c:282).
>
> Note: io_install_bpf() is called directly from the BPF syscall path,
> so `current` is the task invoking BPF_LINK_CREATE.  If BPF link
> registration were ever deferred to a worker thread, this check would
> need revisiting.
>
> Signed-off-by: Ali Raza <elirazamumtaz@gmail.com>
> ---
> v2: Added IORING_SETUP_SINGLE_ISSUER gate; changed -EPERM to -EEXIST to
>     match register.c:733; removed security/exploit framing from commit
>     message; acknowledged that `current` may not be valid if BPF link
>     creation is ever deferred to a worker thread.
>
>  io_uring/bpf-ops.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/io_uring/bpf-ops.c b/io_uring/bpf-ops.c
> index 937e48bef40b..84578614cc0b 100644
> --- a/io_uring/bpf-ops.c
> +++ b/io_uring/bpf-ops.c
> @@ -162,6 +162,9 @@ static int io_install_bpf(struct io_ring_ctx *ctx, struct io_uring_bpf_ops *ops)
>  		return -EOPNOTSUPP;
>  	if (!(ctx->flags & IORING_SETUP_DEFER_TASKRUN))
>  		return -EOPNOTSUPP;
> +	if ((ctx->flags & IORING_SETUP_SINGLE_ISSUER) &&
> +	    ctx->submitter_task && ctx->submitter_task != current)

The ctx->flags & IORING_SETUP_SINGLE_ISSUER check is redundant. IIUC,
->submitter_task can only be set if the ring is set with
IORING_SETUP_SINGLE_ISSUER.

> +		return -EEXIST;
>
>  	if (ctx->bpf_ops)
>  		return -EBUSY;
> --
> 2.43.0

-- 
Gabriel Krisman Bertazi

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3] io_uring: add submitter_task consistency check to io_install_bpf()
  2026-04-27  8:55       ` Pavel Begunkov
  2026-04-27 19:24         ` [PATCH v2] io_uring: add submitter_task consistency check to io_install_bpf() Ali Raza
@ 2026-04-28 12:27         ` Ali Raza
  1 sibling, 0 replies; 9+ messages in thread
From: Ali Raza @ 2026-04-28 12:27 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, Pavel Begunkov, Gabriel Krisman Bertazi, Ali Raza

io_uring_register() already guards against a different task touching
a SINGLE_ISSUER ring (register.c:733):

    if (ctx->submitter_task && ctx->submitter_task != current)
        return -EEXIST;

bpf_io_reg() calls io_install_bpf() without an equivalent guard.  Add
the same check for consistency.

Note: io_install_bpf() is called directly from the BPF syscall path,
so `current` is the task invoking BPF_LINK_CREATE.  If BPF link
registration were ever deferred to a worker thread, this check would
need revisiting.

Signed-off-by: Ali Raza <elirazamumtaz@gmail.com>
---
v3: Dropped redundant IORING_SETUP_SINGLE_ISSUER gate per Gabriel
    (submitter_task can only be set with SINGLE_ISSUER, so the check
    is implicit).  Now matches register.c:733 exactly.
v2: Added IORING_SETUP_SINGLE_ISSUER gate; changed -EPERM to -EEXIST
    to match register.c:733; removed security/exploit framing from
    commit message.

 io_uring/bpf-ops.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/io_uring/bpf-ops.c b/io_uring/bpf-ops.c
index 937e48bef40b..0eabbd1fe24d 100644
--- a/io_uring/bpf-ops.c
+++ b/io_uring/bpf-ops.c
@@ -162,6 +162,8 @@ static int io_install_bpf(struct io_ring_ctx *ctx, struct io_uring_bpf_ops *ops)
 		return -EOPNOTSUPP;
 	if (!(ctx->flags & IORING_SETUP_DEFER_TASKRUN))
 		return -EOPNOTSUPP;
+	if (ctx->submitter_task && ctx->submitter_task != current)
+		return -EEXIST;

 	if (ctx->bpf_ops)
 		return -EBUSY;
--
2.43.0

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-04-28 12:27 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-22 15:53 [PATCH] io_uring: fix missing submitter_task ownership check in bpf_io_reg() Ali Raza
2026-04-22 21:20 ` Gabriel Krisman Bertazi
2026-04-22 21:46   ` Jens Axboe
2026-04-22 21:58   ` Pavel Begunkov
2026-04-23  8:40     ` Ali Raza
2026-04-27  8:55       ` Pavel Begunkov
2026-04-27 19:24         ` [PATCH v2] io_uring: add submitter_task consistency check to io_install_bpf() Ali Raza
2026-04-27 21:47           ` Gabriel Krisman Bertazi
2026-04-28 12:27         ` [PATCH v3] " Ali Raza

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox