| @@ -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) { |