Browse Source

HBSD: as preparation to TOCTOU fix and to hbsdcontrol extend secadm's rules

This change introduces the prefer_acl keyword, to control the order of
rule evaluation.

When the prefer_acl property was set on a specific rule, then it
overrides the settings came from FS-EA based hbsdcontrol.

FYI: by default the hbsdcontrol's settings overrides the secadm rules,
since hbsdcontrol's evaluation is after the MAC framework's check.

Signed-off-by: Oliver Pinter <oliver.pinter@hardenedbsd.org>
master
Oliver Pinter 2 years ago
parent
commit
947e73dd5e
4 changed files with 75 additions and 5 deletions
  1. +18
    -3
      README
  2. +15
    -1
      kmod/secadm_vnode.c
  3. +2
    -0
      libsecadm/secadm.h
  4. +40
    -1
      secadm/secadm.c

+ 18
- 3
README View File

@@ -59,18 +59,30 @@ The flags that can be passed to `secadm add pax` are:
* M, m: Enable, disable MPROTECT
* P, p: Enable, disable PAGEEXEC
* S, s: Enable, disable SEGVGUARD
* O, o: Enable, disable hbsdcontrol based FS-EA rules overriding

By default, `secadm show` will show the active ruleset in abbreviated
format. secadm now integrates with libxo to provide ruleset output in
JSON, UCL, or XML formats. Specify a different format by using the -f
option to `secadm show`. For example, `secadm show -f ucl`.

Order of rule evaluation
========================

When the kernel is compiled with the PAX_CONTROL_EXTATTR kernel option, the
order of the evaluation is secadm then hbsdcontrol. This ensures that
the hbsdcontrol's settings always take precedence. To make secadm's
rules take precedence, use the O flag for that rule (prefer_acl is the
long option).

Requirements
============

* HardenedBSD version 31 or greater:
- `sysctl hardening.version` should show 31
* HardenedBSD version 1200055 or greater:
- `sysctl hardening.version` should show 1200055
* HardenedBSD kernel compiled with options PAX_CONTROL_ACL
* textproc/libucl
* textproc/libxo

Installation And Usage
======================
@@ -116,6 +128,8 @@ secadm currently supports toggling ASLR, SEGVGUARD, mprotect(exec)
hardening, and on certain HardenedBSD builds, PAGEEXEC hardening. In
the etc directory, you will find secadm.rules.sample, which shows
how to write rules.
You can use the prefer_acl keyword, to ensure secadm's rule takes
in effect over the file system extended attributes based settings.

secadm uses libucl for parsing its config file. As it stands right
now, the order of the rules do not matter, but that could change with
@@ -134,7 +148,8 @@ secadm {
pax {
path: "/bin/pwd",
mprotect: true,
pageexec: true
pageexec: true,
prefer_acl: true
}
}
==== End of Example ====

+ 15
- 1
kmod/secadm_vnode.c View File

@@ -47,7 +47,9 @@ static int
secadm_pax_elf(struct image_params *imgp, pax_flag_t flags)
{

#if (__HardenedBSD_version < 1300000 && __HardenedBSD_version > 1200052) || \
#if (__HardenedBSD_version < 1300000 && __HardenedBSD_version > 1200054)
return pax_control_acl_set_flags(curthread, imgp, flags);
#elif (__HardenedBSD_version < 1300000 && __HardenedBSD_version > 1200052) || \
(__HardenedBSD_version < 1200000 && __HardenedBSD_version > 1100048) || \
(__HardenedBSD_version < 1100000 && __HardenedBSD_version > 1000048)
return pax_elf(curthread, imgp, flags);
@@ -185,6 +187,18 @@ secadm_vnode_check_exec(struct ucred *ucred, struct vnode *vp,
PAX_NOTE_NODISALLOWMAP32BIT;
}
}

#ifdef PAX_NOTE_PREFER_ACL
if (rule->sr_pax_data->sp_pax_set &
SECADM_PAX_PREFER_ACL) {
if (rule->sr_pax_data->sp_pax &
SECADM_PAX_PREFER_ACL) {
flags |= PAX_NOTE_PREFER_ACL;
} else {
flags &= ~PAX_NOTE_PREFER_ACL;
}
}
#endif
}
}
rule_inactive:

+ 2
- 0
libsecadm/secadm.h View File

@@ -65,6 +65,7 @@
#define SECADM_PAX_SEGVGUARD_SET 0x00000008
#define SECADM_PAX_SHLIBRANDOM_SET 0x00000010
#define SECADM_PAX_MAP32_SET 0x00000020
#define SECADM_PAX_PREFER_ACL_SET 0x80000000

#define SECADM_PAX_PAGEEXEC 0x00000001
#define SECADM_PAX_MPROTECT 0x00000002
@@ -72,6 +73,7 @@
#define SECADM_PAX_SEGVGUARD 0x00000008
#define SECADM_PAX_SHLIBRANDOM 0x00000010
#define SECADM_PAX_MAP32 0x00000020
#define SECADM_PAX_PREFER_ACL 0x80000000

#define SECADM_INTEGRIFORCE_FLAGS_NONE 0x00000000
#define SECADM_INTEGRIFORCE_FLAGS_WHITELIST 0x00000001

+ 40
- 1
secadm/secadm.c View File

@@ -334,6 +334,13 @@ show_action(int argc, char **argv)
SECADM_PAX_SEGVGUARD ? 'S' : 's'));
}

if (ruleset[i]->sr_pax_data->sp_pax_set &
SECADM_PAX_PREFER_ACL_SET) {
printf("%c",
(ruleset[i]->sr_pax_data->sp_pax &
SECADM_PAX_PREFER_ACL ? 'O' : 'o'));
}

printf("\n");

break;
@@ -834,6 +841,20 @@ add_action(int argc, char **argv)
SECADM_PAX_MPROTECT_SET;
break;

case 'o':
rule->sr_pax_data->sp_pax &=
~(SECADM_PAX_PREFER_ACL);
rule->sr_pax_data->sp_pax_set |=
SECADM_PAX_PREFER_ACL_SET;
break;

case 'O':
rule->sr_pax_data->sp_pax |=
SECADM_PAX_PREFER_ACL;
rule->sr_pax_data->sp_pax_set |=
SECADM_PAX_PREFER_ACL_SET;
break;

case 'p':
/* mprotect requires pageexec */
rule->sr_pax_data->sp_pax &=
@@ -1107,6 +1128,13 @@ emit_rules_xo(secadm_rule_t **ruleset, size_t num_rules, int style)
SECADM_PAX_SHLIBRANDOM ? "true" : "false"));
}

if (ruleset[i]->sr_pax_data->sp_pax_set &
SECADM_PAX_PREFER_ACL_SET) {
xo_emit("{:prefer_acl/%s}/",
(ruleset[i]->sr_pax_data->sp_pax &
SECADM_PAX_PREFER_ACL ? "true" : "false"));
}

xo_close_instance_d();
}
}
@@ -1195,7 +1223,12 @@ emit_rules_ucl(secadm_rule_t **ruleset, size_t num_rules)
(ruleset[i]->sr_pax_data->sp_pax &
SECADM_PAX_SHLIBRANDOM ? "true" : "false"));
}

if (ruleset[i]->sr_pax_data->sp_pax_set &
SECADM_PAX_PREFER_ACL_SET) {
printf(" prefer_acl = %s;\n",
(ruleset[i]->sr_pax_data->sp_pax &
SECADM_PAX_PREFER_ACL ? "true" : "false"));
}
printf(" }\n");
}
}
@@ -1316,6 +1349,12 @@ parse_pax_object(const ucl_object_t *obj, secadm_rule_t *rule)
if (ucl_object_toboolean(cur))
rule->sr_pax_data->sp_pax |=
SECADM_PAX_MAP32;
} else if (!strncmp(key, "prefer_acl", 10)) {
rule->sr_pax_data->sp_pax_set |=
SECADM_PAX_PREFER_ACL_SET;
if (ucl_object_toboolean(cur))
rule->sr_pax_data->sp_pax |=
SECADM_PAX_PREFER_ACL;
} else {
fprintf(stderr,
"Unknown attribute '%s' of PaX rule.\n", key);

Loading…
Cancel
Save