Add a general mechanism for creating and applying
devfs(8) rules in rc(8). It is most useful for applying rules to devfs(5) mount points in /dev or inside jails. The following line of script is sufficient to mount a relatively useful+secure devfs(5) in a jail: devfs_mount_jail /some/jail/dev Some new shell routines available to scripts that source rc.subr(5): o devfs_link - Makes it a little easier to create symlinks o devfs_init_rulesets - Create devfs(8) rulesets from devfs.rules o devfs_set_ruleset - Set a ruleset to a devfs(5) mount o devfs_apply_ruleset - Apply a ruleset to a devfs(5) mount o devfs_domount - Mount devfs(5) and apply some ruleset o devfs_mount_jail - Mount devfs(5) and apply a ruleset appropriate to jails. Additional rulesets can be specified in /etc/devfs.rules. If the devfs_system_ruleset variable is defined in rc.conf and it contains the name of a ruleset defined in /etc/defaults/devfs.rules or user supplied rulesets in /etc/devfs.rules then that ruleset will be applied to /dev at startup by the /etc/rc.d/devfs script. It can also be applied post-startup: /etc/rc.d/devfs start This is a more flexible mechanism than the previous method of using /etc/devfs.conf. However, that method is still available. Note: since devfs(8) doesn't provide any way for creating symlinks as part of a ruleset, anyone wishing to create symlinks in a devfs(5) as part of the bootup sequence will still have to rely on /etc/devfs.conf.
This commit is contained in:
parent
74a9cb0969
commit
130112f793
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
FILES= pccard.conf periodic.conf rc.conf
|
||||
FILES= devfs.rules pccard.conf periodic.conf rc.conf
|
||||
NOOBJ= noobj
|
||||
FILESDIR= /etc/defaults
|
||||
FILESMODE= 644
|
||||
|
64
etc/defaults/devfs.rules
Normal file
64
etc/defaults/devfs.rules
Normal file
@ -0,0 +1,64 @@
|
||||
#
|
||||
# The following are some default rules for devfs(5) mounts.
|
||||
# The format is very simple. Empty lines and lines begining
|
||||
# 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$
|
||||
#
|
||||
|
||||
# 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 null unhide
|
||||
add path zero 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 '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 '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
|
@ -434,6 +434,10 @@ jail_set_hostname_allow="YES" # Allow root user in a jail to change its hostname
|
||||
jail_socket_unixiproute_only="YES" # Route only TCP/IP within a jail
|
||||
jail_sysvipc_allow="NO" # Allow SystemV IPC use from within a jail
|
||||
watchdogd_enable="NO" # Start the software watchdog daemon
|
||||
devfs_rulesets="/etc/defaults/devfs.rules /etc/devfs.rules" # Files containing
|
||||
# devfs(8) rules.
|
||||
devfs_system_ruleset="" # The name of a ruleset to apply to /dev
|
||||
|
||||
|
||||
##############################################################
|
||||
### Define source_rc_confs, the mechanism used by /etc/rc.* ##
|
||||
|
@ -11,9 +11,19 @@
|
||||
. /etc/rc.subr
|
||||
|
||||
name="devfs"
|
||||
start_cmd='read_devfs_conf'
|
||||
start_cmd='devfs_start'
|
||||
stop_cmd=':'
|
||||
|
||||
devfs_start()
|
||||
{
|
||||
if [ -n "$devfs_system_ruleset" ]; then
|
||||
devfs_init_rulesets
|
||||
devfs_set_ruleset $devfs_system_ruleset /dev
|
||||
devfs_apply_ruleset $devfs_system_ruleset /dev
|
||||
fi
|
||||
read_devfs_conf
|
||||
}
|
||||
|
||||
read_devfs_conf()
|
||||
{
|
||||
if [ -r /etc/devfs.conf ]; then
|
||||
|
218
etc/rc.subr
218
etc/rc.subr
@ -1033,3 +1033,221 @@ backup_file()
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
# devfs_link dir src link
|
||||
# Make a symbolic link 'link' to src in chroot/dev.
|
||||
# Returns 0 on sucess.
|
||||
#
|
||||
devfs_link()
|
||||
{
|
||||
local dir src link _me
|
||||
dir="$1"
|
||||
src="$2"
|
||||
link="$3"
|
||||
_me="devfs_link"
|
||||
|
||||
if [ -z "$dir" -o -z "$src" -o -z "$link" ]; then
|
||||
warn "devfs_link(): requires three arguments."
|
||||
return 1
|
||||
fi
|
||||
if [ -z "$dir" ]; then
|
||||
warn "$_me: the directory ($dir) does not exist"
|
||||
return 1
|
||||
fi
|
||||
cd ${chroot}/dev
|
||||
if ! ln -sf $src $link ; then
|
||||
warn "$_me: unable to link $link --> $src in $dir"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# devfs_rulesets_from_file file
|
||||
# Reads a set of devfs commands from file, and creates
|
||||
# the specified rulesets with their rules. Returns non-zero
|
||||
# if there was an error.
|
||||
#
|
||||
devfs_rulesets_from_file()
|
||||
{
|
||||
local file _err _me
|
||||
file="$1"
|
||||
_me="devfs_rulesets_from_file"
|
||||
_err=0
|
||||
|
||||
if [ -z "$file" ]; then
|
||||
warn "$_me: you must specify a file"
|
||||
return 1
|
||||
fi
|
||||
if [ ! -e "$file" ]; then
|
||||
debug "$_me: no such file ($file)"
|
||||
return 0
|
||||
fi
|
||||
debug "reading rulesets from file ($file)"
|
||||
{ while read line
|
||||
do
|
||||
case $line in
|
||||
\#*)
|
||||
continue
|
||||
;;
|
||||
\[*\]*)
|
||||
rulenum=`expr "$line" : "\[.*=\([0-9]*\)\]"`
|
||||
if [ -z "$rulenum" ]; then
|
||||
warn "$_me: cannot extract rule number ($line)"
|
||||
_err=1
|
||||
break
|
||||
fi
|
||||
rulename=`expr "$line" : "\[\(.*\)=[0-9]*\]"`
|
||||
if [ -z "$rulename" ]; then
|
||||
warn "$_me: cannot extract rule name ($line)"
|
||||
_err=1
|
||||
break;
|
||||
fi
|
||||
eval $rulename=\$rulenum
|
||||
debug "found ruleset: $rulename=$rulenum"
|
||||
if ! /sbin/devfs rule -s $rulenum delset ; then
|
||||
_err=1
|
||||
break
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
rulecmd="${line%%"\#*"}"
|
||||
# evaluate the command incase it includes
|
||||
# other rules
|
||||
if [ -n "$rulecmd" ]; then
|
||||
debug "adding rule ($rulecmd)"
|
||||
if ! eval /sbin/devfs rule -s $rulenum $rulecmd
|
||||
then
|
||||
_err=1
|
||||
break
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if [ $_err -ne 0 ]; then
|
||||
debug "error in $_me"
|
||||
break
|
||||
fi
|
||||
done } < $file
|
||||
return $_err
|
||||
}
|
||||
|
||||
# devfs_init_rulesets
|
||||
# Initializes rulesets from configuration files. Returns
|
||||
# non-zero if there was an error.
|
||||
#
|
||||
devfs_init_rulesets()
|
||||
{
|
||||
local file _me
|
||||
_me="devfs_init_rulesets"
|
||||
|
||||
# Go through this only once
|
||||
if [ -n "$devfs_rulesets_init" ]; then
|
||||
debug "$_me: devfs rulesets already initialized"
|
||||
return
|
||||
fi
|
||||
for file in $devfs_rulesets ; do
|
||||
devfs_rulesets_from_file $file || return 1
|
||||
done
|
||||
devfs_rulesets_init=1
|
||||
debug "$_me: devfs rulesets initialized"
|
||||
return 0
|
||||
}
|
||||
|
||||
# devfs_set_ruleset ruleset [dir]
|
||||
# Sets the default ruleset of dir to ruleset. The ruleset arguement
|
||||
# must be a ruleset name as specified in devfs.rules(5) file.
|
||||
# Returns non-zero if it could not set it successfully.
|
||||
#
|
||||
devfs_set_ruleset()
|
||||
{
|
||||
local devdir rs _me
|
||||
[ -n "$1" ] && eval rs=\$$1 || rs=
|
||||
[ -n "$2" ] && devdir="-m "$2"" || devdir=
|
||||
_me="devfs_set_ruleset"
|
||||
|
||||
if [ -z "$rs" ]; then
|
||||
warn "$_me: you must specify a ruleset number"
|
||||
return 1
|
||||
fi
|
||||
debug "$_me: setting ruleset ($rs) on mount-point (${devdir#-m })"
|
||||
if ! /sbin/devfs $devdir ruleset $rs ; then
|
||||
warn "$_me: unable to set ruleset $rs to ${devdir#-m }"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# devfs_apply_ruleset ruleset [dir]
|
||||
# Apply ruleset number $ruleset to the devfs mountpoint $dir.
|
||||
# The ruleset argument must be a ruleset name as specified
|
||||
# in a devfs.rules(5) file. Returns 0 on success or non-zero
|
||||
# if it could not apply the ruleset.
|
||||
#
|
||||
devfs_apply_ruleset()
|
||||
{
|
||||
local devdir rs _me
|
||||
[ -n "$1" ] && eval rs=\$$1 || rs=
|
||||
[ -n "$2" ] && devdir="-m "$2"" || devdir=
|
||||
_me="devfs_apply_ruleset"
|
||||
|
||||
if [ -z "$rs" ]; then
|
||||
warn "$_me: you must specify a ruleset"
|
||||
return 1
|
||||
fi
|
||||
debug "$_me: applying ruleset ($rs) to mount-point (${devdir#-m })"
|
||||
if ! /sbin/devfs $devdir rule -s $rs applyset ; then
|
||||
warn "$_me: unable to apply ruleset $rs to ${devdir#-m }"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# devfs_domount dir [ruleset]
|
||||
# Mount devfs on dir. If ruleset is specified it is set
|
||||
# on the mount-point. It must also be a ruleset name as specified
|
||||
# in a devfs.rules(5) file. Returns 0 on success.
|
||||
#
|
||||
devfs_domount()
|
||||
{
|
||||
local devdir rs _me
|
||||
devdir="$1"
|
||||
[ -n "$2" ] && rs=$2 || rs=
|
||||
_me="devfs_domount()"
|
||||
|
||||
if [ -z "$devdir" ]; then
|
||||
warn "$_me: you must specify a mount-point"
|
||||
return 1
|
||||
fi
|
||||
debug "$_me: mount-point is ($devdir), ruleset is ($rs)"
|
||||
if ! mount -t devfs dev "$devdir" ; then
|
||||
warn "$_me: Unable to mount devfs on $devdir"
|
||||
return 1
|
||||
fi
|
||||
if [ -n "$rs" ]; then
|
||||
devfs_init_rulesets
|
||||
devfs_set_ruleset $rs $devdir
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# devfs_mount_jail dir [ruleset]
|
||||
# Mounts a devfs file system appropriate for jails
|
||||
# on the directory dir. If ruleset is specified, the ruleset
|
||||
# it names will be used instead. If present, ruleset must
|
||||
# be the name of a ruleset as defined in a devfs.rules(5) file.
|
||||
# This function returns non-zero if an error occurs.
|
||||
#
|
||||
devfs_mount_jail()
|
||||
{
|
||||
local jdev rs _me
|
||||
jdev="$1"
|
||||
[ -n "$2" ] && rs=$2 || rs="devfsrules_jail"
|
||||
_me="devfs_mount_jail"
|
||||
|
||||
devfs_init_rulesets
|
||||
if ! devfs_domount "$jdev" $rs ; then
|
||||
warn "$_me: devfs was not mounted on $jdev"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user