From 155335ed8e909903445a31422c0edacd32f9f733 Mon Sep 17 00:00:00 2001 From: Shawn Webb Date: Sun, 13 Dec 2020 10:07:45 -0500 Subject: [PATCH] HBSD: Add new kernel config option: HARDEN_KLD This separates out the KLD hardening features into its own kernel config option, rather than including the feature in PAX_HARDENING. We still zero out the kernel addresses of loaded modules in the KLD stat syscall. Removing HARDEN_KLD from the kernel configenables DTrace to resolve kernel symbols. DTrace can't resolve symbols with zeroed-out kernel addresses in the KLD stat syscall. Ideally, DTrace needs to be enhanced to not use the KLD KPI to resolve kernel symbols. A separate faciilty/KPI may need to be created. I leave this task to the community to implement. When implemented, HARDEN_KLD can be re-enabled. Signed-off-by: Shawn Webb Reported-by: @tuto2 issue: #22 MFC-to: 12-STABLE --- sys/amd64/conf/HARDENEDBSD | 1 + sys/arm64/conf/HARDENEDBSD | 3 +++ sys/conf/options | 3 +++ sys/kern/kern_linker.c | 6 +++--- sys/kern/kern_module.c | 14 ++++++++++++++ sys/kern/kern_priv.c | 2 +- 6 files changed, 25 insertions(+), 4 deletions(-) diff --git a/sys/amd64/conf/HARDENEDBSD b/sys/amd64/conf/HARDENEDBSD index 2ca01204b6bc14..ae560310431b56 100644 --- a/sys/amd64/conf/HARDENEDBSD +++ b/sys/amd64/conf/HARDENEDBSD @@ -90,6 +90,7 @@ options RACCT # Resource accounting framework options RCTL # Resource limits # HardenedBSD hardening options +options HARDEN_KLD # Harden the kernel module interface options PAX # PaX framework options PAX_CONTROL_ACL # PaX MAC framework, required for secadm options PAX_CONTROL_ACL_OVERRIDE_SUPPORT # Allow to override hbsdcontrol settings with ACLs diff --git a/sys/arm64/conf/HARDENEDBSD b/sys/arm64/conf/HARDENEDBSD index 4c6d13d2131f1f..896c7ba61e6b11 100644 --- a/sys/arm64/conf/HARDENEDBSD +++ b/sys/arm64/conf/HARDENEDBSD @@ -1,6 +1,8 @@ include GENERIC ident HARDENEDBSD +# HardenedBSD hardening options +options HARDEN_KLD # Harden the kernel module interface options PAX options PAX_CONTROL_ACL options PAX_CONTROL_ACL_OVERRIDE_SUPPORT @@ -13,4 +15,5 @@ options PAX_NOEXEC options PAX_SEGVGUARD nooptions COMPAT_FREEBSD32 +# Needed for ThunderX2 systems options NUMA diff --git a/sys/conf/options b/sys/conf/options index 6511d43a015a9a..a23a341ca5b6f1 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -964,6 +964,9 @@ RACCT_DEFAULT_TO_DISABLED opt_global.h # Resource Limits RCTL opt_global.h +# HardenedBSD general hardening features +HARDEN_KLD opt_pax.h + # PaX-inspired hardening features PAX opt_pax.h PAX_ASLR opt_pax.h diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 4276b55f5aeb9a..61af35d13db3a7 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -1309,7 +1309,7 @@ kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat) bcopy(lf->filename, &stat->name[0], namelen); stat->refs = lf->refs; stat->id = lf->id; -#ifdef PAX_HARDENING +#ifdef HARDEN_KLD stat->address = NULL; #else stat->address = lf->address; @@ -1411,7 +1411,7 @@ sys_kldsym(struct thread *td, struct kldsym_args *uap) error = ENOENT; else if (LINKER_LOOKUP_SYMBOL(lf, symstr, &sym) == 0 && LINKER_SYMBOL_VALUES(lf, sym, &symval) == 0) { -#ifdef PAX_HARDENING +#ifdef HARDEN_KLD lookup.symvalue = (uintptr_t) NULL; #else lookup.symvalue = (uintptr_t) symval.value; @@ -1424,7 +1424,7 @@ sys_kldsym(struct thread *td, struct kldsym_args *uap) TAILQ_FOREACH(lf, &linker_files, link) { if (LINKER_LOOKUP_SYMBOL(lf, symstr, &sym) == 0 && LINKER_SYMBOL_VALUES(lf, sym, &symval) == 0) { -#ifdef PAX_HARDENING +#ifdef HARDEN_KLD lookup.symvalue = (uintptr_t)NULL; #else lookup.symvalue = (uintptr_t)symval.value; diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c index 899200473a247d..4471f63e0eeb18 100644 --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -29,6 +29,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_pax.h" + #include #include #include @@ -312,9 +314,13 @@ sys_modnext(struct thread *td, struct modnext_args *uap) module_t mod; int error; +#ifdef HARDEN_KLD error = priv_check(td, PRIV_KLD_STAT); if (error) return (error); +#else + error = 0; +#endif td->td_retval[0] = -1; @@ -347,9 +353,11 @@ sys_modfnext(struct thread *td, struct modfnext_args *uap) module_t mod; int error; +#ifdef HARDEN_KLD error = priv_check(td, PRIV_KLD_STAT); if (error) return (error); +#endif td->td_retval[0] = -1; @@ -385,9 +393,11 @@ sys_modstat(struct thread *td, struct modstat_args *uap) struct module_stat *stat; char *name; +#ifdef HARDEN_KLD error = priv_check(td, PRIV_KLD_STAT); if (error) return (error); +#endif MOD_SLOCK; mod = module_lookupbyid(uap->modid); @@ -439,9 +449,11 @@ sys_modfind(struct thread *td, struct modfind_args *uap) char name[MAXMODNAME]; module_t mod; +#ifdef HARDEN_KLD error = priv_check(td, PRIV_KLD_STAT); if (error) return (error); +#endif if ((error = copyinstr(uap->name, name, sizeof name, 0)) != 0) return (error); @@ -490,9 +502,11 @@ freebsd32_modstat(struct thread *td, struct freebsd32_modstat_args *uap) struct module_stat32 *stat32; char *name; +#ifdef HARDEN_KLD error = priv_check(td, PRIV_KLD_STAT); if (error) return (error); +#endif MOD_SLOCK; mod = module_lookupbyid(uap->modid); diff --git a/sys/kern/kern_priv.c b/sys/kern/kern_priv.c index acd8e5fbeb6509..bd373087467ca2 100644 --- a/sys/kern/kern_priv.c +++ b/sys/kern/kern_priv.c @@ -271,7 +271,7 @@ priv_check_cred(struct ucred *cred, int priv) } } -#if !defined(PAX_HARDENING) +#if !defined(HARDEN_KLD) /* * Inspecting kernel module information should be root-only * when PAX_HARDENING is set.