summaryrefslogtreecommitdiff
path: root/tools/testing/selftests
diff options
context:
space:
mode:
authorMicah Morton <mortonm@chromium.org>2022-06-16 20:09:55 +0300
committerMicah Morton <mortonm@chromium.org>2022-07-15 21:24:42 +0300
commit64b634830c919979de4b18163e15d30df66e64a8 (patch)
treeb707dfa688aaf7ba5a10692f5553a23d48b47ce4 /tools/testing/selftests
parent3e3374d382ff250502fbc4407001ac793d5c4e7f (diff)
downloadlinux-64b634830c919979de4b18163e15d30df66e64a8.tar.xz
LSM: SafeSetID: add setgroups() testing to selftest
Selftest already has support for testing UID and GID transitions. Signed-off-by: Micah Morton <mortonm@chromium.org>
Diffstat (limited to 'tools/testing/selftests')
-rw-r--r--tools/testing/selftests/safesetid/safesetid-test.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/tools/testing/selftests/safesetid/safesetid-test.c b/tools/testing/selftests/safesetid/safesetid-test.c
index a653c47a4ab5..eb9bf0aee951 100644
--- a/tools/testing/selftests/safesetid/safesetid-test.c
+++ b/tools/testing/selftests/safesetid/safesetid-test.c
@@ -375,6 +375,71 @@ static void test_setgid(gid_t child_gid, bool expect_success)
die("should not reach here\n");
}
+static void test_setgroups(gid_t* child_groups, size_t len, bool expect_success)
+{
+ pid_t cpid, w;
+ int wstatus;
+ gid_t groupset[len];
+ int i, j;
+
+ cpid = fork();
+ if (cpid == -1) {
+ die("fork\n");
+ }
+
+ if (cpid == 0) { /* Code executed by child */
+ if (setgroups(len, child_groups) != 0)
+ exit(EXIT_FAILURE);
+ if (getgroups(len, groupset) != len)
+ exit(EXIT_FAILURE);
+ for (i = 0; i < len; i++) {
+ for (j = 0; j < len; j++) {
+ if (child_groups[i] == groupset[j])
+ break;
+ if (j == len - 1)
+ exit(EXIT_FAILURE);
+ }
+ }
+ exit(EXIT_SUCCESS);
+ } else { /* Code executed by parent */
+ do {
+ w = waitpid(cpid, &wstatus, WUNTRACED | WCONTINUED);
+ if (w == -1) {
+ die("waitpid\n");
+ }
+
+ if (WIFEXITED(wstatus)) {
+ if (WEXITSTATUS(wstatus) == EXIT_SUCCESS) {
+ if (expect_success) {
+ return;
+ } else {
+ die("unexpected success\n");
+ }
+ } else {
+ if (expect_success) {
+ die("unexpected failure\n");
+ } else {
+ return;
+ }
+ }
+ } else if (WIFSIGNALED(wstatus)) {
+ if (WTERMSIG(wstatus) == 9) {
+ if (expect_success)
+ die("killed unexpectedly\n");
+ else
+ return;
+ } else {
+ die("unexpected signal: %d\n", wstatus);
+ }
+ } else {
+ die("unexpected status: %d\n", wstatus);
+ }
+ } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
+ }
+
+ die("should not reach here\n");
+}
+
static void ensure_users_exist(void)
{
@@ -452,6 +517,10 @@ int main(int argc, char **argv)
test_setgid(ALLOWED_CHILD2_UGID, true);
test_setgid(NO_POLICY_UGID, false);
+ gid_t allowed_supp_groups[2] = {ALLOWED_CHILD1_UGID, ALLOWED_CHILD2_UGID};
+ gid_t disallowed_supp_groups[2] = {ROOT_UGID, NO_POLICY_UGID};
+ test_setgroups(allowed_supp_groups, 2, true);
+ test_setgroups(disallowed_supp_groups, 2, false);
if (!test_userns(false)) {
die("test_userns worked when it should fail\n");