Module Name: src
Committed By: riastradh
Date: Tue Apr 19 01:34:52 UTC 2022
Modified Files:
src/sys/uvm: uvm_mmap.c
Log Message:
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.
ok chs@
To generate a diff of this commit:
cvs rdiff -u -r1.177 -r1.178 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.177 src/sys/uvm/uvm_mmap.c:1.178
--- src/sys/uvm/uvm_mmap.c:1.177 Sun Mar 27 20:18:05 2022
+++ src/sys/uvm/uvm_mmap.c Tue Apr 19 01:34:52 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_mmap.c,v 1.177 2022/03/27 20:18:05 hannken Exp $ */
+/* $NetBSD: uvm_mmap.c,v 1.178 2022/04/19 01:34:52 riastradh 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.177 2022/03/27 20:18:05 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.178 2022/04/19 01:34:52 riastradh Exp $");
#include "opt_compat_netbsd.h"
#include "opt_pax.h"
@@ -277,7 +277,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;
@@ -349,6 +350,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);
}
/*
@@ -401,10 +408,21 @@ sys_mmap(struct lwp *l, const struct sys
/*
* now let kernel internal function uvm_mmap do the work.
*/
-
error = uvm_mmap(&p->p_vmspace->vm_map, &addr, size, prot, maxprot,
flags, advice, uobj, pos, p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
+ /*
+ * If the user provided a hint, and we couldn't satisfy that
+ * hint, try again with the default address.
+ */
+ if (error && addrhint) {
+ 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);
+ }
+
/* remember to add offset */
*retval = (register_t)(addr + pageoff);