Skip to content

Commit

Permalink
HBSD: allow to set PaX features as jail parameters
Browse files Browse the repository at this point in the history
The hardening parameters are configureable since this commit
at jail creation time. The same named jail settings provided
as the sysctls are in the hardening. sysctl leaf.

Example jail.conf sniplet:

  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  exec.clean;
  mount.devfs;

  path = "/usr/jails/$name";
  host.hostname = "$name";

  hbsdnx {
          hardening.pax.segvguard.status = 3;
          hardening.pax.mprotect.status = 3;
          hardening.pax.pageexec.status = 3;
          hardening.pax.aslr.status = 3;
          persist;
  }

Currently the sysctls are mutable after the jail startup,
but in the future this will change. The same is true for
the nested jails. Now the hardening settings are modifiable
for the child jails.

github-issue: #292
MFC-to: 10-STABLE
MFC-to: 11-STABLE
Signed-off-by: Oliver Pinter <oliver.pinter@hardenedbsd.org>
(cherry picked from commit c8fa0e69ffb064787b08b65ccfa3a41fac548be8)
Signed-off-by: Oliver Pinter <oliver.pinter@hardenedbsd.org>
(cherry picked from commit 5b16da4)
Signed-off-by: Oliver Pinter <oliver.pinter@hardenedbsd.org>
  • Loading branch information
opntr committed Feb 10, 2018
1 parent b0416f5 commit 45748d2
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 36 deletions.
1 change: 1 addition & 0 deletions sys/amd64/conf/HARDENEDBSD
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ 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
options PAX_CONTROL_EXTATTR # extattr based control framework for hbsdcontrol
options PAX_JAIL_SUPPORT # Allow to override PAX settings per jail
options PAX_SYSCTLS # sysctls for run-time options
options PAX_ASLR # Address Space Layout Randomization
options PAX_NOEXEC # Remove WX pages from user-space and enforce W^X
Expand Down
1 change: 1 addition & 0 deletions sys/conf/NOTES
Original file line number Diff line number Diff line change
Expand Up @@ -3081,6 +3081,7 @@ options PAX_HARDENING # Other hardening features
options PAX_NOEXEC # Remove WX pages from user-space and enforce W^X
options PAX_SEGVGUARD # Track and ban failing process
options PAX_SYSCTLS # Run-time settings for PAX and Hardening
options PAX_JAIL_SUPPORT # Allow to override PAX settings per jail
options PAX_INSECURE_MODE # Allow to override INVARIANTS enforcements
options HBSD_DEBUG

Expand Down
1 change: 1 addition & 0 deletions sys/conf/options
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,7 @@ PAX_INSECURE_MODE opt_pax.h
PAX_CONTROL_ACL opt_pax.h
PAX_CONTROL_ACL_OVERRIDE_SUPPORT opt_pax.h
PAX_CONTROL_EXTATTR opt_pax.h
PAX_JAIL_SUPPORT opt_pax.h
HBSD_DEBUG opt_pax.h

# ASLR overwritable defaults
Expand Down
22 changes: 20 additions & 2 deletions sys/hardenedbsd/hbsd_pax_SKEL.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,19 @@ static int sysctl_pax_SKEL(SYSCTL_HANDLER_ARGS);
SYSCTL_NODE(_hardening_pax, OID_AUTO, SKEL, CTLFLAG_RD, 0,
"SKEL feature.");

SYSCTL_HBSD_4STATE(pax_SKEL_statusx, pr_hbsd.SKEL.status, _hardening_pax_SKEL, status,
SYSCTL_HBSD_4STATE(pax_SKEL_status, pr_hbsd.SKEL.status, _hardening_pax_SKEL, status,
CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_SECURE);
#endif

TUNABLE_INT("hardening.SKEL.state", &pax_SKEL_status);

#ifdef PAX_JAIL_SUPPORT
SYSCTL_JAIL_PARAM_SUBNODE(hardening, SKEL, "SKEL");
SYSCTL_JAIL_PARAM(_hardening_SKEL, status,
CTLTYPE_INT | CTLFLAG_RD, "I",
"SKEL status");
#endif

static void
pax_SKEL_sysinit(void)
{
Expand All @@ -92,9 +99,12 @@ pax_SKEL_sysinit(void)
SYSINIT(pax_SKEL, SI_SUB_PAX, SI_ORDER_SECOND, pax_SKEL_sysinit, NULL);

void
pax_SKEL_init_prison(struct prison *pr)
pax_SKEL_init_prison(struct prison *pr, struct vfsoptlist *opts)
{
struct prison *pr_p;
#ifdef PAX_JAIL_SUPPORT
pax_state_t new_state;
#endif

CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n",
__func__, pr->pr_name);
Expand All @@ -108,6 +118,14 @@ pax_SKEL_init_prison(struct prison *pr)
pr_p = pr->pr_parent;

pr->pr_hbsd.SKEL.status = pr_p->pr_hbsd.SKEL.status;
#ifdef PAX_JAIL_SUPPORT
if (vfs_copyopt(opts, "hardening.pax.SKEL.status",
&new_state, sizeof(new_state)) != ENOENT) {
if (pax_feature_validate_state(&new_state)) {
pr->pr_hbsd.SKEL.status = new_state;
}
}
#endif /* PAX_JAIL_SUPPORT */
}
}

Expand Down
60 changes: 56 additions & 4 deletions sys/hardenedbsd/hbsd_pax_aslr.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ktr.h>
#include <sys/libkern.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
Expand Down Expand Up @@ -260,6 +261,27 @@ SYSCTL_HBSD_4STATE(pax_disallow_map32bit_status_global, pr_hbsd.aslr.disallow_ma

#endif /* PAX_SYSCTLS */

#ifdef PAX_JAIL_SUPPORT
SYSCTL_DECL(_security_jail_param_hardening_pax);

SYSCTL_JAIL_PARAM_SUBNODE(hardening_pax, aslr, "ASLR");
SYSCTL_JAIL_PARAM(_hardening_pax_aslr, status,
CTLTYPE_INT | CTLFLAG_RD, "I",
"ASLR status");
#ifdef COMPAT_FREEBSD32
SYSCTL_JAIL_PARAM_SUBNODE(hardening_pax_aslr, compat, "ASLR (compat)");
SYSCTL_JAIL_PARAM(_hardening_pax_aslr_compat, status,
CTLTYPE_INT | CTLFLAG_RD, "I",
"ASLR (compat) status");
#endif /* COMPAT_FREEBSD32 */
#ifdef MAP_32BIT
SYSCTL_JAIL_PARAM_SUBNODE(hardening_pax, disallow_map32bit, "MAP_32BIT");
SYSCTL_JAIL_PARAM(_hardening_pax_disallow_map32bit, status,
CTLTYPE_INT | CTLFLAG_RD, "I",
"MAP_32BIT status");
#endif /* MAP_32BIT */
#endif /* PAX_JAIL_SUPPORT */


/*
* ASLR functions
Expand All @@ -268,7 +290,7 @@ SYSCTL_HBSD_4STATE(pax_disallow_map32bit_status_global, pr_hbsd.aslr.disallow_ma
static void
pax_aslr_sysinit(void)
{
pax_status_t old_state;
pax_state_t old_state;

old_state = pax_aslr_status;
if (!pax_feature_validate_state(&pax_aslr_status)) {
Expand Down Expand Up @@ -472,9 +494,12 @@ pax_aslr_init(struct image_params *imgp)
}

void
pax_aslr_init_prison(struct prison *pr)
pax_aslr_init_prison(struct prison *pr, struct vfsoptlist *opts)
{
struct prison *pr_p;
#ifdef PAX_JAIL_SUPPORT
pax_state_t new_state;
#endif

CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n",
__func__, pr->pr_name);
Expand All @@ -492,18 +517,37 @@ pax_aslr_init_prison(struct prison *pr)
pr_p = pr->pr_parent;

pr->pr_hbsd.aslr.status = pr_p->pr_hbsd.aslr.status;
#ifdef PAX_JAIL_SUPPORT
if (vfs_copyopt(opts, "hardening.pax.aslr.status",
&new_state, sizeof(new_state)) != ENOENT) {
if (pax_feature_validate_state(&new_state)) {
pr->pr_hbsd.aslr.status = new_state;
}
}
#endif /* PAX_JAIL_SUPPORT */
#ifdef MAP_32BIT
pr->pr_hbsd.aslr.disallow_map32bit_status =
pr_p->pr_hbsd.aslr.disallow_map32bit_status;
#endif
#ifdef PAX_JAIL_SUPPORT
if (vfs_copyopt(opts, "hardening.pax.disallow_map32bit.status",
&new_state, sizeof(new_state)) != ENOENT) {
if (pax_feature_validate_state(&new_state)) {
pr->pr_hbsd.aslr.disallow_map32bit_status = new_state;
}
}
#endif /* PAX_JAIL_SUPPORT */
#endif /* MAP_32BIT */
}
}

#ifdef COMPAT_FREEBSD32
void
pax_aslr_init_prison32(struct prison *pr)
pax_aslr_init_prison32(struct prison *pr, struct vfsoptlist *opts)
{
struct prison *pr_p;
#ifdef PAX_JAIL_SUPPORT
pax_state_t new_state;
#endif

CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n",
__func__, pr->pr_name);
Expand All @@ -518,6 +562,14 @@ pax_aslr_init_prison32(struct prison *pr)
pr_p = pr->pr_parent;

pr->pr_hbsd.aslr.compat_status = pr_p->pr_hbsd.aslr.compat_status;
#ifdef PAX_JAIL_SUPPORT
if (vfs_copyopt(opts, "hardening.pax.aslr.compat.status",
&new_state, sizeof(new_state)) != ENOENT) {
if (pax_feature_validate_state(&new_state)) {
pr->pr_hbsd.aslr.compat_status = new_state;
}
}
#endif
}
}
#endif /* COMPAT_FREEBSD32 */
Expand Down
19 changes: 12 additions & 7 deletions sys/hardenedbsd/hbsd_pax_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ CTASSERT(PAX_NOTE_NOSHLIBRANDOM == PAX_HARDENING_NOSHLIBRANDOM);
SYSCTL_NODE(_hardening, OID_AUTO, pax, CTLFLAG_RD, 0,
"PaX (exploit mitigation) features.");

#ifdef PAX_JAIL_SUPPORT
SYSCTL_JAIL_PARAM_NODE(hardening, "HardenedBSD features.");
SYSCTL_JAIL_PARAM_SUBNODE(hardening, pax, "PaX (exploit mitigation) features");
#endif

#if defined(PAX_CONTROL_ACL) || defined(PAX_CONTROL_EXTATTR)
SYSCTL_NODE(_hardening, OID_AUTO, control, CTLFLAG_RD, 0,
"PaX features control subnode.");
Expand Down Expand Up @@ -388,20 +393,20 @@ SYSINIT(pax, SI_SUB_PAX, SI_ORDER_FIRST, pax_sysinit, NULL);
* @return none
*/
void
pax_init_prison(struct prison *pr)
pax_init_prison(struct prison *pr, struct vfsoptlist *opts)
{

CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n",
__func__, pr->pr_name);

pax_aslr_init_prison(pr);
pax_hardening_init_prison(pr);
pax_noexec_init_prison(pr);
pax_segvguard_init_prison(pr);
pax_aslr_init_prison(pr, opts);
pax_hardening_init_prison(pr, opts);
pax_noexec_init_prison(pr, opts);
pax_segvguard_init_prison(pr, opts);
#ifdef COMPAT_FREEBSD32
pax_aslr_init_prison32(pr);
pax_aslr_init_prison32(pr, opts);
#endif
pax_log_init_prison(pr);
pax_log_init_prison(pr, opts);
}

/*
Expand Down
28 changes: 26 additions & 2 deletions sys/hardenedbsd/hbsd_pax_hardening.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ __FBSDID("$FreeBSD$");
#include <sys/ktr.h>
#include <sys/libkern.h>
#include <sys/lock.h>
#include <sys/sx.h>
#include <sys/mount.h>
#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/stat.h>
#include <sys/sx.h>
#include <sys/sysctl.h>

#include "hbsd_pax_internal.h"
Expand Down Expand Up @@ -77,6 +78,14 @@ SYSCTL_HBSD_2STATE(pax_procfs_harden_global, pr_hbsd.hardening.procfs_harden,
"Harden procfs, disabling write of /proc/pid/mem");
#endif

#if 0
#ifdef PAX_JAIL_SUPPORT
SYSCTL_JAIL_PARAM(hardening, procfs_harden,
CTLTYPE_INT | CTLFLAG_RD, "I",
"disabling write of /proc/pid/mem");
#endif
#endif

static void
pax_hardening_sysinit(void)
{
Expand Down Expand Up @@ -111,9 +120,14 @@ pax_hardening_sysinit(void)
SYSINIT(pax_hardening, SI_SUB_PAX, SI_ORDER_SECOND, pax_hardening_sysinit, NULL);

void
pax_hardening_init_prison(struct prison *pr)
pax_hardening_init_prison(struct prison *pr, struct vfsoptlist *opts)
{
struct prison *pr_p;
#if 0
#ifdef PAX_JAIL_SUPPORT
pax_state_t new_state;
#endif
#endif

CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n",
__func__, pr->pr_name);
Expand All @@ -129,6 +143,16 @@ pax_hardening_init_prison(struct prison *pr)

pr->pr_hbsd.hardening.procfs_harden =
pr_p->pr_hbsd.hardening.procfs_harden;
#if 0
#ifdef PAX_JAIL_SUPPORT
if (vfs_copyopt(opts, "hardening.procfs_harden",
&new_state, sizeof(new_state)) != ENOENT) {
if (pax_feature_simple_validate_state(&new_state)) {
pr->pr_hbsd.hardening.procfs_harden = new_state;
}
}
#endif /* PAX_JAIL_SUPPORT */
#endif
}
}

Expand Down
39 changes: 36 additions & 3 deletions sys/hardenedbsd/hbsd_pax_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
#include <sys/imgact.h>
#include <sys/jail.h>
#include <sys/ktr.h>
#include <sys/mount.h>
#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/sbuf.h>
#include <sys/jail.h>
#include <machine/stdarg.h>

#ifdef DDB
Expand Down Expand Up @@ -139,6 +140,18 @@ SYSCTL_HBSD_2STATE(hardening_log_ulog, pr_hbsd.log.ulog, _hardening_log, ulog,
"log to syslog ");
#endif

#ifdef PAX_JAIL_SUPPORT
SYSCTL_DECL(_security_jail_param_hardening);

SYSCTL_JAIL_PARAM_SUBNODE(hardening, log, "Hardening related logging");
SYSCTL_JAIL_PARAM(_hardening_log, log,
CTLTYPE_INT | CTLFLAG_RD, "I",
"log to syslog");
SYSCTL_JAIL_PARAM(_hardening_log, ulog,
CTLTYPE_INT | CTLFLAG_RD, "I",
"log to syslog");
#endif


static void
hardening_log_sysinit(void)
Expand Down Expand Up @@ -168,9 +181,12 @@ hardening_log_sysinit(void)
SYSINIT(hardening_log, SI_SUB_PAX, SI_ORDER_SECOND, hardening_log_sysinit, NULL);

void
pax_log_init_prison(struct prison *pr)
pax_log_init_prison(struct prison *pr, struct vfsoptlist *opts)
{
struct prison *pr_p;
#ifdef PAX_JAIL_SUPPORT
pax_state_t new_state;
#endif

CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n",
__func__, pr->pr_name);
Expand All @@ -185,7 +201,24 @@ pax_log_init_prison(struct prison *pr)
pr_p = pr->pr_parent;

pr->pr_hbsd.log.log = pr_p->pr_hbsd.log.log;
#ifdef PAX_JAIL_SUPPORT
if (vfs_copyopt(opts, "hardening.log.log",
&new_state, sizeof(new_state)) != ENOENT) {
if (pax_feature_validate_state(&new_state)) {
pr->pr_hbsd.log.log = new_state;
}
}
#endif /* PAX_JAIL_SUPPORT */

pr->pr_hbsd.log.ulog = pr_p->pr_hbsd.log.ulog;
#ifdef PAX_JAIL_SUPPORT
if (vfs_copyopt(opts, "hardening.log.ulog",
&new_state, sizeof(new_state)) != ENOENT) {
if (pax_feature_validate_state(&new_state)) {
pr->pr_hbsd.log.ulog = new_state;
}
}
#endif /* PAX_JAIL_SUPPORT */
}
}

Expand Down
Loading

0 comments on commit 45748d2

Please sign in to comment.