mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
io_uring/bpf-ops: clear bpf_ctx while submitting SQEs
bpf_io_uring_submit_sqes() calls io_submit_sqes() from inside the loop
program, with current->bpf_ctx set, and requests issued inline run with
it set too. The socket code uses has_current_bpf_ctx() to recognize
calls from bpf_setsockopt() and friends, where the caller holds the
socket lock and has already been vetted, and skips both.
So a SOCKET_URING_OP_SETSOCKOPT from the SQ passes sockopt_capable()
without the capability, and runs without lock_sock(). A task with no
capability can set SO_MARK, IP_TRANSPARENT or TCP_REPAIR, and two
threads changing IP_OPTIONS on one socket, one through the ring, double
free in no time. SOCK_DESTROY via IORING_OP_SENDMSG ends up in
tcp_abort() without the lock the same way.
Clear the run context around io_submit_sqes(). The SQEs come from
userspace and must be issued like those of any other ring. They still
run inside the program's RCU tasks trace read section, so a request
that sleeps there holds up that grace period, but other request types
do that already.
Fixes: 890819248a ("io_uring/bpf-ops: add kfunc helpers")
Signed-off-by: Chris Mason <mason@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
51bab09b7c
commit
8543a39f03
|
|
@ -17,8 +17,22 @@ __bpf_kfunc_start_defs();
|
|||
__bpf_kfunc int bpf_io_uring_submit_sqes(struct iou_ctx *loop_ctx, u32 nr)
|
||||
{
|
||||
struct io_ring_ctx *ctx = io_loop_demangle_ctx(loop_ctx);
|
||||
struct bpf_run_ctx *old_run_ctx;
|
||||
int ret;
|
||||
|
||||
return io_submit_sqes(ctx, nr);
|
||||
/*
|
||||
* The requests come from the SQ, which user space can write, so they
|
||||
* are issued for the task and not for the BPF program. Hide the run
|
||||
* context of the program from them. The users of has_current_bpf_ctx(),
|
||||
* such as sockopt_lock_sock() and sockopt_capable(), take a context for
|
||||
* a call from a BPF helper, whose caller holds the socket lock already
|
||||
* and needs no capability.
|
||||
*/
|
||||
old_run_ctx = bpf_set_run_ctx(NULL);
|
||||
ret = io_submit_sqes(ctx, nr);
|
||||
bpf_reset_run_ctx(old_run_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
__bpf_kfunc
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user