1 /* $OpenBSD: setgid_child.c,v 1.1 2014/08/27 07:36:14 blambert Exp $ */ 2 /* 3 * Written by Bret Stephen Lambert <blambert@openbsd.org> 2014 4 * Public Domain. 5 */ 6 7 #include <sys/types.h> 8 #include <sys/param.h> 9 #include <sys/proc.h> 10 #include <sys/sysctl.h> 11 #include <sys/wait.h> 12 13 #include <err.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <pwd.h> 17 #include <unistd.h> 18 19 #include "setuid_regress.h" 20 21 int 22 main(int argc, const char *argv[]) 23 { 24 struct kinfo_proc kproc; 25 struct passwd *pw; 26 pid_t pid; 27 int status; 28 29 if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) 30 err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); 31 32 if (setgid(pw->pw_gid) == -1) 33 err(1, "setgid"); 34 35 switch ((pid = fork())) { 36 37 default: 38 waitpid(pid, &status, 0); 39 if (WIFSIGNALED(status)) 40 errx(1, "child exited due to signal %d", 41 WTERMSIG(status)); 42 else if (WEXITSTATUS(status) != 0) 43 errx(1, "child exited with status %d", 44 WEXITSTATUS(status)); 45 break; 46 47 case 0: 48 /* 49 * From the setgid man page: 50 * The setgid() function sets the real and effective user IDs 51 * and the saved set-user-ID of the current process 52 */ 53 checkgids(pw->pw_gid, pw->pw_gid, pw->pw_gid, "setgid child"); 54 55 /* should only respond to setgid upon exec */ 56 if (issetugid()) 57 errx(1, "child incorrectly marked as issetugid()"); 58 59 if (read_kproc_pid(&kproc, getpid()) == -1) 60 err(1, "kproc read failed"); 61 62 if (!(kproc.p_psflags & PS_SUGID)) 63 errx(1, "PS_SUGID not set"); 64 if (kproc.p_psflags & PS_SUGIDEXEC) 65 errx(1, "PS_SUGIDEXEC incorrectly set"); 66 67 break; 68 69 case -1: 70 err(1, "fork"); 71 /* NOTREACHED */ 72 } 73 74 exit(0); 75 } 76