From 78004e9a87f240df03e2f73120d291763c32e0a7 Mon Sep 17 00:00:00 2001 From: Ali Ahmet Memis Date: Fri, 21 Aug 2026 01:45:27 +0000 Subject: openrisc: fix arbitrary kernel memory access via or1k_atomic syscall sys_or1k_atomic() (syscall 244 in the "or1k" ABI) takes two user pointers, v1 and v2, and swaps the words they point to in hand-written assembly. l.lwz r29,0(r4) l.lwz r27,0(r5) l.sw 0(r4),r27 l.sw 0(r5),r29 The pointers are not checked with access_ok(). The four memory accesses also have no exception table entries. A caller passes a kernel address as either pointer, and the syscall reads from and writes to it directly. This gives an unprivileged process a kernel read/write primitive. It overwrites kernel data such as the sys_call_table, gaining code execution in kernel context. Check both pointers before entering the critical section. Add fixups for the four memory accesses so faults on valid but unmapped user addresses return -EFAULT. [shorne@gmail.com: fix comment style] Fixes: 9d02a4283e9c ("OpenRISC: Boot code") Cc: stable@vger.kernel.org Signed-off-by: Ali Ahmet Memis Signed-off-by: Stafford Horne --- fs/fuse/args.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 fs/fuse/args.h (limited to 'fs/fuse/args.h') diff --git a/fs/fuse/args.h b/fs/fuse/args.h new file mode 100644 index 000000000..ecfe51a19 --- /dev/null +++ b/fs/fuse/args.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _FS_FUSE_ARGS_H +#define _FS_FUSE_ARGS_H + +#include + +struct fuse_mount; + +/** One input argument of a request */ +struct fuse_in_arg { + unsigned size; + const void *value; +}; + +/** One output argument of a request */ +struct fuse_arg { + unsigned size; + void *value; +}; + +struct fuse_args { + u64 nodeid; + u32 opcode; + u32 uid; + u32 gid; + u32 pid; + u8 in_numargs; + u8 out_numargs; + u8 ext_idx; + bool force:1; + bool noreply:1; + bool nocreds:1; + bool in_pages:1; + bool out_pages:1; + bool user_pages:1; + bool out_argvar:1; + bool page_zeroing:1; + bool page_replace:1; + bool may_block:1; + bool is_ext:1; + bool is_pinned:1; + bool invalidate_vmap:1; + bool abort_on_kill:1; + struct fuse_in_arg in_args[4]; + struct fuse_arg out_args[2]; + void (*end)(struct fuse_args *args, int error); + /* Used for kvec iter backed by vmalloc address */ + void *vmap_base; +}; + +/** FUSE folio descriptor */ +struct fuse_folio_desc { + unsigned int length; + unsigned int offset; +}; + +struct fuse_args_pages { + struct fuse_args args; + struct folio **folios; + struct fuse_folio_desc *descs; + unsigned int num_folios; +}; + +#endif /* _FS_FUSE_ARGS_H */ -- cgit v1.3.1