From 2844b95f67aae4c9867fc307d4996373d9a6bb8e Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Fri, 22 Mar 2019 07:55:18 +0000 Subject: [PATCH] test: add selinux00 test This tests if CRIU can restore a process with the same policy as during checkpointing. The test selinux00 is started and if SELinux is available the test process moves itself to another process context. To make this possible either a new SELinux policy needs to be available containing: https://github.com/fedora-selinux/selinux-policy/commit/2d537cabbb2df614ea598ac20873c653cbf271a8 Or for a short time SELinux is switched to permissive mode. The correct SELinux setup is done by zdtm/static/selinux00.checkskip and zdtm/static/selinux00.hook and after the test the previous SELinux policy state is restored. After the test case is restored the test case checks if it still has the same SELinux process context as before. If not the test cases fails. Signed-off-by: Adrian Reber --- test/zdtm/static/Makefile | 1 + test/zdtm/static/selinux00.c | 108 +++++++++++++++++++++++++++ test/zdtm/static/selinux00.checkskip | 25 +++++++ test/zdtm/static/selinux00.desc | 1 + test/zdtm/static/selinux00.hook | 32 ++++++++ 5 files changed, 167 insertions(+) create mode 100644 test/zdtm/static/selinux00.c create mode 100755 test/zdtm/static/selinux00.checkskip create mode 100644 test/zdtm/static/selinux00.desc create mode 100755 test/zdtm/static/selinux00.hook 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