diff --git a/.gitignore b/.gitignore index 745b739..0f580f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,8 @@ -SOURCES/libselinux-2.9.tar.gz +/libselinux-2.7.tar.gz +/libselinux-2.8-rc1.tar.gz +/libselinux-2.8-rc2.tar.gz +/libselinux-2.8-rc3.tar.gz +/libselinux-2.8.tar.gz +/libselinux-2.9-rc1.tar.gz +/libselinux-2.9-rc2.tar.gz /libselinux-2.9.tar.gz diff --git a/STAGE1-libselinux b/STAGE1-libselinux new file mode 100644 index 0000000..6887de7 --- /dev/null +++ b/STAGE1-libselinux @@ -0,0 +1,24 @@ +# TLSFLAGS are set in order to avoid a bogus check in +# libselinux/src/Makefile. +srpm libselinux +mcd $BUILDDIR/t-libselinux +rsync -av $SRC/libselinux*/ ./ +# libselinux uses $prefix/include for both -I and *.pc, which +# prevents cross compiling. +sed 's@-I$(INCLUDEDIR)@@' < src/Makefile > src/Makefile.stage1 +mv src/Makefile.stage1 src/Makefile +make $J \ + CC=${TARGET}-gcc \ + AS=${TARGET}-as \ + AR=${TARGET}-ar \ + STRIP=${TARGET}-strip \ + RANLIB=${TARGET}-ranlib \ + CFLAGS="" \ + TLSFLAGS="" \ + all +ARGS="DESTDIR=${ROOTFS}" +if [ "$SUFFIX" = "64" ] +then + ARGS="$ARGS LIBDIR=${ROOTFS}/usr/lib64 SHLIBDIR=${ROOTFS}/usr/lib64" +fi +make $J $ARGS install diff --git a/libselinux-fedora.patch b/libselinux-fedora.patch new file mode 100644 index 0000000..7ab572a --- /dev/null +++ b/libselinux-fedora.patch @@ -0,0 +1,279 @@ +diff --git libselinux-2.9/include/selinux/av_permissions.h libselinux-2.9/include/selinux/av_permissions.h +index c1269af..631f027 100644 +--- libselinux-2.9/include/selinux/av_permissions.h ++++ libselinux-2.9/include/selinux/av_permissions.h +@@ -876,6 +876,8 @@ + #define NSCD__SHMEMHOST 0x00000080UL + #define NSCD__GETSERV 0x00000100UL + #define NSCD__SHMEMSERV 0x00000200UL ++#define NSCD__GETNETGRP 0x00000400UL ++#define NSCD__SHMEMNETGRP 0x00000800UL + #define ASSOCIATION__SENDTO 0x00000001UL + #define ASSOCIATION__RECVFROM 0x00000002UL + #define ASSOCIATION__SETCONTEXT 0x00000004UL +diff --git libselinux-2.9/man/man8/selinux.8 libselinux-2.9/man/man8/selinux.8 +index e37aee6..bf23b65 100644 +--- libselinux-2.9/man/man8/selinux.8 ++++ libselinux-2.9/man/man8/selinux.8 +@@ -91,11 +91,13 @@ This manual page was written by Dan Walsh . + .BR sepolicy (8), + .BR system-config-selinux (8), + .BR togglesebool (8), +-.BR restorecon (8), + .BR fixfiles (8), ++.BR restorecon (8), + .BR setfiles (8), + .BR semanage (8), + .BR sepolicy (8) ++.BR seinfo (8), ++.BR sesearch (8) + + Every confined service on the system has a man page in the following format: + .br +diff --git libselinux-2.9/src/avc_sidtab.c libselinux-2.9/src/avc_sidtab.c +index 9669264..c775430 100644 +--- libselinux-2.9/src/avc_sidtab.c ++++ libselinux-2.9/src/avc_sidtab.c +@@ -81,6 +81,11 @@ sidtab_context_to_sid(struct sidtab *s, + int hvalue, rc = 0; + struct sidtab_node *cur; + ++ if (! ctx) { ++ errno=EINVAL; ++ return -1; ++ } ++ + *sid = NULL; + hvalue = sidtab_hash(ctx); + +diff --git libselinux-2.9/src/canonicalize_context.c libselinux-2.9/src/canonicalize_context.c +index ba4c9a2..c815872 100644 +--- libselinux-2.9/src/canonicalize_context.c ++++ libselinux-2.9/src/canonicalize_context.c +@@ -17,6 +17,11 @@ int security_canonicalize_context_raw(const char * con, + size_t size; + int fd, ret; + ++ if (! con) { ++ errno=EINVAL; ++ return -1; ++ } ++ + if (!selinux_mnt) { + errno = ENOENT; + return -1; +diff --git libselinux-2.9/src/check_context.c libselinux-2.9/src/check_context.c +index 8a7997f..5be8434 100644 +--- libselinux-2.9/src/check_context.c ++++ libselinux-2.9/src/check_context.c +@@ -14,6 +14,11 @@ int security_check_context_raw(const char * con) + char path[PATH_MAX]; + int fd, ret; + ++ if (! con) { ++ errno=EINVAL; ++ return -1; ++ } ++ + if (!selinux_mnt) { + errno = ENOENT; + return -1; +diff --git libselinux-2.9/src/compute_av.c libselinux-2.9/src/compute_av.c +index a47cffe..6d285a2 100644 +--- libselinux-2.9/src/compute_av.c ++++ libselinux-2.9/src/compute_av.c +@@ -27,6 +27,11 @@ int security_compute_av_flags_raw(const char * scon, + return -1; + } + ++ if ((! scon) || (! tcon)) { ++ errno=EINVAL; ++ return -1; ++ } ++ + snprintf(path, sizeof path, "%s/access", selinux_mnt); + fd = open(path, O_RDWR | O_CLOEXEC); + if (fd < 0) +diff --git libselinux-2.9/src/compute_create.c libselinux-2.9/src/compute_create.c +index 0975aea..3e6a48c 100644 +--- libselinux-2.9/src/compute_create.c ++++ libselinux-2.9/src/compute_create.c +@@ -64,6 +64,11 @@ int security_compute_create_name_raw(const char * scon, + return -1; + } + ++ if ((! scon) || (! tcon)) { ++ errno=EINVAL; ++ return -1; ++ } ++ + snprintf(path, sizeof path, "%s/create", selinux_mnt); + fd = open(path, O_RDWR | O_CLOEXEC); + if (fd < 0) +diff --git libselinux-2.9/src/compute_member.c libselinux-2.9/src/compute_member.c +index 4e2d221..d1dd977 100644 +--- libselinux-2.9/src/compute_member.c ++++ libselinux-2.9/src/compute_member.c +@@ -25,6 +25,11 @@ int security_compute_member_raw(const char * scon, + return -1; + } + ++ if ((! scon) || (! tcon)) { ++ errno=EINVAL; ++ return -1; ++ } ++ + snprintf(path, sizeof path, "%s/member", selinux_mnt); + fd = open(path, O_RDWR | O_CLOEXEC); + if (fd < 0) +diff --git libselinux-2.9/src/compute_relabel.c libselinux-2.9/src/compute_relabel.c +index 49f77ef..c3db7c0 100644 +--- libselinux-2.9/src/compute_relabel.c ++++ libselinux-2.9/src/compute_relabel.c +@@ -25,6 +25,11 @@ int security_compute_relabel_raw(const char * scon, + return -1; + } + ++ if ((! scon) || (! tcon)) { ++ errno=EINVAL; ++ return -1; ++ } ++ + snprintf(path, sizeof path, "%s/relabel", selinux_mnt); + fd = open(path, O_RDWR | O_CLOEXEC); + if (fd < 0) +diff --git libselinux-2.9/src/compute_user.c libselinux-2.9/src/compute_user.c +index 7b88121..401fd10 100644 +--- libselinux-2.9/src/compute_user.c ++++ libselinux-2.9/src/compute_user.c +@@ -24,6 +24,11 @@ int security_compute_user_raw(const char * scon, + return -1; + } + ++ if (! scon) { ++ errno=EINVAL; ++ return -1; ++ } ++ + snprintf(path, sizeof path, "%s/user", selinux_mnt); + fd = open(path, O_RDWR | O_CLOEXEC); + if (fd < 0) +diff --git libselinux-2.9/src/fsetfilecon.c libselinux-2.9/src/fsetfilecon.c +index 52707d0..0cbe12d 100644 +--- libselinux-2.9/src/fsetfilecon.c ++++ libselinux-2.9/src/fsetfilecon.c +@@ -9,8 +9,12 @@ + + int fsetfilecon_raw(int fd, const char * context) + { +- int rc = fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, +- 0); ++ int rc; ++ if (! context) { ++ errno=EINVAL; ++ return -1; ++ } ++ rc = fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0); + if (rc < 0 && errno == ENOTSUP) { + char * ccontext = NULL; + int err = errno; +diff --git libselinux-2.9/src/lsetfilecon.c libselinux-2.9/src/lsetfilecon.c +index 1d3b28a..ea6d70b 100644 +--- libselinux-2.9/src/lsetfilecon.c ++++ libselinux-2.9/src/lsetfilecon.c +@@ -9,8 +9,13 @@ + + int lsetfilecon_raw(const char *path, const char * context) + { +- int rc = lsetxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1, +- 0); ++ int rc; ++ if (! context) { ++ errno=EINVAL; ++ return -1; ++ } ++ ++ rc = lsetxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0); + if (rc < 0 && errno == ENOTSUP) { + char * ccontext = NULL; + int err = errno; +diff --git libselinux-2.9/src/procattr.c libselinux-2.9/src/procattr.c +index c6799ef..cbb6824 100644 +--- libselinux-2.9/src/procattr.c ++++ libselinux-2.9/src/procattr.c +@@ -24,6 +24,7 @@ static __thread char destructor_initialized; + + /* Bionic and glibc >= 2.30 declare gettid() system call wrapper in unistd.h and + * has a definition for it */ ++#ifndef OVERRIDE_GETTID + #ifdef __BIONIC__ + #define OVERRIDE_GETTID 0 + #elif !defined(__GLIBC_PREREQ) +@@ -33,6 +34,7 @@ static __thread char destructor_initialized; + #else + #define OVERRIDE_GETTID 0 + #endif ++#endif + + #if OVERRIDE_GETTID + static pid_t gettid(void) +diff --git libselinux-2.9/src/selinuxswig.i libselinux-2.9/src/selinuxswig.i +index dbdb4c3..9c5b926 100644 +--- libselinux-2.9/src/selinuxswig.i ++++ libselinux-2.9/src/selinuxswig.i +@@ -5,7 +5,9 @@ + %module selinux + %{ + #include "../include/selinux/avc.h" ++ #include "../include/selinux/av_permissions.h" + #include "../include/selinux/context.h" ++ #include "../include/selinux/flask.h" + #include "../include/selinux/get_context_list.h" + #include "../include/selinux/get_default_type.h" + #include "../include/selinux/label.h" +@@ -58,7 +60,9 @@ + %ignore avc_netlink_check_nb; + + %include "../include/selinux/avc.h" ++%include "../include/selinux/av_permissions.h" + %include "../include/selinux/context.h" ++%include "../include/selinux/flask.h" + %include "../include/selinux/get_context_list.h" + %include "../include/selinux/get_default_type.h" + %include "../include/selinux/label.h" +diff --git libselinux-2.9/src/selinuxswig_python.i libselinux-2.9/src/selinuxswig_python.i +index 4c73bf9..6eaab08 100644 +--- libselinux-2.9/src/selinuxswig_python.i ++++ libselinux-2.9/src/selinuxswig_python.i +@@ -1,10 +1,11 @@ + /* Author: James Athey + */ + +-/* Never build rpm_execcon interface */ ++/* Never build rpm_execcon interface unless you need to have ACG compatibility + #ifndef DISABLE_RPM + #define DISABLE_RPM + #endif ++*/ + + %module selinux + %{ +diff --git libselinux-2.9/src/setfilecon.c libselinux-2.9/src/setfilecon.c +index d05969c..3f0200e 100644 +--- libselinux-2.9/src/setfilecon.c ++++ libselinux-2.9/src/setfilecon.c +@@ -9,8 +9,12 @@ + + int setfilecon_raw(const char *path, const char * context) + { +- int rc = setxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1, +- 0); ++ int rc; ++ if (! context) { ++ errno=EINVAL; ++ return -1; ++ } ++ rc = setxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0); + if (rc < 0 && errno == ENOTSUP) { + char * ccontext = NULL; + int err = errno; diff --git a/rubytest.rb b/rubytest.rb new file mode 100644 index 0000000..b586e31 --- /dev/null +++ b/rubytest.rb @@ -0,0 +1,6 @@ +require 'selinux' +print "selinux\n" +print "Is selinux enabled? " + Selinux.is_selinux_enabled().to_s + "\n" +print "Is selinux enforce? " + Selinux.security_getenforce().to_s + "\n" +print "Setfscreatecon? " + Selinux.setfscreatecon("system_u:object_r:etc_t:s0").to_s + "\n" +print "/etc -> " + Selinux.matchpathcon("/etc", 0)[1] + "\n" diff --git a/tests/getsebool/Makefile b/tests/getsebool/Makefile new file mode 100644 index 0000000..6dc11d4 --- /dev/null +++ b/tests/getsebool/Makefile @@ -0,0 +1,64 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/libselinux/Sanity/getsebool +# Description: Does getsebool work as expected? +# Author: Milos Malik +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2017 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/libselinux/Sanity/getsebool +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Milos Malik " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Does getsebool work as expected?" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 5m" >> $(METADATA) + @echo "RunFor: libselinux" >> $(METADATA) + @echo "Requires: libselinux" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "Releases: -RHEL4 -RHELClient5 -RHELServer5" >> $(METADATA) + + rhts-lint $(METADATA) + diff --git a/tests/getsebool/PURPOSE b/tests/getsebool/PURPOSE new file mode 100644 index 0000000..b6af3e4 --- /dev/null +++ b/tests/getsebool/PURPOSE @@ -0,0 +1,5 @@ +PURPOSE of /CoreOS/libselinux/Sanity/getsebool +Author: Milos Malik + +Does getsebool work as expected? + diff --git a/tests/getsebool/runtest.sh b/tests/getsebool/runtest.sh new file mode 100755 index 0000000..de64a6e --- /dev/null +++ b/tests/getsebool/runtest.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/libselinux/Sanity/getsebool +# Description: Does getsebool work as expected? +# Author: Milos Malik +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2017 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="libselinux" +if rlIsRHEL 5 6 ; then + SELINUX_FS_MOUNT="/selinux" +else # RHEL-7 and above + SELINUX_FS_MOUNT="/sys/fs/selinux" +fi + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm ${PACKAGE} + rlAssertRpm ${PACKAGE}-utils + rlRun "getsebool" 0,1 + OUTPUT_FILE=`mktemp` + rlPhaseEnd + + rlPhaseStartTest + rlRun "getsebool -a" + rlRun "umount ${SELINUX_FS_MOUNT}" + rlRun "getsebool -a 2>&1 | tee ${OUTPUT_FILE}" + rlAssertGrep "selinux.*disabled" ${OUTPUT_FILE} -i + rlRun "mount -t selinuxfs none ${SELINUX_FS_MOUNT}" + rlRun "mkdir booleans" + rlRun "mount --bind ./booleans ${SELINUX_FS_MOUNT}/booleans" + rlRun "getsebool -a 2>&1 | tee ${OUTPUT_FILE}" + rlAssertGrep "unable to get boolean name.*no such file or directory" ${OUTPUT_FILE} -i + rlRun "getsebool xen_use_nfs 2>&1 | tee ${OUTPUT_FILE}" + rlAssertGrep "error getting active value for" ${OUTPUT_FILE} -i + rlRun "umount ${SELINUX_FS_MOUNT}/booleans" + rlRun "rmdir booleans" + rlPhaseEnd + + rlPhaseStartCleanup + rm -f ${OUTPUT_FILE} + rlPhaseEnd +rlJournalPrintText +rlJournalEnd + diff --git a/tests/realpath_not_final-function/Makefile b/tests/realpath_not_final-function/Makefile new file mode 100644 index 0000000..b0af891 --- /dev/null +++ b/tests/realpath_not_final-function/Makefile @@ -0,0 +1,63 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/libselinux/Sanity/realpath_not_final-function +# Description: Test realpath_not_final function +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/libselinux/Sanity/realpath_not_final-function +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE test*.c + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Jan Zarsky " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Test realpath_not_final function" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 5m" >> $(METADATA) + @echo "RunFor: libselinux" >> $(METADATA) + @echo "Requires: libselinux libselinux-devel glibc gcc" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2+" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "Releases: -RHEL4 -RHELClient5 -RHELServer5 -RHEL6" >> $(METADATA) + + rhts-lint $(METADATA) diff --git a/tests/realpath_not_final-function/PURPOSE b/tests/realpath_not_final-function/PURPOSE new file mode 100644 index 0000000..8305d70 --- /dev/null +++ b/tests/realpath_not_final-function/PURPOSE @@ -0,0 +1,3 @@ +PURPOSE of /CoreOS/libselinux/Sanity/realpath_not_final-function +Description: Test realpath_not_final function +Author: Jan Zarsky diff --git a/tests/realpath_not_final-function/runtest.sh b/tests/realpath_not_final-function/runtest.sh new file mode 100755 index 0000000..e5e2476 --- /dev/null +++ b/tests/realpath_not_final-function/runtest.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/libselinux/Sanity/realpath_not_final-function +# Description: Test realpath_not_final function +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="libselinux" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm ${PACKAGE} + rlAssertRpm ${PACKAGE}-devel + rlAssertRpm "glibc" + rlAssertRpm "gcc" + + rlRun -l "gcc test.c -o test -lselinux -Wall -Wextra -std=c99" + rlPhaseEnd + + rlPhaseStartTest + # syntax: ./test name [resolved_path] + rlRun "./test NULL" 139 + rlRun "./test /somedir/somefile NULL" 255 + rlRun "./test NULL NULL" 139 + + rlRun "./test /tmp | tee output" + rlRun "grep 'realpath_not_final: /tmp' output" + + rlRun "./test //tmp | tee output" + rlRun "grep -E 'realpath_not_final: /tmp|realpath_not_final: //tmp' output" + + rlRun "./test ///tmp | tee output" + rlRun "grep -E 'realpath_not_final: /tmp|realpath_not_final: //tmp' output" + + rlRun "./test ////tmp | tee output" + rlRun "grep -E 'realpath_not_final: /tmp|realpath_not_final: //tmp' output" + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "rm -f test output" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd diff --git a/tests/realpath_not_final-function/test.c b/tests/realpath_not_final-function/test.c new file mode 100644 index 0000000..5833acd --- /dev/null +++ b/tests/realpath_not_final-function/test.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include + +int main (int argc, char **argv) { + if (argc < 2) { + printf("Invalid number of arguments\n"); + return -1; + } + + char *name; + + if (strcmp(argv[1], "NULL") == 0) { + name = NULL; + } + else { + name = argv[1]; + } + + char *resolved_path; + + if (argc == 3 && (strcmp(argv[1], "NULL") == 0)) { + resolved_path = NULL; + } + else { + resolved_path = malloc(PATH_MAX); + + if (resolved_path == NULL) { + printf("Error while allocating memory\n"); + } + } + + printf("Executing: realpath_not_final(%s, resolved_path)\n", name); + + int result = realpath_not_final(name, resolved_path); + + printf("realpath_not_final: %s\n", resolved_path); + + free(resolved_path); + return result; +} diff --git a/tests/selabel-functions/Makefile b/tests/selabel-functions/Makefile new file mode 100644 index 0000000..46112ef --- /dev/null +++ b/tests/selabel-functions/Makefile @@ -0,0 +1,63 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/libselinux/Sanity/selabel-functions +# Description: Test selabel functions +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/libselinux/Sanity/selabel-functions +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE test_*.c + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Jan Zarsky " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Test selabel functions" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 5m" >> $(METADATA) + @echo "RunFor: libselinux" >> $(METADATA) + @echo "Requires: libselinux libselinux-devel glibc gcc" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2+" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "Releases: -RHEL4 -RHELClient5 -RHELServer5" >> $(METADATA) + + rhts-lint $(METADATA) diff --git a/tests/selabel-functions/PURPOSE b/tests/selabel-functions/PURPOSE new file mode 100644 index 0000000..aa07643 --- /dev/null +++ b/tests/selabel-functions/PURPOSE @@ -0,0 +1,3 @@ +PURPOSE of /CoreOS/libselinux/Sanity/selabel-functions +Description: Test selabel functions +Author: Jan Zarsky diff --git a/tests/selabel-functions/runtest.sh b/tests/selabel-functions/runtest.sh new file mode 100755 index 0000000..64d593f --- /dev/null +++ b/tests/selabel-functions/runtest.sh @@ -0,0 +1,858 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/libselinux/Sanity/selabel-functions +# Description: Test selabel functions +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/bin/rhts-environment.sh || exit 1 +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="libselinux" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm ${PACKAGE} + rlAssertRpm ${PACKAGE}-devel + rlAssertRpm "glibc" + rlAssertRpm "gcc" + + if rlIsRHEL 6; then + rlRun -l "gcc test_open.c -o test_open -lselinux -Wall -Wextra -std=c99 -DRHEL6" + rlRun -l "gcc test_lookup.c -o test_lookup -lselinux -Wall -Wextra -std=c99 -DRHEL6" + rlRun -l "gcc test_stats.c -o test_stats -lselinux -Wall -Wextra -std=c99 -DRHEL6" + else + rlRun -l "gcc test_open.c -o test_open -lselinux -Wall -Wextra -std=c99" + rlRun -l "gcc test_lookup.c -o test_lookup -lselinux -Wall -Wextra -std=c99" + rlRun -l "gcc test_partial.c -o test_partial -lselinux -Wall -Wextra -std=c99" + rlRun -l "gcc test_best.c -o test_best -lselinux -Wall -Wextra -std=c99" + rlRun -l "gcc test_stats.c -o test_stats -lselinux -Wall -Wextra -std=c99" + rlRun -l "gcc test_digest.c -o test_digest -lselinux -Wall -Wextra -std=c99" + fi + + rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory" + rlPhaseEnd + + rlPhaseStartTest "selabel_open" + # syntax: ./test_open BACKEND OPT_PATH OPT_SUBSET OPT_VALIDATE OPT_BASEONLY [nopt] + + rlLogInfo "Normal run" + rlRun "./test_open CTX_FILE NULL NULL 0 0" + + rlLogInfo "Backends" + rlRun "./test_open CTX_MEDIA NULL NULL 0 0" 0 + rlRun "./test_open CTX_X NULL NULL 0 0" 0 + rlRun "./test_open CTX_DB NULL NULL 0 0" 0 + if rlIsRHEL "7" || rlIsFedora "<26"; then + rlRun "./test_open CTX_ANDROID_PROP NULL NULL 0 0" 0 + rlRun "./test_open 5 NULL NULL 0 0" 22 + fi + rlRun "./test_open 2147483647 NULL NULL 0 0" 22 + + rlLogInfo "Parameter nopt" + rlRun "./test_open CTX_FILE NULL NULL 0 0 2147483647" 22,139 + rlRun "./test_open CTX_MEDIA NULL NULL 0 0 2147483647" 22,139 + rlRun "./test_open CTX_X NULL NULL 0 0 2147483647" 22,139 + rlRun "./test_open CTX_DB NULL NULL 0 0 2147483647" 22,139 + if rlIsRHEL "7" || rlIsFedora "<26"; then + rlRun "./test_open CTX_ANDROID_PROP NULL NULL 0 0 2147483647" 22,139 + fi + + rlRun "./test_open CTX_FILE NULL NULL 0 0 1" + rlRun "./test_open CTX_MEDIA NULL NULL 0 0 1" + rlRun "./test_open CTX_X NULL NULL 0 0 1" + rlRun "./test_open CTX_DB NULL NULL 0 0 1" + if rlIsRHEL "7" || rlIsFedora "<26"; then + rlRun "./test_open CTX_ANDROID_PROP NULL NULL 0 0 1" + fi + + rlRun "./test_open CTX_FILE NULL NULL 0 0 0" + rlRun "./test_open CTX_MEDIA NULL NULL 0 0 0" + rlRun "./test_open CTX_X NULL NULL 0 0 0" + rlRun "./test_open CTX_DB NULL NULL 0 0 0" + if rlIsRHEL "7" || rlIsFedora "<26"; then + rlRun "./test_open CTX_ANDROID_PROP NULL NULL 0 0 0" + fi + + rlRun "./test_open CTX_FILE NULL NULL 0 0 -1" 22,139 + rlRun "./test_open CTX_MEDIA NULL NULL 0 0 -1" 22,139 + rlRun "./test_open CTX_X NULL NULL 0 0 -1" 22,139 + rlRun "./test_open CTX_DB NULL NULL 0 0 -1" 22,139 + if rlIsRHEL "7" || rlIsFedora "<26"; then + rlRun "./test_open CTX_ANDROID_PROP NULL NULL 0 0 -1" 22,139 + fi + + rlLogInfo "Path option" + rlRun "cat > $TmpDir/my_contexts < $TmpDir/my_contexts < >(tee output >&2)" 0 + rlRun "grep 'line' output" 1 + + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 0 + else + rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(tee output >&2)" 22 + fi + rlRun "grep 'line 1 is missing fields' output" + + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 0 + else + rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(tee output >&2)" 22 + fi + rlRun "grep 'line 1 has invalid context my_user_u:my_role_r:my_type_t:s0' output" + + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 0 + else + rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(tee output >&2)" 22 + fi + rlRun "grep 'line 1 has invalid file type invalid_file_type' output" + + rlRun "cat > $TmpDir/my_contexts <> +EOF" + rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(tee output >&2)" 0 + rlRun "grep 'line 1' output" 1 + + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 0 + rlRun "grep 'Multiple same specifications' output" 1 + + rlLogInfo "Two same rules for the same path" + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 22 + rlRun "grep 'Multiple same specifications' output" + + rlLogInfo "Two different rules for the same path" + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 22 + rlRun "grep 'Multiple different specifications' output" + + rlLogInfo "Two different rules for same path but with different file type" + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 0 + rlRun "grep 'Multiple different specifications' output" 1 + + rlLogInfo "Two different rules for same path one general and one with file type" + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 22 + rlRun "grep 'Multiple different specifications' output" + rlPhaseEnd + + if rlIsRHEL ">=7" || rlIsFedora; then + rlPhaseStartTest "file contexts files" + rlLogInfo "subs file" + rlRun "cat > $TmpDir/my_contexts < $TmpDir/my_contexts.subs < $TmpDir/my_contexts < $TmpDir/my_contexts.subs_dist < $TmpDir/my_contexts < $TmpDir/my_contexts.local < $TmpDir/my_contexts < $TmpDir/my_contexts.homedirs <>" + rlRun "./test_lookup CTX_FILE NULL NULL 0 0 /tmp/somefile 0 2> >(tee output >&2)" 2 \ + "Run selabel_lookup on file with default context <>" + rlRun "grep 'selabel_lookup - ERROR: No such file or directory' output" 0 + rlPhaseEnd + fi + + rlPhaseStartTest "media contexts files" + rlLogInfo "Valid entries" + rlRun "cat > $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < >(tee output >&2)" 2 + rlRun "grep 'selabel_lookup - ERROR: No such file or directory' output" + + rlLogInfo "Invalid entries" + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 2 + rlRun "grep 'line 1 is missing fields' output" + + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 22 + rlRun "grep 'has invalid context some_u:some_r:some_t:s0' output" + +# defaultContext=$(cat /etc/selinux/targeted/contexts/removable_context) + +# rlLogInfo "empty contexts file" +# rlRun "cat > $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < >(tee output >&2)" 2 + rlRun "grep 'line 1 is missing fields' output" + + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 2 + rlRun "grep 'line 1 is missing fields' output" + + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 2 + rlRun "grep 'line 1 has invalid object type some_property' output" + + rlLogInfo "Wildcard matching" + rlRun "cat > $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts <=7" || rlIsFedora; then + rlRun "cat >> $TmpDir/my_contexts <=7" || rlIsFedora; then + rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_language DB_LANGUAGE | tee output" 0 + rlRun "grep 'selabel_lookup context: system_u:object_r:sepgsql_lang_t:s0' output" + rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_exception DB_EXCEPTION | tee output" 0 + rlRun "grep 'selabel_lookup context: system_u:object_r:usr_t:s0' output" + rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_datatype DB_DATATYPE | tee output" 0 + rlRun "grep 'selabel_lookup context: system_u:object_r:bin_t:s0' output" + fi + + rlLogInfo "Comments and empty lines" + rlRun "cat > $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < >(tee output >&2)" 2 + rlRun "grep 'line 1 has invalid format' output" + + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 2 + rlRun "grep 'line 1 has invalid format' output" + + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 2 + rlRun "grep 'line 1 has invalid object type one' output" + + rlRun "cat > $TmpDir/my_contexts < >(tee output >&2)" 2 + rlRun "grep 'line 1 has invalid format' output" + + rlLogInfo "Normal run" + rlRun "./test_lookup CTX_DB NULL NULL 0 0 my_database DB_DATABASE | tee output" + rlRun "grep 'selabel_lookup context: system_u:object_r:sepgsql_db_t:s0' output" + rlRun "grep 'selabel_lookup_raw context: system_u:object_r:sepgsql_db_t:s0' output" + rlPhaseEnd + + if rlIsRHEL ">=7" || rlIsFedora; then + rlPhaseStartTest "baseonly option" + rlRun "cat > $TmpDir/my_contexts < $TmpDir/my_contexts.subs < $TmpDir/my_contexts.local < $TmpDir/my_contexts.homedirs < $TmpDir/my_contexts < $TmpDir/my_contexts <=7" || rlIsFedora; then + rlPhaseStartTest "selabel_partial_match" + # syntax: ./test_partial BACKEND OPT_PATH OPT_SUBSET OPT_VALIDATE OPT_BASEONLY path [nohandle] + + rlLogInfo "nonsupporting backends" + rlRun "./test_partial CTX_MEDIA NULL NULL 0 0 /somedir | tee output" 0 + rlRun "grep 'selabel_partial_match: true' output" 0 + rlRun "./test_partial CTX_DB NULL NULL 0 0 /somedir | tee output" 0 + rlRun "grep 'selabel_partial_match: true' output" 0 + rlRun "./test_partial CTX_X NULL NULL 0 0 /somedir | tee output" 0 + rlRun "grep 'selabel_partial_match: true' output" 0 + + rlLogInfo "null as handle" + rlRun "./test_partial CTX_FILE NULL NULL 0 0 /somedir nohandle" 22,139 + + rlLogInfo "nonexisting entry" + rlRun "cat > $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts <=7" || rlIsFedora; then + rlPhaseStartTest "selabel_best_match" + # syntax: ./test_best BACKEND OPT_PATH OPT_SUBSET OPT_VALIDATE OPT_BASEONLY path mode [nohandle] + + rlLogInfo "nonsupported backends" + rlRun "./test_best CTX_MEDIA NULL NULL 0 0 /somedir 0" 95 + rlRun "./test_best CTX_DB NULL NULL 0 0 /somedir 0" 95 + rlRun "./test_best CTX_X NULL NULL 0 0 /somedir 0" 95 + + rlLogInfo "null as handle" + rlRun "./test_best CTX_FILE NULL NULL 0 0 /somedir 0 nohandle" 22,139 + + rlLogInfo "null as key" + rlRun "./test_best CTX_FILE NULL NULL 0 0 NULL 0" 22 + + rlLogInfo "nonexisting entry" + rlRun "cat > $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts < $TmpDir/my_contexts <=7" || rlIsFedora; then + rlPhaseStartTest "selabel_digest" + # syntax: ./test_digest BACKEND OPT_PATH OPT_VALIDATE OPT_DIGEST [nohandle] + + rlRun "./test_digest CTX_FILE NULL 0 0" 22 + rlRun "./test_digest CTX_FILE NULL 0 0 nohandle" 139 + + rlRun "./test_digest CTX_FILE NULL 0 1" 0 + rlRun "./test_digest CTX_MEDIA NULL 0 1" 0 + rlRun "./test_digest CTX_X NULL 0 1" 0 + rlRun "./test_digest CTX_DB NULL 0 1" 0 + + rlRun "cat > $TmpDir/my_contexts < +#include +#include +#include +#include +#include +#include + +int main (int argc, char **argv) +{ + struct selabel_handle *hnd = NULL; + unsigned int backend = 0; + + struct selinux_opt selabel_option [] = { + { SELABEL_OPT_PATH, NULL }, + { SELABEL_OPT_SUBSET, NULL }, + { SELABEL_OPT_VALIDATE, (char *) 1 }, + { SELABEL_OPT_BASEONLY, (char *) 1 } + }; + + if (argc < 8) { + fprintf(stderr, "Invalid number of arguments\n"); + return 255; + } + + // set backend + if (strcmp(argv[1], "CTX_FILE") == 0) + backend = SELABEL_CTX_FILE; + else if (strcmp(argv[1], "CTX_MEDIA") == 0) + backend = SELABEL_CTX_MEDIA; + else if (strcmp(argv[1], "CTX_X") == 0) + backend = SELABEL_CTX_X; + else if (strcmp(argv[1], "CTX_DB") == 0) + backend = SELABEL_CTX_DB; +#ifndef RHEL6 + else if (strcmp(argv[1], "CTX_ANDROID_PROP") == 0) + backend = SELABEL_CTX_ANDROID_PROP; +#endif + else + backend = strtoul(argv[1], NULL, 10); + + if ((argc == 9) && (strcmp(argv[8], "nohandle") == 0)) { + hnd = NULL; + } + else { + // set file contexts path + if (strcmp(argv[2], "NULL") == 0) { + selabel_option[0].value = NULL; + } + else { + selabel_option[0].value = argv[2]; + } + + // set subset + if (strcmp(argv[3], "NULL") == 0) { + selabel_option[1].value = NULL; + } + else { + selabel_option[1].value = argv[3]; + } + + // set validate + if (strcmp(argv[4], "0") == 0) { + selabel_option[2].value = NULL; + } + else { + selabel_option[2].value = (char *) 1; + } + + // set baseonly + if (strcmp(argv[5], "0") == 0) { + selabel_option[3].value = NULL; + } + else { + selabel_option[3].value = (char *) 1; + } + + printf("selabel_options: "); + printf("SELABEL_OPT_PATH = %s, ", selabel_option[0].value); + printf("SELABEL_OPT_SUBSET = %s, ", selabel_option[1].value); + printf("SELABEL_OPT_VALIDATE = %ld, ", (long int)(intptr_t) selabel_option[2].value); + printf("SELABEL_OPT_BASEONLY = %ld\n", (long int)(intptr_t) selabel_option[3].value); + + printf("Executing: selabel_open(SELABEL_%s, &selabel_option, 4)\n", argv[1]); + + errno = 0; + + if ((hnd = selabel_open(backend, selabel_option, 4)) == NULL) { + perror("selabel_open - ERROR"); + return 255; + } + } + + int result; + security_context_t selabel_context; + char *path; + + if (strcmp(argv[6], "NULL") == 0) { + path = NULL; + } + else { + path = argv[6]; + } + + // notice the base 8 + int mode = strtol(argv[7], NULL, 8); + + int alias_cnt = argc-8; + const char **aliases = malloc((alias_cnt + 1)*sizeof(const char *)); + + if (aliases == NULL) + return 255; + + printf("aliases:"); + + for (int i = 0; i < alias_cnt; i++) { + aliases[i] = argv[8 + i]; + printf(" %s", argv[8 + i]); + } + + printf("\n"); + + aliases[alias_cnt] = NULL; + + printf("Executing: selabel_lookup_best_match(hnd, &selabel_context, %s, aliases, %d)\n", path, mode); + + errno = 0; + int e1 = 0, e2 = 0; + + if ((result = selabel_lookup_best_match(hnd, &selabel_context, path, aliases, mode)) == -1) { + e1 = errno; + perror("selabel_lookup_best_match - ERROR"); + } + else { + printf("selabel_lookup_best_match context: %s\n", selabel_context); + freecon(selabel_context); + } + + printf("Executing: selabel_lookup_best_match_raw(hnd, &selabel_context, %s, aliases, %d)\n", path, mode); + + errno = 0; + + if ((result = selabel_lookup_best_match_raw(hnd, &selabel_context, path, aliases, mode)) == -1) { + e2 = errno; + perror("selabel_lookup_best_match_raw - ERROR"); + } + else { + printf("selabel_lookup_best_match_raw context: %s\n", selabel_context); + freecon(selabel_context); + } + + if (hnd != NULL) + selabel_close(hnd); + + if (e1 == e2) + return e1; + else + return 255; +} diff --git a/tests/selabel-functions/test_digest.c b/tests/selabel-functions/test_digest.c new file mode 100644 index 0000000..0681f7b --- /dev/null +++ b/tests/selabel-functions/test_digest.c @@ -0,0 +1,121 @@ +#include +#include +#include +#include +#include +#include +#include + +int main (int argc, char **argv) +{ + struct selabel_handle *hnd = NULL; + unsigned int backend = 0; + + struct selinux_opt selabel_option [] = { + { SELABEL_OPT_PATH, NULL }, + { SELABEL_OPT_VALIDATE, (char *) 1 }, + { SELABEL_OPT_DIGEST, (char *) 1 } + }; + + if (argc < 5) { + fprintf(stderr, "Invalid number of arguments\n"); + return 255; + } + + // set backend + if (strcmp(argv[1], "CTX_FILE") == 0) + backend = SELABEL_CTX_FILE; + else if (strcmp(argv[1], "CTX_MEDIA") == 0) + backend = SELABEL_CTX_MEDIA; + else if (strcmp(argv[1], "CTX_X") == 0) + backend = SELABEL_CTX_X; + else if (strcmp(argv[1], "CTX_DB") == 0) + backend = SELABEL_CTX_DB; +#ifndef RHEL6 + else if (strcmp(argv[1], "CTX_ANDROID_PROP") == 0) + backend = SELABEL_CTX_ANDROID_PROP; +#endif + else + backend = strtoul(argv[1], NULL, 10); + + + if ((argc == 6) && (strcmp(argv[5], "nohandle") == 0)) { + hnd = NULL; + } + else { + // set file contexts path + if (strcmp(argv[2], "NULL") == 0) { + selabel_option[0].value = NULL; + } + else { + selabel_option[0].value = argv[2]; + } + + // set validate + if (strcmp(argv[3], "0") == 0) { + selabel_option[1].value = NULL; + } + else { + selabel_option[1].value = (char *) 1; + } + + // set digest + if (strcmp(argv[4], "0") == 0) { + selabel_option[2].value = NULL; + } + else { + selabel_option[2].value = (char *) 1; + } + + printf("selabel_options: "); + printf("SELABEL_OPT_PATH = %s, ", selabel_option[0].value); + printf("SELABEL_OPT_VALIDATE = %ld, ", (long int)(intptr_t) selabel_option[1].value); + printf("SELABEL_OPT_DIGEST = %ld, ", (long int)(intptr_t) selabel_option[2].value); + + printf("Executing: selabel_open(SELABEL_%s, &selabel_option, 3)\n", argv[1]); + + errno = 0; + + if ((hnd = selabel_open(backend, selabel_option, 3)) == NULL) { + perror("selabel_open - ERROR"); + return 255; + } + } + + unsigned char *digest; + size_t digest_len; + char **specfiles; + size_t num_specfiles; + int result, e = 0; + + printf("Executing: selabel_digest(hnd, digest, digest_len, specfiles, num_specfiles)\n"); + + errno = 0; + + if ((result = selabel_digest(hnd, &digest, &digest_len, &specfiles, &num_specfiles)) == -1) { + e = errno; + perror("selabel_digest - ERROR"); + } + else { + printf("digest_len: %lu\n", digest_len); + + printf("digest: "); + + for (size_t i = 0; i < digest_len; i++) + printf("%2x", digest[i]); + + printf("\n"); + + printf("num_specfiles: %lu\n", num_specfiles); + + printf("specfiles:\n"); + + for (size_t i = 0; i < num_specfiles; i++) + printf("specfile: %s\n", specfiles[i]); + } + + if (hnd != NULL) + selabel_close(hnd); + + return e; +} diff --git a/tests/selabel-functions/test_lookup.c b/tests/selabel-functions/test_lookup.c new file mode 100644 index 0000000..ee0caaa --- /dev/null +++ b/tests/selabel-functions/test_lookup.c @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include +#include + +int main (int argc, char **argv) +{ + struct selabel_handle *hnd = NULL; + unsigned int backend = 0; + + struct selinux_opt selabel_option [] = { + { SELABEL_OPT_PATH, NULL }, + { SELABEL_OPT_SUBSET, NULL }, + { SELABEL_OPT_VALIDATE, (char *) 1 }, + { SELABEL_OPT_BASEONLY, (char *) 1 } + }; + + if (argc < 8) { + fprintf(stderr, "Invalid number of arguments\n"); + return 255; + } + + // set backend + if (strcmp(argv[1], "CTX_FILE") == 0) + backend = SELABEL_CTX_FILE; + else if (strcmp(argv[1], "CTX_MEDIA") == 0) + backend = SELABEL_CTX_MEDIA; + else if (strcmp(argv[1], "CTX_X") == 0) + backend = SELABEL_CTX_X; + else if (strcmp(argv[1], "CTX_DB") == 0) + backend = SELABEL_CTX_DB; +#ifndef RHEL6 + else if (strcmp(argv[1], "CTX_ANDROID_PROP") == 0) + backend = SELABEL_CTX_ANDROID_PROP; +#endif + else + backend = strtoul(argv[1], NULL, 10); + + + if ((argc == 9) && (strcmp(argv[8], "nohandle") == 0)) { + hnd = NULL; + } + else { + // set file contexts path + if (strcmp(argv[2], "NULL") == 0) { + selabel_option[0].value = NULL; + } + else { + selabel_option[0].value = argv[2]; + } + + // set subset + if (strcmp(argv[3], "NULL") == 0) { + selabel_option[1].value = NULL; + } + else { + selabel_option[1].value = argv[3]; + } + + // set validate + if (strcmp(argv[4], "0") == 0) { + selabel_option[2].value = NULL; + } + else { + selabel_option[2].value = (char *) 1; + } + + // set baseonly + if (strcmp(argv[5], "0") == 0) { + selabel_option[3].value = NULL; + } + else { + selabel_option[3].value = (char *) 1; + } + + printf("selabel_options: "); + printf("SELABEL_OPT_PATH = %s, ", selabel_option[0].value); + printf("SELABEL_OPT_SUBSET = %s, ", selabel_option[1].value); + printf("SELABEL_OPT_VALIDATE = %ld, ", (long int)(intptr_t) selabel_option[2].value); + printf("SELABEL_OPT_BASEONLY = %ld\n", (long int)(intptr_t) selabel_option[3].value); + + printf("Executing: selabel_open(SELABEL_%s, &selabel_option, 4)\n", argv[1]); + + errno = 0; + + if ((hnd = selabel_open(backend, selabel_option, 4)) == NULL) { + perror("selabel_open - ERROR"); + return 255; + } + } + + int result; + security_context_t selabel_context; + char *path; + int mode; + + if (strcmp(argv[7], "X_PROP") == 0) + mode = SELABEL_X_PROP; + else if (strcmp(argv[7], "X_SELN") == 0) + mode = SELABEL_X_SELN; + else if (strcmp(argv[7], "X_EXT") == 0) + mode = SELABEL_X_EXT; + else if (strcmp(argv[7], "X_EVENT") == 0) + mode = SELABEL_X_EVENT; + else if (strcmp(argv[7], "X_CLIENT") == 0) + mode = SELABEL_X_CLIENT; + else if (strcmp(argv[7], "X_POLYPROP") == 0) + mode = SELABEL_X_POLYPROP; + else if (strcmp(argv[7], "X_POLYSELN") == 0) + mode = SELABEL_X_POLYSELN; + else if (strcmp(argv[7], "DB_DATABASE") == 0) + mode = SELABEL_DB_DATABASE; + else if (strcmp(argv[7], "DB_SCHEMA") == 0) + mode = SELABEL_DB_SCHEMA; + else if (strcmp(argv[7], "DB_VIEW") == 0) + mode = SELABEL_DB_VIEW; + else if (strcmp(argv[7], "DB_TABLE") == 0) + mode = SELABEL_DB_TABLE; + else if (strcmp(argv[7], "DB_COLUMN") == 0) + mode = SELABEL_DB_COLUMN; + else if (strcmp(argv[7], "DB_TUPLE") == 0) + mode = SELABEL_DB_TUPLE; + else if (strcmp(argv[7], "DB_PROCEDURE") == 0) + mode = SELABEL_DB_PROCEDURE; + else if (strcmp(argv[7], "DB_SEQUENCE") == 0) + mode = SELABEL_DB_SEQUENCE; + else if (strcmp(argv[7], "DB_BLOB") == 0) + mode = SELABEL_DB_BLOB; +#ifndef RHEL6 + else if (strcmp(argv[7], "DB_LANGUAGE") == 0) + mode = SELABEL_DB_LANGUAGE; + else if (strcmp(argv[7], "DB_EXCEPTION") == 0) + mode = SELABEL_DB_EXCEPTION; + else if (strcmp(argv[7], "DB_DATATYPE") == 0) + mode = SELABEL_DB_DATATYPE; +#endif + else + // notice the base 8 + mode = strtol(argv[7], NULL, 8); + + int e1 = 0, e2 = 0; + + if (strcmp(argv[6], "NULL") == 0) { + path = NULL; + } + else if (strcmp(argv[6], "'*'") == 0) { + path = "*"; + } + else { + path = argv[6]; + } + + printf("Executing: selabel_lookup(hnd, &selabel_context, %s, %d)\n", path, mode); + + errno = 0; + + if ((result = selabel_lookup(hnd, &selabel_context, path, mode)) == -1) { + e1 = errno; + perror("selabel_lookup - ERROR"); + } + else { + printf("selabel_lookup context: %s\n", selabel_context); + freecon(selabel_context); + } + + printf("Executing: selabel_lookup_raw(hnd, &selabel_context, %s, %d)\n", path, mode); + + errno = 0; + + if ((result = selabel_lookup_raw(hnd, &selabel_context, path, mode)) == -1) { + e2 = errno; + perror("selabel_lookup_raw - ERROR"); + } + else { + printf("selabel_lookup_raw context: %s\n", selabel_context); + freecon(selabel_context); + } + + if (hnd != NULL) + selabel_close(hnd); + + if (e1 == e2) + return e1; + else + return 255; +} diff --git a/tests/selabel-functions/test_open.c b/tests/selabel-functions/test_open.c new file mode 100644 index 0000000..87f61ee --- /dev/null +++ b/tests/selabel-functions/test_open.c @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include +#include + +int main (int argc, char **argv) +{ + struct selabel_handle *hnd = NULL; + int nopt = 0; + unsigned int backend = 0; + + struct selinux_opt selabel_option [] = { + { SELABEL_OPT_PATH, NULL }, + { SELABEL_OPT_SUBSET, NULL }, + { SELABEL_OPT_VALIDATE, (char *) 1 }, + { SELABEL_OPT_BASEONLY, (char *) 1 } + }; + + if (argc < 6) { + fprintf(stderr, "Invalid number of arguments\n"); + return 255; + } + + // set backend + if (strcmp(argv[1], "CTX_FILE") == 0) + backend = SELABEL_CTX_FILE; + else if (strcmp(argv[1], "CTX_MEDIA") == 0) + backend = SELABEL_CTX_MEDIA; + else if (strcmp(argv[1], "CTX_X") == 0) + backend = SELABEL_CTX_X; + else if (strcmp(argv[1], "CTX_DB") == 0) + backend = SELABEL_CTX_DB; +#ifndef RHEL6 + else if (strcmp(argv[1], "CTX_ANDROID_PROP") == 0) + backend = SELABEL_CTX_ANDROID_PROP; +#endif + else + backend = strtoul(argv[1], NULL, 10); + + // set file contexts path + if (strcmp(argv[2], "NULL") == 0) { + selabel_option[0].value = NULL; + } + else { + selabel_option[0].value = argv[2]; + } + + // set subset + if (strcmp(argv[3], "NULL") == 0) { + selabel_option[1].value = NULL; + } + else { + selabel_option[1].value = argv[3]; + } + + // set validate + if (strcmp(argv[4], "0") == 0) { + selabel_option[2].value = NULL; + } + else { + selabel_option[2].value = (char *) 1; + } + + // set baseonly + if (strcmp(argv[5], "0") == 0) { + selabel_option[3].value = NULL; + } + else { + selabel_option[3].value = (char *) 1; + } + + if (argc == 7) { + nopt = strtol(argv[6], NULL, 10); + } + else { + nopt = 4; + } + + printf("selabel_options: "); + printf("SELABEL_OPT_PATH = %s, ", selabel_option[0].value); + printf("SELABEL_OPT_SUBSET = %s, ", selabel_option[1].value); + printf("SELABEL_OPT_VALIDATE = %ld, ", (long int)(intptr_t) selabel_option[2].value); + printf("SELABEL_OPT_BASEONLY = %ld\n", (long int)(intptr_t) selabel_option[3].value); + + printf("Executing: selabel_open(SELABEL_%s, &selabel_option, %d)\n\n", argv[1], nopt); + + errno = 0; + + if ((hnd = selabel_open(backend, selabel_option, nopt)) == NULL) { + int e = errno; + perror("selabel_open - ERROR"); + return e; + } + + selabel_close(hnd); + return 0; +} diff --git a/tests/selabel-functions/test_partial.c b/tests/selabel-functions/test_partial.c new file mode 100644 index 0000000..4513cfa --- /dev/null +++ b/tests/selabel-functions/test_partial.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include +#include + +int main (int argc, char **argv) +{ + struct selabel_handle *hnd = NULL; + unsigned int backend = 0; + + struct selinux_opt selabel_option [] = { + { SELABEL_OPT_PATH, NULL }, + { SELABEL_OPT_SUBSET, NULL }, + { SELABEL_OPT_VALIDATE, (char *) 1 }, + { SELABEL_OPT_BASEONLY, (char *) 1 } + }; + + if (argc < 7) { + fprintf(stderr, "Invalid number of arguments\n"); + return 255; + } + + // set backend + if (strcmp(argv[1], "CTX_FILE") == 0) + backend = SELABEL_CTX_FILE; + else if (strcmp(argv[1], "CTX_MEDIA") == 0) + backend = SELABEL_CTX_MEDIA; + else if (strcmp(argv[1], "CTX_X") == 0) + backend = SELABEL_CTX_X; + else if (strcmp(argv[1], "CTX_DB") == 0) + backend = SELABEL_CTX_DB; +#ifndef RHEL6 + else if (strcmp(argv[1], "CTX_ANDROID_PROP") == 0) + backend = SELABEL_CTX_ANDROID_PROP; +#endif + else + backend = strtoul(argv[1], NULL, 10); + + if ((argc == 8) && (strcmp(argv[7], "nohandle") == 0)) { + hnd = NULL; + } + else { + // set file contexts path + if (strcmp(argv[2], "NULL") == 0) { + selabel_option[0].value = NULL; + } + else { + selabel_option[0].value = argv[2]; + } + + // set subset + if (strcmp(argv[3], "NULL") == 0) { + selabel_option[1].value = NULL; + } + else { + selabel_option[1].value = argv[3]; + } + + // set validate + if (strcmp(argv[4], "0") == 0) { + selabel_option[2].value = NULL; + } + else { + selabel_option[2].value = (char *) 1; + } + + // set baseonly + if (strcmp(argv[5], "0") == 0) { + selabel_option[3].value = NULL; + } + else { + selabel_option[3].value = (char *) 1; + } + + printf("selabel_options: "); + printf("SELABEL_OPT_PATH = %s, ", selabel_option[0].value); + printf("SELABEL_OPT_SUBSET = %s, ", selabel_option[1].value); + printf("SELABEL_OPT_VALIDATE = %ld, ", (long int)(intptr_t) selabel_option[2].value); + printf("SELABEL_OPT_BASEONLY = %ld\n", (long int)(intptr_t) selabel_option[3].value); + + printf("Executing: selabel_open(SELABEL_%s, &selabel_option, 4)\n", argv[1]); + + errno = 0; + + if ((hnd = selabel_open(backend, selabel_option, 4)) == NULL) { + int e = errno; + perror("selabel_open - ERROR"); + return e; + } + } + + char *path; + + if (strcmp(argv[6], "NULL") == 0) { + path = NULL; + } + else { + path = argv[6]; + } + + printf("Executing: selabel_partial_match(hnd, %s)\n", path); + + errno = 0; + + if (selabel_partial_match(hnd, path)) + printf("selabel_partial_match: true\n"); + else + printf("selabel_partial_match: false\n"); + + selabel_close(hnd); + return 0; +} diff --git a/tests/selabel-functions/test_stats.c b/tests/selabel-functions/test_stats.c new file mode 100644 index 0000000..b048b98 --- /dev/null +++ b/tests/selabel-functions/test_stats.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include +#include + +int main (int argc, char **argv) +{ + struct selabel_handle *hnd = NULL; + unsigned int backend = 0; + + struct selinux_opt selabel_option [] = { + { SELABEL_OPT_PATH, NULL }, + { SELABEL_OPT_VALIDATE, (char *) 1 } + }; + + if (argc < 4) { + fprintf(stderr, "Invalid number of arguments\n"); + return 255; + } + + // set backend + if (strcmp(argv[1], "CTX_FILE") == 0) + backend = SELABEL_CTX_FILE; + else if (strcmp(argv[1], "CTX_MEDIA") == 0) + backend = SELABEL_CTX_MEDIA; + else if (strcmp(argv[1], "CTX_X") == 0) + backend = SELABEL_CTX_X; + else if (strcmp(argv[1], "CTX_DB") == 0) + backend = SELABEL_CTX_DB; +#ifndef RHEL6 + else if (strcmp(argv[1], "CTX_ANDROID_PROP") == 0) + backend = SELABEL_CTX_ANDROID_PROP; +#endif + else + backend = strtoul(argv[1], NULL, 10); + + + if ((argc == 5) && (strcmp(argv[4], "nohandle") == 0)) { + hnd = NULL; + } + else { + // set file contexts path + if (strcmp(argv[2], "NULL") == 0) { + selabel_option[0].value = NULL; + } + else { + selabel_option[0].value = argv[2]; + } + + // set validate + if (strcmp(argv[3], "0") == 0) { + selabel_option[1].value = NULL; + } + else { + selabel_option[1].value = (char *) 1; + } + + printf("selabel_options: "); + printf("SELABEL_OPT_PATH = %s, ", selabel_option[0].value); + printf("SELABEL_OPT_VALIDATE = %ld, ", (long int)(intptr_t) selabel_option[1].value); + + printf("Executing: selabel_open(SELABEL_%s, &selabel_option, 2)\n", argv[1]); + + errno = 0; + + if ((hnd = selabel_open(backend, selabel_option, 2)) == NULL) { + perror("selabel_open - ERROR"); + return 255; + } + } + + printf("Executing: selabel_stats(hnd)\n"); + + selabel_stats(hnd); + + if (hnd != NULL) + selabel_close(hnd); + + return 0; +} diff --git a/tests/selinux_boolean_sub-function/Makefile b/tests/selinux_boolean_sub-function/Makefile new file mode 100644 index 0000000..e701520 --- /dev/null +++ b/tests/selinux_boolean_sub-function/Makefile @@ -0,0 +1,63 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/libselinux/Sanity/selinux_boolean_sub-function +# Description: Test selinux_boolean_sub function +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/libselinux/Sanity/selinux_boolean_sub-function +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE test*.c + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Jan Zarsky " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Test selinux_boolean_sub function" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 5m" >> $(METADATA) + @echo "RunFor: libselinux" >> $(METADATA) + @echo "Requires: libselinux libselinux-devel glibc gcc" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2+" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "Releases: -RHEL4 -RHELClient5 -RHELServer5 -RHEL6" >> $(METADATA) + + rhts-lint $(METADATA) diff --git a/tests/selinux_boolean_sub-function/PURPOSE b/tests/selinux_boolean_sub-function/PURPOSE new file mode 100644 index 0000000..289e8e7 --- /dev/null +++ b/tests/selinux_boolean_sub-function/PURPOSE @@ -0,0 +1,3 @@ +PURPOSE of /CoreOS/libselinux/Sanity/selinux_boolean_sub-function +Description: Test selinux_boolean_sub function +Author: Jan Zarsky diff --git a/tests/selinux_boolean_sub-function/runtest.sh b/tests/selinux_boolean_sub-function/runtest.sh new file mode 100755 index 0000000..63539c7 --- /dev/null +++ b/tests/selinux_boolean_sub-function/runtest.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/libselinux/Sanity/selinux_boolean_sub-function +# Description: Test selinux_boolean_sub function +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="libselinux" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm ${PACKAGE} + rlAssertRpm ${PACKAGE}-devel + rlAssertRpm "glibc" + rlAssertRpm "gcc" + + rlRun -l "gcc test.c -o test -lselinux -Wall -Wextra -std=c99" + rlPhaseEnd + + rlPhaseStartTest + rlRun "./test NULL | tee output" + rlRun "grep 'selinux_boolean_sub: (null)' output" + + rlRun "./test my_nonexisting_record | tee output" + rlRun "grep 'selinux_boolean_sub: my_nonexisting_record' output" + + policy_type="$(grep -E '^SELINUXTYPE=' /etc/selinux/config | cut -c13- | tr '[:upper:]' '[:lower:]' | tr -d ' ')" + line1="$(cat /etc/selinux/$policy_type/booleans.subs_dist | head -n 1)" + line2="$(cat /etc/selinux/$policy_type/booleans.subs_dist | head -n 7 | tail -n 1)" + line3="$(cat /etc/selinux/$policy_type/booleans.subs_dist | tail -n 1)" + + input="$(echo $line1 | awk '{ print $1 }')" + output="$(echo $line1 | awk '{ print $2 }')" + + rlRun "./test $input | tee output" + rlRun "grep 'selinux_boolean_sub: $output' output" + + input="$(echo $line2 | awk '{ print $1 }')" + output="$(echo $line2 | awk '{ print $2 }')" + + rlRun "./test $input | tee output" + rlRun "grep 'selinux_boolean_sub: $output' output" + + input="$(echo $line3 | awk '{ print $1 }')" + output="$(echo $line3 | awk '{ print $2 }')" + + rlRun "./test $input | tee output" + rlRun "grep 'selinux_boolean_sub: $output' output" + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "rm -f test output" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd diff --git a/tests/selinux_boolean_sub-function/test.c b/tests/selinux_boolean_sub-function/test.c new file mode 100644 index 0000000..f6479b8 --- /dev/null +++ b/tests/selinux_boolean_sub-function/test.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include + +int main (int argc, char **argv) { + if (argc < 2) { + printf("Invalid number of arguments"); + return -1; + } + + char *boolean_name; + + if (strcmp(argv[1], "NULL") == 0) { + boolean_name = NULL; + } + else { + boolean_name = argv[1]; + } + + printf("Executing: selinux_boolean_sub(%s)\n", boolean_name); + + char *result = selinux_boolean_sub(boolean_name); + + printf("selinux_boolean_sub: %s\n", result); + + free(result); + return 0; +} diff --git a/tests/selinux_restorecon-functions/Makefile b/tests/selinux_restorecon-functions/Makefile new file mode 100644 index 0000000..631f5a8 --- /dev/null +++ b/tests/selinux_restorecon-functions/Makefile @@ -0,0 +1,63 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/libselinux/Sanity/selinux_restorecon-functions +# Description: Test functions in selinux_restorecon.c +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/libselinux/Sanity/selinux_restorecon-functions +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE test_restorecon.c test_exclude_list.c test_sehandle.c + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Jan Zarsky " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Test functions in selinux_restorecon.c" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 5m" >> $(METADATA) + @echo "RunFor: libselinux" >> $(METADATA) + @echo "Requires: libselinux libselinux-devel glibc strace" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2+" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "Releases: -RHEL4 -RHELClient5 -RHELServer5" >> $(METADATA) + + rhts-lint $(METADATA) diff --git a/tests/selinux_restorecon-functions/PURPOSE b/tests/selinux_restorecon-functions/PURPOSE new file mode 100644 index 0000000..8a2f7ba --- /dev/null +++ b/tests/selinux_restorecon-functions/PURPOSE @@ -0,0 +1,3 @@ +PURPOSE of /CoreOS/libselinux/Sanity/selinux_restorecon-functions +Description: Test functions in selinux_restorecon.c +Author: Jan Zarsky diff --git a/tests/selinux_restorecon-functions/runtest.sh b/tests/selinux_restorecon-functions/runtest.sh new file mode 100755 index 0000000..5a51998 --- /dev/null +++ b/tests/selinux_restorecon-functions/runtest.sh @@ -0,0 +1,367 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/libselinux/Sanity/selinux_restorecon-functions +# Description: Test functions in selinux_restorecon.c +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/bin/rhts-environment.sh || exit 1 +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="libselinux" + +function createTestFiles { + rlLogInfo "Creating testing files" + + TmpDir="/home/user/testdir" + rlRun "mkdir $TmpDir" + + rlRun "pushd $TmpDir" + + rlRun "mkdir -p a/b" + + rlRun "touch afile" + rlRun "touch a/bfile" + rlRun "touch a/b/cfile" + + rlRun "popd" +} + +function changeContext { + rlLogInfo "Changing context of testing files" + + rlRun "pushd $TmpDir" + + rlRun "chcon -t var_log_t ." + rlRun "chcon -t var_log_t a" + rlRun "chcon -t var_log_t a/b" + rlRun "chcon -t var_log_t afile" + rlRun "chcon -t var_log_t a/bfile" + rlRun "chcon -t var_log_t a/b/cfile" + + rlRun "popd" +} + +function deleteTestFiles { + rlLogInfo "Deleting testing files" + + rlRun "rm -rf $TmpDir" +} + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm ${PACKAGE} + rlAssertRpm ${PACKAGE}-devel + rlAssertRpm "glibc" + rlAssertRpm "strace" + + rlRun -l "gcc test_restorecon.c -o test_restorecon -lselinux -pedantic -Wall -Wextra -std=c99" + rlRun -l "gcc test_exclude_list.c -o test_exclude_list -lselinux -pedantic -Wall -Wextra -std=c99" + rlRun -l "gcc test_sehandle.c -o test_sehandle -lselinux -pedantic -Wall -Wextra -std=c99" + + rlRun "useradd user" + rlPhaseEnd + + rlPhaseStartTest "test call" + createTestFiles + + rlRun "./test_restorecon $TmpDir" 0 "Calling selinux_restorecon" + + deleteTestFiles + rlPhaseEnd + + rlPhaseStartTest "test call with flags" + createTestFiles + + rlRun "./test_restorecon $TmpDir IGNORE_DIGEST IGNORE_DIGEST NOCHANGE VERBOSE PROGRESS RECURSE \ + SET_SPECFILE_CTX REALPATH XDEV" 0 "Calling selinux_restorecon with all flags" + + deleteTestFiles + rlPhaseEnd + + rlPhaseStartTest "invalid path" + rlRun "./test_restorecon EMPTY" 255 "Calling selinux_restorecon with empty path" + + # should probably return both 139 (segfault) or 255, but it is not so important + rlRun "./test_restorecon NULL" 139,255 "Calling selinux_restorecon with null as path" + rlRun "./test_restorecon NULL REALPATH" 139,255 "Calling selinux_restorecon with null as path and REALPATH flag" + + rlRun "./test_restorecon /nonexistent" 255 "Calling selinux_restorecon with nonexisting path" + rlPhaseEnd + + rlPhaseStartTest "no flags" + createTestFiles + changeContext + + rlRun "strace -ostrace.out -s 64 ./test_restorecon $TmpDir" 0 "Calling selinux_restorecon" + + rlLogInfo "Checking lgetxattr calls" + rlRun "grep lgetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out | grep var_log_t" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out | grep var_log_t" 1 + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out | grep var_log_t" 1 + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out | grep var_log_t" 1 + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out | grep var_log_t" 1 + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out | grep var_log_t" 1 + + rlLogInfo "Checking lsetxattr calls" + rlRun "grep lsetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out | grep user_home_t" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out | grep user_home_t" 1 + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out | grep user_home_t" 1 + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out | grep user_home_t" 1 + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out | grep user_home_t" 1 + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out | grep user_home_t" 1 + + rlRun "rm -f strace.out" + rlRun "rm -f strace_xattr.out" + + deleteTestFiles + rlPhaseEnd + + rlPhaseStartTest "RECURSE flag" + createTestFiles + changeContext + + rlRun "strace -ostrace.out -s 64 ./test_restorecon $TmpDir RECURSE" 0 "Calling selinux_restorecon with RECURSE flag" + + rlLogInfo "Checking lgetxattr calls" + rlRun "grep lgetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out | grep var_log_t" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out | grep var_log_t" + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out | grep var_log_t" + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out | grep var_log_t" + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out | grep var_log_t" + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out | grep var_log_t" + + rlLogInfo "Checking lsetxattr calls" + rlRun "grep lsetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out | grep user_home_t" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out | grep user_home_t" + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out | grep user_home_t" + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out | grep user_home_t" + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out | grep user_home_t" + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out | grep user_home_t" + + rlRun "rm -f strace.out" + rlRun "rm -f strace_xattr.out" + + deleteTestFiles + rlPhaseEnd + + rlPhaseStartTest "NOCHANGE flag" + createTestFiles + changeContext + + rlRun "strace -ostrace.out -s 64 ./test_restorecon $TmpDir RECURSE NOCHANGE" 0 "Calling selinux_restorecon with NOCHANGE flag" + + rlLogInfo "Checking lsetxattr calls" + rlRun "grep lsetxattr strace.out" 1 + + rlRun "rm -f strace.out" + + deleteTestFiles + rlPhaseEnd + + rlPhaseStartTest "/sys directory" + # directory that supports security.restorecon_last xattr + rlRun "strace -ostrace.out -s 64 ./test_restorecon /var/log RECURSE NOCHANGE" 0 "Calling selinux_restorecon on /tmp" + + rlRun "grep security.restorecon_last strace.out" 0 + + # directory that does not supports security.restorecon_last xattr + rlRun "strace -ostrace.out -s 64 ./test_restorecon /sys RECURSE NOCHANGE" 0 "Calling selinux_restorecon on /sys" + + rlRun "grep security.restorecon_last strace.out" 1 + + rlRun "rm -f strace.out" + rlPhaseEnd + + rlPhaseStartTest "no IGNORE_DIGEST flag" + createTestFiles + + # run restorecon first time + rlRun "strace -ostrace.out -s 64 ./test_restorecon $TmpDir RECURSE" 0 "Calling selinux_restorecon for the first time" + + rlLogInfo "Checking lgetxattr calls" + rlRun "grep lgetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out" + + # run restorecon second time + rlRun "strace -ostrace.out -s 64 ./test_restorecon $TmpDir RECURSE" 0 "Calling selinux_restorecon for the second time" + + rlLogInfo "Checking lgetxattr calls" + rlRun "grep lgetxattr strace.out | grep security.selinux" 1 + + rlRun "rm -f strace.out" + rlRun "rm -f strace_xattr.out" + + deleteTestFiles + rlPhaseEnd + + rlPhaseStartTest "IGNORE_DIGEST flag" + createTestFiles + + # run restorecon first time + rlRun "strace -ostrace.out -s 64 ./test_restorecon $TmpDir RECURSE" 0 "Calling selinux_restorecon for the first time" + + rlLogInfo "Checking lgetxattr calls" + rlRun "grep lgetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out" + + # run restorecon second time + rlRun "strace -ostrace.out -s 64 ./test_restorecon $TmpDir RECURSE IGNORE_DIGEST" 0 "Calling selinux_restorecon for the second time" + + rlLogInfo "Checking lgetxattr calls" + rlRun "grep lgetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out" + + rlRun "rm -f strace.out" + rlRun "rm -f strace_xattr.out" + + deleteTestFiles + rlPhaseEnd + + rlPhaseStartTest "selinux_restorecon_set_exclude_list" + createTestFiles + + # empty exclude list + rlRun "strace -ostrace.out -s 64 ./test_exclude_list EMPTY $TmpDir" 0 "Calling selinux_restorecon_set_exclude_list with empty list" + + rlLogInfo "Checking lgetxattr calls" + rlRun "grep lgetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out" + + # null as list + if rlIsFedora ">=26"; then + rlRun "strace -ostrace.out -s 64 ./test_exclude_list NULL $TmpDir" 139 "Calling selinux_restorecon_set_exclude_list with null as list" + else + rlRun "strace -ostrace.out -s 64 ./test_exclude_list NULL $TmpDir" 0 "Calling selinux_restorecon_set_exclude_list with null as list" + + rlLogInfo "Checking lgetxattr calls" + rlRun "grep lgetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out" + fi + + # exclude $TmpDir/a + rlRun "strace -ostrace.out -s 64 ./test_exclude_list $TmpDir/a $TmpDir" 0 "Calling selinux_restorecon_set_exclude_list" + + rlLogInfo "Checking lgetxattr calls" + rlRun "grep lgetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out" 1 + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out" 1 + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out" 1 + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out" 1 + + rlRun "rm -f strace.out" + rlRun "rm -f strace_xattr.out" + + deleteTestFiles + rlPhaseEnd + + rlPhaseStartTest "selinux_restorecon_set_sehandle" + createTestFiles + + # null sehandle + rlRun "./test_sehandle NULL $TmpDir" 139,255 "Calling selinux_restorecon_set_sehandle with null handle" + + # invalid sehandle + rlRun "./test_sehandle INVALID $TmpDir" 139,255 "Calling selinux_restorecon_set_sehandle with invalid handle" + + # default sehandle + rlRun "strace -ostrace.out -s 64 ./test_sehandle DEFAULT $TmpDir" 0 "Calling selinux_restorecon_set_sehandle with default handle" + + rlLogInfo "Checking lgetxattr calls" + rlRun "grep lgetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out" + + # custom sehandle + rlRun "strace -ostrace.out -s 64 ./test_sehandle CUSTOM $TmpDir" 0 "Calling selinux_restorecon_set_sehandle with custom handle" + + rlLogInfo "Checking lgetxattr calls" + rlRun "grep lgetxattr strace.out | grep security.selinux > strace_xattr.out" + + rlRun "grep \"\\\"$TmpDir\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/afile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/bfile\\\"\" strace_xattr.out" + rlRun "grep \"\\\"$TmpDir/a/b/cfile\\\"\" strace_xattr.out" + + rlRun "rm -f strace.out" + rlRun "rm -f strace_xattr.out" + + deleteTestFiles + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "rm -f test_restorecon test_exclude_list test_sehandle" + + rlRun "userdel -r user" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd diff --git a/tests/selinux_restorecon-functions/test_exclude_list.c b/tests/selinux_restorecon-functions/test_exclude_list.c new file mode 100644 index 0000000..776eb5d --- /dev/null +++ b/tests/selinux_restorecon-functions/test_exclude_list.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + char *path = NULL; + const char **list = NULL; + unsigned int flags = 0; + + if (argc < 3) { + fprintf(stderr, "Invalid number of arguments\n"); + return 1; + } + + // set restorecon path + if (strcmp(argv[2], "EMPTY") == 0) { + path = ""; + } + else if (strcmp(argv[2], "NULL") == 0) { + path = NULL; + } + else { + path = argv[2]; + } + + // set restorecon flags + flags |= SELINUX_RESTORECON_RECURSE; + flags |= SELINUX_RESTORECON_IGNORE_DIGEST; + + // set exclude list + if (strcmp(argv[1], "NULL") == 0) { + list = NULL; + } + else if (strcmp(argv[1], "EMPTY") == 0) { + list = malloc(sizeof(char*)); + list[0] = NULL; + } + else { + list = malloc(2*sizeof(char*)); + list[0] = argv[1]; + list[1] = NULL; + } + + printf("Running selinux_restorecon_set_exclude_list();\n"); + + selinux_restorecon_set_exclude_list(list); + + printf("Running selinux_restorecon(\"%s\", %#08x);\n", path, flags); + + return selinux_restorecon(path, flags); +} diff --git a/tests/selinux_restorecon-functions/test_restorecon.c b/tests/selinux_restorecon-functions/test_restorecon.c new file mode 100644 index 0000000..03600ac --- /dev/null +++ b/tests/selinux_restorecon-functions/test_restorecon.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + unsigned int flags = 0; + char *path = NULL; + + if (argc < 2) { + fprintf(stderr, "Invalid number of arguments\n"); + return 1; + } + + // set path + if (strcmp(argv[1], "EMPTY") == 0) { + path = ""; + } + else if (strcmp(argv[1], "NULL") == 0) { + path = NULL; + } + else { + path = argv[1]; + } + + // set flags (if any) + if (argc >= 3) { + for (int i = 2; i < argc; i++) + if (strcmp(argv[i], "IGNORE_DIGEST") == 0) + flags |= SELINUX_RESTORECON_IGNORE_DIGEST; + else if (strcmp(argv[i], "NOCHANGE") == 0) + flags |= SELINUX_RESTORECON_NOCHANGE; + else if (strcmp(argv[i], "VERBOSE") == 0) + flags |= SELINUX_RESTORECON_VERBOSE; + else if (strcmp(argv[i], "PROGRESS") == 0) + flags |= SELINUX_RESTORECON_PROGRESS; + else if (strcmp(argv[i], "RECURSE") == 0) + flags |= SELINUX_RESTORECON_RECURSE; + else if (strcmp(argv[i], "SET_SPECFILE_CTX") == 0) + flags |= SELINUX_RESTORECON_SET_SPECFILE_CTX; + else if (strcmp(argv[i], "REALPATH") == 0) + flags |= SELINUX_RESTORECON_REALPATH; + else if (strcmp(argv[i], "XDEV") == 0) + flags |= SELINUX_RESTORECON_XDEV; + else { + fprintf(stderr, "Invalid flag %s\n", argv[i]); + return 1; + } + + } + + printf("Running selinux_restorecon(\"%s\", %#08x);\n", path, flags); + + return selinux_restorecon(path, flags); +} diff --git a/tests/selinux_restorecon-functions/test_sehandle.c b/tests/selinux_restorecon-functions/test_sehandle.c new file mode 100644 index 0000000..c954180 --- /dev/null +++ b/tests/selinux_restorecon-functions/test_sehandle.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + struct selabel_handle *hndl = NULL; + char *path = NULL; + unsigned int flags = 0; + + if (argc < 3) { + fprintf(stderr, "Invalid number of arguments\n"); + return 1; + } + + // set restorecon path + if (strcmp(argv[2], "EMPTY") == 0) { + path = ""; + } + else if (strcmp(argv[2], "NULL") == 0) { + path = NULL; + } + else { + path = argv[2]; + } + + // set restorecon flags + flags |= SELINUX_RESTORECON_RECURSE; + flags |= SELINUX_RESTORECON_IGNORE_DIGEST; + + // set sehandle + if (strcmp(argv[1], "DEFAULT") == 0) { + hndl = selinux_restorecon_default_handle(); + + if (hndl == NULL) { + return 1; + } + } + else if (strcmp(argv[1], "INVALID") == 0) { + hndl = (struct selabel_handle *) 1; + } + else if (strcmp(argv[1], "NULL") == 0) { + hndl = NULL; + } + else if (strcmp(argv[1], "CUSTOM") == 0) { + struct selinux_opt options[] = { + { SELABEL_OPT_DIGEST, (char *)1 }, + { SELABEL_OPT_BASEONLY, (char *)1 } + }; + + hndl = selabel_open(SELABEL_CTX_FILE, options, 2); + } + + printf("Running selinux_restorecon_set_sehandle();\n"); + + selinux_restorecon_set_sehandle(hndl); + + printf("Running selinux_restorecon(\"%s\", %#08x);\n", path, flags); + + return selinux_restorecon(path, flags); +} diff --git a/tests/selinux_restorecon/Makefile b/tests/selinux_restorecon/Makefile new file mode 100644 index 0000000..4903787 --- /dev/null +++ b/tests/selinux_restorecon/Makefile @@ -0,0 +1,64 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/libselinux/Sanity/selinux_restorecon +# Description: Does selinux_restorecon work correctly? +# Author: Milos Malik +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/libselinux/Sanity/selinux_restorecon +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Milos Malik " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Does selinux_restorecon work correctly?" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 10m" >> $(METADATA) + @echo "RunFor: libselinux" >> $(METADATA) + @echo "Requires: libselinux libselinux-utils attr" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "Releases: -RHEL4 -RHEL6 -RHELClient5 -RHELServer5" >> $(METADATA) + + rhts-lint $(METADATA) + diff --git a/tests/selinux_restorecon/PURPOSE b/tests/selinux_restorecon/PURPOSE new file mode 100644 index 0000000..9ee17e1 --- /dev/null +++ b/tests/selinux_restorecon/PURPOSE @@ -0,0 +1,5 @@ +PURPOSE of /CoreOS/libselinux/Sanity/selinux_restorecon +Author: Milos Malik + +Does selinux_restorecon work correctly? The program was added in RHEL-7.3. + diff --git a/tests/selinux_restorecon/runtest.sh b/tests/selinux_restorecon/runtest.sh new file mode 100755 index 0000000..05b813b --- /dev/null +++ b/tests/selinux_restorecon/runtest.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/libselinux/Sanity/selinux_restorecon +# Description: Does selinux_restorecon work correctly? +# Author: Milos Malik +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="libselinux" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm ${PACKAGE} + rlAssertRpm ${PACKAGE}-utils + rlPhaseEnd + + rlPhaseStartTest "valid options / combinations" + rlRun "selinux_restorecon --help" 0-255 + for CUR_DIR in /boot /etc /opt /root /usr /var ; do + rlRun "setfattr -x security.restorecon_last ${CUR_DIR}" 0,1 + rlRun "getfattr -m . -d ${CUR_DIR} | grep security.restorecon_last=" 1 + rlRun "selinux_restorecon -R -d -C ${CUR_DIR} 2>&1 | grep -i \"updated digest for.*${CUR_DIR}\"" 1 + rlRun "getfattr -m . -d ${CUR_DIR} | grep security.restorecon_last=" + rlRun "selinux_restorecon -R -v -d -C ${CUR_DIR} 2>&1 | grep -i \"updated digest for.*${CUR_DIR}\"" + done + rlRun "chcon -u unconfined_u /root" + rlRun "ls -dZ /root | grep unconfined_u:" + rlRun "selinux_restorecon -R -v -d -C /root 2>&1 | grep -i relabeled" 1 + rlRun "ls -dZ /root | grep unconfined_u:" + rlRun "selinux_restorecon -R -v -d -C -F /root 2>&1 | grep -i relabeled" + rlRun "ls -dZ /root | grep system_u:" + rlPhaseEnd + + rlPhaseStartTest "invalid options / combinations" + rlRun "selinux_restorecon -v -P 2>&1 | grep -i \"mutually exclusive\"" + rlRun "selinux_restorecon -f 2>&1 | grep -i \"option requires an argument\"" + rlRun "selinux_restorecon -p 2>&1 | grep -i \"option requires an argument\"" + rlRun "selinux_restorecon /non-existent 2>&1 | grep -i \"No such file or directory\"" + rlPhaseEnd + + rlPhaseStartTest + OUTPUT_FILE=`mktemp` + rlRun "selinux_restorecon -R -v -C /root 2>&1 | tee ${OUTPUT_FILE}" + rlRun "grep -q -e /sys/fs/selinux/ -e /sys/kernel/security/ ${OUTPUT_FILE}" 1 + rlRun "selinux_restorecon -R -v -C -r /root 2>&1 | tee ${OUTPUT_FILE}" + rlRun "grep -q -e /sys/fs/selinux/ -e /sys/kernel/security/ ${OUTPUT_FILE}" 1 + rm -f ${OUTPUT_FILE} + rlPhaseEnd + + rlPhaseStartCleanup + rlPhaseEnd +rlJournalPrintText +rlJournalEnd + diff --git a/tests/selinux_sestatus-functions/Makefile b/tests/selinux_sestatus-functions/Makefile new file mode 100644 index 0000000..d3ad9e8 --- /dev/null +++ b/tests/selinux_sestatus-functions/Makefile @@ -0,0 +1,63 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/libselinux/Sanity/selinux_sestatus-functions +# Description: Test sestatus.c functions +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/libselinux/Sanity/selinux_sestatus-functions +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE test.c + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Jan Zarsky " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Test sestatus.c functions" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 5m" >> $(METADATA) + @echo "RunFor: libselinux" >> $(METADATA) + @echo "Requires: libselinux libselinux-devel glibc" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2+" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "Releases: -RHEL4 -RHELClient5 -RHELServer5 -RHEL6" >> $(METADATA) + + rhts-lint $(METADATA) diff --git a/tests/selinux_sestatus-functions/PURPOSE b/tests/selinux_sestatus-functions/PURPOSE new file mode 100644 index 0000000..c638364 --- /dev/null +++ b/tests/selinux_sestatus-functions/PURPOSE @@ -0,0 +1,3 @@ +PURPOSE of /CoreOS/libselinux/Sanity/selinux_sestatus-functions +Description: Test sestatus.c functions +Author: Jan Zarsky diff --git a/tests/selinux_sestatus-functions/runtest.sh b/tests/selinux_sestatus-functions/runtest.sh new file mode 100755 index 0000000..a89d644 --- /dev/null +++ b/tests/selinux_sestatus-functions/runtest.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/libselinux/Sanity/selinux_sestatus-functions +# Description: Test sestatus.c functions +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="libselinux" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm ${PACKAGE} + rlAssertRpm ${PACKAGE}-devel + rlAssertRpm "glibc" + + rlRun -l "gcc test.c -o test -lselinux -pedantic -Wall -Wextra -std=c99" + rlPhaseEnd + + rlPhaseStartTest + rlRun "./test > res.txt" + rlRun -l "cat res.txt" + + SELINUX_MNT=$(cat /proc/mounts | grep selinux | cut -d " " -f 2) + + rlRun "grep \"(before open) selinux_status_getenforce -1\" res.txt" + rlRun "grep \"(before open) selinux_status_policyload -1\" res.txt" + rlRun "grep \"(before open) selinux_status_deny_unknown -1\" res.txt" + rlRun "grep \"(before open) selinux_status_updated -1\" res.txt" + + rlRun "grep \"selinux_status_open 0\" res.txt" + rlRun "grep \"selinux_status_getenforce $(cat $SELINUX_MNT/enforce)\" res.txt" + rlRun "grep -E \"selinux_status_policyload [0-9]\" res.txt" + rlRun "grep \"selinux_status_deny_unknown $(cat $SELINUX_MNT/deny_unknown)\" res.txt" + rlRun "grep \"selinux_status_updated 0\" res.txt" + rlRun "grep \"selinux_status_close void\" res.txt" + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "rm -f test" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd diff --git a/tests/selinux_sestatus-functions/test.c b/tests/selinux_sestatus-functions/test.c new file mode 100644 index 0000000..4733eb8 --- /dev/null +++ b/tests/selinux_sestatus-functions/test.c @@ -0,0 +1,38 @@ +#include +#include +#include + +int main(__attribute__((unused)) int argc, __attribute__((unused)) char **argv) { + printf("(before open) selinux_status_getenforce %d\n", + selinux_status_getenforce()); + + printf("(before open) selinux_status_policyload %d\n", + selinux_status_policyload()); + + printf("(before open) selinux_status_deny_unknown %d\n", + selinux_status_deny_unknown()); + + printf("(before open) selinux_status_updated %d\n", + selinux_status_updated()); + + + printf("selinux_status_open %d\n", + selinux_status_open(1)); + + printf("selinux_status_getenforce %d\n", + selinux_status_getenforce()); + + printf("selinux_status_policyload %d\n", + selinux_status_policyload()); + + printf("selinux_status_deny_unknown %d\n", + selinux_status_deny_unknown()); + + printf("selinux_status_updated %d\n", + selinux_status_updated()); + + printf("selinux_status_close void\n"); + selinux_status_close(); + + return 0; +} diff --git a/tests/selinux_set_callback/Makefile b/tests/selinux_set_callback/Makefile new file mode 100644 index 0000000..0a43858 --- /dev/null +++ b/tests/selinux_set_callback/Makefile @@ -0,0 +1,63 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/libselinux/Sanity/selinux_set_callback +# Description: Test selinux_set_callback function +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/libselinux/Sanity/selinux_set_callback +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE test_*.c + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh test_*.c + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Jan Zarsky " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Test selinux_set_callback function" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 5m" >> $(METADATA) + @echo "RunFor: libselinux" >> $(METADATA) + @echo "Requires: libselinux gcc glibc libselinux-devel" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2+" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "Releases: -RHEL4 -RHELClient5 -RHELServer5" >> $(METADATA) + + rhts-lint $(METADATA) diff --git a/tests/selinux_set_callback/PURPOSE b/tests/selinux_set_callback/PURPOSE new file mode 100644 index 0000000..d28b307 --- /dev/null +++ b/tests/selinux_set_callback/PURPOSE @@ -0,0 +1,3 @@ +PURPOSE of /CoreOS/libselinux/Sanity/selinux_set_callback +Description: Test selinux_set_callback function +Author: Jan Zarsky diff --git a/tests/selinux_set_callback/runtest.sh b/tests/selinux_set_callback/runtest.sh new file mode 100755 index 0000000..d432497 --- /dev/null +++ b/tests/selinux_set_callback/runtest.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/libselinux/Sanity/selinux_set_callback +# Description: Test selinux_set_callback function +# Author: Jan Zarsky +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="libselinux" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm ${PACKAGE} + rlAssertRpm ${PACKAGE}-devel + rlAssertRpm "glibc" + rlAssertRpm "gcc" + + rlRun -l "gcc test_callback.c -o test_callback -lselinux -Wall -Wextra -Wno-unused-parameter -std=c99" + rlPhaseEnd + + rlPhaseStartTest + rlRun "./test_callback > out 2> err" + + rlRun "cat out" + rlRun "cat err" + + rlRun "grep 'function my_log' out" + rlRun "grep 'function my_audit' out" + rlRun "grep 'function my_validate' out" + rlRun "grep 'function my_setenforce' out" + rlRun "grep 'function my_policyload' out" + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "rm -f test_callback out err" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd diff --git a/tests/selinux_set_callback/test_callback.c b/tests/selinux_set_callback/test_callback.c new file mode 100644 index 0000000..240bd11 --- /dev/null +++ b/tests/selinux_set_callback/test_callback.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int validate_counter = 0; + +int my_log(int type, const char *fmt, ...) { + printf("function my_log, type: %d, fmt: %s\n", type, fmt); + return 0; +} + +int my_audit(void *auditdata, security_class_t cls, char *msgbuf, size_t msgbufsize) { + printf("function my_audit, auditdata: %p, cls: %u, msgbuf: %s, msgbufsize: %lu\n", auditdata, cls, msgbuf, msgbufsize); + return 0; +} + +int my_validate(char **ctx) { + if (validate_counter++ == 0) + printf("function my_validate, ctx: %p\n", (void *) ctx); + + return 0; +} + +int my_setenforce(int enforcing) { + printf("function my_setenforce, enforcing: %d\n", enforcing); + return 0; +} + +int my_policyload(int seqno) { + printf("function my_policyload, seqno: %d\n", seqno); + return 0; +} + +int main (int argc, char **argv) { + int exit_code = 0; + + // LOG + printf("setting LOG callback\n"); + selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) my_log); + + if (selinux_get_callback(SELINUX_CB_LOG).func_log != my_log) { + printf("ERROR: selinux_get_callback() does not match\n"); + exit_code = 1; + } + + // AUDIT + printf("setting AUDIT callback\n"); + selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) my_audit); + + if (selinux_get_callback(SELINUX_CB_AUDIT).func_audit != my_audit) { + printf("ERROR: selinux_get_callback() does not match\n"); + exit_code = 1; + } + + printf("calling avc_audit to call audit and log functions\n"); + + avc_init("", NULL, NULL, NULL, NULL); + + struct security_id ssid = { "asdf", 5 }; + struct security_id tsid = { "asdf", 5 }; + struct av_decision avd = { 1, 0, 1, 0, 0, 0 }; + + avc_audit(&ssid, &tsid, 0, 1, &avd, 0, NULL); + + // VALIDATE + printf("setting VALIDATE callback\n"); + selinux_set_callback(SELINUX_CB_VALIDATE, (union selinux_callback) my_validate); + + if (selinux_get_callback(SELINUX_CB_VALIDATE).func_validate != my_validate) { + printf("ERROR: selinux_get_callback() does not match\n"); + exit_code = 1; + } + + struct selabel_handle *hnd = NULL; + struct selinux_opt selabel_option [] = { + { SELABEL_OPT_VALIDATE, (char *) 1 } + }; + + hnd = selabel_open(SELABEL_CTX_FILE, selabel_option, 1); + selabel_close(hnd); + + // SETENFORCE + printf("setting SETENFORCE callback\n"); + selinux_set_callback(SELINUX_CB_SETENFORCE, (union selinux_callback) my_setenforce); + + if (selinux_get_callback(SELINUX_CB_SETENFORCE).func_setenforce != my_setenforce) { + printf("ERROR: selinux_get_callback() does not match\n"); + exit_code = 1; + } + + int enforcing = security_getenforce(); + + printf("calling security_setenforce to call setenforce function\n"); + + if (enforcing == 1) { + security_setenforce(0); + security_setenforce(1); + } + else { + security_setenforce(1); + security_setenforce(0); + } + + // triggers callbacks + avc_has_perm_noaudit(&ssid, &tsid, 0, 1, NULL, &avd); + + // POLICYLOAD + printf("setting POLICYLOAD callback\n"); + selinux_set_callback(SELINUX_CB_POLICYLOAD, (union selinux_callback) my_policyload); + + if (selinux_get_callback(SELINUX_CB_POLICYLOAD).func_policyload != my_policyload) { + printf("ERROR: selinux_get_callback() does not match\n"); + exit_code = 1; + } + + selinux_mkload_policy(1); + + // triggers callbacks + avc_has_perm_noaudit(&ssid, &tsid, 0, 1, NULL, &avd); + + return exit_code; +} diff --git a/tests/setenforce/Makefile b/tests/setenforce/Makefile new file mode 100644 index 0000000..6a0365a --- /dev/null +++ b/tests/setenforce/Makefile @@ -0,0 +1,64 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/libselinux/Sanity/setenforce +# Description: Does setenforce work as expected? Does it produce correct audit messages? +# Author: Milos Malik +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/libselinux/Sanity/setenforce +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Milos Malik " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Does setenforce work as expected? Does it produce correct audit messages?" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 5m" >> $(METADATA) + @echo "RunFor: libselinux" >> $(METADATA) + @echo "Requires: audit libselinux libselinux-utils e2fsprogs" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "Releases: -RHEL4 -RHELClient5 -RHELServer5" >> $(METADATA) + + rhts-lint $(METADATA) + diff --git a/tests/setenforce/PURPOSE b/tests/setenforce/PURPOSE new file mode 100644 index 0000000..de8a77e --- /dev/null +++ b/tests/setenforce/PURPOSE @@ -0,0 +1,5 @@ +PURPOSE of /CoreOS/libselinux/Sanity/setenforce +Author: Milos Malik + +Does setenforce work as expected? Does it produce correct audit messages? + diff --git a/tests/setenforce/runtest.sh b/tests/setenforce/runtest.sh new file mode 100644 index 0000000..1378eae --- /dev/null +++ b/tests/setenforce/runtest.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/libselinux/Sanity/setenforce +# Description: Does setenforce work as expected? Does it produce correct audit messages? +# Author: Milos Malik +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="libselinux" +if rlIsRHEL 5 6 ; then + SELINUX_FS_MOUNT="/selinux" +else # RHEL-7 and above + SELINUX_FS_MOUNT="/sys/fs/selinux" +fi + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm ${PACKAGE} + rlAssertRpm ${PACKAGE}-utils + rlRun "setenforce --help" 0,1 + OUTPUT_FILE=`mktemp` + export LC_ALL=en_US.utf8 + rlPhaseEnd + + rlPhaseStartTest "basic use" + START_DATE_TIME=`date "+%m/%d/%Y %T"` + sleep 1 + rlRun "setenforce 1" + rlRun "grep 1 ${SELINUX_FS_MOUNT}/enforce" + rlRun "setenforce 0" + rlRun "grep 0 ${SELINUX_FS_MOUNT}/enforce" + rlRun "setenforce 1" + sleep 5 + rlRun "ausearch --input-logs -m MAC_STATUS -i -ts ${START_DATE_TIME} | grep 'type=MAC_STATUS.*enforcing=1.*old_enforcing=0'" + rlRun "ausearch --input-logs -m MAC_STATUS -i -ts ${START_DATE_TIME} | grep 'type=MAC_STATUS.*enforcing=0.*old_enforcing=1'" + if rlIsRHEL ; then + rlRun "ausearch --input-logs -m MAC_STATUS -i -ts ${START_DATE_TIME} | grep 'type=SYSCALL.*comm=setenforce'" + fi + rlPhaseEnd + + rlPhaseStartTest "extreme cases" + rlRun "umount ${SELINUX_FS_MOUNT}" + for OPTION in 1 0 Enforcing Permissive ; do + rlRun "setenforce ${OPTION} 2>&1 | tee ${OUTPUT_FILE}" + rlAssertGrep "selinux.*disabled" ${OUTPUT_FILE} -i + done + rlRun "mount -t selinuxfs none ${SELINUX_FS_MOUNT}" + rlRun "touch ./enforce" + rlRun "chattr +i ./enforce" + rlRun "mount --bind ./enforce ${SELINUX_FS_MOUNT}/enforce" + for OPTION in 1 0 Enforcing Permissive ; do + rlRun "setenforce ${OPTION} 2>&1 | tee ${OUTPUT_FILE}" + rlAssertGrep "setenforce.*failed" ${OUTPUT_FILE} -i + done + rlRun "umount ${SELINUX_FS_MOUNT}/enforce" + rlRun "chattr -i ./enforce" + rlRun "rm -f ./enforce" + rlPhaseEnd + + rlPhaseStartCleanup + rm -f ${OUTPUT_FILE} + rlPhaseEnd +rlJournalPrintText +rlJournalEnd + diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..7fc5ec2 --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,41 @@ +--- +# Test to run in classic context +- hosts: localhost + roles: + - role: standard-test-beakerlib + tags: + - classic + repositories: + - repo: "https://src.fedoraproject.org/tests/selinux.git" + dest: "selinux" + fmf_filter: "tier: 1 | component: libselinux" + +# Tests to run inside a container +- hosts: localhost + roles: + - role: standard-test-beakerlib + tags: + - container + repositories: + - repo: "https://src.fedoraproject.org/tests/selinux.git" + dest: "selinux" + tests: + - selinux/libselinux/realpath_not_final-function + required_packages: + - libselinux + - libselinux-devel + - glibc + - gcc + +# Tests to run for Atomic Host +- hosts: localhost + roles: + - role: standard-test-beakerlib + tags: + - atomic + repositories: + - repo: "https://src.fedoraproject.org/tests/selinux.git" + dest: "selinux" + tests: + - selinux/libselinux/getsebool + - selinux/libselinux/setenforce