Skip to content

Commit

Permalink
test: add selinux00 test
Browse files Browse the repository at this point in the history
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:

fedora-selinux/selinux-policy@2d537ca

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 <areber@redhat.com>
  • Loading branch information
adrianreber authored and avagin committed Mar 23, 2019
1 parent 8eb4309 commit 26e165e
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/zdtm/static/Makefile
Expand Up @@ -210,6 +210,7 @@ TST_NOFILE := \
config_inotify_irmap \
thp_disable \
pid_file \
selinux00 \
# jobctl00 \
ifneq ($(SRCARCH),arm)
Expand Down
108 changes: 108 additions & 0 deletions test/zdtm/static/selinux00.c
@@ -0,0 +1,108 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <linux/limits.h>
#include <signal.h>
#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 <areber@redhat.com>";

/* 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;
}
25 changes: 25 additions & 0 deletions 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
1 change: 1 addition & 0 deletions test/zdtm/static/selinux00.desc
@@ -0,0 +1 @@
{'flavor': 'h'}
32 changes: 32 additions & 0 deletions 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

0 comments on commit 26e165e

Please sign in to comment.