+25,7 @@ #include #include #include +#include #include #include @@ -1519,7 +1520,7 @@ static struct fuse_init_args *fuse_new_init(struct fuse_mount *fm) * This is just an information flag for fuse server. No need to check * the reply - server is either sending IORING_OP_URING_CMD or not. */ - if (fuse_uring_enabled()) + if (fm->fc->system_io_uring && fuse_uring_enabled()) flags |= FUSE_OVER_IO_URING; ia->in.flags = flags; @@ -1935,6 +1936,46 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) } EXPORT_SYMBOL_GPL(fuse_fill_super_common); +/* Check if system wide io-uring is enabled */ +static void check_system_io_uring(struct fuse_conn *fc, struct fuse_fs_context *ctx) +{ + struct cred *new_cred = NULL; + const struct cred *old_cred = NULL; + int allowed; + + /* + * Mount might be from an unprivileged user using s-bit + * fusermount, the check if system wide io-uring is enabled + * needs to drop privileges + * then. + */ + if (ctx->user_id.val != 0 && ctx->group_id.val != 0) { + new_cred = prepare_creds(); + if (!new_cred) + return; + + cap_clear(new_cred->cap_effective); + cap_clear(new_cred->cap_permitted); + cap_clear(new_cred->cap_inheritable); + + if (ctx->user_id_present) + new_cred->uid = new_cred->euid = ctx->user_id; + + if (ctx->group_id_present) + new_cred->gid = new_cred->egid = new_cred->fsgid = ctx->group_id; + + old_cred = override_creds(new_cred); + } + + allowed = io_uring_allowed(); + fc->system_io_uring = io_uring_allowed() == 0; + + if (old_cred) + revert_creds(old_cred); + if (new_cred) + put_cred(new_cred); +} + static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) { struct fuse_fs_context *ctx = fsc->fs_private; @@ -1962,6 +2003,8 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) fm = get_fuse_mount_super(sb); + check_system_io_uring(fm->fc, ctx); + return fuse_send_init(fm); } diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h index 85fe4e6b275c7de260ea9a8552b8e1c3e7f7e5ec..eaee221b1ed566fcba5a01885e6a4b9073026f93 100644 --- a/include/linux/io_uring.h +++ b/include/linux/io_uring.h @@ -12,6 +12,7 @@ void __io_uring_free(struct task_struct *tsk); void io_uring_unreg_ringfd(void); const char *io_uring_get_opcode(u8 opcode); bool io_is_uring_fops(struct file *file); +int io_uring_allowed(void); static inline void io_uring_files_cancel(void) { diff --git a/include/linux/io_uring/io_uring.h b/include/linux/io_uring/io_uring.h new file mode 100644 index 0000000000000000000000000000000000000000..a28d58ea218ff7cc7518a66bd37ece1eacee30fb --- /dev/null +++ b/include/linux/io_uring/io_uring.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _LINUX_IO_URING_H +#define _LINUX_IO_URING_H + +int io_uring_allowed(void); + +#endif diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 820ef05276667e74c259723bf9f3c605cf9d0505..52cb209d4c7499620ae5d8b7ad1362810e84821f 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -76,6 +76,7 @@ #include #include +#include #include "io-wq.h" @@ -3936,7 +3937,7 @@ static long io_uring_setup(u32 entries, struct io_uring_params __user *params) return io_uring_create(entries, &p, params); } -static inline int io_uring_allowed(void) +int io_uring_allowed(void) { int disabled = READ_ONCE(sysctl_io_uring_disabled); kgid_t io_uring_group; @@ -3957,6 +3958,7 @@ static inline int io_uring_allowed(void) allowed_lsm: return security_uring_allowed(); } +EXPORT_SYMBOL_GPL(io_uring_allowed); SYSCALL_DEFINE2(io_uring_setup, u32, entries, struct io_uring_params __user *, params) --- base-commit: 6548d364a3e850326831799d7e3ea2d7bb97ba08 change-id: 20251021-io-uring-fix-check-systemwide-io-uring-enable-f290e75be229 Best regards, -- Bernd Schubert [PATCH RFC] fuse: check if system-wide io_uring is enabledBernd Schubert undefinedMiklos Szeredi , Jens Axboe undefined undefined undefined undefined undefined undefined undefinedŒ