mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-04 15:13:58 +01:00
HBSD: Harden LD_PRELOAD
Add a new sysctl node, hardening.harden_rtld, that will drive the RTLD's hardening logic. Hardening LD_PRELOAD is a good first step towards a generalized RTLD hardening approach. LD_PRELOAD is a common code injection technique. Signed-off-by: Shawn Webb <shawn.webb@hardenedbsd.org> MFC-to: 13-STABLE
This commit is contained in:
parent
fbfea2c1d2
commit
e9e9c42998
@ -204,6 +204,9 @@ static void rtld_fill_dl_phdr_info(const Obj_Entry *obj,
|
||||
static uint32_t gnu_hash(const char *);
|
||||
static bool matched_symbol(SymLook *, const Obj_Entry *, Sym_Match_Result *,
|
||||
const unsigned long);
|
||||
#ifdef HARDENEDBSD
|
||||
static bool cache_harden_rtld(void);
|
||||
#endif
|
||||
|
||||
void r_debug_state(struct r_debug *, struct link_map *) __noinline __exported;
|
||||
void _r_debug_postinit(struct link_map *) __noinline __exported;
|
||||
@ -242,6 +245,7 @@ static unsigned int obj_loads; /* Number of loads of objects (gen count) */
|
||||
|
||||
#ifdef HARDENEDBSD
|
||||
static Elf_Word pax_flags = 0; /* PaX / HardenedBSD flags */
|
||||
static bool harden_rtld = true;
|
||||
#endif
|
||||
|
||||
static Objlist list_global = /* Objects dlopened with RTLD_GLOBAL */
|
||||
@ -327,6 +331,23 @@ const char *ld_env_prefix = LD_;
|
||||
|
||||
static void (*rtld_exit_ptr)(void);
|
||||
|
||||
static bool
|
||||
cache_harden_rtld(void)
|
||||
{
|
||||
int err, res;
|
||||
size_t sz;
|
||||
|
||||
sz = sizeof(int);
|
||||
err = sysctlbyname("hardening.harden_rtld", &res, &sz, NULL, 0);
|
||||
if (err == 0) {
|
||||
harden_rtld = res;
|
||||
} else {
|
||||
harden_rtld = true;
|
||||
}
|
||||
|
||||
return (harden_rtld);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in a DoneList with an allocation large enough to hold all of
|
||||
* the currently-loaded objects. Keep this as a macro since it calls
|
||||
@ -614,6 +635,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
||||
pax_flags = aux_info[AT_PAXFLAGS]->a_un.a_val;
|
||||
aux_info[AT_PAXFLAGS]->a_un.a_val = 0;
|
||||
}
|
||||
|
||||
cache_harden_rtld();
|
||||
#endif
|
||||
|
||||
trust = !issetugid();
|
||||
@ -2728,6 +2751,10 @@ load_preload_objects(const char *penv, bool isfd)
|
||||
if (penv == NULL)
|
||||
return (0);
|
||||
|
||||
if (harden_rtld) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
p = psave = xstrdup(penv);
|
||||
p += strspn(p, delim);
|
||||
while (*p != '\0') {
|
||||
|
@ -65,12 +65,14 @@ static int pax_randomize_pids_global = PAX_FEATURE_SIMPLE_ENABLED;
|
||||
static int pax_init_hardening_global = PAX_FEATURE_SIMPLE_ENABLED;
|
||||
static int pax_insecure_kmod_global = PAX_FEATURE_SIMPLE_DISABLED;
|
||||
static int pax_tpe_global = PAX_FEATURE_OPTIN;
|
||||
static int harden_rtld_global = PAX_FEATURE_SIMPLE_ENABLED;
|
||||
#else
|
||||
static int pax_procfs_harden_global = PAX_FEATURE_SIMPLE_DISABLED;
|
||||
static int pax_randomize_pids_global = PAX_FEATURE_SIMPLE_DISABLED;
|
||||
static int pax_init_hardening_global = PAX_FEATURE_SIMPLE_DISABLED;
|
||||
static int pax_insecure_kmod_global = PAX_FEATURE_SIMPLE_ENABLED;
|
||||
static int pax_tpe_global = PAX_FEATURE_OPTIN;
|
||||
static int harden_rtld_global = PAX_FEATURE_SIMPLE_DISABLED;
|
||||
#endif
|
||||
|
||||
static int pax_tpe_gid = 0;
|
||||
@ -86,6 +88,7 @@ TUNABLE_INT("hardening.tpe.gid", &pax_tpe_gid);
|
||||
TUNABLE_INT("hardening.tpe.negate", &pax_tpe_negate);
|
||||
TUNABLE_INT("hardening.tpe.all", &pax_tpe_all);
|
||||
TUNABLE_INT("hardening.tpe.root_owned", &pax_tpe_root_owned);
|
||||
TUNABLE_INT("hardening.harden_rtld", &harden_rtld_global);
|
||||
|
||||
#ifdef PAX_SYSCTLS
|
||||
SYSCTL_DECL(_hardening_pax);
|
||||
@ -97,6 +100,10 @@ SYSCTL_HBSD_2STATE(pax_procfs_harden_global, pr_hbsd.hardening.procfs_harden,
|
||||
SYSCTL_HBSD_2STATE_GLOBAL(pax_insecure_kmod_global, _hardening, insecure_kmod,
|
||||
CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_SECURE,
|
||||
"Enable loading of inecure kernel modules");
|
||||
SYSCTL_HBSD_2STATE(harden_rtld_global, pr_hbsd.hardening.harden_rtld,
|
||||
_hardening, harden_rtld,
|
||||
CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_SECURE,
|
||||
"Harden RTLD");
|
||||
|
||||
SYSCTL_DECL(_hardening_pax);
|
||||
SYSCTL_NODE(_hardening_pax, OID_AUTO, tpe, CTLFLAG_RD, 0,
|
||||
@ -193,6 +200,7 @@ pax_hardening_init_prison(struct prison *pr, struct vfsoptlist *opts)
|
||||
pr->pr_hbsd.hardening.procfs_harden =
|
||||
pax_procfs_harden_global;
|
||||
pr->pr_hbsd.hardening.tpe = pax_tpe_global;
|
||||
pr->pr_hbsd.hardening.harden_rtld = harden_rtld_global;
|
||||
pr->pr_allow &= ~(PR_ALLOW_UNPRIV_DEBUG);
|
||||
} else {
|
||||
KASSERT(pr->pr_parent != NULL,
|
||||
@ -202,6 +210,8 @@ pax_hardening_init_prison(struct prison *pr, struct vfsoptlist *opts)
|
||||
pr->pr_hbsd.hardening.procfs_harden =
|
||||
pr_p->pr_hbsd.hardening.procfs_harden;
|
||||
pr->pr_hbsd.hardening.tpe = pr_p->pr_hbsd.hardening.tpe;
|
||||
pr->pr_hbsd.hardening.harden_rtld =
|
||||
pr_p->pr_hbsd.hardening.harden_rtld;
|
||||
#if 0
|
||||
error = pax_handle_prison_param(opts, "hardening.procfs_harden",
|
||||
&pr->pr_hbsd.hardening.procfs_harden);
|
||||
|
@ -64,6 +64,7 @@ struct hbsd_features {
|
||||
int tpe_all;
|
||||
int tpe_negate;
|
||||
int tpe_root_owned;
|
||||
pax_state_t harden_rtld;
|
||||
} hardening;
|
||||
struct hbsd_log {
|
||||
pax_state_t log; /* (p) Per-jail logging status */
|
||||
|
Loading…
Reference in New Issue
Block a user