HBSD: Prevent executable superpage mappings

Superpage alignment degrades ASLR effectiveness. Prevent superpage
alignment for executable code.

Signed-off-by:	Shawn Webb <shawn.webb@hardenedbsd.org>
MFC-to:		14-STABLE
MFC-to:		13-STABLE
See-Also: https://zolutal.github.io/aslrnt/
See-Also: https://grsecurity.net/toolchain_necromancy_past_mistakes_haunting_aslr
This commit is contained in:
Shawn Webb 2024-07-08 22:34:29 +00:00
parent c30d6b31c2
commit 4d6fa59190
No known key found for this signature in database
5 changed files with 45 additions and 3 deletions

View File

@ -208,8 +208,15 @@ map_object(int fd, const char *path, const struct stat *sb)
base_addr = (caddr_t) base_vaddr;
base_flags = __getosreldate() >= P_OSREL_MAP_GUARD ? MAP_GUARD :
MAP_PRIVATE | MAP_ANON | MAP_NOCORE;
if (npagesizes > 1 && rtld_round_page(segs[0]->p_filesz) >= pagesizes[1])
base_flags |= MAP_ALIGNED_SUPER;
#ifdef HARDENEDBSD
if (!is_rtld_hardened()) {
#endif
if (npagesizes > 1 && rtld_round_page(segs[0]->p_filesz)
>= pagesizes[1])
base_flags |= MAP_ALIGNED_SUPER;
#ifdef HARDENEDBSD
}
#endif
if (base_vaddr != 0)
base_flags |= MAP_FIXED | MAP_EXCL;

View File

@ -339,13 +339,22 @@ cache_harden_rtld(void)
sz = sizeof(int);
err = sysctlbyname("hardening.harden_rtld", &res, &sz, NULL, 0);
if (err == 0) {
harden_rtld = res;
if (res < 0) {
harden_rtld = true;
}
harden_rtld = (res > 0);
} else {
harden_rtld = true;
}
return (harden_rtld);
}
bool
is_rtld_hardened(void)
{
return (harden_rtld == true);
}
#endif
/*

View File

@ -414,4 +414,11 @@ void ifunc_init(Elf_Auxinfo[__min_size(AT_COUNT)]);
void init_pltgot(Obj_Entry *);
void allocate_initial_tls(Obj_Entry *);
/*
* HardenedBSD additions.
*/
#ifdef HARDENEDBSD
bool is_rtld_hardened(void);
#endif
#endif /* } */

View File

@ -1033,13 +1033,20 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
* loadable segment to the max supported superpage size. Too
* large alignment requests are not useful and are indicators
* of corrupted or outright malicious binary.
*
* HardenedBSD note: Enforce smallest unit alignment. Do not permit
* superpage mappings.
*/
maxalign = PAGE_SIZE;
#ifdef PAX_ASLR
maxsalign = PAGE_SIZE * 1024;
#else
maxsalign = PAGE_SIZE * 1024;
for (i = MAXPAGESIZES - 1; i > 0; i--) {
if (pagesizes[i] > maxsalign)
maxsalign = pagesizes[i];
}
#endif
mapsz = 0;

View File

@ -287,6 +287,18 @@ kern_mmap(struct thread *td, const struct mmap_req *mrp)
if (pax_disallow_map32bit_active(td, flags))
return (EPERM);
#endif
#if defined(PAX_ASLR)
/*
* Disallow executable superpage mappings. Encourage smaller granularity
* so as not to reduce ASLR effectiveness.
*/
if (pax_aslr_active(p)) {
if (align == MAP_ALIGNED_SUPER &&
((prot & PROT_EXEC) == PROT_EXEC)) {
align = 0;
}
}
#endif
/*
* Check for illegal addresses. Watch out for address wrap... Note