scenario.c (75482) | scenario.c (75485) |
---|---|
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 * | 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 75482 2001-04-13 16:09:40Z rwatson $ | 26 * $FreeBSD: head/tools/regression/security/proc_to_proc/scenario.c 75485 2001-04-13 16:25:25Z rwatson $ |
27 */ 28 | 27 */ 28 |
29#include <sys/types.h> | 29#include <sys/param.h> 30#include <sys/uio.h> |
30#include <sys/ptrace.h> 31#include <sys/time.h> 32#include <sys/resource.h> 33#include <sys/syscall.h> 34#include <sys/wait.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> |
|
35 36#include <assert.h> 37#include <errno.h> 38#include <signal.h> 39#include <stdio.h> 40#include <string.h> 41#include <unistd.h> 42 --- 6 unchanged lines hidden (view full) --- 49}; 50 51/* 52 * Description of a scenario. 53 */ 54struct scenario { 55 struct cred *sc_cred1, *sc_cred2; /* credentials of p1 and p2 */ 56 int sc_canptrace_errno; /* desired ptrace failure */ | 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 */ |
|
57 int sc_cansighup_errno; /* desired SIGHUP failure */ 58 int sc_cansigsegv_errno; /* desired SIGSEGV failure */ 59 int sc_cansee_errno; /* desired getprio failure */ 60 int sc_cansched_errno; /* desired setprio failure */ 61 char *sc_name; /* test name */ 62}; 63 64/* --- 16 unchanged lines hidden (view full) --- 81/* 12 */{ 0, 1001, 1001, 0 }, /* setuid2 */ 82/* 13 */{ 0, 1001, 1001, 1 }, /* setuid2 + issetugid */ 83}; 84 85/* 86 * Table of scenarios. 87 */ 88static const struct scenario scenarios[] = { | 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[] = { |
89/* cred1 cred2 ptrace sighup sigsegv see sched name */ 90{ &creds[0], &creds[0], 0, 0, 0, 0, 0, "0. priv on priv"}, 91{ &creds[0], &creds[1], 0, 0, 0, 0, 0, "1. priv on priv"}, 92{ &creds[1], &creds[0], 0, 0, 0, 0, 0, "2. priv on priv"}, 93{ &creds[1], &creds[1], 0, 0, 0, 0, 0, "3. priv on priv"}, | 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"}, |
94/* privileged on unprivileged */ | 97/* privileged on unprivileged */ |
95{ &creds[0], &creds[2], 0, 0, 0, 0, 0, "4. priv on unpriv1"}, 96{ &creds[0], &creds[3], 0, 0, 0, 0, 0, "5. priv on unpriv1"}, 97{ &creds[1], &creds[2], 0, 0, 0, 0, 0, "6. priv on unpriv1"}, 98{ &creds[1], &creds[3], 0, 0, 0, 0, 0, "7. priv on unpriv1"}, | 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"}, |
99/* unprivileged on privileged */ | 102/* unprivileged on privileged */ |
100{ &creds[2], &creds[0], EPERM, EPERM, EPERM, 0, EPERM, "8. unpriv1 on priv"}, 101{ &creds[2], &creds[1], EPERM, EPERM, EPERM, 0, EPERM, "9. unpriv1 on priv"}, 102{ &creds[3], &creds[0], EPERM, EPERM, EPERM, 0, EPERM, "10. unpriv1 on priv"}, 103{ &creds[3], &creds[1], EPERM, EPERM, EPERM, 0, EPERM, "11. unpriv1 on priv"}, | 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"}, |
104/* unprivileged on same unprivileged */ | 107/* unprivileged on same unprivileged */ |
105{ &creds[2], &creds[2], 0, 0, 0, 0, 0, "12. unpriv1 on unpriv1"}, 106{ &creds[2], &creds[3], EPERM, 0, EPERM, 0, 0, "13. unpriv1 on unpriv1"}, 107{ &creds[3], &creds[2], 0, 0, 0, 0, 0, "14. unpriv1 on unpriv1"}, 108{ &creds[3], &creds[3], EPERM, 0, EPERM, 0, 0, "15. unpriv1 on unpriv1"}, | 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"}, |
109/* unprivileged on different unprivileged */ | 112/* unprivileged on different unprivileged */ |
110{ &creds[2], &creds[4], EPERM, EPERM, EPERM, 0, EPERM, "16. unpriv1 on unpriv2"}, 111{ &creds[2], &creds[5], EPERM, EPERM, EPERM, 0, EPERM, "17. unpriv1 on unpriv2"}, 112{ &creds[3], &creds[4], EPERM, EPERM, EPERM, 0, EPERM, "18. unpriv1 on unpriv2"}, 113{ &creds[3], &creds[5], EPERM, EPERM, EPERM, 0, EPERM, "19. unpriv1 on unpriv2"}, | 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"}, |
114/* unprivileged on daemon, same */ | 117/* unprivileged on daemon, same */ |
115{ &creds[2], &creds[6], EPERM, EPERM, EPERM, 0, EPERM, "20. unpriv1 on daemon1"}, 116{ &creds[2], &creds[7], EPERM, EPERM, EPERM, 0, EPERM, "21. unpriv1 on daemon1"}, 117{ &creds[3], &creds[6], EPERM, EPERM, EPERM, 0, EPERM, "22. unpriv1 on daemon1"}, 118{ &creds[3], &creds[7], EPERM, EPERM, EPERM, 0, EPERM, "23. unpriv1 on daemon1"}, | 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"}, |
119/* unprivileged on daemon, different */ | 122/* unprivileged on daemon, different */ |
120{ &creds[2], &creds[8], EPERM, EPERM, EPERM, 0, EPERM, "24. unpriv1 on daemon2"}, 121{ &creds[2], &creds[9], EPERM, EPERM, EPERM, 0, EPERM, "25. unpriv1 on daemon2"}, 122{ &creds[3], &creds[8], EPERM, EPERM, EPERM, 0, EPERM, "26. unpriv1 on daemon2"}, 123{ &creds[3], &creds[9], EPERM, EPERM, EPERM, 0, EPERM, "27. unpriv1 on daemon2"}, | 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"}, |
124/* unprivileged on setuid, same */ | 127/* unprivileged on setuid, same */ |
125{ &creds[2], &creds[10], EPERM, 0, 0, 0, 0, "28. unpriv1 on setuid1"}, 126{ &creds[2], &creds[11], EPERM, 0, EPERM, 0, 0, "29. unpriv1 on setuid1"}, 127{ &creds[3], &creds[10], EPERM, 0, 0, 0, 0, "30. unpriv1 on setuid1"}, 128{ &creds[3], &creds[11], EPERM, 0, EPERM, 0, 0, "31. unpriv1 on setuid1"}, | 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"}, |
129/* unprivileged on setuid, different */ | 132/* unprivileged on setuid, different */ |
130{ &creds[2], &creds[12], EPERM, EPERM, EPERM, 0, EPERM, "32. unpriv1 on setuid2"}, 131{ &creds[2], &creds[13], EPERM, EPERM, EPERM, 0, EPERM, "33. unpriv1 on setuid2"}, 132{ &creds[3], &creds[12], EPERM, EPERM, EPERM, 0, EPERM, "34. unpriv1 on setuid2"}, 133{ &creds[3], &creds[13], EPERM, EPERM, EPERM, 0, EPERM, "35. unpriv1 on setuid2"}, | 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"}, |
134}; 135int scenarios_count = sizeof(scenarios) / sizeof(struct scenario); 136 137/* 138 * Convert an error number to a compact string representation. For now, 139 * implement only the error numbers we are likely to see. 140 */ 141static char * --- 11 unchanged lines hidden (view full) --- 153 return ("ENOSYS"); 154 case ESRCH: 155 return ("ESRCH"); 156 case EOPNOTSUPP: 157 return ("EOPNOTSUPP"); 158 case 0: 159 return ("0"); 160 default: | 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); |
|
161 return ("unknown"); 162 } 163} 164 165/* 166 * Return a process credential describing the current process. 167 */ 168static int --- 72 unchanged lines hidden (view full) --- 241cred_print(FILE *output, struct cred *cred) 242{ 243 244 fprintf(output, "(e:%d r:%d s:%d P_SUGID:%d)", cred->cr_euid, 245 cred->cr_ruid, cred->cr_svuid, cred->cr_issetugid); 246} 247 248#define LOOP_PTRACE 0 | 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 |
249#define LOOP_SIGHUP 1 250#define LOOP_SIGSEGV 2 251#define LOOP_SEE 3 252#define LOOP_SCHED 4 | 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 |
253#define LOOP_MAX LOOP_SCHED 254 255/* 256 * Enact a scenario by looping through the four test cases for the scenario, 257 * spawning off pairs of processes with the desired credentials, and 258 * reporting results to stdout. 259 */ 260static int 261enact_scenario(int scenario) 262{ 263 pid_t pid1, pid2; | 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; |
264 char *name; | 269 char *name, *tracefile; |
265 int error, desirederror, loop; 266 267 for (loop = 0; loop < LOOP_MAX+1; loop++) { 268 /* 269 * Spawn the first child, target of the operation. 270 */ 271 pid1 = fork(); 272 switch (pid1) { --- 53 unchanged lines hidden (view full) --- 326 switch (loop) { 327 case LOOP_PTRACE: 328 error = ptrace(PT_ATTACH, pid1, NULL, 0); 329 error = errno; 330 name = "ptrace"; 331 desirederror = 332 scenarios[scenario].sc_canptrace_errno; 333 break; | 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; |
|
334 case LOOP_SIGHUP: 335 error = kill(pid1, SIGHUP); 336 error = errno; 337 name = "sighup"; 338 desirederror = 339 scenarios[scenario].sc_cansighup_errno; 340 break; 341 case LOOP_SIGSEGV: --- 69 unchanged lines hidden --- | 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 --- |