From ba5eb097fd11504834fc9fe31e52ba630129802a Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Mon, 18 Apr 2022 18:51:32 +0000 Subject: [PATCH] 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@ --- sys/uvm/uvm_mmap.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c index f7dfbf32a914..c105c186a422 100644 --- a/sys/uvm/uvm_mmap.c +++ b/sys/uvm/uvm_mmap.c @@ -277,7 +277,8 @@ sys_mmap(struct lwp *l, const struct sys_mmap_args *uap, register_t *retval) 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_mmap_args *uap, register_t *retval) 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_mmap_args *uap, register_t *retval) /* * 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);