Solved [Solved] Customised DEVFS rules unhiding everything in jails

I have a machine running ( uname -srmi) FreeBSD 9.2-RELEASE-p4 i386 GENERIC. The server hosts a number of jails installed and maintained using sysutils/ezjail. Most of the jails are configured to use the "devfsrules_jail" ruleset from /etc/defaults/devfs.rules*. For these jails, there is only the restricted list of devices shown in the jailed /dev. However, for a couple of my jails I needed to unhide additional devices. For these, I configured rulesets in /etc/devfs.rules. Unfortunately, these rulesets are not being applied as I intended and all devices on the host are visible in the jailed /dev.

/etc/devfs.rules, containing my rulesets:
Code:
[devfsrules_jail_dhcp=12]
add include $devfsrules_jail
add path 'bpf*' unhide

[devfsrules_jail_print=13]
add include $devfsrules_jail
add path lpt0 unhide

I changed the following lines from the default in my sysutils/ezjail configuration files to reference these rulesets:
/usr/local/etc/ezjail/dhcp_mydomain_com:
Code:
export jail_print_mydomain_com_devfs_ruleset="devfsrules_jail_dhcp"
/usr/local/etc/ezjail/print_mydomain_com:
Code:
export jail_print_mydomain_com_devfs_ruleset="devfsrules_jail_print"

I examined how /usr/local/etc/rc.d/ezjail works. Essentially it sources the configuration files in /usr/local/etc/ezjail/ and then calls /etc/rc.d/jail, which expects a variable named "jail_<jail name>_devfs_ruleset" to be set for each jail, which is used when mounting the jailed /dev. I tried changing the setting to a non-existent ruleset, which generated an error when starting the jail, so the variable is certainly being used.

I checked that my rules in /etc/devfs.rules were being loaded:
Code:
# devfs rule -s 12 show
100 include 4
200 path bpf* unhide

# devfs rule -s 13 show
Password:
100 include 4
200 path lpt0 unhide

I also checked that the rules from /etc/defaults/devfs.rules were being correctly shown by devfs(8) (already demonstrated by correct application in my other jails).

Having found PR kern/187079: [jail] devfs_load_rulesets has to be enabled for mount.devfs to behave like expected (noting that for most of my jails, the rules were being applied just fine) and looked at rc.conf(8), I tried adding the following to /etc/rc.conf and rebooting, but it had no effect:
Code:
devfs_load_rulesets="YES"
devfs_rulesets="/etc/defaults/devfs.rules /etc/devfs.rules"

I believe I have replicated the issue by using mount(8). The following shows device counts when mounting DEVFS with the different rulesets. As can be seen, ruleset 4 is being correctly applied, reducing the number of visible devices, but my rulesets (12 and 13) leave all devices visible:
Code:
# mkdir /tmp/{dev-ruleset4,dev-ruleset12,dev-ruleset13}
# mount -t devfs -o ruleset=4 devfs /tmp/dev-ruleset4
# mount -t devfs -o ruleset=12 devfs /tmp/dev-ruleset12
# mount -t devfs -o ruleset=13 devfs /tmp/dev-ruleset13
# ls /tmp/dev-ruleset4 | wc -l
      11
# ls /tmp/dev-ruleset12 | wc -l
      97
# ls /tmp/dev-ruleset13 | wc -l
      97

Is there something I have not configured correctly? Can anyone suggest where to look next?

Ad [*] To save readers from searching for /etc/defaults/devfs.rules:
Code:
#
# The following are some default rules for devfs(5) mounts.
# The format is very simple. Empty lines and lines beginning
# with a hash '#' are ignored. If the hash mark occurs anywhere
# other than the beginning of a line, it and any subsequent
# characters will be ignored.  A line in between brackets '[]'
# denotes the beginning of a ruleset. In the brackets should
# be a name for the rule and its ruleset number. Any other lines
# will be considered to be the 'action' part of a rule
# passed to the devfs(8) command. These will be passed
# "as-is" to the devfs(8) command with the exception that
# any references to other rulesets will be expanded first. These
# references must include a dollar sign '$' in front of the
# name to be expanded properly.
#
# $FreeBSD: release/9.2.0/etc/defaults/devfs.rules 233566 2012-03-27 17:24:51Z mm $
#

# Very basic and secure ruleset: Hide everything.
# Used as a basis for other rules.
#
[devfsrules_hide_all=1]
add hide

# Basic devices typically necessary.
# Requires: devfsrules_hide_all
#
[devfsrules_unhide_basic=2]
add path log unhide
add path null unhide
add path zero unhide
add path crypto unhide
add path random unhide
add path urandom unhide

# Devices typically needed to support logged-in users.
# Requires: devfsrules_hide_all
#
[devfsrules_unhide_login=3]
add path 'ptyp*' unhide
add path 'ptyq*' unhide
add path 'ptyr*' unhide
add path 'ptys*' unhide
add path 'ptyP*' unhide
add path 'ptyQ*' unhide
add path 'ptyR*' unhide
add path 'ptyS*' unhide
add path 'ptyl*' unhide
add path 'ptym*' unhide
add path 'ptyn*' unhide
add path 'ptyo*' unhide
add path 'ptyL*' unhide
add path 'ptyM*' unhide
add path 'ptyN*' unhide
add path 'ptyO*' unhide
add path 'ttyp*' unhide
add path 'ttyq*' unhide
add path 'ttyr*' unhide
add path 'ttys*' unhide
add path 'ttyP*' unhide
add path 'ttyQ*' unhide
add path 'ttyR*' unhide
add path 'ttyS*' unhide
add path 'ttyl*' unhide
add path 'ttym*' unhide
add path 'ttyn*' unhide
add path 'ttyo*' unhide
add path 'ttyL*' unhide
add path 'ttyM*' unhide
add path 'ttyN*' unhide
add path 'ttyO*' unhide
add path ptmx unhide
add path pts unhide
add path 'pts/*' unhide
add path fd unhide
add path 'fd/*' unhide
add path stdin unhide
add path stdout unhide
add path stderr unhide

# Devices usually found in a jail.
#
[devfsrules_jail=4]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add path zfs unhide
 
Re: Customised DEVFS rules unhiding everything in affected j

After much head-scratching, I found the following in the devfs(8) man page:
include ruleset
[...]
Include commands in the referenced ruleset are not resolved.

So it's not possible to stack rulesets the way I was trying to do; include commands must reference rulesets containing actual rules, not other include commands. The rule in the devfsrules_hide_all ruleset (from /etc/defaults/devfs.rules) was therefore not being applied to my jails, resulting in all the devices being visible.

I changed /etc/devfs.rules to the following and now everything is working as I expect, with only the specified devices available in the /dev of my jails:
Code:
[devfsrules_jail_dhcp=12]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add path zfs unhide
add path 'bpf*' unhide

[devfsrules_jail_print=13]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add path zfs unhide
add path lpt0 unhide
 
Back
Top