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 --- arch/microblaze/lib/memset.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 arch/microblaze/lib/memset.c (limited to 'arch/microblaze/lib/memset.c') diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c new file mode 100644 index 000000000..7c2352d56 --- /dev/null +++ b/arch/microblaze/lib/memset.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2008-2009 Michal Simek + * Copyright (C) 2008-2009 PetaLogix + * Copyright (C) 2007 John Williams + * + * Reasonably optimised generic C-code for memset on Microblaze + * This is generic C code to do efficient, alignment-aware memcpy. + * + * It is based on demo code originally Copyright 2001 by Intel Corp, taken from + * http://www.embedded.com/showArticle.jhtml?articleID=19205567 + * + * Attempts were made, unsuccessfully, to contact the original + * author of this code (Michael Morrow, Intel). Below is the original + * copyright notice. + * + * This software has been developed by Intel Corporation. + * Intel specifically disclaims all warranties, express or + * implied, and all liability, including consequential and + * other indirect damages, for the use of this program, including + * liability for infringement of any proprietary rights, + * and including the warranties of merchantability and fitness + * for a particular purpose. Intel does not assume any + * responsibility for and errors which may appear in this program + * not any responsibility to update it. + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_OPT_LIB_FUNCTION +void *memset(void *v_src, int c, __kernel_size_t n) +{ + char *src = v_src; + uint32_t *i_src; + uint32_t w32 = 0; + + /* Truncate c to 8 bits */ + c = (c & 0xFF); + + if (unlikely(c)) { + /* Make a repeating word out of it */ + w32 = c; + w32 |= w32 << 8; + w32 |= w32 << 16; + } + + if (likely(n >= 4)) { + /* Align the destination to a word boundary */ + /* This is done in an endian independent manner */ + switch ((unsigned) src & 3) { + case 1: + *src++ = c; + --n; + fallthrough; + case 2: + *src++ = c; + --n; + fallthrough; + case 3: + *src++ = c; + --n; + } + + i_src = (void *)src; + + /* Do as many full-word copies as we can */ + for (; n >= 4; n -= 4) + *i_src++ = w32; + + src = (void *)i_src; + } + + /* Simple, byte oriented memset or the rest of count. */ + switch (n) { + case 3: + *src++ = c; + fallthrough; + case 2: + *src++ = c; + fallthrough; + case 1: + *src++ = c; + break; + default: + break; + } + + return v_src; +} +EXPORT_SYMBOL(memset); +#endif /* CONFIG_OPT_LIB_FUNCTION */ -- cgit v1.3.1