Compare commits

...

No commits in common. "c8" and "stream-libselinux-python-2.8-rhel-8.10.0" have entirely different histories.

65 changed files with 5135 additions and 847 deletions

View File

@ -1 +1 @@
c53911ee9da673f7653ab1afe66c0b2bf5fb5ac9 SOURCES/libselinux-2.9.tar.gz
c53911ee9da673f7653ab1afe66c0b2bf5fb5ac9 libselinux-2.9.tar.gz

View File

@ -1,7 +1,7 @@
From f71fc47524bef3c4cd8a412e43d13daebd1c418b Mon Sep 17 00:00:00 2001
From: Miroslav Grepl <mgrepl@redhat.com>
Date: Wed, 16 Jul 2014 08:28:03 +0200
Subject: [PATCH] Fix selinux man page to refer seinfo and sesearch tools.
Subject: [PATCH 1/5] Fix selinux man page to refer seinfo and sesearch tools.
---
libselinux/man/man8/selinux.8 | 4 +++-

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,172 @@
From f785c53174fd0ebad913e105382360f9d46205d8 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <plautrba@redhat.com>
Date: Tue, 31 May 2022 13:37:12 +0200
Subject: [PATCH] Revert "libselinux: restorecon: pin file to avoid TOCTOU
issues"
Content-type: text/plain
This reverts commit 7e979b56fd2cee28f647376a7233d2ac2d12ca50.
The reverted commit broke `setfiles` when it's run from a chroot
without /proc mounted, e.g.
# chroot /mnt/sysimage
chroot# setfiles -e /proc -e /sys /sys /etc/selinux/targeted/contexts/files/file_contexts /
[strace]
openat(AT_FDCWD, "/", O_RDONLY|O_EXCL|O_NOFOLLOW|O_PATH) = 3
newfstatat(3, "", {st_mode=S_IFDIR|0555, st_size=4096, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1697c91000
fgetxattr(3, "security.selinux", 0x55be8881d3f0, 255) = -1 EBADF (Bad file descriptor)
fcntl(3, F_GETFL) = 0x220000 (flags O_RDONLY|O_NOFOLLOW|O_PATH)
getxattr("/proc/self/fd/3", "security.selinux", 0x55be8881d3f0, 255) = -1 ENOENT (No such file or directory)
[/strace]
setfiles: Could not set context for /: No such file or directory
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
---
libselinux/src/selinux_restorecon.c | 43 ++++++++++++-----------------
1 file changed, 18 insertions(+), 25 deletions(-)
diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c
index dc222b425c95..a50005353265 100644
--- a/libselinux/src/selinux_restorecon.c
+++ b/libselinux/src/selinux_restorecon.c
@@ -623,13 +623,13 @@ out:
return rc;
}
-static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool first)
+static int restorecon_sb(const char *pathname, const struct stat *sb,
+ struct rest_flags *flags, bool first)
{
char *newcon = NULL;
char *curcon = NULL;
char *newtypecon = NULL;
- int fd = -1, rc;
- struct stat stat_buf;
+ int rc;
bool updated = false;
const char *lookup_path = pathname;
float pc;
@@ -644,21 +644,13 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi
lookup_path += rootpathlen;
}
- fd = open(pathname, O_PATH | O_NOFOLLOW | O_EXCL);
- if (fd < 0)
- goto err;
-
- rc = fstat(fd, &stat_buf);
- if (rc < 0)
- goto err;
-
if (rootpath != NULL && lookup_path[0] == '\0')
/* this is actually the root dir of the alt root. */
rc = selabel_lookup_raw(fc_sehandle, &newcon, "/",
- stat_buf.st_mode);
+ sb->st_mode);
else
rc = selabel_lookup_raw(fc_sehandle, &newcon, lookup_path,
- stat_buf.st_mode);
+ sb->st_mode);
if (rc < 0) {
if (errno == ENOENT) {
@@ -667,10 +659,10 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi
"Warning no default label for %s\n",
lookup_path);
- goto out; /* no match, but not an error */
+ return 0; /* no match, but not an error */
}
- goto err;
+ return -1;
}
if (flags->progress) {
@@ -690,17 +682,19 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi
}
if (flags->add_assoc) {
- rc = filespec_add(stat_buf.st_ino, newcon, pathname, flags);
+ rc = filespec_add(sb->st_ino, newcon, pathname, flags);
if (rc < 0) {
selinux_log(SELINUX_ERROR,
"filespec_add error: %s\n", pathname);
- goto out1;
+ freecon(newcon);
+ return -1;
}
if (rc > 0) {
/* Already an association and it took precedence. */
- goto out;
+ freecon(newcon);
+ return 0;
}
}
@@ -708,7 +702,7 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi
selinux_log(SELINUX_INFO, "%s matched by %s\n",
pathname, newcon);
- if (fgetfilecon_raw(fd, &curcon) < 0) {
+ if (lgetfilecon_raw(pathname, &curcon) < 0) {
if (errno != ENODATA)
goto err;
@@ -741,7 +735,7 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi
}
if (!flags->nochange) {
- if (fsetfilecon(fd, newcon) < 0)
+ if (lsetfilecon(pathname, newcon) < 0)
goto err;
updated = true;
}
@@ -766,8 +760,6 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi
out:
rc = 0;
out1:
- if (fd >= 0)
- close(fd);
freecon(curcon);
freecon(newcon);
return rc;
@@ -865,6 +857,7 @@ static void *selinux_restorecon_thread(void *arg)
FTSENT *ftsent;
int error;
char ent_path[PATH_MAX];
+ struct stat ent_st;
bool first = false;
if (state->parallel)
@@ -962,11 +955,11 @@ loop_body:
/* fall through */
default:
strcpy(ent_path, ftsent->fts_path);
-
+ ent_st = *ftsent->fts_statp;
if (state->parallel)
pthread_mutex_unlock(&state->mutex);
- error = restorecon_sb(ent_path, &state->flags,
+ error = restorecon_sb(ent_path, &ent_st, &state->flags,
first);
if (state->parallel) {
@@ -1162,7 +1155,7 @@ static int selinux_restorecon_common(const char *pathname_orig,
goto cleanup;
}
- error = restorecon_sb(pathname, &state.flags, true);
+ error = restorecon_sb(pathname, &sb, &state.flags, true);
goto cleanup;
}
--
2.36.1

View File

@ -1,7 +1,7 @@
From ad3d3a0bf819f5895a6884357c2d0e18ea1ef314 Mon Sep 17 00:00:00 2001
From: Dan Walsh <dwalsh@redhat.com>
Date: Mon, 23 Dec 2013 09:50:54 -0500
Subject: [PATCH] Verify context input to funtions to make sure the context
Subject: [PATCH 2/5] Verify context input to funtions to make sure the context
field is not null.
Return errno EINVAL, to prevent segfault.

View File

@ -1,8 +1,8 @@
From a6e839be2c5a77c22a8c72cad001e3f87eaedf2e Mon Sep 17 00:00:00 2001
From 431f72836d6c02450725cf6ffb1c7223b9fa6acc Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <plautrba@redhat.com>
Date: Mon, 11 Mar 2019 15:26:43 +0100
Subject: [PATCH] libselinux: Allow to override OVERRIDE_GETTID from command
line
Subject: [PATCH 3/5] libselinux: Allow to override OVERRIDE_GETTID from
command line
$ make CFLAGS="$CFLAGS -DOVERRIDE_GETTID=0" ...

View File

@ -1,8 +1,8 @@
From be420729fbf4adc8b32ca3722fa6ca46bb51413d Mon Sep 17 00:00:00 2001
From dca54ca1a8ab0b256e7834f7f5e97375427fbfd9 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <plautrba@redhat.com>
Date: Wed, 27 Feb 2019 09:37:17 +0100
Subject: [PATCH] Bring some old permission and flask constants back to Python
bindings
Subject: [PATCH 4/5] Bring some old permission and flask constants back to
Python bindings
---
libselinux/src/selinuxswig.i | 4 ++++

View File

@ -1,7 +1,7 @@
From 903c54bf62ffba3c95e22e74c9c43838cd3935a0 Mon Sep 17 00:00:00 2001
From 8384ffa7a371c8845c145951363da5d978ab98b5 Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Tue, 28 Feb 2017 16:12:43 +0100
Subject: [PATCH] libselinux: add missing av_permission values
Subject: [PATCH 5/5] libselinux: add missing av_permission values
Add missing av_permission values to av_permissions.h for the sake of
completeness (this interface is obsolete - these values are now

View File

@ -1,8 +1,8 @@
From 67d490a38a319126f371eaf66a5fc922d7005b1f Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <plautrba@redhat.com>
Date: Thu, 16 May 2019 15:01:59 +0200
Subject: [PATCH] libselinux: Use Python distutils to install SELinux python
bindings
Subject: [PATCH 6/6] libselinux: Use Python distutils to install SELinux
python bindings
SWIG-4.0 changed its behavior so that it uses: from . import _selinux which
looks for _selinux module in the same directory as where __init__.py is -
@ -173,5 +173,5 @@ index 00000000..b12e7869
+ ],
+)
--
2.21.0
2.22.0

View File

@ -1,8 +1,8 @@
From 6ec8116ee64a25a0c5eb543f0b12ed25f1348c45 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <plautrba@redhat.com>
Date: Thu, 27 Jun 2019 11:17:13 +0200
Subject: [PATCH] libselinux: Do not use SWIG_CFLAGS when Python bindings are
built
Subject: [PATCH 7/7] libselinux: Do not use SWIG_CFLAGS when Python bindings
are built
Fixes:
https://rpmdiff.engineering.redhat.com/run/410372/7/
@ -40,5 +40,5 @@ index 826c830c..f64f23a8 100644
rubywrap: all $(SWIGRUBYSO)
--
2.21.0
2.22.0

View File

@ -1,66 +0,0 @@
From 90a4f2b9a5194a2d1ab4c45b7a90bbb6c8099a68 Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Tue, 2 Jul 2019 14:09:05 +0200
Subject: [PATCH] Fix mcstrans secolor examples
According to "check_dominance" function:
Range defined as "s15:c0.c1023" does not dominate any other range than
"s15:c0.c1023" (does not dominate "s15", "s15:c0.c200", etc.).
While range defined as "s15-s15:c0.c1023" dominates all of the above.
This is either a bug, or "s15:c0.c1023" should not be used in the
examples.
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
---
libselinux/man/man5/secolor.conf.5 | 4 ++--
libselinux/man/ru/man5/secolor.conf.5 | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libselinux/man/man5/secolor.conf.5 b/libselinux/man/man5/secolor.conf.5
index b834577a..a3bf2da1 100644
--- a/libselinux/man/man5/secolor.conf.5
+++ b/libselinux/man/man5/secolor.conf.5
@@ -123,7 +123,7 @@ range s7\-s7:c0.c1023 = black red
.br
range s9\-s9:c0.c1023 = black orange
.br
-range s15:c0.c1023 = black yellow
+range s15\-s15:c0.c1023 = black yellow
.RE
.sp
@@ -165,7 +165,7 @@ type xguest_t = black green
.br
user sysadm_u = white black
.br
-range s0:c0.c1023 = black white
+range s0-s0:c0.c1023 = black white
.br
user * = black white
.br
diff --git a/libselinux/man/ru/man5/secolor.conf.5 b/libselinux/man/ru/man5/secolor.conf.5
index 4c1236ae..bcae80c1 100644
--- a/libselinux/man/ru/man5/secolor.conf.5
+++ b/libselinux/man/ru/man5/secolor.conf.5
@@ -121,7 +121,7 @@ range s7\-s7:c0.c1023 = black red
.br
range s9\-s9:c0.c1023 = black orange
.br
-range s15:c0.c1023 = black yellow
+range s15\-s15:c0.c1023 = black yellow
.RE
.sp
@@ -163,7 +163,7 @@ type xguest_t = black green
.br
user sysadm_u = white black
.br
-range s0:c0.c1023 = black white
+range s0\-s0:c0.c1023 = black white
.br
user * = black white
.br
--
2.21.0

View File

@ -1,354 +0,0 @@
From bfee1a3131580a7b9d8a7366764b8e78d99a9f1b Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <plautrba@redhat.com>
Date: Mon, 17 Feb 2020 21:47:35 +0100
Subject: [PATCH] libselinux: Eliminate use of security_compute_user()
get_ordered_context_list() code used to ask the kernel to compute the complete
set of reachable contexts using /sys/fs/selinux/user aka
security_compute_user(). This set can be so huge so that it doesn't fit into a
kernel page and security_compute_user() fails. Even if it doesn't fail,
get_ordered_context_list() throws away the vast majority of the returned
contexts because they don't match anything in
/etc/selinux/targeted/contexts/default_contexts or
/etc/selinux/targeted/contexts/users/
get_ordered_context_list() is rewritten to compute set of contexts based on
/etc/selinux/targeted/contexts/users/ and
/etc/selinux/targeted/contexts/default_contexts files and to return only valid
contexts, using security_check_context(), from this set.
Fixes: https://github.com/SELinuxProject/selinux/issues/28
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
---
libselinux/src/get_context_list.c | 212 +++++++++++++-----------------
1 file changed, 93 insertions(+), 119 deletions(-)
diff --git a/libselinux/src/get_context_list.c b/libselinux/src/get_context_list.c
index 689e4658..26d7b3b9 100644
--- a/libselinux/src/get_context_list.c
+++ b/libselinux/src/get_context_list.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include <stdio.h>
#include <stdio_ext.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
@@ -114,64 +115,41 @@ int get_default_context(const char *user,
return 0;
}
-static int find_partialcon(char ** list,
- unsigned int nreach, char *part)
+static int is_in_reachable(char **reachable, const char *usercon_str)
{
- const char *conrole, *contype;
- char *partrole, *parttype, *ptr;
- context_t con;
- unsigned int i;
+ if (!reachable)
+ return 0;
- partrole = part;
- ptr = part;
- while (*ptr && !isspace(*ptr) && *ptr != ':')
- ptr++;
- if (*ptr != ':')
- return -1;
- *ptr++ = 0;
- parttype = ptr;
- while (*ptr && !isspace(*ptr) && *ptr != ':')
- ptr++;
- *ptr = 0;
-
- for (i = 0; i < nreach; i++) {
- con = context_new(list[i]);
- if (!con)
- return -1;
- conrole = context_role_get(con);
- contype = context_type_get(con);
- if (!conrole || !contype) {
- context_free(con);
- return -1;
- }
- if (!strcmp(conrole, partrole) && !strcmp(contype, parttype)) {
- context_free(con);
- return i;
+ for (; *reachable != NULL; reachable++) {
+ if (strcmp(*reachable, usercon_str) == 0) {
+ return 1;
}
- context_free(con);
}
-
- return -1;
+ return 0;
}
-static int get_context_order(FILE * fp,
+static int get_context_user(FILE * fp,
char * fromcon,
- char ** reachable,
- unsigned int nreach,
- unsigned int *ordering, unsigned int *nordered)
+ const char * user,
+ char ***reachable,
+ unsigned int *nreachable)
{
char *start, *end = NULL;
char *line = NULL;
- size_t line_len = 0;
+ size_t line_len = 0, usercon_len;
+ size_t user_len = strlen(user);
ssize_t len;
int found = 0;
- const char *fromrole, *fromtype;
+ const char *fromrole, *fromtype, *fromlevel;
char *linerole, *linetype;
- unsigned int i;
+ char **new_reachable = NULL;
+ char *usercon_str;
context_t con;
+ context_t usercon;
+
int rc;
- errno = -EINVAL;
+ errno = EINVAL;
/* Extract the role and type of the fromcon for matching.
User identity and MLS range can be variable. */
@@ -180,6 +158,7 @@ static int get_context_order(FILE * fp,
return -1;
fromrole = context_role_get(con);
fromtype = context_type_get(con);
+ fromlevel = context_range_get(con);
if (!fromrole || !fromtype) {
context_free(con);
return -1;
@@ -243,23 +222,75 @@ static int get_context_order(FILE * fp,
if (*end)
*end++ = 0;
- /* Check for a match in the reachable list. */
- rc = find_partialcon(reachable, nreach, start);
- if (rc < 0) {
- /* No match, skip it. */
+ /* Check whether a new context is valid */
+ if (SIZE_MAX - user_len < strlen(start) + 2) {
+ fprintf(stderr, "%s: one of partial contexts is too big\n", __FUNCTION__);
+ errno = EINVAL;
+ rc = -1;
+ goto out;
+ }
+ usercon_len = user_len + strlen(start) + 2;
+ usercon_str = malloc(usercon_len);
+ if (!usercon_str) {
+ rc = -1;
+ goto out;
+ }
+
+ /* set range from fromcon in the new usercon */
+ snprintf(usercon_str, usercon_len, "%s:%s", user, start);
+ usercon = context_new(usercon_str);
+ if (!usercon) {
+ if (errno != EINVAL) {
+ free(usercon_str);
+ rc = -1;
+ goto out;
+ }
+ fprintf(stderr,
+ "%s: can't create a context from %s, skipping\n",
+ __FUNCTION__, usercon_str);
+ free(usercon_str);
start = end;
continue;
}
+ free(usercon_str);
+ if (context_range_set(usercon, fromlevel) != 0) {
+ context_free(usercon);
+ rc = -1;
+ goto out;
+ }
+ usercon_str = context_str(usercon);
+ if (!usercon_str) {
+ context_free(usercon);
+ rc = -1;
+ goto out;
+ }
- /* If a match is found and the entry is not already ordered
- (e.g. due to prior match in prior config file), then set
- the ordering for it. */
- i = rc;
- if (ordering[i] == nreach)
- ordering[i] = (*nordered)++;
+ /* check whether usercon is already in reachable */
+ if (is_in_reachable(*reachable, usercon_str)) {
+ context_free(usercon);
+ start = end;
+ continue;
+ }
+ if (security_check_context(usercon_str) == 0) {
+ new_reachable = realloc(*reachable, (*nreachable + 2) * sizeof(char *));
+ if (!new_reachable) {
+ context_free(usercon);
+ rc = -1;
+ goto out;
+ }
+ *reachable = new_reachable;
+ new_reachable[*nreachable] = strdup(usercon_str);
+ if (new_reachable[*nreachable] == NULL) {
+ context_free(usercon);
+ rc = -1;
+ goto out;
+ }
+ new_reachable[*nreachable + 1] = 0;
+ *nreachable += 1;
+ }
+ context_free(usercon);
start = end;
}
-
rc = 0;
out:
@@ -313,21 +344,6 @@ static int get_failsafe_context(const char *user, char ** newcon)
return 0;
}
-struct context_order {
- char * con;
- unsigned int order;
-};
-
-static int order_compare(const void *A, const void *B)
-{
- const struct context_order *c1 = A, *c2 = B;
- if (c1->order < c2->order)
- return -1;
- else if (c1->order > c2->order)
- return 1;
- return strcmp(c1->con, c2->con);
-}
-
int get_ordered_context_list_with_level(const char *user,
const char *level,
char * fromcon,
@@ -395,11 +411,8 @@ int get_ordered_context_list(const char *user,
char *** list)
{
char **reachable = NULL;
- unsigned int *ordering = NULL;
- struct context_order *co = NULL;
- char **ptr;
int rc = 0;
- unsigned int nreach = 0, nordered = 0, freefrom = 0, i;
+ unsigned nreachable = 0, freefrom = 0;
FILE *fp;
char *fname = NULL;
size_t fname_len;
@@ -413,23 +426,6 @@ int get_ordered_context_list(const char *user,
freefrom = 1;
}
- /* Determine the set of reachable contexts for the user. */
- rc = security_compute_user(fromcon, user, &reachable);
- if (rc < 0)
- goto failsafe;
- nreach = 0;
- for (ptr = reachable; *ptr; ptr++)
- nreach++;
- if (!nreach)
- goto failsafe;
-
- /* Initialize ordering array. */
- ordering = malloc(nreach * sizeof(unsigned int));
- if (!ordering)
- goto failsafe;
- for (i = 0; i < nreach; i++)
- ordering[i] = nreach;
-
/* Determine the ordering to apply from the optional per-user config
and from the global config. */
fname_len = strlen(user_contexts_path) + strlen(user) + 2;
@@ -440,8 +436,8 @@ int get_ordered_context_list(const char *user,
fp = fopen(fname, "re");
if (fp) {
__fsetlocking(fp, FSETLOCKING_BYCALLER);
- rc = get_context_order(fp, fromcon, reachable, nreach, ordering,
- &nordered);
+ rc = get_context_user(fp, fromcon, user, &reachable, &nreachable);
+
fclose(fp);
if (rc < 0 && errno != ENOENT) {
fprintf(stderr,
@@ -454,8 +450,7 @@ int get_ordered_context_list(const char *user,
fp = fopen(selinux_default_context_path(), "re");
if (fp) {
__fsetlocking(fp, FSETLOCKING_BYCALLER);
- rc = get_context_order(fp, fromcon, reachable, nreach, ordering,
- &nordered);
+ rc = get_context_user(fp, fromcon, user, &reachable, &nreachable);
fclose(fp);
if (rc < 0 && errno != ENOENT) {
fprintf(stderr,
@@ -463,40 +458,19 @@ int get_ordered_context_list(const char *user,
__FUNCTION__, selinux_default_context_path());
/* Fall through */
}
- rc = 0;
}
- if (!nordered)
+ if (!nreachable)
goto failsafe;
- /* Apply the ordering. */
- co = malloc(nreach * sizeof(struct context_order));
- if (!co)
- goto failsafe;
- for (i = 0; i < nreach; i++) {
- co[i].con = reachable[i];
- co[i].order = ordering[i];
- }
- qsort(co, nreach, sizeof(struct context_order), order_compare);
- for (i = 0; i < nreach; i++)
- reachable[i] = co[i].con;
- free(co);
-
- /* Only report the ordered entries to the caller. */
- if (nordered <= nreach) {
- for (i = nordered; i < nreach; i++)
- free(reachable[i]);
- reachable[nordered] = NULL;
- rc = nordered;
- }
-
out:
- if (rc > 0)
+ if (nreachable > 0) {
*list = reachable;
+ rc = nreachable;
+ }
else
freeconary(reachable);
- free(ordering);
if (freefrom)
freecon(fromcon);
@@ -519,7 +493,7 @@ int get_ordered_context_list(const char *user,
reachable = NULL;
goto out;
}
- rc = 1; /* one context in the list */
+ nreachable = 1; /* one context in the list */
goto out;
}
--
2.25.4

View File

@ -1,168 +0,0 @@
From d4c22fcd5943fe35db648dee971f631d40b3eb94 Mon Sep 17 00:00:00 2001
From: Stephen Smalley <sds@tycho.nsa.gov>
Date: Thu, 20 Feb 2020 10:40:19 -0500
Subject: [PATCH] libselinux: deprecate security_compute_user(), update man
pages
commit 1f89c4e7879fcf6da5d8d1b025dcc03371f30fc9 ("libselinux: Eliminate
use of security_compute_user()") eliminated the use of
security_compute_user() by get_ordered_context_list(). Deprecate
all use of security_compute_user() by updating the headers and man
pages and logging a warning message on any calls to it. Remove
the example utility that called the interface. While here, also
fix the documentation of correct usage of the user argument to these
interfaces.
Fixes: https://github.com/SELinuxProject/selinux/issues/70
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: Petr Lautrbach <plautrba@redhat.com>
---
libselinux/include/selinux/selinux.h | 8 +++-
.../man/man3/get_ordered_context_list.3 | 24 +++++++++---
libselinux/man/man3/security_compute_av.3 | 5 ++-
libselinux/src/compute_user.c | 3 ++
libselinux/utils/compute_user.c | 38 -------------------
5 files changed, 31 insertions(+), 47 deletions(-)
delete mode 100644 libselinux/utils/compute_user.c
diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h
index a34d54fc..a5ada324 100644
--- a/libselinux/include/selinux/selinux.h
+++ b/libselinux/include/selinux/selinux.h
@@ -246,8 +246,12 @@ extern int security_compute_member_raw(const char * scon,
security_class_t tclass,
char ** newcon);
-/* Compute the set of reachable user contexts and set *con to refer to
- the NULL-terminated array of contexts. Caller must free via freeconary. */
+/*
+ * Compute the set of reachable user contexts and set *con to refer to
+ * the NULL-terminated array of contexts. Caller must free via freeconary.
+ * These interfaces are deprecated. Use get_ordered_context_list() or
+ * one of its variant interfaces instead.
+ */
extern int security_compute_user(const char * scon,
const char *username,
char *** con);
diff --git a/libselinux/man/man3/get_ordered_context_list.3 b/libselinux/man/man3/get_ordered_context_list.3
index e084da40..3ed14a96 100644
--- a/libselinux/man/man3/get_ordered_context_list.3
+++ b/libselinux/man/man3/get_ordered_context_list.3
@@ -26,14 +26,28 @@ get_ordered_context_list, get_ordered_context_list_with_level, get_default_conte
.BI "int get_default_type(const char *" role ", char **" type );
.
.SH "DESCRIPTION"
+
+This family of functions can be used to obtain either a prioritized list of
+all reachable security contexts for a given SELinux user or a single default
+(highest priority) context for a given SELinux user for use by login-like
+programs. These functions takes a SELinux user identity that must
+be defined in the SELinux policy as their input, not a Linux username.
+Most callers should typically first call
+.BR getseuserbyname(3)
+to look up the SELinux user identity and level for a given
+Linux username and then invoke one of
+.BR get_ordered_context_list_with_level ()
+or
+.BR get_default_context_with_level ()
+with the returned SELinux user and level as inputs.
+
.BR get_ordered_context_list ()
-invokes the
-.BR security_compute_user (3)
-function to obtain the list of contexts for the specified
+obtains the list of contexts for the specified
+SELinux
.I user
-that are reachable from the specified
+identity that are reachable from the specified
.I fromcon
-context. The function then orders the resulting list based on the global
+context based on the global
.I \%/etc/selinux/{SELINUXTYPE}/contexts/default_contexts
file and the per-user
.I \%/etc/selinux/{SELINUXTYPE}/contexts/users/<username>
diff --git a/libselinux/man/man3/security_compute_av.3 b/libselinux/man/man3/security_compute_av.3
index 2aade5fe..8e1f746a 100644
--- a/libselinux/man/man3/security_compute_av.3
+++ b/libselinux/man/man3/security_compute_av.3
@@ -97,8 +97,9 @@ instance.
.BR security_compute_user ()
is used to determine the set of user contexts that can be reached from a
-source context. It is mainly used by
-.BR get_ordered_context_list ().
+source context. This function is deprecated; use
+.BR get_ordered_context_list (3)
+instead.
.BR security_get_initial_context ()
is used to get the context of a kernel initial security identifier specified by
diff --git a/libselinux/src/compute_user.c b/libselinux/src/compute_user.c
index 401fd107..0f55de84 100644
--- a/libselinux/src/compute_user.c
+++ b/libselinux/src/compute_user.c
@@ -8,6 +8,7 @@
#include "selinux_internal.h"
#include "policy.h"
#include <limits.h>
+#include "callbacks.h"
int security_compute_user_raw(const char * scon,
const char *user, char *** con)
@@ -24,6 +25,8 @@ int security_compute_user_raw(const char * scon,
return -1;
}
+ selinux_log(SELINUX_WARNING, "Direct use of security_compute_user() is deprecated, switch to get_ordered_context_list()\n");
+
if (! scon) {
errno=EINVAL;
return -1;
diff --git a/libselinux/utils/compute_user.c b/libselinux/utils/compute_user.c
deleted file mode 100644
index cae62b26..00000000
--- a/libselinux/utils/compute_user.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include <unistd.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <ctype.h>
-#include <selinux/selinux.h>
-
-int main(int argc, char **argv)
-{
- char **buf, **ptr;
- int ret;
-
- if (argc != 3) {
- fprintf(stderr, "usage: %s context user\n", argv[0]);
- exit(1);
- }
-
- ret = security_compute_user(argv[1], argv[2], &buf);
- if (ret < 0) {
- fprintf(stderr, "%s: security_compute_user(%s,%s) failed\n",
- argv[0], argv[1], argv[2]);
- exit(2);
- }
-
- if (!buf[0]) {
- printf("none\n");
- exit(0);
- }
-
- for (ptr = buf; *ptr; ptr++) {
- printf("%s\n", *ptr);
- }
- freeconary(buf);
- exit(0);
-}
--
2.25.4

View File

@ -1,39 +0,0 @@
From c556c6ad0b94cf3ba4b441a1a0930f2468434227 Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Wed, 10 Feb 2021 18:05:29 +0100
Subject: [PATCH] selinux(8,5): Describe fcontext regular expressions
Describe which type of regular expression is used in file context
definitions and which flags are in effect.
Explain how local file context modifications are processed.
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Acked-by: Petr Lautrbach <plautrba@redhat.com>
---
libselinux/man/man5/selabel_file.5 | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/libselinux/man/man5/selabel_file.5 b/libselinux/man/man5/selabel_file.5
index e97bd826..baba7776 100644
--- a/libselinux/man/man5/selabel_file.5
+++ b/libselinux/man/man5/selabel_file.5
@@ -125,7 +125,14 @@ Where:
.RS
.I pathname
.RS
-An entry that defines the pathname that may be in the form of a regular expression.
+An entry that defines the path to be labeled.
+May contain either a fully qualified path,
+or a Perl compatible regular expression (PCRE),
+describing fully qualified path(s).
+The only PCRE flag in use is PCRE2_DOTALL,
+which causes a wildcard '.' to match anything, including a new line.
+Strings representing paths are processed as bytes (as opposed to Unicode),
+meaning that non-ASCII characters are not matched by a single wildcard.
.RE
.I file_type
.RS
--
2.35.3

View File

@ -1,88 +0,0 @@
From 9bf63bb85d4d2cab73181ee1d8d0b07961ce4a80 Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Thu, 17 Feb 2022 14:14:15 +0100
Subject: [PATCH] libselinux: Strip spaces before values in config
Spaces before values in /etc/selinux/config should be ignored just as
spaces after them are.
E.g. "SELINUXTYPE= targeted" should be a valid value.
Fixes:
# sed -i 's/^SELINUXTYPE=/SELINUXTYPE= /g' /etc/selinux/config
# dnf install <any_package>
...
RPM: error: selabel_open: (/etc/selinux/ targeted/contexts/files/file_contexts) No such file or directory
RPM: error: Plugin selinux: hook tsm_pre failed
...
Error: Could not run transaction.
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
---
libselinux/src/selinux_config.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c
index b06cb63b..0892b87c 100644
--- a/libselinux/src/selinux_config.c
+++ b/libselinux/src/selinux_config.c
@@ -91,6 +91,7 @@ int selinux_getenforcemode(int *enforce)
FILE *cfg = fopen(SELINUXCONFIG, "re");
if (cfg) {
char *buf;
+ char *tag;
int len = sizeof(SELINUXTAG) - 1;
buf = malloc(selinux_page_size);
if (!buf) {
@@ -100,21 +101,24 @@ int selinux_getenforcemode(int *enforce)
while (fgets_unlocked(buf, selinux_page_size, cfg)) {
if (strncmp(buf, SELINUXTAG, len))
continue;
+ tag = buf+len;
+ while (isspace(*tag))
+ tag++;
if (!strncasecmp
- (buf + len, "enforcing", sizeof("enforcing") - 1)) {
+ (tag, "enforcing", sizeof("enforcing") - 1)) {
*enforce = 1;
ret = 0;
break;
} else
if (!strncasecmp
- (buf + len, "permissive",
+ (tag, "permissive",
sizeof("permissive") - 1)) {
*enforce = 0;
ret = 0;
break;
} else
if (!strncasecmp
- (buf + len, "disabled",
+ (tag, "disabled",
sizeof("disabled") - 1)) {
*enforce = -1;
ret = 0;
@@ -177,7 +181,10 @@ static void init_selinux_config(void)
if (!strncasecmp(buf_p, SELINUXTYPETAG,
sizeof(SELINUXTYPETAG) - 1)) {
- type = strdup(buf_p + sizeof(SELINUXTYPETAG) - 1);
+ buf_p += sizeof(SELINUXTYPETAG) - 1;
+ while (isspace(*buf_p))
+ buf_p++;
+ type = strdup(buf_p);
if (!type)
return;
end = type + strlen(type) - 1;
@@ -199,6 +206,8 @@ static void init_selinux_config(void)
} else if (!strncmp(buf_p, REQUIRESEUSERS,
sizeof(REQUIRESEUSERS) - 1)) {
value = buf_p + sizeof(REQUIRESEUSERS) - 1;
+ while (isspace(*value))
+ value++;
intptr = &require_seusers;
} else {
continue;
--
2.35.3

View File

@ -1,46 +0,0 @@
From 9a04499cebedac3f585c0240e6cf68f786ae62b7 Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Mon, 31 Oct 2022 17:00:43 +0100
Subject: [PATCH] libselinux: Ignore missing directories when -i is used
Currently "-i" only ignores a file whose parent directory exists. Start also
ignoring paths with missing components.
Fixes:
# restorecon -i -v -R /var/log/missingdir/missingfile; echo $?
255
restorecon: SELinux: Could not get canonical path for /var/log/missingdir/missingfile restorecon: No such file or directory.
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
---
libselinux/src/selinux_restorecon.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c
index 5f189235..2ff73db6 100644
--- a/libselinux/src/selinux_restorecon.c
+++ b/libselinux/src/selinux_restorecon.c
@@ -820,6 +820,10 @@ int selinux_restorecon(const char *pathname_orig,
pathname = realpath(pathname_orig, NULL);
if (!pathname) {
free(basename_cpy);
+ /* missing parent directory */
+ if (flags.ignore_noent && errno == ENOENT) {
+ return 0;
+ }
goto realpatherr;
}
} else {
@@ -833,6 +837,9 @@ int selinux_restorecon(const char *pathname_orig,
free(dirname_cpy);
if (!pathdnamer) {
free(basename_cpy);
+ if (flags.ignore_noent && errno == ENOENT) {
+ return 0;
+ }
goto realpatherr;
}
if (!strcmp(pathdnamer, "/"))
--
2.37.3

View File

@ -1,42 +0,0 @@
From 599f1ec818d50ffc9690fea8c03b5fe278f30ed4 Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Wed, 7 Dec 2022 09:19:29 +0100
Subject: [PATCH] libselinux/restorecon: Fix memory leak - xattr_value
Fix memory leak introduced by commit
9a04499cebedac3f585c0240e6cf68f786ae62b7
libselinux: Ignore missing directories when -i is used
Error: RESOURCE_LEAK:
selinux_restorecon.c:804: alloc_fn: Storage is returned from allocation function "malloc".
selinux_restorecon.c:804: var_assign: Assigning: "xattr_value" = storage returned from "malloc(fc_digest_len)".
selinux_restorecon.c:825: leaked_storage: Variable "xattr_value" going out of scope leaks the storage it points to.
Resolves: rhbz#2137965
---
libselinux/src/selinux_restorecon.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c
index 2ff73db6..b3702764 100644
--- a/libselinux/src/selinux_restorecon.c
+++ b/libselinux/src/selinux_restorecon.c
@@ -822,6 +822,7 @@ int selinux_restorecon(const char *pathname_orig,
free(basename_cpy);
/* missing parent directory */
if (flags.ignore_noent && errno == ENOENT) {
+ free(xattr_value);
return 0;
}
goto realpatherr;
@@ -838,6 +839,7 @@ int selinux_restorecon(const char *pathname_orig,
if (!pathdnamer) {
free(basename_cpy);
if (flags.ignore_noent && errno == ENOENT) {
+ free(xattr_value);
return 0;
}
goto realpatherr;
--
2.37.3

24
STAGE1-libselinux Normal file
View File

@ -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

7
gating.yaml Normal file
View File

@ -0,0 +1,7 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}

View File

@ -6,7 +6,7 @@
%endif
%define libsepolver 2.9-1
%define libselinuxrelease 8
%define libselinuxrelease 2.1
Summary: SELinux library and simple utilities
Name: libselinux
@ -26,13 +26,6 @@ Patch0004: 0004-Bring-some-old-permission-and-flask-constants-back-t.patch
Patch0005: 0005-libselinux-add-missing-av_permission-values.patch
Patch0006: 0006-libselinux-Use-Python-distutils-to-install-SELinux-p.patch
Patch0007: 0007-libselinux-Do-not-use-SWIG_CFLAGS-when-Python-bindin.patch
Patch0008: 0008-Fix-mcstrans-secolor-examples.patch
Patch0009: 0009-libselinux-Eliminate-use-of-security_compute_user.patch
Patch0010: 0010-libselinux-deprecate-security_compute_user-update-ma.patch
Patch0011: 0011-selinux-8-5-Describe-fcontext-regular-expressions.patch
Patch0012: 0012-libselinux-Strip-spaces-before-values-in-config.patch
Patch0013: 0013-libselinux-Ignore-missing-directories-when-i-is-used.patch
Patch0014: 0014-libselinux-restorecon-Fix-memory-leak-xattr_value.patch
BuildRequires: gcc
%if 0%{?with_ruby}
@ -280,25 +273,6 @@ rm -f %{buildroot}%{_mandir}/man8/togglesebool*
%endif
%changelog
* Wed Dec 07 2022 Vit Mojzis <vmojzis@redhat.com> - 2.9-8
- restorecon: Fix memory leak - xattr_value (#2137965)
* Tue Dec 06 2022 Vit Mojzis <vmojzis@redhat.com> - 2.9-7
- Restorecon: Ignore missing directories when -i is used (#2137965)
* Thu Jul 07 2022 Vit Mojzis <vmojzis@redhat.com> - 2.9-6
- Describe fcontext regular expressions (#1904059)
- Strip spaces before values in config (#2012145)
* Tue Oct 20 2020 Vit Mojzis <vmojzis@redhat.com> - 2.9-5
- Deprecate security_compute_user(), update man pages (#1879368)
* Thu Sep 24 2020 Vit Mojzis <vmojzis@redhat.com> - 2.9-4
- Eliminate use of security_compute_user() (#1879368)
* Fri Nov 08 2019 Vit Mojzis <vmojzis@redhat.com> - 2.9-3
- Fix mcstrans secolor examples in secolor.conf man page (#1770270)
* Mon Jun 24 2019 Petr Lautrbach <plautrba@redhat.com> - 2.9-2.1
- Use Python distutils to install SELinux python bindings (#1719771)
- Move sefcontext_compile to -utils package (#1612518)

6
rubytest.rb Normal file
View File

@ -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"

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (libselinux-2.9.tar.gz) = 727b211d09f374d45aa3fa4dec7fd5463dfdcf5aaa47f7fcaccee51fb74896c3aa1a6f0bac9cdd47ebe4929effff13f66f5f70447b27b783dca5f7b1576d30d0

64
tests/getsebool/Makefile Normal file
View File

@ -0,0 +1,64 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/libselinux/Sanity/getsebool
# Description: Does getsebool work as expected?
# Author: Milos Malik <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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 <mmalik@redhat.com>" > $(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)

5
tests/getsebool/PURPOSE Normal file
View File

@ -0,0 +1,5 @@
PURPOSE of /CoreOS/libselinux/Sanity/getsebool
Author: Milos Malik <mmalik@redhat.com>
Does getsebool work as expected?

68
tests/getsebool/runtest.sh Executable file
View File

@ -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 <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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

View File

@ -0,0 +1,63 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/libselinux/Sanity/realpath_not_final-function
# Description: Test realpath_not_final function
# Author: Jan Zarsky <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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 <jzarsky@redhat.com>" > $(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)

View File

@ -0,0 +1,3 @@
PURPOSE of /CoreOS/libselinux/Sanity/realpath_not_final-function
Description: Test realpath_not_final function
Author: Jan Zarsky <jzarsky@redhat.com>

View File

@ -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 <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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

View File

@ -0,0 +1,44 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <selinux/selinux.h>
#include <linux/limits.h>
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;
}

View File

@ -0,0 +1,63 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/libselinux/Sanity/selabel-functions
# Description: Test selabel functions
# Author: Jan Zarsky <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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 <jzarsky@redhat.com>" > $(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)

View File

@ -0,0 +1,3 @@
PURPOSE of /CoreOS/libselinux/Sanity/selabel-functions
Description: Test selabel functions
Author: Jan Zarsky <jzarsky@redhat.com>

View File

@ -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 <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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 <<EOF
EOF"
rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 0 0"
rlRun "./test_open CTX_MEDIA $TmpDir/my_contexts NULL 0 0"
rlRun "./test_open CTX_X $TmpDir/my_contexts NULL 0 0"
rlRun "./test_open CTX_DB $TmpDir/my_contexts NULL 0 0"
if rlIsRHEL "7" || rlIsFedora "<26"; then
rlRun "./test_open CTX_ANDROID_PROP $TmpDir/my_contexts NULL 0 0"
fi
rlRun "./test_open CTX_FILE /nonexistent NULL 0 0" 2
rlRun "./test_open CTX_MEDIA /nonexistent NULL 0 0" 2
rlRun "./test_open CTX_X /nonexistent NULL 0 0" 2
rlRun "./test_open CTX_DB /nonexistent NULL 0 0" 2
if rlIsRHEL "7" || rlIsFedora "<26"; then
rlRun "./test_open CTX_ANDROID_PROP /nonexistent NULL 0 0" 2
fi
rlLogInfo "Subset option"
rlRun "./test_open CTX_FILE NULL /etc 0 0"
rlLogInfo "Baseonly option"
rlRun "./test_open CTX_FILE NULL NULL 0 1"
rlLogInfo "Validate option"
rlRun "./test_open CTX_FILE NULL NULL 1 0"
rlRun "./test_open CTX_MEDIA NULL NULL 1 0"
rlRun "./test_open CTX_X NULL NULL 1 0"
rlRun "./test_open CTX_DB NULL NULL 1 0"
if rlIsRHEL "7" || rlIsFedora "<26"; then
rlRun "./test_open CTX_ANDROID_PROP NULL NULL 1 0"
fi
rlPhaseEnd
rlPhaseStartTest "selabel_lookup and selabel_lookup_raw"
rlLogInfo "Handle"
rlRun "./test_lookup CTX_FILE NULL NULL 0 0 some_input 0 nohandle" 139
rlRun "./test_lookup CTX_MEDIA NULL NULL 0 0 some_input 0 nohandle" 139
rlRun "./test_lookup CTX_X NULL NULL 0 0 some_input 0 nohandle" 139
rlRun "./test_lookup CTX_DB NULL NULL 0 0 some_input 0 nohandle" 139
if rlIsRHEL "7" || rlIsFedora "<26"; then
rlRun "./test_lookup CTX_ANDROID_PROP NULL NULL 0 0 some_input 0 nohandle" 139
fi
rlLogInfo "Path"
if rlIsRHEL 6; then
rlRun "./test_lookup CTX_FILE NULL NULL 0 0 NULL 0" 2,139
rlRun "./test_lookup CTX_MEDIA NULL NULL 0 0 NULL 0" 2,139
rlRun "./test_lookup CTX_X NULL NULL 0 0 NULL 0" 2,139
rlRun "./test_lookup CTX_DB NULL NULL 0 0 NULL 0" 2,139
else
rlRun "./test_lookup CTX_FILE NULL NULL 0 0 NULL 0" 22
rlRun "./test_lookup CTX_MEDIA NULL NULL 0 0 NULL 0" 22
rlRun "./test_lookup CTX_X NULL NULL 0 0 NULL 0" 22
rlRun "./test_lookup CTX_DB NULL NULL 0 0 NULL 0" 22
# ANDROID_PROP backend does not set handle and returns NULL as handle
# (see test_lookup.c for handling NULL handle)
rlRun "./test_lookup CTX_ANDROID_PROP NULL NULL 0 0 NULL 0" 255
fi
rlPhaseEnd
rlPhaseStartTest "validate option"
rlLogInfo "Invalid entries"
rlRun "cat > $TmpDir/my_contexts <<EOF
EOF"
rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(tee output >&2)" 0
rlRun "grep 'line' output" 1
rlRun "cat > $TmpDir/my_contexts <<EOF
one
EOF"
if rlIsRHEL 6; then
rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(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 <<EOF
$TmpDir my_user_u:my_role_r:my_type_t:s0
EOF"
if rlIsFedora "<27" || rlIsRHEL "<=7"; then
rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(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 <<EOF
$TmpDir invalid_file_type system_u:object_r:var_t:s0
EOF"
if rlIsRHEL 6; then
rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(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
$TmpDir <<none>>
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 <<EOF
#$TmpDir system_u:object_r:var_t:s0
$TmpDir system_u:object_r:var_t:s0
EOF"
rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(tee output >&2)" 0
rlRun "grep 'Multiple same specifications' output" 1
rlLogInfo "Two same rules for the same path"
rlRun "cat > $TmpDir/my_contexts <<EOF
$TmpDir system_u:object_r:var_t:s0
$TmpDir system_u:object_r:var_t:s0
EOF"
rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(tee output >&2)" 22
rlRun "grep 'Multiple same specifications' output"
rlLogInfo "Two different rules for the same path"
rlRun "cat > $TmpDir/my_contexts <<EOF
$TmpDir system_u:object_r:bin_t:s0
$TmpDir system_u:object_r:usr_t:s0
EOF"
rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(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 <<EOF
$TmpDir -- system_u:object_r:bin_t:s0
$TmpDir -d system_u:object_r:usr_t:s0
EOF"
rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(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 <<EOF
$TmpDir system_u:object_r:bin_t:s0
$TmpDir -- system_u:object_r:usr_t:s0
EOF"
rlRun "./test_open CTX_FILE $TmpDir/my_contexts NULL 1 0 2> >(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 <<EOF
$TmpDir system_u:object_r:var_t:s0
EOF"
rlRun "cat > $TmpDir/my_contexts.subs <<EOF
/somepath $TmpDir
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somepath 0 | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:var_t:s0' output" 0
rlRun "rm -f $TmpDir/my_contexts.subs"
rlLogInfo "subs_dist file"
rlRun "cat > $TmpDir/my_contexts <<EOF
$TmpDir system_u:object_r:var_t:s0
EOF"
rlRun "cat > $TmpDir/my_contexts.subs_dist <<EOF
/somepath $TmpDir
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somepath 0 | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:var_t:s0' output" 0
rlRun "rm -f $TmpDir/my_contexts.subs_dist"
rlLogInfo "local file"
rlRun "cat > $TmpDir/my_contexts <<EOF
EOF"
rlRun "cat > $TmpDir/my_contexts.local <<EOF
$TmpDir system_u:object_r:var_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 $TmpDir 0 | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:var_t:s0' output" 0
rlRun "rm -f $TmpDir/my_contexts.local"
rlLogInfo "homedirs file"
rlRun "cat > $TmpDir/my_contexts <<EOF
EOF"
rlRun "cat > $TmpDir/my_contexts.homedirs <<EOF
$TmpDir system_u:object_r:var_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 $TmpDir 0 | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:var_t:s0' output" 0
rlRun "rm -f $TmpDir/my_contexts.homedirs"
rlLogInfo "Normal run"
rlRun "./test_lookup CTX_FILE NULL NULL 0 0 /nonexistent 0 | tee output" 0 \
"Run selabel_lookup"
rlRun "grep 'selabel_lookup context: system_u:object_r:etc_runtime_t:s0' output" 0 \
"Check context returned by selabel_lookup"
rlRun "grep 'selabel_lookup_raw context: system_u:object_r:etc_runtime_t:s0' output" 0 \
"Check context returned by selabel_lookup_raw"
rlLogInfo "Context is <<none>>"
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 <<none>>"
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 <<EOF
floppy system_u:object_r:tmp_t:s0
cdrom system_u:object_r:var_t:s0
EOF"
rlRun "./test_lookup CTX_MEDIA $TmpDir/my_contexts NULL 1 0 floppy 0 | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:tmp_t:s0' output"
rlRun "cat > $TmpDir/my_contexts <<EOF
floppy system_u:object_r:tmp_t:s0
floppy system_u:object_r:var_t:s0
EOF"
rlRun "./test_lookup CTX_MEDIA $TmpDir/my_contexts NULL 1 0 floppy 0 | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:tmp_t:s0' output"
rlLogInfo "No entries"
rlRun "cat > $TmpDir/my_contexts <<EOF
EOF"
rlRun "./test_lookup CTX_MEDIA $TmpDir/my_contexts NULL 1 0 floppy 0 2> >(tee output >&2)" 2
rlRun "grep 'selabel_lookup - ERROR: No such file or directory' output"
rlLogInfo "Invalid entries"
rlRun "cat > $TmpDir/my_contexts <<EOF
floppy
EOF"
rlRun "./test_lookup CTX_MEDIA $TmpDir/my_contexts NULL 1 0 floppy 0 2> >(tee output >&2)" 2
rlRun "grep 'line 1 is missing fields' output"
rlRun "cat > $TmpDir/my_contexts <<EOF
floppy some_u:some_r:some_t:s0
EOF"
rlRun "./test_lookup CTX_MEDIA $TmpDir/my_contexts NULL 1 0 floppy 0 2> >(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 <<EOF
#EOF"
# rlRun "./test_lookup CTX_MEDIA $TmpDir/my_contexts NULL 1 0 floppy 0 | tee output" 0
# rlRun "grep 'selabel_lookup context: $defaultContext' output" 0
# rlLogInfo "invalid contexts file"
# rlRun "cat > $TmpDir/my_contexts <<EOF
#some_removable some_u:some_r:some_t:s0
#EOF"
# rlRun "./test_lookup CTX_MEDIA $TmpDir/my_contexts NULL 1 0 floppy 0 | tee output" 0
# rlRun "grep 'selabel_lookup context: $defaultContext' output" 0
rlLogInfo "CTX_MEDIA backend"
# syntax: ./test_lookup CTX_MEDIA OPT_PATH NULL OPT_VALIDATE 0 path 0
rlLogInfo "Normal run"
rlRun "./test_lookup CTX_MEDIA NULL NULL 0 0 floppy 0 | tee output" 0 \
"Run selabel_lookup"
rlRun "grep 'selabel_lookup context: system_u:object_r:removable_device_t:s0' output" 0 \
"Check context returned by selabel_lookup"
rlRun "grep 'selabel_lookup_raw context: system_u:object_r:removable_device_t:s0' output" 0 \
"Check context returned by selabel_lookup_raw"
rlPhaseEnd
rlPhaseStartTest "x contexts files"
rlLogInfo "Valid entries"
rlRun "cat > $TmpDir/my_contexts <<EOF
client * system_u:object_r:tmp_t:s0
selection PRIMARY system_u:object_r:var_t:s0
EOF"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 PRIMARY X_SELN | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:var_t:s0' output"
rlLogInfo "Comments and empty lines"
rlRun "cat > $TmpDir/my_contexts <<EOF
# some comment
client * system_u:object_r:tmp_t:s0
selection PRIMARY system_u:object_r:var_t:s0
EOF"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 PRIMARY X_SELN | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:var_t:s0' output"
rlLogInfo "Object names"
rlRun "cat > $TmpDir/my_contexts <<EOF
property * system_u:object_r:tmp_t:s0
selection * system_u:object_r:var_t:s0
extension * system_u:object_r:usr_t:s0
event * system_u:object_r:man_t:s0
client * system_u:object_r:lib_t:s0
poly_property * system_u:object_r:bin_t:s0
poly_selection * system_u:object_r:remote_t:s0
EOF"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 '*' X_PROP | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:tmp_t:s0' output"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 '*' X_SELN | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:var_t:s0' output"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 '*' X_EXT | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:usr_t:s0' output"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 '*' X_EVENT | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:man_t:s0' output"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 '*' X_CLIENT | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:lib_t:s0' output"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 '*' X_POLYPROP | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:bin_t:s0' output"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 '*' X_POLYSELN | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:remote_t:s0' output"
rlLogInfo "Empty file"
rlRun "cat > $TmpDir/my_contexts <<EOF
EOF"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 PRIMARY X_SELN" 2
rlLogInfo "Invalid entries"
rlRun "cat > $TmpDir/my_contexts <<EOF
property
EOF"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 PRIMARY X_SELN 2> >(tee output >&2)" 2
rlRun "grep 'line 1 is missing fields' output"
rlRun "cat > $TmpDir/my_contexts <<EOF
property *
EOF"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 PRIMARY X_SELN 2> >(tee output >&2)" 2
rlRun "grep 'line 1 is missing fields' output"
rlRun "cat > $TmpDir/my_contexts <<EOF
some_property * system_u:object_r:tmp_t:s0
EOF"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 PRIMARY X_SELN 2> >(tee output >&2)" 2
rlRun "grep 'line 1 has invalid object type some_property' output"
rlLogInfo "Wildcard matching"
rlRun "cat > $TmpDir/my_contexts <<EOF
property * system_u:object_r:tmp_t:s0
EOF"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 SOME_PROPERTY X_PROP | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:tmp_t:s0' output"
rlRun "cat > $TmpDir/my_contexts <<EOF
property CUT_BUFFER0 system_u:object_r:tmp_t:s0
property * system_u:object_r:usr_t:s0
property CUT_BUFFER1 system_u:object_r:var_t:s0
EOF"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 CUT_BUFFER0 X_PROP | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:tmp_t:s0' output"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 CUT_BUFFER1 X_PROP | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:usr_t:s0' output"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 CUT_BUFFER2 X_PROP | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:usr_t:s0' output"
rlLogInfo "Substitution matching"
rlRun "cat > $TmpDir/my_contexts <<EOF
property CUT_BUFFER? system_u:object_r:tmp_t:s0
EOF"
rlRun "./test_lookup CTX_X $TmpDir/my_contexts NULL 1 0 CUT_BUFFER3 X_PROP | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:tmp_t:s0' output"
rlLogInfo "Normal run"
rlRun "./test_lookup CTX_X NULL NULL 0 0 asdf X_CLIENT | tee output" 0 \
"Run selabel_lookup"
rlRun "grep 'selabel_lookup context: system_u:object_r:remote_t:s0' output" 0 \
"Check context returned by selabel_lookup"
rlRun "grep 'selabel_lookup_raw context: system_u:object_r:remote_t:s0' output" 0 \
"Check context returned by selabel_lookup_raw"
rlPhaseEnd
rlPhaseStartTest "db contexts files"
rlLogInfo "Valid entries"
rlRun "cat > $TmpDir/my_contexts <<EOF
db_database my_database system_u:object_r:sepgsql_db_t:s0
db_schema my_schema system_u:object_r:sepgsql_schema_t:s0
db_view my_view system_u:object_r:sepgsql_view_t:s0
db_table my_table system_u:object_r:sepgsql_table_t:s0
db_column my_column system_u:object_r:var_t:s0
db_tuple my_tuple system_u:object_r:tmp_t:s0
db_procedure my_procedure system_u:object_r:sepgsql_proc_exec_t:s0
db_sequence my_sequence system_u:object_r:sepgsql_seq_t:s0
db_blob my_blob system_u:object_r:sepgsql_blob_t:s0
EOF"
if rlIsRHEL ">=7" || rlIsFedora; then
rlRun "cat >> $TmpDir/my_contexts <<EOF
db_language my_language system_u:object_r:sepgsql_lang_t:s0
db_exception my_exception system_u:object_r:usr_t:s0
db_datatype my_datatype system_u:object_r:bin_t:s0
EOF"
fi
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_database DB_DATABASE | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:sepgsql_db_t:s0' output"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_schema DB_SCHEMA | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:sepgsql_schema_t:s0' output"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_view DB_VIEW | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:sepgsql_view_t:s0' output"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_table DB_TABLE | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:sepgsql_table_t:s0' output"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_column DB_COLUMN | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:var_t:s0' output"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_tuple DB_TUPLE | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:tmp_t:s0' output"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_procedure DB_PROCEDURE | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:sepgsql_proc_exec_t:s0' output"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_sequence DB_SEQUENCE | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:sepgsql_seq_t:s0' output"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_blob DB_BLOB | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:sepgsql_blob_t:s0' output"
if rlIsRHEL ">=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 <<EOF
# something
db_database my_database system_u:object_r:sepgsql_db_t:s0
EOF"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_database DB_DATABASE | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:sepgsql_db_t:s0' output"
rlLogInfo "Wildcard matching"
rlRun "cat > $TmpDir/my_contexts <<EOF
db_database my_database system_u:object_r:var_t:s0
db_database my_database* system_u:object_r:bin_t:s0
db_database * system_u:object_r:usr_t:s0
EOF"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_database DB_DATABASE | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:var_t:s0' output"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_database_asdf DB_DATABASE | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:bin_t:s0' output"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_asdf DB_DATABASE | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:usr_t:s0' output"
rlRun "cat > $TmpDir/my_contexts <<EOF
db_database * system_u:object_r:usr_t:s0
db_database my_* system_u:object_r:bin_t:s0
EOF"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_database DB_DATABASE | tee output" 0
rlRun "grep 'selabel_lookup context: system_u:object_r:usr_t:s0' output"
rlLogInfo "Empty file"
rlRun "cat > $TmpDir/my_contexts <<EOF
EOF"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 1 0 my_database DB_DATABASE " 2
rlLogInfo "Invalid entries"
rlRun "cat > $TmpDir/my_contexts <<EOF
one
EOF"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 0 0 my_database DB_DATABASE 2> >(tee output >&2)" 2
rlRun "grep 'line 1 has invalid format' output"
rlRun "cat > $TmpDir/my_contexts <<EOF
one two
EOF"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 0 0 my_database DB_DATABASE 2> >(tee output >&2)" 2
rlRun "grep 'line 1 has invalid format' output"
rlRun "cat > $TmpDir/my_contexts <<EOF
one two three
EOF"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 0 0 my_database DB_DATABASE 2> >(tee output >&2)" 2
rlRun "grep 'line 1 has invalid object type one' output"
rlRun "cat > $TmpDir/my_contexts <<EOF
one two three four
EOF"
rlRun "./test_lookup CTX_DB $TmpDir/my_contexts NULL 0 0 my_database DB_DATABASE 2> >(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 <<EOF
$TmpDir.* system_u:object_r:var_t:s0
EOF"
rlRun "cat > $TmpDir/my_contexts.subs <<EOF
/somepath $TmpDir
EOF"
rlRun "cat > $TmpDir/my_contexts.local <<EOF
$TmpDir/local system_u:object_r:bin_t:s0
EOF"
rlRun "cat > $TmpDir/my_contexts.homedirs <<EOF
$TmpDir/homedirs system_u:object_r:usr_t:s0
EOF"
# without baseonly option, the rule in my_contexts will be overridden
# by a rule in my_contexts.local file
# .subs file should work even with baseonly option
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somepath/local 0 | tee output" 0 \
"Running selabel_open without baseonly option"
rlRun "grep 'selabel_lookup context: system_u:object_r:bin_t:s0' output" 0
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 1 /somepath/local 0 | tee output" 0 \
"Running selabel_open with baseonly option"
rlRun "grep 'selabel_lookup context: system_u:object_r:var_t:s0' output" 0
# without baseonly option, the rule in my_contexts will be overridden
# by a rule in my_contexts.homedirs file
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somepath/homedirs 0 | tee output" 0 \
"Running selabel_open without baseonly option"
rlRun "grep 'selabel_lookup context: system_u:object_r:usr_t:s0' output" 0
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 1 /somepath/homedirs 0 | tee output" 0 \
"Running selabel_open with baseonly option"
rlRun "grep 'selabel_lookup context: system_u:object_r:var_t:s0' output" 0
rlRun "rm -f $TmpDir/my_contexts.subs"
rlRun "rm -f $TmpDir/my_contexts.local"
rlRun "rm -f $TmpDir/my_contexts.homedirs"
rlPhaseEnd
fi
rlPhaseStartTest "selabel_lookup advanced tests"
rlLogInfo "Custom file contexts file"
rlRun "cat > $TmpDir/my_contexts <<EOF
$TmpDir my_user_u:my_role_r:my_type_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 $TmpDir 0 | tee output" 0
rlRun "grep 'selabel_lookup context: my_user_u:my_role_r:my_type_t:s0' output" 0
rlLogInfo "Rules for different file types"
rlRun "cat > $TmpDir/my_contexts <<EOF
$TmpDir -- user_u:role_r:regular_type_t:s0
$TmpDir -b user_u:role_r:block_type_t:s0
$TmpDir -c user_u:role_r:char_type_t:s0
$TmpDir -d user_u:role_r:dir_type_t:s0
$TmpDir -p user_u:role_r:pipe_type_t:s0
$TmpDir -l user_u:role_r:symlink_type_t:s0
$TmpDir -s user_u:role_r:socket_type_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 $TmpDir 0010000 | tee output"
rlRun "grep 'selabel_lookup context: user_u:role_r:pipe_type_t:s0' output"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 $TmpDir 0020000 | tee output"
rlRun "grep 'selabel_lookup context: user_u:role_r:char_type_t:s0' output"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 $TmpDir 0040000 | tee output"
rlRun "grep 'selabel_lookup context: user_u:role_r:dir_type_t:s0' output"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 $TmpDir 0060000 | tee output"
rlRun "grep 'selabel_lookup context: user_u:role_r:block_type_t:s0' output"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 $TmpDir 0100000 | tee output"
rlRun "grep 'selabel_lookup context: user_u:role_r:regular_type_t:s0' output"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 $TmpDir 0120000 | tee output"
rlRun "grep 'selabel_lookup context: user_u:role_r:symlink_type_t:s0' output"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 $TmpDir 0140000 | tee output"
rlRun "grep 'selabel_lookup context: user_u:role_r:socket_type_t:s0' output"
rlPhaseEnd
if rlIsRHEL ">=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 <<EOF
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0" 2
rlRun "./test_partial CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir | tee output" 0
rlRun "grep 'selabel_partial_match: false' output" 0
rlLogInfo "full match"
rlRun "cat > $TmpDir/my_contexts <<EOF
/somedir user_u:role_r:type_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 | tee output" 0
rlRun "grep 'selabel_lookup context: user_u:role_r:type_t:s0' output"
rlRun "./test_partial CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir | tee output" 0
rlRun "grep 'selabel_partial_match: true' output" 0
rlLogInfo "partial match"
rlRun "cat > $TmpDir/my_contexts <<EOF
/somedir42 user_u:role_r:type_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0" 2
rlRun "./test_partial CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir | tee output" 0
rlRun "grep 'selabel_partial_match: true' output" 0
rlPhaseEnd
fi
if rlIsRHEL ">=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 <<EOF
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0" 2
rlRun "./test_best CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0" 2
rlLogInfo "exact match without aliases"
rlRun "cat > $TmpDir/my_contexts <<EOF
/somedir user_u:role_r:type_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 | tee output" 0
rlRun "grep 'selabel_lookup context: user_u:role_r:type_t:s0' output"
# same as selabel_lookup
rlRun "./test_best CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 | tee output" 0
rlRun "grep 'selabel_lookup_best_match context: user_u:role_r:type_t:s0' output"
rlLogInfo "regex match without aliases"
rlRun "cat > $TmpDir/my_contexts <<EOF
/some.* user_u:role_r:type_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 | tee output" 0
rlRun "grep 'selabel_lookup context: user_u:role_r:type_t:s0' output"
# same as selabel_lookup
rlRun "./test_best CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 | tee output" 0
rlRun "grep 'selabel_lookup_best_match context: user_u:role_r:type_t:s0' output"
rlLogInfo "exact match with exactly matching alias"
rlRun "cat > $TmpDir/my_contexts <<EOF
/somedir user_u:role_r:orig_t:s0
/somesymlink user_u:role_r:link_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 | tee output" 0
rlRun "grep 'selabel_lookup context: user_u:role_r:orig_t:s0' output"
# original context should be chosen when found
rlRun "./test_best CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 /somesymlink | tee output" 0
rlRun "grep 'selabel_lookup_best_match context: user_u:role_r:orig_t:s0' output"
rlLogInfo "no match with exactly matching alias"
rlRun "cat > $TmpDir/my_contexts <<EOF
/somesymlink user_u:role_r:type_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0" 2
# when there is no context for path, alias context should be chosen
rlRun "./test_best CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 /somesymlink | tee output" 0
rlRun "grep 'selabel_lookup_best_match context: user_u:role_r:type_t:s0' output"
rlLogInfo "no match with multiple exactly matching aliases"
rlRun "cat > $TmpDir/my_contexts <<EOF
/firstsymlink user_u:role_r:first_t:s0
/secondsymlink user_u:role_r:second_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0" 2
# with no context for path and multiple aliases, first exact match should be chosen
rlRun "./test_best CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 /firstsymlink /secondsymlink | tee output" 0
rlRun "grep 'selabel_lookup_best_match context: user_u:role_r:first_t:s0' output"
rlLogInfo "no match with multiple regex matching aliases"
rlRun "cat > $TmpDir/my_contexts <<EOF
/short.* user_u:role_r:short_t:s0
/verylong.* user_u:role_r:long_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0" 2
# with no context for path and multiple regex aliases, match with longest prefix should be chosen
rlRun "./test_best CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 /shortsymlink /verylongsymlink | tee output" 0
rlRun "grep 'selabel_lookup_best_match context: user_u:role_r:long_t:s0' output"
rlLogInfo "regex match with multiple regex matching aliases"
rlRun "cat > $TmpDir/my_contexts <<EOF
/some.* user_u:role_r:orig_t:s0
/short.* user_u:role_r:short_t:s0
/verylong.* user_u:role_r:long_t:s0
EOF"
rlRun "./test_lookup CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 | tee output" 0
rlRun "grep 'selabel_lookup context: user_u:role_r:orig_t:s0' output"
# with regex matching context for path and multiple regex aliases, match with longest prefix should be chosen
# (among both original path and aliases)
rlRun "./test_best CTX_FILE $TmpDir/my_contexts NULL 0 0 /somedir 0 /shortsymlink /verylongsymlink | tee output" 0
rlRun "grep 'selabel_lookup_best_match context: user_u:role_r:long_t:s0' output"
rlPhaseEnd
fi
rlPhaseStartTest "selabel_stats"
# syntax: ./test_stats BACKEND OPT_PATH OPT_VALIDATE [nohandle]
rlLogInfo "calling selabel_test - not checking output"
rlRun "cat > $TmpDir/my_contexts <<EOF
EOF"
rlRun "./test_stats CTX_FILE $TmpDir/my_contexts 0" 0
rlRun "./test_stats CTX_MEDIA $TmpDir/my_contexts 0" 0
rlRun "./test_stats CTX_X $TmpDir/my_contexts 0" 0
rlRun "./test_stats CTX_DB $TmpDir/my_contexts 0" 0
if rlIsRHEL "7" || rlIsFedora "<26"; then
rlRun "./test_stats CTX_ANDROID_PROP $TmpDir/my_contexts 0" 0
fi
rlRun "./test_stats CTX_FILE $TmpDir/my_contexts 0 nohandle" 139
rlPhaseEnd
if rlIsRHEL ">=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 <<EOF
EOF"
if rlIsRHEL "7" || rlIsFedora "<26"; then
rlRun "./test_digest CTX_ANDROID_PROP $TmpDir/my_contexts 0 1" 0
fi
rlPhaseEnd
fi
rlPhaseStartCleanup
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlRun "rm -f test_open test_lookup test_partial test_best test_stats test_digest output"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

View File

@ -0,0 +1,159 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
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;
}

View File

@ -0,0 +1,121 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
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;
}

View File

@ -0,0 +1,189 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
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;
}

View File

@ -0,0 +1,100 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
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;
}

View File

@ -0,0 +1,115 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
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;
}

View File

@ -0,0 +1,83 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
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;
}

View File

@ -0,0 +1,63 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/libselinux/Sanity/selinux_boolean_sub-function
# Description: Test selinux_boolean_sub function
# Author: Jan Zarsky <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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 <jzarsky@redhat.com>" > $(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)

View File

@ -0,0 +1,3 @@
PURPOSE of /CoreOS/libselinux/Sanity/selinux_boolean_sub-function
Description: Test selinux_boolean_sub function
Author: Jan Zarsky <jzarsky@redhat.com>

View File

@ -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 <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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

View File

@ -0,0 +1,31 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <selinux/selinux.h>
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;
}

View File

@ -0,0 +1,63 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/libselinux/Sanity/selinux_restorecon-functions
# Description: Test functions in selinux_restorecon.c
# Author: Jan Zarsky <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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 <jzarsky@redhat.com>" > $(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)

View File

@ -0,0 +1,3 @@
PURPOSE of /CoreOS/libselinux/Sanity/selinux_restorecon-functions
Description: Test functions in selinux_restorecon.c
Author: Jan Zarsky <jzarsky@redhat.com>

View File

@ -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 <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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

View File

@ -0,0 +1,55 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <selinux/selinux.h>
#include <selinux/context.h>
#include <selinux/label.h>
#include <selinux/restorecon.h>
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);
}

View File

@ -0,0 +1,57 @@
#include <stdio.h>
#include <string.h>
#include <selinux/selinux.h>
#include <selinux/context.h>
#include <selinux/label.h>
#include <selinux/restorecon.h>
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);
}

View File

@ -0,0 +1,64 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <selinux/selinux.h>
#include <selinux/context.h>
#include <selinux/label.h>
#include <selinux/restorecon.h>
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);
}

View File

@ -0,0 +1,64 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/libselinux/Sanity/selinux_restorecon
# Description: Does selinux_restorecon work correctly?
# Author: Milos Malik <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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 <mmalik@redhat.com>" > $(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)

View File

@ -0,0 +1,5 @@
PURPOSE of /CoreOS/libselinux/Sanity/selinux_restorecon
Author: Milos Malik <mmalik@redhat.com>
Does selinux_restorecon work correctly? The program was added in RHEL-7.3.

View File

@ -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 <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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

View File

@ -0,0 +1,63 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/libselinux/Sanity/selinux_sestatus-functions
# Description: Test sestatus.c functions
# Author: Jan Zarsky <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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 <jzarsky@redhat.com>" > $(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)

View File

@ -0,0 +1,3 @@
PURPOSE of /CoreOS/libselinux/Sanity/selinux_sestatus-functions
Description: Test sestatus.c functions
Author: Jan Zarsky <jzarsky@redhat.com>

View File

@ -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 <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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

View File

@ -0,0 +1,38 @@
#include <stdio.h>
#include <selinux/selinux.h>
#include <selinux/avc.h>
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;
}

View File

@ -0,0 +1,63 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/libselinux/Sanity/selinux_set_callback
# Description: Test selinux_set_callback function
# Author: Jan Zarsky <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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 <jzarsky@redhat.com>" > $(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)

View File

@ -0,0 +1,3 @@
PURPOSE of /CoreOS/libselinux/Sanity/selinux_set_callback
Description: Test selinux_set_callback function
Author: Jan Zarsky <jzarsky@redhat.com>

View File

@ -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 <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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

View File

@ -0,0 +1,127 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <selinux/selinux.h>
#include <selinux/avc.h>
#include <selinux/label.h>
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;
}

64
tests/setenforce/Makefile Normal file
View File

@ -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 <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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 <mmalik@redhat.com>" > $(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)

5
tests/setenforce/PURPOSE Normal file
View File

@ -0,0 +1,5 @@
PURPOSE of /CoreOS/libselinux/Sanity/setenforce
Author: Milos Malik <mmalik@redhat.com>
Does setenforce work as expected? Does it produce correct audit messages?

View File

@ -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 <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 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

41
tests/tests.yml Normal file
View File

@ -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