Subject: UVM permissions check for ARM_SYNC_ICACHE syscall
To: None <port-arm@NetBSD.org>
From: Todd Poynor <tpoynor@danger.com>
List: port-arm
Date: 11/06/2007 16:09:42
The ARM_SYNC_ICACHE syscall will invalidate any I cache (and clean and
invalidate any D cache) ranges requested by userspace, including
kernel virtual addresses. It may be possible for a rogue program to
cause some mischief by invalidating modifications made by the kernel.
The suggested patch below fails the arm_sync_icache() with EINVAL if
the address range is not fully mapped writeable to the process. Any
suggestions appreciated. -- Todd
Index: netbsd/src/sys/arch/arm/arm32/sys_machdep.c
===================================================================
--- netbsd.orig/src/sys/arch/arm/arm32/sys_machdep.c
+++ netbsd/src/sys/arch/arm/arm32/sys_machdep.c
@@ -66,11 +66,26 @@ arm32_sync_icache(p, args, retval)
register_t *retval;
{
struct arm_sync_icache_args ua;
+ struct vmspace *vm;
int error;
+ int rv;
if ((error = copyin(args, &ua, sizeof(ua))) != 0)
return (error);
+ if ((error = proc_vmspace_getref(p, &vm)) != 0)
+ return (error);
+
+ vm_map_lock(&vm->vm_map);
+ rv = uvm_map_checkprot(&vm->vm_map, ua.addr, ua.addr + ua.len,
+ VM_PROT_WRITE);
+ vm_map_unlock(&vm->vm_map);
+ uvmspace_free(vm);
+
+ if (rv == 0) {
+ return EINVAL;
+ }
+
cpu_icache_sync_range(ua.addr, ua.len);
*retval = 0;