Introducing secadm 0.1-beta1

When we first introduced our ASLR patch upstream to FreeBSD, we provided a mechanism via ugidfw for system administrators and users to toggle ASLR and other security features on a per-binary basis. However, this mechanism was more of a hack than a production-ready solution. We have been hard at work to rearchitect a new production-ready implementation. We designed an application that we like to call secadm, short for Security Administration. This application will serve as the basis for advanced administration of the security features we implement in HardenedBSD. As it stands right now, secadm requires certain features that exist in HardenedBSD and not FreeBSD.

Version 0.1-beta1 is a preview release: our Christmas present to you! It supports the toggling of ASLR, SEGVGUARD, mprotect(exec) hardening, and PAGEEXEC. It works on a per-jail basis. Rules created/modified in one jail do not affect other jails, including child jails. As it stands right now, parent jails cannot modify the rules loaded in child jails.

You can find the tarfile here. You can find the signature here. The tarball was signed with Shawn Webb's GPG key that has a fingerprint of 2ABA B6BD EF6A F486 BE89 3D9E 6A84 658F 5245 6EEE.

From the README file:

Author: Shawn Webb <>
Copyright (c) 2014 Shawn Webb
License: 2-Clause BSD License


secadm is a project to replace the mac_bsdextended(4)/ugidfw(8)
integration the HardenedBSD project has done for ASLR, SEGVGUARD, and
PTrace hardening. The secadm project will be implemented as a custom
ports entry in the HardenedBSD/freebsd-ports repo. The port will
consist of three parts: a kernel module that integrates with the MAC
framework, a shared library that communicates between kernel and
userland, and an application that consumes the shared library.

The MAC module will work on a per-jail basis. It will communicate
with userland via a sysctl node. The MAC module should hook into the
execve() call to set per-process security/hardening flags, such as
toggling ASLR or SEGVGUARD. Each jail manages its own rules. Rules
applied in one jail do not interact or impact other jails.

The shared library will be named libsecadm and will simply act as a
communication layer between userland applications and the sysctl.
The shared library will perform the same sanitization and sanity
checking on all rule changes, including the removal of rules, that the
MAC module performs.

The userland application will be named secadm. It will consume libsecadm
and libucl. Rules will be written in json to allow for a
configuration file format that is readable and parseable by both
humans and machines. Using the json format will also allow for
additional flexibility and dynamic content. One can imagine secadm
deployed in a security appliance where the rulesets are created and
updated via a web service API.

secadm will initially support toggling ASLR, SEGVGUARD, and PTrace
hardening. It will work on a per-jail and per-file basis.


* HardenedBSD version 9 or greater:
  - `sysctl hardening.version` should show 9
* textproc/libucl

Installation And Usage

# make
# make install

Edit your rules:
# vi secadm/config.conf.sample

Activate them. Please note that setting a new ruleset will flush your
previously-loaded rules.
# secadm -c secadm/config.conf.sample set

To verify that your ruleset loaded successfully:
# secadm list

To flush rules:
# secadm flush

Writing Application Rules

secadm currently supports toggling ASLR, SEGVGUARD, mprotect(exec)
hardening, and on certain HardenedBSD builds, PAGEEXEC hardening. In
the secadm directory, you will find config.conf.sample, which shows
how to write rules.

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
time as we add new features. The sample config file is in a relaxed
JSON format, though libucl supports different syntaxes. Please refer
to libucl's documentation for help in learning the different possible

In the root object, secadm expects an applications array. Each entry
in the applications array must be an object. That object must have the
following fields:

	1. path (string): The fully-qualified path of the program
	2. features (object): An object that describes each of the
	   features we are toggling. Supported features:
	   a. aslr (boolean): toggles ASLR
	   b. segvguard (boolean): toggles SEGVGUARD
	   c. mprotect (boolean): toggles mprotect(exec) hardening
	   d. pageexec (boolean): toggles PAGEEXEC

When you combine that all together, you should get the following
example. Let's say we want to force ASLR and SEGVGUARD off with
/bin/ls and force mprotect(exec) hardening and PAGEEXEC on with
/bin/pwd. This is what you would write:

==== Start of Example ====
	"applications": [
			"path": "/bin/ls",
			"features": {
				"aslr": false,
				"segvguard": false
			"path": "/bin/pwd",
			"features": {
				"mprotect": true,
				"pageexec": true
==== End of Example ====