diff options
Diffstat (limited to 'nptl/tst-setuid1.c')
| -rw-r--r-- | nptl/tst-setuid1.c | 1085 |
1 files changed, 1085 insertions, 0 deletions
diff --git a/nptl/tst-setuid1.c b/nptl/tst-setuid1.c new file mode 100644 index 0000000000..f026c576d6 --- /dev/null +++ b/nptl/tst-setuid1.c @@ -0,0 +1,1085 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jaku@redhat.com>, 2004. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <pthread.h> +#include <pwd.h> +#include <grp.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/wait.h> +#include <unistd.h> + + +static pthread_barrier_t b3, b4; +static uid_t prev_ruid, prev_euid, prev_suid, nobody_uid; +static gid_t prev_rgid, prev_egid, prev_sgid, nobody_gid; +enum ACTION { PREPARE, SET, CHECK_BEFORE, CHECK_AFTER }; +#define TESTNO(arg) ((long int) (arg) & 0xff) +#define THREADNO(arg) ((long int) (arg) >> 8) + + +static void +check_prev_uid (int tno) +{ + uid_t ruid, euid, suid; + if (getresuid (&ruid, &euid, &suid) < 0) + { + printf ("getresuid failed: %d %m\n", tno); + exit (1); + } + + if (ruid != prev_ruid || euid != prev_euid || suid != prev_suid) + { + printf ("uids before in %d (%d %d %d) != (%d %d %d)\n", tno, + ruid, euid, suid, prev_ruid, prev_euid, prev_suid); + exit (1); + } +} + + +static void +check_prev_gid (int tno) +{ + gid_t rgid, egid, sgid; + if (getresgid (&rgid, &egid, &sgid) < 0) + { + printf ("getresgid failed: %d %m\n", tno); + exit (1); + } + + if (rgid != prev_rgid || egid != prev_egid || sgid != prev_sgid) + { + printf ("gids before in %d (%d %d %d) != (%d %d %d)\n", tno, + rgid, egid, sgid, prev_rgid, prev_egid, prev_sgid); + exit (1); + } +} + + +static void +test_setuid1 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_uid (tno); + + if (action == SET && setuid (nobody_uid) < 0) + { + printf ("setuid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + uid_t ruid, euid, suid; + if (getresuid (&ruid, &euid, &suid) < 0) + { + printf ("getresuid failed: %d %m\n", tno); + exit (1); + } + + if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid) + { + printf ("after setuid %d (%d %d %d) != (%d %d %d)\n", tno, + ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid); + exit (1); + } + } +} + + +static void +test_setuid2 (enum ACTION action, int tno) +{ + if (action == PREPARE) + { + if (setresuid (nobody_uid, nobody_uid, -1) < 0) + { + printf ("setresuid failed: %m\n"); + exit (1); + } + + prev_ruid = nobody_uid; + prev_euid = nobody_uid; + return; + } + + if (action != CHECK_AFTER) + check_prev_uid (tno); + + if (action == SET && setuid (prev_suid) < 0) + { + printf ("setuid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + uid_t ruid, euid, suid; + if (getresuid (&ruid, &euid, &suid) < 0) + { + printf ("getresuid failed: %d %m\n", tno); + exit (1); + } + + if (ruid != nobody_uid || euid != prev_suid || suid != prev_suid) + { + printf ("after setuid %d (%d %d %d) != (%d %d %d)\n", tno, + ruid, euid, suid, nobody_uid, prev_suid, prev_suid); + exit (1); + } + } +} + + +static void +test_seteuid1 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_uid (tno); + + if (action == SET && seteuid (nobody_uid) < 0) + { + printf ("seteuid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + uid_t ruid, euid, suid; + if (getresuid (&ruid, &euid, &suid) < 0) + { + printf ("getresuid failed: %d %m\n", tno); + exit (1); + } + + if (ruid != prev_ruid || euid != nobody_uid || suid != prev_suid) + { + printf ("after seteuid %d (%d %d %d) != (%d %d %d)\n", tno, + ruid, euid, suid, prev_ruid, nobody_uid, prev_suid); + exit (1); + } + } +} + + +static void +test_seteuid2 (enum ACTION action, int tno) +{ + if (action == PREPARE) + { + if (setresuid (nobody_uid, nobody_uid, -1) < 0) + { + printf ("setresuid failed: %m\n"); + exit (1); + } + + prev_ruid = nobody_uid; + prev_euid = nobody_uid; + nobody_uid = prev_suid; + return; + } + + test_seteuid1 (action, tno); +} + + +static void +test_setreuid1 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_uid (tno); + + if (action == SET && setreuid (-1, nobody_uid) < 0) + { + printf ("setreuid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + uid_t ruid, euid, suid, esuid; + if (getresuid (&ruid, &euid, &suid) < 0) + { + printf ("getresuid failed: %d %m\n", tno); + exit (1); + } + + if (prev_ruid != nobody_uid) + esuid = nobody_uid; + else + esuid = prev_suid; + + if (ruid != prev_ruid || euid != nobody_uid || suid != esuid) + { + printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno, + ruid, euid, suid, prev_ruid, nobody_uid, esuid); + exit (1); + } + } +} + + +static void +test_setreuid2 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_uid (tno); + + if (action == SET && setreuid (nobody_uid, -1) < 0) + { + printf ("setreuid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + uid_t ruid, euid, suid; + if (getresuid (&ruid, &euid, &suid) < 0) + { + printf ("getresuid failed: %d %m\n", tno); + exit (1); + } + + if (ruid != nobody_uid || euid != prev_euid || suid != prev_euid) + { + printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno, + ruid, euid, suid, nobody_uid, prev_euid, prev_euid); + exit (1); + } + } +} + + +static void +test_setreuid3 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_uid (tno); + + if (action == SET && setreuid (nobody_uid, nobody_uid) < 0) + { + printf ("setreuid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + uid_t ruid, euid, suid; + if (getresuid (&ruid, &euid, &suid) < 0) + { + printf ("getresuid failed: %d %m\n", tno); + exit (1); + } + + if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid) + { + printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno, + ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid); + exit (1); + } + } +} + + +static void +test_setreuid4 (enum ACTION action, int tno) +{ + if (action == PREPARE) + { + if (setresuid (nobody_uid, nobody_uid, -1) < 0) + { + printf ("setresuid failed: %m\n"); + exit (1); + } + + prev_ruid = nobody_uid; + prev_euid = nobody_uid; + nobody_uid = prev_suid; + return; + } + + test_setreuid1 (action, tno); +} + + +static void +test_setresuid1 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_uid (tno); + + if (action == SET && setresuid (-1, nobody_uid, -1) < 0) + { + printf ("setresuid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + uid_t ruid, euid, suid; + if (getresuid (&ruid, &euid, &suid) < 0) + { + printf ("getresuid failed: %d %m\n", tno); + exit (1); + } + + if (ruid != prev_ruid || euid != nobody_uid || suid != prev_suid) + { + printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno, + ruid, euid, suid, prev_ruid, nobody_uid, prev_suid); + exit (1); + } + } +} + + +static void +test_setresuid2 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_uid (tno); + + if (action == SET && setresuid (prev_euid, nobody_uid, nobody_uid) < 0) + { + printf ("setresuid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + uid_t ruid, euid, suid; + if (getresuid (&ruid, &euid, &suid) < 0) + { + printf ("getresuid failed: %d %m\n", tno); + exit (1); + } + + if (ruid != prev_euid || euid != nobody_uid || suid != nobody_uid) + { + printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno, + ruid, euid, suid, prev_euid, nobody_uid, nobody_uid); + exit (1); + } + } +} + + +static void +test_setresuid3 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_uid (tno); + + if (action == SET && setresuid (nobody_uid, nobody_uid, nobody_uid) < 0) + { + printf ("setresuid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + uid_t ruid, euid, suid; + if (getresuid (&ruid, &euid, &suid) < 0) + { + printf ("getresuid failed: %d %m\n", tno); + exit (1); + } + + if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid) + { + printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno, + ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid); + exit (1); + } + } +} + + +static void +test_setresuid4 (enum ACTION action, int tno) +{ + if (action == PREPARE) + { + if (setresuid (nobody_uid, nobody_uid, -1) < 0) + { + printf ("setresuid failed: %m\n"); + exit (1); + } + + prev_ruid = nobody_uid; + prev_euid = nobody_uid; + nobody_uid = prev_suid; + return; + } + + test_setresuid1 (action, tno); +} + + +static void +test_setgid1 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_gid (tno); + + if (action == SET && setgid (nobody_gid) < 0) + { + printf ("setgid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + gid_t rgid, egid, sgid; + if (getresgid (&rgid, &egid, &sgid) < 0) + { + printf ("getresgid failed: %d %m\n", tno); + exit (1); + } + + if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid) + { + printf ("after setgid %d (%d %d %d) != (%d %d %d)\n", tno, + rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid); + exit (1); + } + } +} + + +static void +test_setgid2 (enum ACTION action, int tno) +{ + if (action == PREPARE) + { + if (setresgid (nobody_gid, nobody_gid, -1) < 0) + { + printf ("setresgid failed: %m\n"); + exit (1); + } + + prev_rgid = nobody_gid; + prev_egid = nobody_gid; + + if (setresuid (nobody_uid, nobody_uid, -1) < 0) + { + printf ("setresuid failed: %m\n"); + exit (1); + } + + prev_ruid = nobody_uid; + prev_euid = nobody_uid; + return; + } + + if (action != CHECK_AFTER) + check_prev_gid (tno); + + if (action == SET && setgid (prev_sgid) < 0) + { + printf ("setgid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + gid_t rgid, egid, sgid; + if (getresgid (&rgid, &egid, &sgid) < 0) + { + printf ("getresgid failed: %d %m\n", tno); + exit (1); + } + + if (rgid != nobody_gid || egid != prev_sgid || sgid != prev_sgid) + { + printf ("after setgid %d (%d %d %d) != (%d %d %d)\n", tno, + rgid, egid, sgid, nobody_gid, prev_sgid, prev_sgid); + exit (1); + } + } +} + + +static void +test_setegid1 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_gid (tno); + + if (action == SET && setegid (nobody_gid) < 0) + { + printf ("setegid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + gid_t rgid, egid, sgid; + if (getresgid (&rgid, &egid, &sgid) < 0) + { + printf ("getresgid failed: %d %m\n", tno); + exit (1); + } + + if (rgid != prev_rgid || egid != nobody_gid || sgid != prev_sgid) + { + printf ("after setegid %d (%d %d %d) != (%d %d %d)\n", tno, + rgid, egid, sgid, prev_rgid, nobody_gid, prev_sgid); + exit (1); + } + } +} + + +static void +test_setegid2 (enum ACTION action, int tno) +{ + if (action == PREPARE) + { + if (setresgid (nobody_gid, nobody_gid, -1) < 0) + { + printf ("setresgid failed: %m\n"); + exit (1); + } + + prev_rgid = nobody_gid; + prev_egid = nobody_gid; + nobody_gid = prev_sgid; + return; + } + + test_setegid1 (action, tno); +} + + +static void +test_setregid1 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_gid (tno); + + if (action == SET && setregid (-1, nobody_gid) < 0) + { + printf ("setregid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + gid_t rgid, egid, sgid, esgid; + if (getresgid (&rgid, &egid, &sgid) < 0) + { + printf ("getresgid failed: %d %m\n", tno); + exit (1); + } + + if (prev_rgid != nobody_gid) + esgid = nobody_gid; + else + esgid = prev_sgid; + + if (rgid != prev_rgid || egid != nobody_gid || sgid != esgid) + { + printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno, + rgid, egid, sgid, prev_rgid, nobody_gid, esgid); + exit (1); + } + } +} + + +static void +test_setregid2 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_gid (tno); + + if (action == SET && setregid (nobody_gid, -1) < 0) + { + printf ("setregid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + gid_t rgid, egid, sgid; + if (getresgid (&rgid, &egid, &sgid) < 0) + { + printf ("getresgid failed: %d %m\n", tno); + exit (1); + } + + if (rgid != nobody_gid || egid != prev_egid || sgid != prev_egid) + { + printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno, + rgid, egid, sgid, nobody_gid, prev_egid, prev_egid); + exit (1); + } + } +} + + +static void +test_setregid3 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_gid (tno); + + if (action == SET && setregid (nobody_gid, nobody_gid) < 0) + { + printf ("setregid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + gid_t rgid, egid, sgid; + if (getresgid (&rgid, &egid, &sgid) < 0) + { + printf ("getresgid failed: %d %m\n", tno); + exit (1); + } + + if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid) + { + printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno, + rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid); + exit (1); + } + } +} + + +static void +test_setregid4 (enum ACTION action, int tno) +{ + if (action == PREPARE) + { + if (setresgid (nobody_gid, nobody_gid, -1) < 0) + { + printf ("setresgid failed: %m\n"); + exit (1); + } + + prev_rgid = nobody_gid; + prev_egid = nobody_gid; + nobody_gid = prev_sgid; + return; + } + + test_setregid1 (action, tno); +} + + +static void +test_setresgid1 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_gid (tno); + + if (action == SET && setresgid (-1, nobody_gid, -1) < 0) + { + printf ("setresgid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + gid_t rgid, egid, sgid; + if (getresgid (&rgid, &egid, &sgid) < 0) + { + printf ("getresgid failed: %d %m\n", tno); + exit (1); + } + + if (rgid != prev_rgid || egid != nobody_gid || sgid != prev_sgid) + { + printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno, + rgid, egid, sgid, prev_rgid, nobody_gid, prev_sgid); + exit (1); + } + } +} + + +static void +test_setresgid2 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_gid (tno); + + if (action == SET && setresgid (prev_egid, nobody_gid, nobody_gid) < 0) + { + printf ("setresgid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + gid_t rgid, egid, sgid; + if (getresgid (&rgid, &egid, &sgid) < 0) + { + printf ("getresgid failed: %d %m\n", tno); + exit (1); + } + + if (rgid != prev_egid || egid != nobody_gid || sgid != nobody_gid) + { + printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno, + rgid, egid, sgid, prev_egid, nobody_gid, nobody_gid); + exit (1); + } + } +} + + +static void +test_setresgid3 (enum ACTION action, int tno) +{ + if (action == PREPARE) + return; + + if (action != CHECK_AFTER) + check_prev_gid (tno); + + if (action == SET && setresgid (nobody_gid, nobody_gid, nobody_gid) < 0) + { + printf ("setresgid failed: %m\n"); + exit (1); + } + + if (action != CHECK_BEFORE) + { + gid_t rgid, egid, sgid; + if (getresgid (&rgid, &egid, &sgid) < 0) + { + printf ("getresgid failed: %d %m\n", tno); + exit (1); + } + + if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid) + { + printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno, + rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid); + exit (1); + } + } +} + + +static void +test_setresgid4 (enum ACTION action, int tno) +{ + if (action == PREPARE) + { + if (setresgid (nobody_gid, nobody_gid, -1) < 0) + { + printf ("setresgid failed: %m\n"); + exit (1); + } + + prev_rgid = nobody_gid; + prev_egid = nobody_gid; + nobody_gid = prev_sgid; + return; + } + + test_setresgid1 (action, tno); +} + + +static struct setuid_test +{ + const char *name; + void (*test) (enum ACTION, int tno); +} setuid_tests[] = +{ + { "setuid1", test_setuid1 }, + { "setuid2", test_setuid2 }, + { "seteuid1", test_seteuid1 }, + { "seteuid2", test_seteuid2 }, + { "setreuid1", test_setreuid1 }, + { "setreuid2", test_setreuid2 }, + { "setreuid3", test_setreuid3 }, + { "setreuid4", test_setreuid4 }, + { "setresuid1", test_setresuid1 }, + { "setresuid2", test_setresuid2 }, + { "setresuid3", test_setresuid3 }, + { "setresuid4", test_setresuid4 }, + { "setgid1", test_setgid1 }, + { "setgid2", test_setgid2 }, + { "setegid1", test_setegid1 }, + { "setegid2", test_setegid2 }, + { "setregid1", test_setregid1 }, + { "setregid2", test_setregid2 }, + { "setregid3", test_setregid3 }, + { "setregid4", test_setregid4 }, + { "setresgid1", test_setresgid1 }, + { "setresgid2", test_setresgid2 }, + { "setresgid3", test_setresgid3 }, + { "setresgid4", test_setresgid4 } +}; + + +static void * +tf2 (void *arg) +{ + int e = pthread_barrier_wait (&b4); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("barrier_wait failed"); + exit (1); + } + + setuid_tests[TESTNO (arg)].test (CHECK_AFTER, THREADNO (arg)); + return NULL; +} + + +static void * +tf (void *arg) |
