struct task_struct *submitter_task;
struct io_rings *rings;
+ /* cache of ->restrictions.bpf_filters->filters */
+ struct io_bpf_filter __rcu **bpf_filters;
struct percpu_ref refs;
clockid_t clockid;
* __io_uring_run_bpf_filters() returns 0 on success, allow running the
* request, and -EACCES when a request is denied.
*/
-int __io_uring_run_bpf_filters(struct io_restriction *res, struct io_kiocb *req)
+int __io_uring_run_bpf_filters(struct io_bpf_filter __rcu **filters,
+ struct io_kiocb *req)
{
struct io_bpf_filter *filter;
struct io_uring_bpf_ctx bpf_ctx;
int ret;
/* Fast check for existence of filters outside of RCU */
- if (!rcu_access_pointer(res->bpf_filters->filters[req->opcode]))
+ if (!rcu_access_pointer(filters[req->opcode]))
return 0;
/*
* of what we expect, io_init_req() does this.
*/
guard(rcu)();
- filter = rcu_dereference(res->bpf_filters->filters[req->opcode]);
+ filter = rcu_dereference(filters[req->opcode]);
if (!filter)
return 0;
else if (filter == &dummy_filter)
#ifdef CONFIG_IO_URING_BPF
-int __io_uring_run_bpf_filters(struct io_restriction *res, struct io_kiocb *req);
+int __io_uring_run_bpf_filters(struct io_bpf_filter __rcu **filters, struct io_kiocb *req);
int io_register_bpf_filter(struct io_restriction *res,
struct io_uring_bpf __user *arg);
void io_put_bpf_filters(struct io_restriction *res);
-static inline int io_uring_run_bpf_filters(struct io_restriction *res,
+static inline int io_uring_run_bpf_filters(struct io_bpf_filter __rcu **filters,
struct io_kiocb *req)
{
- if (res->bpf_filters)
- return __io_uring_run_bpf_filters(res, req);
+ if (filters)
+ return __io_uring_run_bpf_filters(filters, req);
return 0;
}
{
return -EINVAL;
}
-static inline int io_uring_run_bpf_filters(struct io_restriction *res,
+static inline int io_uring_run_bpf_filters(struct io_bpf_filter __rcu **filters,
struct io_kiocb *req)
{
return 0;
if (unlikely(ret))
return io_submit_fail_init(sqe, req, ret);
- if (unlikely(ctx->restrictions.bpf_filters)) {
- ret = io_uring_run_bpf_filters(&ctx->restrictions, req);
+ if (unlikely(ctx->bpf_filters)) {
+ ret = io_uring_run_bpf_filters(ctx->bpf_filters, req);
if (ret)
return io_submit_fail_init(sqe, req, ret);
}
percpu_ref_exit(&ctx->refs);
free_uid(ctx->user);
io_req_caches_free(ctx);
+
+ if (ctx->restrictions.bpf_filters) {
+ WARN_ON_ONCE(ctx->bpf_filters !=
+ ctx->restrictions.bpf_filters->filters);
+ } else {
+ WARN_ON_ONCE(ctx->bpf_filters);
+ }
io_put_bpf_filters(&ctx->restrictions);
WARN_ON_ONCE(ctx->nr_req_allocated);
if (nr_args != 1)
break;
ret = io_register_bpf_filter(&ctx->restrictions, arg);
+ if (!ret)
+ WRITE_ONCE(ctx->bpf_filters,
+ ctx->restrictions.bpf_filters->filters);
break;
default:
ret = -EINVAL;