Module Name: src Committed By: martin Date: Sat Apr 1 15:56:12 UTC 2023
Modified Files: src/sys/uvm [netbsd-8]: uvm_mmap.c Log Message: Pull up following revision(s) (requested by riastradh in ticket #1815): sys/uvm/uvm_mmap.c: revision 1.180 mmap(2): If we fail with a hint, try again without it. `Hint' here means nonzero addr, but no MAP_FIXED or MAP_TRYFIXED. This is suboptimal -- we could teach uvm_mmap to do a fancier search using the address as a hint. But this should do for now. Candidate fix for PR kern/55533. To generate a diff of this commit: cvs rdiff -u -r1.166.2.2 -r1.166.2.3 src/sys/uvm/uvm_mmap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/uvm/uvm_mmap.c diff -u src/sys/uvm/uvm_mmap.c:1.166.2.2 src/sys/uvm/uvm_mmap.c:1.166.2.3 --- src/sys/uvm/uvm_mmap.c:1.166.2.2 Sun Aug 11 10:01:14 2019 +++ src/sys/uvm/uvm_mmap.c Sat Apr 1 15:56:12 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_mmap.c,v 1.166.2.2 2019/08/11 10:01:14 martin Exp $ */ +/* $NetBSD: uvm_mmap.c,v 1.166.2.3 2023/04/01 15:56:12 martin Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -46,7 +46,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.166.2.2 2019/08/11 10:01:14 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.166.2.3 2023/04/01 15:56:12 martin Exp $"); #include "opt_compat_netbsd.h" #include "opt_pax.h" @@ -290,7 +290,8 @@ sys_mmap(struct lwp *l, const struct sys vsize_t size, pageoff, newsize; vm_prot_t prot, maxprot, extraprot; int flags, fd, advice; - vaddr_t defaddr; + vaddr_t defaddr = 0; /* XXXGCC */ + bool addrhint = false; struct file *fp = NULL; struct uvm_object *uobj; int error; @@ -359,6 +360,12 @@ sys_mmap(struct lwp *l, const struct sys addr = MAX(addr, defaddr); else addr = MIN(addr, defaddr); + + /* + * If addr is nonzero and not the default, then the + * address is a hint. + */ + addrhint = (addr != 0 && addr != defaddr); } /* @@ -409,11 +416,30 @@ sys_mmap(struct lwp *l, const struct sys pax_aslr_mmap(l, &addr, orig_addr, flags); /* - * now let kernel internal function uvm_mmap do the work. + * Now let kernel internal function uvm_mmap do the work. + * + * If the user provided a hint, take a reference to uobj in + * case the first attempt to satisfy the hint fails, so we can + * try again with the default address. */ - + if (addrhint) { + if (uobj) + (*uobj->pgops->pgo_reference)(uobj); + } error = uvm_mmap(&p->p_vmspace->vm_map, &addr, size, prot, maxprot, flags, advice, uobj, pos, p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur); + if (addrhint) { + if (error) { + addr = defaddr; + pax_aslr_mmap(l, &addr, orig_addr, flags); + error = uvm_mmap(&p->p_vmspace->vm_map, &addr, size, + prot, maxprot, flags, advice, uobj, pos, + p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur); + } else if (uobj) { + /* Release the exta reference we took. */ + (*uobj->pgops->pgo_detach)(uobj); + } + } /* remember to add offset */ *retval = (register_t)(addr + pageoff); @@ -903,9 +929,12 @@ sys_munlockall(struct lwp *l, const void * - used by sys_mmap and various framebuffers * - uobj is a struct uvm_object pointer or NULL for MAP_ANON * - caller must page-align the file offset + * + * XXX This appears to leak the uobj in various error branches? Need + * to clean up the contract around uobj reference. */ -int +static int uvm_mmap(struct vm_map *map, vaddr_t *addr, vsize_t size, vm_prot_t prot, vm_prot_t maxprot, int flags, int advice, struct uvm_object *uobj, voff_t foff, vsize_t locklimit)