Sun Mar 1 13:43:51 2015 UTC ()
Detect overflow when rounding length parameter and return ENOMEM.
Fixes PR kern/49692.


(mlelstv)
diff -r1.151 -r1.152 src/sys/uvm/uvm_mmap.c

cvs diff -r1.151 -r1.152 src/sys/uvm/uvm_mmap.c (expand / switch to unified diff)

--- src/sys/uvm/uvm_mmap.c 2015/01/10 23:35:02 1.151
+++ src/sys/uvm/uvm_mmap.c 2015/03/01 13:43:51 1.152
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: uvm_mmap.c,v 1.151 2015/01/10 23:35:02 chs Exp $ */ 1/* $NetBSD: uvm_mmap.c,v 1.152 2015/03/01 13:43:51 mlelstv Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1997 Charles D. Cranor and Washington University. 4 * Copyright (c) 1997 Charles D. Cranor and Washington University.
5 * Copyright (c) 1991, 1993 The Regents of the University of California. 5 * Copyright (c) 1991, 1993 The Regents of the University of California.
6 * Copyright (c) 1988 University of Utah. 6 * Copyright (c) 1988 University of Utah.
7 * 7 *
8 * All rights reserved. 8 * All rights reserved.
9 * 9 *
10 * This code is derived from software contributed to Berkeley by 10 * This code is derived from software contributed to Berkeley by
11 * the Systems Programming Group of the University of Utah Computer 11 * the Systems Programming Group of the University of Utah Computer
12 * Science Department. 12 * Science Department.
13 * 13 *
14 * Redistribution and use in source and binary forms, with or without 14 * Redistribution and use in source and binary forms, with or without
@@ -36,27 +36,27 @@ @@ -36,27 +36,27 @@
36 * SUCH DAMAGE. 36 * SUCH DAMAGE.
37 * 37 *
38 * from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$ 38 * from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
39 * @(#)vm_mmap.c 8.5 (Berkeley) 5/19/94 39 * @(#)vm_mmap.c 8.5 (Berkeley) 5/19/94
40 * from: Id: uvm_mmap.c,v 1.1.2.14 1998/01/05 21:04:26 chuck Exp 40 * from: Id: uvm_mmap.c,v 1.1.2.14 1998/01/05 21:04:26 chuck Exp
41 */ 41 */
42 42
43/* 43/*
44 * uvm_mmap.c: system call interface into VM system, plus kernel vm_mmap 44 * uvm_mmap.c: system call interface into VM system, plus kernel vm_mmap
45 * function. 45 * function.
46 */ 46 */
47 47
48#include <sys/cdefs.h> 48#include <sys/cdefs.h>
49__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.151 2015/01/10 23:35:02 chs Exp $"); 49__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.152 2015/03/01 13:43:51 mlelstv Exp $");
50 50
51#include "opt_compat_netbsd.h" 51#include "opt_compat_netbsd.h"
52#include "opt_pax.h" 52#include "opt_pax.h"
53 53
54#include <sys/types.h> 54#include <sys/types.h>
55#include <sys/file.h> 55#include <sys/file.h>
56#include <sys/filedesc.h> 56#include <sys/filedesc.h>
57#include <sys/resourcevar.h> 57#include <sys/resourcevar.h>
58#include <sys/mman.h> 58#include <sys/mman.h>
59 59
60#if defined(PAX_ASLR) || defined(PAX_MPROTECT) 60#if defined(PAX_ASLR) || defined(PAX_MPROTECT)
61#include <sys/pax.h> 61#include <sys/pax.h>
62#endif /* PAX_ASLR || PAX_MPROTECT */ 62#endif /* PAX_ASLR || PAX_MPROTECT */
@@ -279,27 +279,27 @@ sys_mmap(struct lwp *l, const struct sys @@ -279,27 +279,27 @@ sys_mmap(struct lwp *l, const struct sys
279{ 279{
280 /* { 280 /* {
281 syscallarg(void *) addr; 281 syscallarg(void *) addr;
282 syscallarg(size_t) len; 282 syscallarg(size_t) len;
283 syscallarg(int) prot; 283 syscallarg(int) prot;
284 syscallarg(int) flags; 284 syscallarg(int) flags;
285 syscallarg(int) fd; 285 syscallarg(int) fd;
286 syscallarg(long) pad; 286 syscallarg(long) pad;
287 syscallarg(off_t) pos; 287 syscallarg(off_t) pos;
288 } */ 288 } */
289 struct proc *p = l->l_proc; 289 struct proc *p = l->l_proc;
290 vaddr_t addr; 290 vaddr_t addr;
291 off_t pos; 291 off_t pos;
292 vsize_t size, pageoff; 292 vsize_t size, pageoff, newsize;
293 vm_prot_t prot, maxprot; 293 vm_prot_t prot, maxprot;
294 int flags, fd, advice; 294 int flags, fd, advice;
295 vaddr_t defaddr; 295 vaddr_t defaddr;
296 struct file *fp = NULL; 296 struct file *fp = NULL;
297 struct uvm_object *uobj; 297 struct uvm_object *uobj;
298 int error; 298 int error;
299#ifdef PAX_ASLR 299#ifdef PAX_ASLR
300 vaddr_t orig_addr; 300 vaddr_t orig_addr;
301#endif /* PAX_ASLR */ 301#endif /* PAX_ASLR */
302 302
303 /* 303 /*
304 * first, extract syscall args from the uap. 304 * first, extract syscall args from the uap.
305 */ 305 */
@@ -328,29 +328,33 @@ sys_mmap(struct lwp *l, const struct sys @@ -328,29 +328,33 @@ sys_mmap(struct lwp *l, const struct sys
328 * in compat32. 328 * in compat32.
329 */ 329 */
330 prot |= PROT_EXEC; 330 prot |= PROT_EXEC;
331#endif 331#endif
332 } 332 }
333 if ((flags & (MAP_SHARED|MAP_PRIVATE)) == (MAP_SHARED|MAP_PRIVATE)) 333 if ((flags & (MAP_SHARED|MAP_PRIVATE)) == (MAP_SHARED|MAP_PRIVATE))
334 return (EINVAL); 334 return (EINVAL);
335 335
336 /* 336 /*
337 * align file position and save offset. adjust size. 337 * align file position and save offset. adjust size.
338 */ 338 */
339 339
340 pageoff = (pos & PAGE_MASK); 340 pageoff = (pos & PAGE_MASK);
341 pos -= pageoff; 341 pos -= pageoff;
342 size += pageoff; /* add offset */ 342 newsize = size + pageoff; /* add offset */
343 size = (vsize_t)round_page(size); /* round up */ 343 newsize = (vsize_t)round_page(newsize); /* round up */
 344
 345 if (newsize < size)
 346 return (ENOMEM);
 347 size = newsize;
344 348
345 /* 349 /*
346 * now check (MAP_FIXED) or get (!MAP_FIXED) the "addr" 350 * now check (MAP_FIXED) or get (!MAP_FIXED) the "addr"
347 */ 351 */
348 if (flags & MAP_FIXED) { 352 if (flags & MAP_FIXED) {
349 353
350 /* ensure address and file offset are aligned properly */ 354 /* ensure address and file offset are aligned properly */
351 addr -= pageoff; 355 addr -= pageoff;
352 if (addr & PAGE_MASK) 356 if (addr & PAGE_MASK)
353 return (EINVAL); 357 return (EINVAL);
354 358
355 error = range_test(addr, size, true); 359 error = range_test(addr, size, true);
356 if (error) { 360 if (error) {