diff options
author | Bret Lambert <blambert@cvs.openbsd.org> | 2014-08-27 07:36:15 +0000 |
---|---|---|
committer | Bret Lambert <blambert@cvs.openbsd.org> | 2014-08-27 07:36:15 +0000 |
commit | f1a3173b531e37ef7be4d8586d15b56d3e8fac0b (patch) | |
tree | 96982626c4fa2437626bc3f68cff3e41461323d2 /regress/sys | |
parent | 23297ea3d8ce80230fcadec55b9467ecdb7c1f2b (diff) |
Regression tests for setuid-and-friends.
Thanks to djm@ for good suggestions.
Diffstat (limited to 'regress/sys')
27 files changed, 1702 insertions, 0 deletions
diff --git a/regress/sys/kern/setuid/Makefile b/regress/sys/kern/setuid/Makefile new file mode 100644 index 00000000000..0e15eca9fc7 --- /dev/null +++ b/regress/sys/kern/setuid/Makefile @@ -0,0 +1,115 @@ +# $OpenBSD: Makefile,v 1.1 2014/08/27 07:36:14 blambert Exp $ + +CFLAGS += -Wall -Wformat -pedantic + +REGRESS_TARGETS+= run-regress-setuid_none +REGRESS_TARGETS+= run-regress-setgid_none +REGRESS_TARGETS+= run-regress-setuid +REGRESS_TARGETS+= run-regress-setgid +REGRESS_TARGETS+= run-regress-seteuid +REGRESS_TARGETS+= run-regress-setegid +REGRESS_TARGETS+= run-regress-setuid_child +REGRESS_TARGETS+= run-regress-setgid_child +REGRESS_TARGETS+= run-regress-setresuid +REGRESS_TARGETS+= run-regress-setresgid +REGRESS_TARGETS+= run-regress-suidexec-on-inherit-on +REGRESS_TARGETS+= run-regress-suidexec-on-inherit-inherit +REGRESS_TARGETS+= run-regress-suidexec-off-on-inherit +REGRESS_TARGETS+= run-regress-suidexec-off-off-on +REGRESS_TARGETS+= run-regress-sgidexec-on-inherit-on +REGRESS_TARGETS+= run-regress-sgidexec-on-inherit-inherit +REGRESS_TARGETS+= run-regress-sgidexec-off-on-inherit +REGRESS_TARGETS+= run-regress-sgidexec-off-off-on +REGRESS_TARGETS+= run-regress-suidexec-real-exec-inherit +REGRESS_TARGETS+= run-regress-suidexec-effective-exec-inherit +REGRESS_TARGETS+= run-regress-suidexec-saved-exec-inherit +REGRESS_TARGETS+= run-regress-sgidexec-real-exec-inherit +REGRESS_TARGETS+= run-regress-sgidexec-effective-exec-inherit +REGRESS_TARGETS+= run-regress-sgidexec-saved-exec-inherit + +CLEANFILES+= *.o +CLEANFILES+= setuid_none +CLEANFILES+= setgid_none +CLEANFILES+= setuid +CLEANFILES+= setgid +CLEANFILES+= seteuid +CLEANFILES+= setegid +CLEANFILES+= setuid_child +CLEANFILES+= setgid_child +CLEANFILES+= setresuid +CLEANFILES+= setresgid +CLEANFILES+= setresuid_real_exec +CLEANFILES+= setresuid_effective_exec +CLEANFILES+= setresuid_saved_exec +CLEANFILES+= suidexec_none +CLEANFILES+= suidexec +CLEANFILES+= sgidexec +CLEANFILES+= setresgid_real_exec +CLEANFILES+= setresgid_effective_exec +CLEANFILES+= setresgid_saved_exec +CLEANFILES+= sgidexec_none +CLEANFILES+= suidexec_inherit +CLEANFILES+= sgidexec_inherit +CLEANFILES+= setuid_exec_inherit +CLEANFILES+= setgid_exec_inherit + +run-regress-setuid_none: setuid_none + ./setuid_none +run-regress-setgid_none: setgid_none + ./setgid_none +run-regress-setuid: setuid + ${SUDO} ./setuid +run-regress-setgid: setgid + ${SUDO} ./setgid +run-regress-seteuid: seteuid + ${SUDO} ./seteuid +run-regress-setegid: setegid + ${SUDO} ./setegid +run-regress-setuid_child: setuid_child + ${SUDO} ./setuid_child +run-regress-setgid_child: setgid_child + ${SUDO} ./setgid_child +run-regress-setresuid: setresuid + ${SUDO} ./setresuid +run-regress-setresgid: setresgid + ${SUDO} ./setresgid + +run-regress-suidexec-on-inherit-on: suidexec-install + ${SUDO} ./suidexec ./suidexec_inherit ./suidexec +run-regress-suidexec-off-on-inherit: suidexec-install + ${SUDO} ./suidexec_none ./suidexec ./suidexec_inherit +run-regress-suidexec-on-inherit-inherit: suidexec-install + ${SUDO} ./suidexec ./suidexec_inherit ./suidexec_inherit +run-regress-suidexec-off-off-on: suidexec-install + ${SUDO} ./suidexec_none ./suidexec_none ./suidexec +run-regress-suidexec-real-exec-inherit: suidexec-install + ${SUDO} ./setresuid_real_exec ./setuid_exec_inherit +run-regress-suidexec-effective-exec-inherit: suidexec-install + ${SUDO} ./setresuid_effective_exec ./setuid_exec_inherit +run-regress-suidexec-saved-exec-inherit: suidexec-install + ${SUDO} ./setresuid_saved_exec ./setuid_exec_inherit + +run-regress-sgidexec-on-inherit-on: sgidexec-install + ${SUDO} ./sgidexec ./sgidexec_inherit ./sgidexec +run-regress-sgidexec-off-on-inherit: sgidexec-install + ${SUDO} ./sgidexec_none ./sgidexec ./sgidexec_inherit +run-regress-sgidexec-on-inherit-inherit: sgidexec-install + ${SUDO} ./sgidexec ./sgidexec_inherit ./sgidexec_inherit +run-regress-sgidexec-off-off-on: sgidexec-install + ${SUDO} ./sgidexec_none ./sgidexec_none ./sgidexec +run-regress-sgidexec-real-exec-inherit: sgidexec-install + ${SUDO} ./setresgid_real_exec ./setgid_exec_inherit +run-regress-sgidexec-effective-exec-inherit: sgidexec-install + ${SUDO} ./setresgid_effective_exec ./setgid_exec_inherit +run-regress-sgidexec-saved-exec-inherit: sgidexec-install + ${SUDO} ./setresgid_saved_exec ./setgid_exec_inherit + +suidexec-install: suidexec suidexec_none suidexec_inherit setresuid_real_exec setresuid_effective_exec setresuid_saved_exec setuid_exec_inherit + ${SUDO} chown nobody:nobody ./suidexec + ${SUDO} chmod 4555 ./suidexec + +sgidexec-install: sgidexec sgidexec_none sgidexec_inherit setresgid_real_exec setresgid_effective_exec setresgid_saved_exec setgid_exec_inherit + ${SUDO} chown nobody:nobody ./sgidexec + ${SUDO} chmod 2555 ./sgidexec + +.include <bsd.regress.mk> diff --git a/regress/sys/kern/setuid/setegid.c b/regress/sys/kern/setuid/setegid.c new file mode 100644 index 00000000000..e62d0eb7860 --- /dev/null +++ b/regress/sys/kern/setuid/setegid.c @@ -0,0 +1,64 @@ +/* $OpenBSD: setegid.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, const char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + gid_t gid; + + gid = getgid(); + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + if (setegid(pw->pw_gid) == -1) + err(1, "setegid 0"); + + if (getegid() != pw->pw_gid) + errx(1, "mismatched effective gids"); + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read 0 failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + /* at this point, we should be able to reset our gid */ + if (setegid(gid) == -1) + err(1, "setegid 1"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read 0 failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + exit(0); +} diff --git a/regress/sys/kern/setuid/seteuid.c b/regress/sys/kern/setuid/seteuid.c new file mode 100644 index 00000000000..7da65acb307 --- /dev/null +++ b/regress/sys/kern/setuid/seteuid.c @@ -0,0 +1,66 @@ +/* $OpenBSD: seteuid.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, const char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + uid_t uid; + + uid = getuid(); + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + if (seteuid(pw->pw_uid) == -1) + err(1, "seteuid 0"); + + if (geteuid() != pw->pw_uid) + errx(1, "mismatched effective uids"); + + checkuids(uid, pw->pw_uid, uid, "seteuid"); + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read 0 failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + /* at this point, we should be able to reset our uid */ + if (seteuid(uid) == -1) + err(1, "seteuid 1"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read 1 failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setgid.c b/regress/sys/kern/setuid/setgid.c new file mode 100644 index 00000000000..ee2b04a5cf1 --- /dev/null +++ b/regress/sys/kern/setuid/setgid.c @@ -0,0 +1,52 @@ +/* $OpenBSD: setgid.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, const char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + /* + * From the setgid man page: + * The setgid() function sets the real and effective group IDs + * and the saved set-group-ID of the current process + */ + if (setgid(pw->pw_gid) == -1) + err(1, "setgid"); + checkgids(pw->pw_gid, pw->pw_gid, pw->pw_gid, "setgid"); + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setgid_child.c b/regress/sys/kern/setuid/setgid_child.c new file mode 100644 index 00000000000..982e2057d2c --- /dev/null +++ b/regress/sys/kern/setuid/setgid_child.c @@ -0,0 +1,75 @@ +/* $OpenBSD: setgid_child.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, const char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + pid_t pid; + int status; + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + if (setgid(pw->pw_gid) == -1) + err(1, "setgid"); + + switch ((pid = fork())) { + + default: + waitpid(pid, &status, 0); + if (WIFSIGNALED(status)) + errx(1, "child exited due to signal %d", + WTERMSIG(status)); + else if (WEXITSTATUS(status) != 0) + errx(1, "child exited with status %d", + WEXITSTATUS(status)); + break; + + case 0: + /* + * From the setgid man page: + * The setgid() function sets the real and effective user IDs + * and the saved set-user-ID of the current process + */ + checkgids(pw->pw_gid, pw->pw_gid, pw->pw_gid, "setgid child"); + + /* should only respond to setgid upon exec */ + if (issetugid()) + errx(1, "child incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + break; + + case -1: + err(1, "fork"); + /* NOTREACHED */ + } + + exit(0); +} diff --git a/regress/sys/kern/setuid/setgid_exec_inherit.c b/regress/sys/kern/setuid/setgid_exec_inherit.c new file mode 100644 index 00000000000..6074c488ca7 --- /dev/null +++ b/regress/sys/kern/setuid/setgid_exec_inherit.c @@ -0,0 +1,51 @@ +/* $OpenBSD: setgid_exec_inherit.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + char *toexec = NULL; + + if (argc > 1) { + argv++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + if (!issetugid()) + errx(1, "process not marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (kproc.p_psflags & PS_SUGID) + errx(1, "PS_SUGID incorrectly set"); + if (!(kproc.p_psflags & PS_SUGIDEXEC)) + errx(1, "PS_SUGIDEXEC not set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setgid_none.c b/regress/sys/kern/setuid/setgid_none.c new file mode 100644 index 00000000000..6f3d9a7cfd0 --- /dev/null +++ b/regress/sys/kern/setuid/setgid_none.c @@ -0,0 +1,44 @@ +/* $OpenBSD: setgid_none.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, const char *argv[]) +{ + struct kinfo_proc kproc; + gid_t gid; + + gid = getgid(); + + checkgids(gid, gid, gid, "checkgid"); + + /* should only respond to setgid upon exec */ + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (kproc.p_psflags & PS_SUGID) + errx(1, "PS_SUGID incorrectly set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setresgid.c b/regress/sys/kern/setuid/setresgid.c new file mode 100644 index 00000000000..a295d3609f5 --- /dev/null +++ b/regress/sys/kern/setuid/setresgid.c @@ -0,0 +1,102 @@ +/* $OpenBSD: setresgid.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, const char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + gid_t gid; + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + gid = getgid(); + + if (setresgid(pw->pw_gid, -1, -1) == -1) + err(1, "setgid 0"); + checkgids(pw->pw_gid, gid, gid, "0"); + + /* should only respond to setgid upon exec */ + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + /* we should be able to roll back our gids for now */ + if (setresgid(gid, -1, -1) == -1) + err(1, "setgid 1"); + checkgids(gid, gid, gid, "1"); + + if (setresgid(-1, pw->pw_gid, -1) == -1) + err(1, "setgid 2"); + checkgids(gid, pw->pw_gid, gid, "2"); + + /* we should be able to roll back our gids for now */ + if (setresgid(-1, gid, -1) == -1) + err(1, "setgid 3"); + checkgids(gid, gid, gid, "3"); + + /* + * after changing our saved gid and dropping superuser privs, + * we should be able to change our real and effective gids to + * that of our saved gid, but not to anything else + */ + + if (setresgid(-1, -1, pw->pw_gid) == -1) + err(1, "setgid 4"); + checkgids(gid, gid, pw->pw_gid, "4"); + + if (setresuid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) + err(1, "setresuid 4"); + + if (setresgid(pw->pw_gid, -1, -1) == -1) + err(1, "setgid 5"); + checkgids(pw->pw_gid, gid, pw->pw_gid, "5"); + + if (setresgid(-1, pw->pw_gid, -1) == -1) + err(1, "setgid 6"); + checkgids(pw->pw_gid, pw->pw_gid, pw->pw_gid, "6"); + + if (setresgid(gid, -1, -1) != -1) + errx(1, "incorrectly capable of setting real gid"); + checkgids(pw->pw_gid, pw->pw_gid, pw->pw_gid, "7"); + + if (setresgid(-1, gid, -1) != -1) + errx(1, "incorrectly capable of setting effective gid"); + checkgids(pw->pw_gid, pw->pw_gid, pw->pw_gid, "9"); + + if (setresgid(-1, -1, gid) != -1) + errx(1, "incorrectly capable of setting saved gid"); + checkgids(pw->pw_gid, pw->pw_gid, pw->pw_gid, "9"); + + /* sanity-check use of -1 as noop */ + if (setresgid(-1, -1, -1) == -1) + errx(1, "-1 not properly recognized as noop"); + checkgids(pw->pw_gid, pw->pw_gid, pw->pw_gid, "9"); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setresgid_effective_exec.c b/regress/sys/kern/setuid/setresgid_effective_exec.c new file mode 100644 index 00000000000..33767fa8bd3 --- /dev/null +++ b/regress/sys/kern/setuid/setresgid_effective_exec.c @@ -0,0 +1,62 @@ +/* $OpenBSD: setresgid_effective_exec.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + char *toexec = NULL; + gid_t gid; + + if (argc > 1) { + argv++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + gid = getgid(); + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + if (setresgid(-1, pw->pw_gid, -1) == -1) + err(1, "setgid"); + checkgids(gid, pw->pw_gid, gid, "setgid"); + + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setresgid_real_exec.c b/regress/sys/kern/setuid/setresgid_real_exec.c new file mode 100644 index 00000000000..fd9b9d32c20 --- /dev/null +++ b/regress/sys/kern/setuid/setresgid_real_exec.c @@ -0,0 +1,62 @@ +/* $OpenBSD: setresgid_real_exec.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + char *toexec = NULL; + gid_t gid; + + if (argc > 1) { + argv++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + gid = getgid(); + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + if (setresgid(pw->pw_gid, -1, -1) == -1) + err(1, "setgid"); + checkgids(pw->pw_gid, gid, gid, "setgid"); + + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setresgid_saved_exec.c b/regress/sys/kern/setuid/setresgid_saved_exec.c new file mode 100644 index 00000000000..f1f6bf0cfd3 --- /dev/null +++ b/regress/sys/kern/setuid/setresgid_saved_exec.c @@ -0,0 +1,62 @@ +/* $OpenBSD: setresgid_saved_exec.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + char *toexec = NULL; + gid_t gid; + + if (argc > 1) { + argv++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + gid = getgid(); + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + if (setresgid(-1, -1, pw->pw_gid) == -1) + err(1, "setgid"); + checkgids(gid, gid, pw->pw_gid, "setgid"); + + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setresuid.c b/regress/sys/kern/setuid/setresuid.c new file mode 100644 index 00000000000..0721d254482 --- /dev/null +++ b/regress/sys/kern/setuid/setresuid.c @@ -0,0 +1,99 @@ +/* $OpenBSD: setresuid.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, const char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + uid_t uid; + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + uid = getuid(); + + if (setresuid(pw->pw_uid, -1, -1) == -1) + err(1, "setuid 0"); + checkuids(pw->pw_uid, uid, uid, "0"); + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + /* we should be able to roll back our uids for now */ + if (setresuid(uid, -1, -1) == -1) + err(1, "setuid 1"); + checkuids(uid, uid, uid, "1"); + + if (setresuid(-1, pw->pw_uid, -1) == -1) + err(1, "setuid 2"); + checkuids(uid, pw->pw_uid, uid, "2"); + + /* we should be able to roll back our uids for now */ + if (setresuid(-1, uid, -1) == -1) + err(1, "setuid 3"); + checkuids(uid, uid, uid, "3"); + + /* + * after changing our saved uid, we should be able to change + * our real and effective uids to that of our saved uid, + * but not to anything else + */ + + if (setresuid(-1, -1, pw->pw_uid) == -1) + err(1, "setuid 4"); + checkuids(uid, uid, pw->pw_uid, "4"); + + if (setresuid(pw->pw_uid, -1, -1) == -1) + err(1, "setuid 5"); + checkuids(pw->pw_uid, uid, pw->pw_uid, "5"); + + if (setresuid(-1, pw->pw_uid, -1) == -1) + err(1, "setuid 6"); + checkuids(pw->pw_uid, pw->pw_uid, pw->pw_uid, "6"); + + if (setresuid(uid, -1, -1) != -1) + errx(1, "incorrectly capable of setting real uid"); + checkuids(pw->pw_uid, pw->pw_uid, pw->pw_uid, "7"); + + if (setresuid(-1, uid, -1) != -1) + errx(1, "incorrectly capable of setting effective uid"); + checkuids(pw->pw_uid, pw->pw_uid, pw->pw_uid, "9"); + + if (setresuid(-1, -1, uid) != -1) + errx(1, "incorrectly capable of setting saved uid"); + checkuids(pw->pw_uid, pw->pw_uid, pw->pw_uid, "9"); + + /* sanity-check use of -1 as noop */ + if (setresuid(-1, -1, -1) == -1) + errx(1, "-1 not properly recognized as noop"); + checkuids(pw->pw_uid, pw->pw_uid, pw->pw_uid, "9"); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setresuid_effective_exec.c b/regress/sys/kern/setuid/setresuid_effective_exec.c new file mode 100644 index 00000000000..860a47ef519 --- /dev/null +++ b/regress/sys/kern/setuid/setresuid_effective_exec.c @@ -0,0 +1,63 @@ +/* $OpenBSD: setresuid_effective_exec.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + char *toexec = NULL; + uid_t uid; + + if (argc > 1) { + argv ++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + uid = getuid(); + + if (setresuid(-1, pw->pw_uid, -1) == -1) + err(1, "setuid"); + checkuids(uid, pw->pw_uid, uid, "setuid"); + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "process incorrectly as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setresuid_real_exec.c b/regress/sys/kern/setuid/setresuid_real_exec.c new file mode 100644 index 00000000000..18fff09291e --- /dev/null +++ b/regress/sys/kern/setuid/setresuid_real_exec.c @@ -0,0 +1,63 @@ +/* $OpenBSD: setresuid_real_exec.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + char *toexec = NULL; + uid_t uid; + + if (argc > 1) { + argv ++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + uid = getuid(); + + if (setresuid(pw->pw_uid, -1, -1) == -1) + err(1, "setuid"); + checkuids(pw->pw_uid, uid, uid, "setuid"); + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "process incorrectly as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setresuid_saved_exec.c b/regress/sys/kern/setuid/setresuid_saved_exec.c new file mode 100644 index 00000000000..9d76fccbb07 --- /dev/null +++ b/regress/sys/kern/setuid/setresuid_saved_exec.c @@ -0,0 +1,63 @@ +/* $OpenBSD: setresuid_saved_exec.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + char *toexec = NULL; + uid_t uid; + + if (argc > 1) { + argv ++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + uid = getuid(); + + if (setresuid(-1, -1, pw->pw_uid) == -1) + err(1, "setuid"); + checkuids(uid, uid, pw->pw_uid, "setuid"); + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "process incorrectly as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setuid.c b/regress/sys/kern/setuid/setuid.c new file mode 100644 index 00000000000..79ecc57f136 --- /dev/null +++ b/regress/sys/kern/setuid/setuid.c @@ -0,0 +1,52 @@ +/* $OpenBSD: setuid.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, const char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + /* + * From the setuid man page: + * The setuid() function sets the real and effective user IDs + * and the saved set-user-ID of the current process + */ + if (setuid(pw->pw_uid) == -1) + err(1, "setuid"); + checkuids(pw->pw_uid, pw->pw_uid, pw->pw_uid, "getresuid"); + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setuid_child.c b/regress/sys/kern/setuid/setuid_child.c new file mode 100644 index 00000000000..eed09ba09c2 --- /dev/null +++ b/regress/sys/kern/setuid/setuid_child.c @@ -0,0 +1,75 @@ +/* $OpenBSD: setuid_child.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, const char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + pid_t pid; + int status; + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + if (setuid(pw->pw_uid) == -1) + err(1, "setuid"); + + switch ((pid = fork())) { + + default: + waitpid(pid, &status, 0); + if (WIFSIGNALED(status)) + errx(1, "child exited due to signal %d", + WTERMSIG(status)); + else if (WEXITSTATUS(status) != 0) + errx(1, "child exited with status %d", + WEXITSTATUS(status)); + break; + + case 0: + /* + * From the setuid man page: + * The setuid() function sets the real and effective user IDs + * and the saved set-user-ID of the current process + */ + checkuids(pw->pw_uid, pw->pw_uid, pw->pw_uid, "setuid child"); + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "child incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + break; + + case -1: + err(1, "fork"); + /* NOTREACHED */ + } + + exit(0); +} diff --git a/regress/sys/kern/setuid/setuid_exec_inherit.c b/regress/sys/kern/setuid/setuid_exec_inherit.c new file mode 100644 index 00000000000..b2bd33a2f12 --- /dev/null +++ b/regress/sys/kern/setuid/setuid_exec_inherit.c @@ -0,0 +1,51 @@ +/* $OpenBSD: setuid_exec_inherit.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + char *toexec = NULL; + + if (argc > 1) { + argv++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + if (!issetugid()) + errx(1, "process not marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (kproc.p_psflags & PS_SUGID) + errx(1, "PS_SUGID incorrectly set"); + if (!(kproc.p_psflags & PS_SUGIDEXEC)) + errx(1, "PS_SUGIDEXEC not set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setuid_none.c b/regress/sys/kern/setuid/setuid_none.c new file mode 100644 index 00000000000..4c13366d0b6 --- /dev/null +++ b/regress/sys/kern/setuid/setuid_none.c @@ -0,0 +1,44 @@ +/* $OpenBSD: setuid_none.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + uid_t uid; + + uid = getuid(); + + checkuids(uid, uid, uid, "getuid"); + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (kproc.p_psflags & PS_SUGID) + errx(1, "PS_SUGID incorrectly set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setuid_real_exec.c b/regress/sys/kern/setuid/setuid_real_exec.c new file mode 100644 index 00000000000..2b0d73ed0fb --- /dev/null +++ b/regress/sys/kern/setuid/setuid_real_exec.c @@ -0,0 +1,63 @@ +/* $OpenBSD: setuid_real_exec.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + struct passwd *pw; + char *toexec = NULL; + uid_t uid; + + if (argc > 1) { + argv ++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) + err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); + + uid = getuid(); + + if (setresuid(pw->pw_uid, -1, -1) == -1) + err(1, "setuid"); + checkuids(pw->pw_uid, uid, uid, "setuid"); + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "process incorrectly as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/setuid_regress.h b/regress/sys/kern/setuid/setuid_regress.h new file mode 100644 index 00000000000..655c6aae757 --- /dev/null +++ b/regress/sys/kern/setuid/setuid_regress.h @@ -0,0 +1,66 @@ +/* $OpenBSD: setuid_regress.h,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#ifndef _SETUID_REGRESS_H_ +#define _SETUID_REGRESS_H_ + +#define _SETUID_REGRESS_USER "nobody" + +static inline int +read_kproc_pid(struct kinfo_proc *kproc, pid_t pid) +{ + int args[6]; + size_t size; + + args[0] = CTL_KERN; + args[1] = KERN_PROC; + args[2] = KERN_PROC_PID; + args[3] = pid; + args[4] = sizeof(*kproc); + args[5] = 1; + + size = sizeof(*kproc); + return (sysctl(args, 6, kproc, &size, NULL, 0)); +} + +static inline void +checkuids(uid_t truid, uid_t teuid, uid_t tsuid, const char *str) +{ + uid_t ruid, euid, suid; + + if (getresuid(&ruid, &euid, &suid) == -1) + err(1, "getresuid %s", str); + + if (ruid != truid) + errx(1, "real uid incorrectly set %s: is %u should be %u", + str, ruid, truid); + if (euid != teuid) + errx(1, "effective uid incorrectly set %s: is %u should be %u", + str, euid, teuid); + if (suid != tsuid) + errx(1, "saved uid incorrectly set %s: is %u should be %u", + str, suid, tsuid); +} + +void +checkgids(gid_t trgid, gid_t tegid, gid_t tsgid, const char *str) +{ + gid_t rgid, egid, sgid; + + if (getresgid(&rgid, &egid, &sgid) == -1) + err(1, "getresgid %s", str); + + if (rgid != trgid) + errx(1, "real gid incorrectly set %s: is %u should be %u", + str, rgid, trgid); + if (egid != tegid) + errx(1, "effective gid incorrectly set %s: is %u should be %u", + str, egid, tegid); + if (sgid != tsgid) + errx(1, "saved gid incorrectly set %s: is %u should be %u", + str, sgid, tsgid); +} +#endif diff --git a/regress/sys/kern/setuid/sgidexec.c b/regress/sys/kern/setuid/sgidexec.c new file mode 100644 index 00000000000..094e312b148 --- /dev/null +++ b/regress/sys/kern/setuid/sgidexec.c @@ -0,0 +1,51 @@ +/* $OpenBSD: sgidexec.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + char *toexec = NULL; + + if (argc > 1) { + argv++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (issetugid() != 1) + errx(1, "process not marked as issetugid()"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (!(kproc.p_psflags & PS_SUGIDEXEC)) + errx(1, "PS_SUGIDEXEC not set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/sgidexec_inherit.c b/regress/sys/kern/setuid/sgidexec_inherit.c new file mode 100644 index 00000000000..0d4bec3edbb --- /dev/null +++ b/regress/sys/kern/setuid/sgidexec_inherit.c @@ -0,0 +1,51 @@ +/* $OpenBSD: sgidexec_inherit.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + char *toexec = NULL; + + if (argc > 1) { + argv++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + if (!issetugid()) + errx(1, "process not marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (kproc.p_psflags & PS_SUGID) + errx(1, "PS_SUGID incorrectly set"); + if (!(kproc.p_psflags & PS_SUGIDEXEC)) + errx(1, "PS_SUGIDEXEC not set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/sgidexec_none.c b/regress/sys/kern/setuid/sgidexec_none.c new file mode 100644 index 00000000000..f189ac24ac9 --- /dev/null +++ b/regress/sys/kern/setuid/sgidexec_none.c @@ -0,0 +1,52 @@ +/* $OpenBSD: sgidexec_none.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + char *toexec = NULL; + + if (argc > 1) { + argv++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + /* should only respond to setgid upon exec */ + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (kproc.p_psflags & PS_SUGID) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/suidexec.c b/regress/sys/kern/setuid/suidexec.c new file mode 100644 index 00000000000..0503aecc8bd --- /dev/null +++ b/regress/sys/kern/setuid/suidexec.c @@ -0,0 +1,51 @@ +/* $OpenBSD: suidexec.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + char *toexec = NULL; + + if (argc > 1) { + argv++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (!issetugid()) + errx(1, "process not marked as issetugid()"); + + if (!(kproc.p_psflags & PS_SUGID)) + errx(1, "PS_SUGID not set"); + if (!(kproc.p_psflags & PS_SUGIDEXEC)) + errx(1, "PS_SUGIDEXEC not set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/suidexec_inherit.c b/regress/sys/kern/setuid/suidexec_inherit.c new file mode 100644 index 00000000000..e6db0ece21b --- /dev/null +++ b/regress/sys/kern/setuid/suidexec_inherit.c @@ -0,0 +1,51 @@ +/* $OpenBSD: suidexec_inherit.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + char *toexec = NULL; + + if (argc > 1) { + argv++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + if (!issetugid()) + errx(1, "process not marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (kproc.p_psflags & PS_SUGID) + errx(1, "PS_SUGID incorrectly set"); + if (!(kproc.p_psflags & PS_SUGIDEXEC)) + errx(1, "PS_SUGIDEXEC not set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} diff --git a/regress/sys/kern/setuid/suidexec_none.c b/regress/sys/kern/setuid/suidexec_none.c new file mode 100644 index 00000000000..95fad6c05c4 --- /dev/null +++ b/regress/sys/kern/setuid/suidexec_none.c @@ -0,0 +1,52 @@ +/* $OpenBSD: suidexec_none.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ +/* + * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <unistd.h> + +#include "setuid_regress.h" + +int +main(int argc, char *argv[]) +{ + struct kinfo_proc kproc; + char *toexec = NULL; + + if (argc > 1) { + argv++; + if ((toexec = strdup(argv[0])) == NULL) + err(1, "strdup"); + } + + /* should only respond to setuid upon exec */ + if (issetugid()) + errx(1, "process incorrectly marked as issetugid()"); + + if (read_kproc_pid(&kproc, getpid()) == -1) + err(1, "kproc read failed"); + + if (kproc.p_psflags & PS_SUGID) + errx(1, "PS_SUGID not set"); + if (kproc.p_psflags & PS_SUGIDEXEC) + errx(1, "PS_SUGIDEXEC incorrectly set"); + + if (toexec != NULL) + if (execv(toexec, argv) == -1) + err(1, "exec of %s failed", toexec); + free(toexec); + + exit(0); +} |