ifplugd, udev, Raspbian and SELinux

Please specify version of Debian

Moderator: xeont

ifplugd, udev, Raspbian and SELinux

Postby sdoba » Sat Sep 05, 2015 5:20 am

Hello!

I've recently enabled SELinux on my RaspberryPi and recieved some AVCs denials.

I'm reading SEL documentation and have resolved a few of them. But I'm not sure if I did it right. So please review the first decision.

AVC:
Code: Select all
type=AVC msg=audit(1441426438.990:26): avc:  denied  { read write } for  pid=2176 comm="ifplugd" name="ifplugd.eth0.pid" dev="tmpfs" ino=6593 scontext=system_u:system_r:ifplugd_t:s0 tcontext=system_u:object_r:udev_var_run_t:s0 tclass=file permissive=1
type=AVC msg=audit(1441426438.990:27): avc:  denied  { open } for  pid=2176 comm="ifplugd" path="/run/ifplugd.eth0.pid" dev="tmpfs" ino=6593 scontext=system_u:system_r:ifplugd_t:s0 tcontext=system_u:object_r:udev_var_run_t:s0 tclass=file permissive=1
type=AVC msg=audit(1441426438.990:28): avc:  denied  { lock } for  pid=2176 comm="ifplugd" path="/run/ifplugd.eth0.pid" dev="tmpfs" ino=6593 scontext=system_u:system_r:ifplugd_t:s0 tcontext=system_u:object_r:udev_var_run_t:s0 tclass=file permissive=1
type=AVC msg=audit(1441426438.990:29): avc:  denied  { signull } for  pid=2176 comm="ifplugd" scontext=system_u:system_r:ifplugd_t:s0 tcontext=system_u:system_r:udev_t:s0-s0:c0.c1023 tclass=process permissive=1

While system boot up, udev executes script /lib/udev/ifplugd.agent where it starts ifplugd deamon.
Code: Select all
#!/bin/sh
# udev agent script

HOTPLUGFUNCS=/lib/udev/hotplug.functions
[ -f $HOTPLUGFUNCS ] || exit 1
. $HOTPLUGFUNCS

if [ -z "$INTERFACE" ]; then
    mesg Bad invocation: \$INTERFACE is not set
    exit 1
fi

DAEMON_NAME=ifplugd
DAEMON=/usr/sbin/$DAEMON_NAME
if [ ! -x $DAEMON ]; then
    mesg No $DAEMON_NAME executable: $DAEMON
    exit 1
fi

CFG=/etc/default/$DAEMON_NAME
if [ -f $CFG ]; then
    . $CFG
else
    mesg No $DAEMON_NAME configuration file
    exit 1
fi

# return true (0) if searchifc ($1) is in argument list ($@)
# return false (1) otherwise
search_interfaces () {
    searchifc=$1
    shift

    for i in $@; do
        if [ "$i" = "$searchifc" ] || [ "$i" = "all" ]; then
            return 0
        fi
    done

    return 1
}

# wait for networking to be available, taken from net.agent (ifupdown)
wait_for_interface () {
    waitifc=$1

    while :; do
        ifcstate="$(cat /sys/class/net/${waitifc}/operstate 2>/dev/null || true)"
        if [ "$ifcstate" != down ]; then
                return 0
        fi
        sleep 1
    done
}
ifplugd_daemon () {
    search_interfaces "$INTERFACE" $INTERFACES
    if [ $? -gt 0 ]; then
        # Interface isn't statically managed by ifplugd
        search_interfaces "$INTERFACE" $HOTPLUG_INTERFACES
        if [ $? -eq 0 ]; then
            # Interface is in hotplug allowed list
            case "$ACTION" in
            add|register)
                debug_mesg Invoking $DAEMON_NAME for $INTERFACE

                # check for interface specific arguments
                IF1=$(echo $INTERFACE | sed "s/-/_/")
                A=$(eval echo \$\{ARGS_${IF1}\})
                [ -z "$A" ] && A="$ARGS"

                # wait for loopback interface to exist, we may have
                # been invoked very early in boot sequence
                wait_for_interface lo

                # spawn ifplugd daemon
                exec $DAEMON -i $INTERFACE $A
                ;;
            remove|unregister)
                debug_mesg Stopping $DAEMON_NAME for $INTERFACE

                # kill a running ifplugd daemon
                exec $DAEMON -k -i $INTERFACE
                ;;
            esac
        fi
    fi
}

ifplugd_daemon &

When ifplugd starts, it creates files /var/run/ifplugd.<interface>.pid (/var/run is a symlink to /run). But the script /lib/udev/ifplugd.agent is running in udev_t SEL domain. So the resulting file have wrong context:
Code: Select all
$ ls -lZ /run/ifplugd.eth0.pid
-rw-r--r--. 1 root root system_u:object_r:udev_var_run_t:s0 5 Sep  5 07:13 /run/ifplugd.eth0.pid

The right context should be:
system_u:object_r:ifplugd_var_run_t:s0

I've decided that udev should have permission for domain transition when it runs ifplugd. So I've created a policy:
Code: Select all
module rpi-ifplugd 1.0.0;
require {
   type ifplugd_t;
   type udev_t;
   type ifplugd_exec_t;
   class process transition;
}
type_transition udev_t ifplugd_exec_t : process ifplugd_t;

And it worked!
Code: Select all
$ ls -lZ /run/ifplugd.eth0.pid
-rw-r--r--. 1 root root system_u:object_r:ifplugd_var_run_t:s0 5 Sep  5 08:09 /run/ifplugd.eth0.pid

But I don't know if this decision is good. Please leave a comment. Thanks! :)
sdoba
 
Posts: 1
Joined: Thu Sep 03, 2015 7:17 pm

Re: ifplugd, udev, Raspbian and SELinux

Postby doverride » Thu Mar 17, 2016 3:32 pm

Looks fine to me
doverride
 
Posts: 5
Joined: Thu Mar 17, 2016 11:39 am


Return to SElinux for Debian

Who is online

Users browsing this forum: No registered users and 1 guest
cron