1/*- 2 * Copyright (c) 2001 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/tools/regression/security/proc_to_proc/scenario.c 75485 2001-04-13 16:25:25Z rwatson $ |
27 */ 28 |
29#include <sys/param.h> 30#include <sys/uio.h> |
31#include <sys/ptrace.h> 32#include <sys/time.h> 33#include <sys/resource.h> 34#include <sys/syscall.h> 35#include <sys/wait.h> |
36#include <sys/ktrace.h> |
37 38#include <assert.h> 39#include <errno.h> 40#include <signal.h> 41#include <stdio.h> 42#include <string.h> 43#include <unistd.h> 44 --- 6 unchanged lines hidden (view full) --- 51}; 52 53/* 54 * Description of a scenario. 55 */ 56struct scenario { 57 struct cred *sc_cred1, *sc_cred2; /* credentials of p1 and p2 */ 58 int sc_canptrace_errno; /* desired ptrace failure */ |
59 int sc_canktrace_errno; /* desired ktrace failure */ |
60 int sc_cansighup_errno; /* desired SIGHUP failure */ 61 int sc_cansigsegv_errno; /* desired SIGSEGV failure */ 62 int sc_cansee_errno; /* desired getprio failure */ 63 int sc_cansched_errno; /* desired setprio failure */ 64 char *sc_name; /* test name */ 65}; 66 67/* --- 16 unchanged lines hidden (view full) --- 84/* 12 */{ 0, 1001, 1001, 0 }, /* setuid2 */ 85/* 13 */{ 0, 1001, 1001, 1 }, /* setuid2 + issetugid */ 86}; 87 88/* 89 * Table of scenarios. 90 */ 91static const struct scenario scenarios[] = { |
92/* cred1 cred2 ptrace ktrace, sighup sigsegv see sched name */ 93{ &creds[0], &creds[0], 0, 0, 0, 0, 0, 0, "0. priv on priv"}, 94{ &creds[0], &creds[1], 0, 0, 0, 0, 0, 0, "1. priv on priv"}, 95{ &creds[1], &creds[0], 0, 0, 0, 0, 0, 0, "2. priv on priv"}, 96{ &creds[1], &creds[1], 0, 0, 0, 0, 0, 0, "3. priv on priv"}, |
97/* privileged on unprivileged */ |
98{ &creds[0], &creds[2], 0, 0, 0, 0, 0, 0, "4. priv on unpriv1"}, 99{ &creds[0], &creds[3], 0, 0, 0, 0, 0, 0, "5. priv on unpriv1"}, 100{ &creds[1], &creds[2], 0, 0, 0, 0, 0, 0, "6. priv on unpriv1"}, 101{ &creds[1], &creds[3], 0, 0, 0, 0, 0, 0, "7. priv on unpriv1"}, |
102/* unprivileged on privileged */ |
103{ &creds[2], &creds[0], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "8. unpriv1 on priv"}, 104{ &creds[2], &creds[1], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "9. unpriv1 on priv"}, 105{ &creds[3], &creds[0], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "10. unpriv1 on priv"}, 106{ &creds[3], &creds[1], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "11. unpriv1 on priv"}, |
107/* unprivileged on same unprivileged */ |
108{ &creds[2], &creds[2], 0, 0, 0, 0, 0, 0, "12. unpriv1 on unpriv1"}, 109{ &creds[2], &creds[3], EPERM, EPERM, 0, EPERM, 0, 0, "13. unpriv1 on unpriv1"}, 110{ &creds[3], &creds[2], 0, 0, 0, 0, 0, 0, "14. unpriv1 on unpriv1"}, 111{ &creds[3], &creds[3], EPERM, EPERM, 0, EPERM, 0, 0, "15. unpriv1 on unpriv1"}, |
112/* unprivileged on different unprivileged */ |
113{ &creds[2], &creds[4], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "16. unpriv1 on unpriv2"}, 114{ &creds[2], &creds[5], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "17. unpriv1 on unpriv2"}, 115{ &creds[3], &creds[4], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "18. unpriv1 on unpriv2"}, 116{ &creds[3], &creds[5], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "19. unpriv1 on unpriv2"}, |
117/* unprivileged on daemon, same */ |
118{ &creds[2], &creds[6], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "20. unpriv1 on daemon1"}, 119{ &creds[2], &creds[7], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "21. unpriv1 on daemon1"}, 120{ &creds[3], &creds[6], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "22. unpriv1 on daemon1"}, 121{ &creds[3], &creds[7], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "23. unpriv1 on daemon1"}, |
122/* unprivileged on daemon, different */ |
123{ &creds[2], &creds[8], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "24. unpriv1 on daemon2"}, 124{ &creds[2], &creds[9], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "25. unpriv1 on daemon2"}, 125{ &creds[3], &creds[8], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "26. unpriv1 on daemon2"}, 126{ &creds[3], &creds[9], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "27. unpriv1 on daemon2"}, |
127/* unprivileged on setuid, same */ |
128{ &creds[2], &creds[10], EPERM, EPERM, 0, 0, 0, 0, "28. unpriv1 on setuid1"}, 129{ &creds[2], &creds[11], EPERM, EPERM, 0, EPERM, 0, 0, "29. unpriv1 on setuid1"}, 130{ &creds[3], &creds[10], EPERM, EPERM, 0, 0, 0, 0, "30. unpriv1 on setuid1"}, 131{ &creds[3], &creds[11], EPERM, EPERM, 0, EPERM, 0, 0, "31. unpriv1 on setuid1"}, |
132/* unprivileged on setuid, different */ |
133{ &creds[2], &creds[12], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "32. unpriv1 on setuid2"}, 134{ &creds[2], &creds[13], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "33. unpriv1 on setuid2"}, 135{ &creds[3], &creds[12], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "34. unpriv1 on setuid2"}, 136{ &creds[3], &creds[13], EPERM, EPERM, EPERM, EPERM, 0, EPERM, "35. unpriv1 on setuid2"}, |
137}; 138int scenarios_count = sizeof(scenarios) / sizeof(struct scenario); 139 140/* 141 * Convert an error number to a compact string representation. For now, 142 * implement only the error numbers we are likely to see. 143 */ 144static char * --- 11 unchanged lines hidden (view full) --- 156 return ("ENOSYS"); 157 case ESRCH: 158 return ("ESRCH"); 159 case EOPNOTSUPP: 160 return ("EOPNOTSUPP"); 161 case 0: 162 return ("0"); 163 default: |
164 printf("%d\n", error); |
165 return ("unknown"); 166 } 167} 168 169/* 170 * Return a process credential describing the current process. 171 */ 172static int --- 72 unchanged lines hidden (view full) --- 245cred_print(FILE *output, struct cred *cred) 246{ 247 248 fprintf(output, "(e:%d r:%d s:%d P_SUGID:%d)", cred->cr_euid, 249 cred->cr_ruid, cred->cr_svuid, cred->cr_issetugid); 250} 251 252#define LOOP_PTRACE 0 |
253#define LOOP_KTRACE 1 254#define LOOP_SIGHUP 2 255#define LOOP_SIGSEGV 3 256#define LOOP_SEE 4 257#define LOOP_SCHED 5 |
258#define LOOP_MAX LOOP_SCHED 259 260/* 261 * Enact a scenario by looping through the four test cases for the scenario, 262 * spawning off pairs of processes with the desired credentials, and 263 * reporting results to stdout. 264 */ 265static int 266enact_scenario(int scenario) 267{ 268 pid_t pid1, pid2; |
269 char *name, *tracefile; |
270 int error, desirederror, loop; 271 272 for (loop = 0; loop < LOOP_MAX+1; loop++) { 273 /* 274 * Spawn the first child, target of the operation. 275 */ 276 pid1 = fork(); 277 switch (pid1) { --- 53 unchanged lines hidden (view full) --- 331 switch (loop) { 332 case LOOP_PTRACE: 333 error = ptrace(PT_ATTACH, pid1, NULL, 0); 334 error = errno; 335 name = "ptrace"; 336 desirederror = 337 scenarios[scenario].sc_canptrace_errno; 338 break; |
339 case LOOP_KTRACE: 340 tracefile = mktemp("/tmp/testuid_ktrace.XXXXXX"); 341 if (tracefile == NULL) { 342 error = errno; 343 perror("mktemp"); 344 break; 345 } 346 error = ktrace(tracefile, KTROP_SET, 347 KTRFAC_SYSCALL, pid1); 348 error = errno; 349 name = "ktrace"; 350 desirederror = 351 scenarios[scenario].sc_canktrace_errno; 352 unlink(tracefile); 353 break; |
354 case LOOP_SIGHUP: 355 error = kill(pid1, SIGHUP); 356 error = errno; 357 name = "sighup"; 358 desirederror = 359 scenarios[scenario].sc_cansighup_errno; 360 break; 361 case LOOP_SIGSEGV: --- 69 unchanged lines hidden --- |