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_addr = (caddr_t) base_vaddr;
base_flags = __getosreldate() >= P_OSREL_MAP_GUARD ? MAP_GUARD : base_flags = __getosreldate() >= P_OSREL_MAP_GUARD ? MAP_GUARD :
MAP_PRIVATE | MAP_ANON | MAP_NOCORE; MAP_PRIVATE | MAP_ANON | MAP_NOCORE;
if (npagesizes > 1 && rtld_round_page(segs[0]->p_filesz) >= pagesizes[1]) #ifdef HARDENEDBSD
base_flags |= MAP_ALIGNED_SUPER; 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) if (base_vaddr != 0)
base_flags |= MAP_FIXED | MAP_EXCL; base_flags |= MAP_FIXED | MAP_EXCL;

View File

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

View File

@ -414,4 +414,11 @@ void ifunc_init(Elf_Auxinfo[__min_size(AT_COUNT)]);
void init_pltgot(Obj_Entry *); void init_pltgot(Obj_Entry *);
void allocate_initial_tls(Obj_Entry *); void allocate_initial_tls(Obj_Entry *);
/*
* HardenedBSD additions.
*/
#ifdef HARDENEDBSD
bool is_rtld_hardened(void);
#endif
#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 * loadable segment to the max supported superpage size. Too
* large alignment requests are not useful and are indicators * large alignment requests are not useful and are indicators
* of corrupted or outright malicious binary. * of corrupted or outright malicious binary.
*
* HardenedBSD note: Enforce smallest unit alignment. Do not permit
* superpage mappings.
*/ */
maxalign = PAGE_SIZE; maxalign = PAGE_SIZE;
#ifdef PAX_ASLR
maxsalign = PAGE_SIZE * 1024;
#else
maxsalign = PAGE_SIZE * 1024; maxsalign = PAGE_SIZE * 1024;
for (i = MAXPAGESIZES - 1; i > 0; i--) { for (i = MAXPAGESIZES - 1; i > 0; i--) {
if (pagesizes[i] > maxsalign) if (pagesizes[i] > maxsalign)
maxsalign = pagesizes[i]; maxsalign = pagesizes[i];
} }
#endif
mapsz = 0; 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)) if (pax_disallow_map32bit_active(td, flags))
return (EPERM); return (EPERM);
#endif #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 * Check for illegal addresses. Watch out for address wrap... Note