diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile index 912168cfc..8e3f39276 100644 --- a/test/zdtm/static/Makefile +++ b/test/zdtm/static/Makefile @@ -210,6 +210,7 @@ TST_NOFILE := \ config_inotify_irmap \ thp_disable \ pid_file \ + selinux00 \ # jobctl00 \ ifneq ($(SRCARCH),arm) diff --git a/test/zdtm/static/selinux00.c b/test/zdtm/static/selinux00.c new file mode 100644 index 000000000..dd9096a6f --- /dev/null +++ b/test/zdtm/static/selinux00.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "zdtmtst.h" + +/* Enabling the right policy happens in selinux00.hook and selinx00.checkskip */ + +const char *test_doc = "Check that a SELinux profile is restored"; +const char *test_author = "Adrian Reber "; + +/* This is all based on Tycho's apparmor code */ + +#define CONTEXT "unconfined_u:unconfined_r:unconfined_dbusd_t:s0" + +/* + * This is used to store the state of SELinux. For this test + * SELinux is switched to permissive mode and later the previous + * SELinux state is restored. + */ +char state; + +int check_for_selinux() +{ + if (access("/sys/fs/selinux", F_OK) == 0) + return 0; + return 1; +} + +int setprofile() +{ + int fd, len; + + fd = open("/proc/self/attr/current", O_WRONLY); + if (fd < 0) { + fail("Could not open /proc/self/attr/current\n"); + return -1; + } + + len = write(fd, CONTEXT, strlen(CONTEXT)); + close(fd); + + if (len < 0) { + fail("Could not write context\n"); + return -1; + } + + return 0; +} + +int checkprofile() +{ + int fd; + char context[1024]; + int len; + + + fd = open("/proc/self/attr/current", O_RDONLY); + if (fd < 0) { + fail("Could not open /proc/self/attr/current\n"); + return -1; + } + + len = read(fd, context, strlen(CONTEXT)); + close(fd); + if (len != strlen(CONTEXT)) { + fail("SELinux context has unexpected length %d, expected %zd\n", + len, strlen(CONTEXT)); + return -1; + } + + if (strncmp(context, CONTEXT, strlen(CONTEXT)) != 0) { + fail("Wrong SELinux context %s expected %s\n", context, CONTEXT); + return -1; + } + + return 0; +} + +int main(int argc, char **argv) +{ + test_init(argc, argv); + + if (check_for_selinux()) { + skip("SELinux not found on this system."); + test_daemon(); + test_waitsig(); + pass(); + return 0; + } + + if (setprofile()) + return -1; + + test_daemon(); + test_waitsig(); + + if (checkprofile() == 0) + pass(); + + return 0; +} diff --git a/test/zdtm/static/selinux00.checkskip b/test/zdtm/static/selinux00.checkskip new file mode 100755 index 000000000..8d946a75e --- /dev/null +++ b/test/zdtm/static/selinux00.checkskip @@ -0,0 +1,25 @@ +#!/bin/bash + +test -d /sys/fs/selinux || exit 1 + +# See selinux00.hook for details + +getsebool unconfined_dyntrans_all > /dev/null 2>&1 +RESULT=$? +BOOLEAN=0 + +if [ "$RESULT" = "0" ]; then + BOOLEAN=1 +fi + +if [ "$BOOLEAN" = "1" ]; then + getsebool unconfined_dyntrans_all | grep off -q + RESULT=$? + echo $RESULT > /tmp/zdtm.selinux.state + if [ "$RESULT" = "0" ]; then + setsebool -P unconfined_dyntrans_all 1 + fi +else + cat /sys/fs/selinux/enforce > /tmp/zdtm.selinux.state + setenforce 0 +fi diff --git a/test/zdtm/static/selinux00.desc b/test/zdtm/static/selinux00.desc new file mode 100644 index 000000000..63df42aa6 --- /dev/null +++ b/test/zdtm/static/selinux00.desc @@ -0,0 +1 @@ +{'flavor': 'h'} diff --git a/test/zdtm/static/selinux00.hook b/test/zdtm/static/selinux00.hook new file mode 100755 index 000000000..300766e1f --- /dev/null +++ b/test/zdtm/static/selinux00.hook @@ -0,0 +1,32 @@ +#!/bin/sh + +# This script configures SELinux in such a way to enable the +# test 'selinux00' to be able to dyntransition from one +# SELinux context to another, as well as CRIU to change the +# context of a restored process. +# If a new enough selinux-policy is installed which includes +# https://github.com/fedora-selinux/selinux-policy/commit/2d537cabbb2df614ea598ac20873c653cbf271a8 +# then the boolean 'unconfined_dyntrans_all' will be changed +# to enable this test. If that boolean is not available, +# this just does 'setenforce 0'. + +# also see selinux00.checkskip + +getsebool unconfined_dyntrans_all > /dev/null 2>&1 +RESULT=$? +BOOLEAN=0 + +if [ "$RESULT" = "0" ]; then + BOOLEAN=1 +fi + +[ "$1" = "--post-restore" ] && { + if [ "$BOOLEAN" = "1" ]; then + setsebool -P unconfined_dyntrans_all `cat /tmp/zdtm.selinux.state` + else + setenforce `cat /tmp/zdtm.selinux.state` + rm -f /tmp/zdtm.selinux.state + fi +} + +exit 0