mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 08:43:19 -04:00
HBSD: Do not allow non-stack mappings between bottom-most limit of stack and the top of the stack
The space between the bottom-most limit of the stack and the top of the
stack should not be able to be mapped via mmap(2). This should fully
mitigate Stack Clash in conjunction with the hardened stack guard.
Signed-off-by: Shawn Webb <shawn.webb@hardenedbsd.org>
Sponsored-by: SoldierX
(cherry picked from commit 7e16dbbf12)
This commit is contained in:
parent
fd30a6ef8a
commit
01c6a48b57
1 changed files with 29 additions and 0 deletions
|
|
@ -94,6 +94,8 @@ __FBSDID("$FreeBSD$");
|
|||
#include <sys/pmckern.h>
|
||||
#endif
|
||||
|
||||
static int check_address_limit(struct thread *, vm_offset_t, bool);
|
||||
|
||||
int old_mlock = 0;
|
||||
SYSCTL_INT(_vm, OID_AUTO, old_mlock, CTLFLAG_RWTUN, &old_mlock, 0,
|
||||
"Do not apply RLIMIT_MEMLOCK on mlockall");
|
||||
|
|
@ -108,6 +110,25 @@ struct sbrk_args {
|
|||
};
|
||||
#endif
|
||||
|
||||
static int
|
||||
check_address_limit(struct thread *td, vm_offset_t addr, bool needlock)
|
||||
{
|
||||
rlim_t stacklim;
|
||||
int error;
|
||||
|
||||
error = 0;
|
||||
stacklim = lim_cur(td, RLIMIT_STACK);
|
||||
|
||||
if (needlock)
|
||||
PROC_LOCK(td->td_proc);
|
||||
if (addr >= td->td_proc->p_usrstack - stacklim)
|
||||
error = EINVAL;
|
||||
if (needlock)
|
||||
PROC_UNLOCK(td->td_proc);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
|
|
@ -300,6 +321,11 @@ sys_mmap(td, uap)
|
|||
return (EINVAL);
|
||||
if (addr + size < addr)
|
||||
return (EINVAL);
|
||||
|
||||
/* Address range must be below stack limits. */
|
||||
error = check_address_limit(td, addr, true);
|
||||
if (error)
|
||||
return (error);
|
||||
#ifdef MAP_32BIT
|
||||
if (flags & MAP_32BIT && addr + size > MAP_32BIT_MAX_ADDR)
|
||||
return (EINVAL);
|
||||
|
|
@ -338,7 +364,10 @@ sys_mmap(td, uap)
|
|||
PROC_LOCK(td->td_proc);
|
||||
pax_aslr_mmap(td->td_proc, &addr, (vm_offset_t)uap->addr, flags);
|
||||
pax_aslr_done = 1;
|
||||
error = check_address_limit(td, addr, false);
|
||||
PROC_UNLOCK(td->td_proc);
|
||||
if (error)
|
||||
return (error);
|
||||
#endif
|
||||
}
|
||||
if (size == 0) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue