diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 06fa0b6e..b325e15a 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -1801,8 +1801,9 @@ SYSCALL_DECLARE(mmap) goto out; } - if ((flags & MAP_FIXED) && ((addr < region->user_start) - || (region->user_end <= addr))) { + if (addr < region->user_start + || region->user_end <= addr + || len > (region->user_end - region->user_start)) { ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):ENOMEM\n", addr0, len0, prot, flags0, fd, off0); error = -ENOMEM; diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c index cd981901..f41fa288 100644 --- a/arch/x86_64/kernel/syscall.c +++ b/arch/x86_64/kernel/syscall.c @@ -1570,8 +1570,9 @@ SYSCALL_DECLARE(mmap) goto out; } - if ((flags & MAP_FIXED) && ((addr < region->user_start) - || (region->user_end <= addr))) { + if (addr < region->user_start + || region->user_end <= addr + || len > (region->user_end - region->user_start)) { ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):ENOMEM\n", addr0, len0, prot, flags0, fd, off0); error = -ENOMEM; diff --git a/kernel/syscall.c b/kernel/syscall.c index 4f01f781..489ab1a2 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -7729,6 +7729,7 @@ SYSCALL_DECLARE(mremap) oldaddr, oldsize0, newsize0, flags, newaddr); ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock); + /* check arguments */ if ((oldaddr & ~PAGE_MASK) || (oldsize < 0) || (newsize <= 0) @@ -7744,6 +7745,24 @@ SYSCALL_DECLARE(mremap) goto out; } + if (oldend < oldstart) { + error = -EINVAL; + ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):" + "old range overflow. %d\n", + oldaddr, oldsize0, newsize0, + flags, newaddr, error); + goto out; + } + + if (newsize > (vm->region.user_end - vm->region.user_start)) { + error = -ENOMEM; + ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):" + "cannot allocate. %d\n", + oldaddr, oldsize0, newsize0, + flags, newaddr, error); + goto out; + } + /* check original mapping */ range = lookup_process_memory_range(vm, oldstart, oldstart+PAGE_SIZE); if (!range || (oldstart < range->start) || (range->end < oldend) @@ -7758,15 +7777,6 @@ SYSCALL_DECLARE(mremap) goto out; } - if (oldend < oldstart) { - error = -EINVAL; - ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):" - "old range overflow. %d\n", - oldaddr, oldsize0, newsize0, flags, newaddr, - error); - goto out; - } - /* determine new mapping range */ need_relocate = 0; if (flags & MREMAP_FIXED) {