Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 389425

Summary: dhcpd init script cannot work with dhcpd configuration file in SELinux
Product: Gentoo Linux Reporter: Veovis <veovis8>
Component: HardenedAssignee: Sven Vermeulen (RETIRED) <swift>
Status: VERIFIED FIXED    
Severity: normal CC: selinux
Priority: Normal    
Version: unspecified   
Hardware: All   
OS: Linux   
Whiteboard:
Package list:
Runtime testing required: ---
Attachments: patch to ebuild

Description Veovis 2011-11-03 17:19:04 UTC
Created attachment 291591 [details]
patch to ebuild

It seems that some specific type are not applied in /etc/init.d folder.

For example, on my gentoo:
# ls -Z /etc/init.d/dhcpd
system_u:object_r:initrc_exec_t /etc/init.d/dhcpd
# dhcpd init has the generic type initrc_exec_t; like all files in this folder

on a red hat 6, I get that:
[sebastien@redhat ~]$ ls -Z /etc/init.d/dhcpd
-rwxr-xr-x. root root system_u:object_r:dhcpd_initrc_exec_t:s0 /etc/init.d/dhcpd
# dhcpd has a specific type here

In reference policy, from which gentoo selinux is based, /etc/init.d/ are not tagged directly, but through /etc/rc.d folder, which does not exist on gentoo.

We can see that with those commands :
# ebuild /usr/portage/sec-policy/selinux-base-policy/selinux-base-policy-2.20110726-r4.ebuild prepare
# vim /var/tmp/portage/sec-policy/selinux-base-policy-2.20110726-r4/work/refpolicy/policy/modules/services/dhcp.fc

I write a tiny patch on the ebuild to resolve the missing file context.
It replace /etc/rc.d/init.d by /etc/init.d in all *.fc files.

I have not installed the new ebuild yet.
Comment 1 Sven Vermeulen (RETIRED) gentoo-dev 2011-11-03 19:44:55 UTC
It's known, and currently we're not looking at named init script integration (cfr earlier discussions on gentoo-hardened) as that breaks the integrated run_init support.
Comment 2 Sven Vermeulen (RETIRED) gentoo-dev 2011-11-03 19:48:19 UTC
BTW, if you seem to be able to have things working with the named init scripts, that would be great (and I definitely would like to know how you got that done).

The only way I've been able to do so is to drop the integrated run_init support (so have the users always prepend /etc/init.d/* stuff with "run_init").

The reason why refpolicy uses named init scripts is to allow non-sysadm roles to start services (by giving them the appropriate _admin() interface to the service, like "postfix_admin(mailadm_t, mailadm_r)" so that the mailadm users can use "sudo run_init /etc/init.d/postfix start" or so.
Comment 3 Veovis 2011-11-08 17:06:26 UTC
Thank you for your explanations.

To be honest, I'm a complete noob with selinux.
I'll try to dig on run_init, but maybe this is useless for what I'm looking for.

In fact, my real problem is in the content of /etc/init.d/dhcpd (and I think this problem also affects other daemon init script).

There is a call to sed on the dhcpd.conf, which is denied by default by selinux (wrong context).
I'm in permissive mode, so there is juste a log in kern.log, but this prevent me from switching the enforce flag.

I may write a custom module from the kern.log, but it will result in allowing a read access to dhcpd.conf to all process in initrc_exec_t. That seems it's the wrong way.
Comment 4 Sven Vermeulen (RETIRED) gentoo-dev 2011-11-11 17:45:32 UTC
Can you elaborate which denial you get then?

Sed never runs in its "own" domain, it is marked as bin_t so always runs in the domain of whatever is invoking sed. It might however not have the privileges to work with specific files or directories. In that case we need the denial log anyhow.
Comment 5 Veovis 2012-01-06 11:04:42 UTC
Hi again,

This is what I get when I restart dhcpd (on kern.log):
Jan  6 11:57:56 stormrage kernel: type=1400 audit(1325847476.011:685586): avc:  denied  { name_bind } for  pid=24391 comm="dhcpd" src=8646 scontext=system_u:system_r:dhcpd_t tcontext=system_u:object_r:port_t tclass=udp_socket
Jan  6 11:57:56 stormrage kernel: type=1400 audit(1325847476.141:685587): avc:  denied  { read } for  pid=24395 comm="sed" name="dhcpd.conf" dev=sda2 ino=3943260 scontext=system_u:system_r:initrc_t tcontext=system_u:object_r:dhcp_etc_t tclass=file
Jan  6 11:57:56 stormrage kernel: type=1400 audit(1325847476.141:685588): avc:  denied  { open } for  pid=24395 comm="sed" name="dhcpd.conf" dev=sda2 ino=3943260 scontext=system_u:system_r:initrc_t tcontext=system_u:object_r:dhcp_etc_t tclass=file

I've done the restart as root:sysadm_r.
Packages installed:
* sec-policy/selinux-dhcp-2.20110726
* net-misc/dhcp-4.2.3_p1 client ipv6 kernel_linux selinux server ssl vim-syntax

And of course: emerge --info
# emerge --info
Portage 2.1.10.41 (hardened/linux/amd64/selinux, gcc-4.5.3, glibc-2.13-r4, 2.6.39-hardened-r8 x86_64)
=================================================================
System uname: Linux-2.6.39-hardened-r8-x86_64-Intel-R-_Core-TM-_i5-2300_CPU_@_2.80GHz-with-gentoo-2.0.3
Timestamp of tree: Wed, 04 Jan 2012 20:45:01 +0000
app-shells/bash:          4.1_p9
dev-java/java-config:     2.1.11-r3
dev-lang/python:          2.7.2-r3, 3.1.4-r3
dev-util/cmake:           2.8.4-r1
dev-util/pkgconfig:       0.26
sys-apps/baselayout:      2.0.3
sys-apps/openrc:          0.9.4
sys-apps/sandbox:         2.5
sys-devel/autoconf:       2.68
sys-devel/automake:       1.10.3, 1.11.1
sys-devel/binutils:       2.21.1-r1
sys-devel/gcc:            4.5.3-r1
sys-devel/gcc-config:     1.4.1-r1
sys-devel/libtool:        2.4-r1
sys-devel/make:           3.82-r1
sys-kernel/linux-headers: 2.6.39 (virtual/os-headers)
sys-libs/glibc:           2.13-r4
Repositories: gentoo vmware kveer
ACCEPT_KEYWORDS="amd64"
ACCEPT_LICENSE="* -@EULA"
CBUILD="x86_64-pc-linux-gnu"
CFLAGS="-O2 -march=native -mtune=native -mmmx -msse -msse2 -msse3 -msse4.1 -msse4.2 -maes -mpclmul -mpopcnt -mcx16 -mfpmath=sse -fomit-frame-pointer -pipe"
CHOST="x86_64-pc-linux-gnu"
CONFIG_PROTECT="/etc /usr/share/gnupg/qualified.txt /usr/share/openvpn/easy-rsa /var/bind"
CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/env.d/java/ /etc/fonts/fonts.conf /etc/gconf /etc/gentoo-release /etc/php/apache2-php5.3/ext-active/ /etc/php/cgi-php5.3/ext-active/ /etc/php/cli-php5.3/ext-active/ /etc/revdep-rebuild /etc/sandbox.d /etc/terminfo"
CXXFLAGS="-O2 -march=native -mtune=native -mmmx -msse -msse2 -msse3 -msse4.1 -msse4.2 -maes -mpclmul -mpopcnt -mcx16 -mfpmath=sse -fomit-frame-pointer -pipe"
DISTDIR="/usr/portage/distfiles"
FEATURES="assume-digests binpkg-logs distlocks ebuild-locks fixlafiles news parallel-fetch protect-owned sandbox selinux sesandbox sfperms strict unknown-features-warn unmerge-logs unmerge-orphans userfetch usersandbox usersync"
FFLAGS=""
GENTOO_MIRRORS="ftp://mirror.ovh.net/gentoo-distfiles/ ftp://ftp.free.fr/mirrors/ftp.gentoo.org/"
LANG="fr_FR.UTF-8"
LDFLAGS="-Wl,-O1 -Wl,--as-needed -Wl,-O1"
LINGUAS="fr"
MAKEOPTS="-j5"
PKGDIR="/usr/portage/packages"
PORTAGE_CONFIGROOT="/"
PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress --force --whole-file --delete --stats --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages"
PORTAGE_TMPDIR="/var/tmp"
PORTDIR="/usr/portage"
PORTDIR_OVERLAY="/var/lib/layman/vmware /var/lib/layman/kveer"
SYNC="rsync://rsync.fr.gentoo.org/gentoo-portage"
USE="acl amd64 bash-completion berkdb bzip2 caps cli cracklib crypt cups cxx dri gdbm gpm hardened iconv ipv6 justify mmx modules mudflap multilib ncurses nls nptl nptlonly open_perms openmp pam pax_kernel pcre pppd readline selinux session sse sse2 ssl sysfs tcpd threads unicode urandom vim-syntax xorg zlib" ALSA_CARDS="ali5451 als4000 atiixp atiixp-modem bt87x ca0106 cmipci emu10k1x ens1370 ens1371 es1938 es1968 fm801 hda-intel intel8x0 intel8x0m maestro3 trident usb-audio via82xx via82xx-modem ymfpci" ALSA_PCM_PLUGINS="adpcm alaw asym copy dmix dshare dsnoop empty extplug file hooks iec958 ioplug ladspa lfloat linear meter mmap_emul mulaw multi null plug rate route share shm softvol" APACHE2_MODULES="actions alias auth_basic authn_alias authn_anon authn_dbm authn_default authn_file authz_dbm authz_default authz_groupfile authz_host authz_owner authz_user autoindex cache dav dav_fs dav_lock deflate dir disk_cache env expires ext_filter file_cache filter headers include info log_config logio mem_cache mime mime_magic negotiation setenvif speling status unique_id userdir usertrack vhost_alias" APACHE2_MPMS="prefork" CALLIGRA_FEATURES="kexi words flow plan stage tables krita karbon braindump" CAMERAS="ptp2" COLLECTD_PLUGINS="df interface irq load memory rrdtool swap syslog" ELIBC="glibc" GPSD_PROTOCOLS="ashtech aivdm earthmate evermore fv18 garmin garmintxt gpsclock itrax mtk3301 nmea ntrip navcom oceanserver oldstyle oncore rtcm104v2 rtcm104v3 sirf superstar2 timing tsip tripmate tnt ubx" INPUT_DEVICES="keyboard mouse evdev" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" LINGUAS="fr" NGINX_MODULES_HTTP="access autoindex browser charset empty_gif fastcgi geo geoip gzip headers_more proxy referer rewrite scgi secure_link stub_status sub" PHP_TARGETS="php5-3" RUBY_TARGETS="ruby18" USERLAND="GNU" VIDEO_CARDS="fbdev glint intel mach64 mga neomagic nouveau nv r128 radeon savage sis tdfx trident vesa via vmware dummy v4l" XTABLES_ADDONS="geoip gradm ipp2p ipset pknock"
Unset:  CPPFLAGS, CTARGET, EMERGE_DEFAULT_OPTS, INSTALL_MASK, LC_ALL, PORTAGE_BUNZIP2_COMMAND, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS

I have done rlpkg -a, but the log persists.
Currently I am in strict mode permissive.

Sorry to have not respond earlier.
Comment 6 Sven Vermeulen (RETIRED) gentoo-dev 2012-02-06 20:43:00 UTC
Yup, confirmed. Will be fixed in selinux-dhcp-2.20110726-r2.

I did notice that /etc/init.d/dhcp is trying to create /var/{run,lib}/dhcp and set it with the correct owner. I haven't fixed that as it is a one-time thing (which the system administrator can easily do himself). I could allow it by policy, but that would give some additional rights to initrc_t which I am trying to keep sufficiently low (it is already quite a privileged domain, rather not extend it even further if it isn't necessary).
Comment 7 Sven Vermeulen (RETIRED) gentoo-dev 2012-02-20 18:01:02 UTC
In hardened-dev overlay
Comment 8 Sven Vermeulen (RETIRED) gentoo-dev 2012-02-23 18:20:34 UTC
In main tree, ~arch'ed
Comment 9 Sven Vermeulen (RETIRED) gentoo-dev 2012-03-06 20:42:48 UTC
The call to corenet_udp_bind_generic_port isn't correct (anymore). If anything, it would need corenet_udp_bind_all_unreserved_ports. But even without giving this, I am able to succesfully start DHCP. Usually. There are a few tries that fail for an unidentified reason, but generally it seems to work well.
Comment 10 Sven Vermeulen (RETIRED) gentoo-dev 2012-03-06 20:51:44 UTC
Found the culprit...

The name_bind on the UDP is used by BIND to scan for interfaces (see dhcpd-4.2.3-P1/common/discover.c::begin_iface_scan):

        ifaces->sock = socket(local_family, SOCK_DGRAM, IPPROTO_UDP);
        if (ioctl(ifaces->sock, SIOCGLIFNUM, &lifnum) < 0) {
                log_error("Error finding total number of interfaces; %m");
                close(ifaces->sock);
                ifaces->sock = -1;
                return 0;
        }

Previously (pre-20120215 policy) these ports were labeled port_t, now they are unreserved_port_t.
Comment 11 Sven Vermeulen (RETIRED) gentoo-dev 2012-03-06 21:00:37 UTC
Fix will be in the 20120215 series as well now (starting from rev 5). Fix in 20110726 series should be okay.
Comment 12 Veovis 2012-03-07 09:06:24 UTC
I have tested =sec-policy/selinux-base-policy-2.20110726-r13 on a similar machine (amd64 hardened selinux permissive)

The problem I've reported about dhcpd.conf reading is gone, thanks !

It remains the last one you just mentioned:
# dmesg | grep audit | grep dhcpd
546:type=1400 audit(1331074860.059:9): avc:  denied  { name_bind } for  pid=1763 comm="dhcpd" src=63616 scontext=system_u:system_r:dhcpd_t tcontext=system_u:object_r:port_t tclass=udp_socket

I don't know why yet neither understand your post, but I observed that:
illidan ~ # netstat -nlp| grep dhcpd
5:udp        0      0 0.0.0.0:51661           0.0.0.0:*                           1775/dhcpd
6:udp        0      0 0.0.0.0:67              0.0.0.0:*                           1775/dhcpd
7:udp6       0      0 :::63616                :::*                                1775/dhcpd
8:raw        0      0 0.0.0.0:1               0.0.0.0:*               7           1775/dhcpd

I'm OK for the raw binding, and udp port 67, but I'm not with other connexions (udp port 51661 and udp6 port 63616)

About the creation of /var/{run,lib}/dhcp, maybe this should be handle by ebuild ??, On the first start, I got /var/lib/dhcp wrongly tagged in permissive mode). I will re-test this last point...
Comment 13 Veovis 2012-03-07 09:25:05 UTC
About the creation of /var/lib/dhcp by the init:

illidan ~ # rm -R /var/lib/dhcp
illidan ~ # /etc/init.d/dhcpd start
Authenticating root.
Password:
 * /var/lib/dhcp: creating directory
 * /var/lib/dhcp/dhcpd.leases: creating file
 * checkpath: correcting mode
 * Starting dhcpd ...                                    [ ok ]
illidan ~ # ls -Zla /var/lib/dhcp/
total 28K
drwxr-xr-x.  2 root root system_u:object_r:var_lib_t 4,0K  7 mars  10:20 .
drwxr-xr-x. 16 root root system_u:object_r:var_lib_t 4,0K  7 mars  10:20 ..
-rw-r--r--.  1 dhcp dhcp system_u:object_r:var_lib_t  208  7 mars  10:20 dhcpd.leases
-rw-rw-r--.  1 dhcp dhcp system_u:object_r:var_lib_t    0  7 mars  10:20 dhcpd.leases~
illidan ~ # restorecon -R /var/lib/dhcp
illidan ~ # ls -Zla /var/lib/dhcp/
total 28K
drwxr-xr-x.  2 root root system_u:object_r:dhcp_state_t  4,0K  7 mars  10:20 .
drwxr-xr-x. 16 root root system_u:object_r:var_lib_t     4,0K  7 mars  10:20 ..
-rw-r--r--.  1 dhcp dhcp system_u:object_r:dhcpd_state_t  208  7 mars  10:20 dhcpd.leases
-rw-rw-r--.  1 dhcp dhcp system_u:object_r:dhcpd_state_t    0  7 mars  10:20 dhcpd.leases~


I confirms this folder does not have the right label when created by the init script
Comment 14 Sven Vermeulen (RETIRED) gentoo-dev 2012-03-07 22:06:45 UTC
I consider it bad practice that the init script creates the directories. The ebuild should create them and already with the proper privileges.

If you create the directories once (and with proper ownership & run a restorecon against them) then you'll never see the issue anymore.

Regarding the UDP socket binds, from what I quickly gather, it is because you don't instruct dhcpd to bind to a particular interface. For some reason, it then opens UDP sockets (on random, unreserved ports) to capture a list of interfaces to work on/with.
Comment 15 Sven Vermeulen (RETIRED) gentoo-dev 2012-03-22 19:24:55 UTC
In hardened-dev overlay
Comment 16 Sven Vermeulen (RETIRED) gentoo-dev 2012-03-31 12:44:48 UTC
In main tree, ~arch'ed
Comment 17 Sven Vermeulen (RETIRED) gentoo-dev 2012-04-29 15:15:45 UTC
Stable