Changeset 18709 for trunk/base
- Timestamp:
- Jul 24, 2006, 5:55:44 AM (18 years ago)
- Location:
- trunk/base
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/base/src/darwintracelib1.0/darwintrace.c
r18692 r18709 1 1 /* 2 2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. 3 * $Id: darwintrace.c,v 1.14 2006/07/23 00:36:42 pguyot Exp $ 3 * Copyright (c) 2005-2006 Paul Guyot <pguyot@kallisys.net>, 4 * All rights reserved. 5 * 6 * $Id: darwintrace.c,v 1.15 2006/07/24 05:55:43 pguyot Exp $ 4 7 * 5 8 * @APPLE_BSD_LICENSE_HEADER_START@ … … 56 59 * DARWINTRACE_SHOW_PROCESS: show the process id of every access 57 60 * DARWINTRACE_LOG_CREATE: log creation of files as well. 61 * DARWINTRACE_SANDBOX: control creation and writing to files. 58 62 * DARWINTRACE_LOG_FULL_PATH: use F_GETPATH to log the full path. 59 63 * DARWINTRACE_DEBUG_OUTPUT: verbose output of stuff to debug darwintrace. 64 * 65 * global variables (only checked when setup is first called) 66 * DARWINTRACE_LOG 67 * path to the log file (no logging happens if it's unset). 68 * DARWINTRACE_SANDBOX_BOUNDS 69 * : separated allowed paths for the creation of files. 70 * \: -> : 71 * \\ -> \ 60 72 */ 61 73 … … 64 76 #endif 65 77 #ifndef DARWINTRACE_LOG_CREATE 66 #define DARWINTRACE_LOG_CREATE 1 78 #define DARWINTRACE_LOG_CREATE 0 79 #endif 80 #ifndef DARWINTRACE_SANDBOX 81 #define DARWINTRACE_SANDBOX 1 67 82 #endif 68 83 #ifndef DARWINTRACE_DEBUG_OUTPUT … … 80 95 * Prototypes. 81 96 */ 97 inline int __darwintrace_strbeginswith(const char* str, const char* prefix); 82 98 inline void __darwintrace_log_op(const char* op, const char* procname, const char* path, int fd); 83 99 inline void __darwintrace_setup(); … … 91 107 static pid_t __darwintrace_pid = -1; 92 108 #endif 109 #if DARWINTRACE_SANDBOX 110 static char** __darwintrace_sandbox_bounds = NULL; 111 #endif 93 112 94 113 #if __STDC_VERSION__==199901L … … 105 124 #endif 106 125 #endif 126 127 /* 128 * return 0 if str doesn't begin with prefix, 1 otherwise. 129 */ 130 inline int __darwintrace_strbeginswith(const char* str, const char* prefix) { 131 char theCharS; 132 char theCharP; 133 do { 134 theCharS = *str++; 135 theCharP = *prefix++; 136 } while(theCharP && (theCharP == theCharS)); 137 return (theCharP == 0); 138 } 107 139 108 140 inline void __darwintrace_setup() { … … 134 166 if (progname && *progname) { 135 167 strcpy(__darwintrace_progname, *progname); 168 } 169 } 170 #endif 171 #if DARWINTRACE_SANDBOX 172 if (__darwintrace_sandbox_bounds == NULL) { 173 char* paths = getenv("DARWINTRACE_SANDBOX_BOUNDS"); 174 if (paths != NULL) { 175 /* copy the string */ 176 char* copy = strdup(paths); 177 if (copy != NULL) { 178 int nbPaths = 1; 179 int nbAllocatedPaths = 5; 180 char** paths = (char**) malloc(sizeof(char*) * nbAllocatedPaths); 181 char* crsr = copy; 182 char** pathsCrsr = paths; 183 /* first path */ 184 *pathsCrsr++ = crsr; 185 /* parse the paths (modify the copy) */ 186 do { 187 char theChar = *crsr; 188 if (theChar == '\0') { 189 /* the end of the paths */ 190 break; 191 } 192 if (theChar == ':') { 193 /* the end of this path */ 194 *crsr = 0; 195 nbPaths++; 196 if (nbPaths == nbAllocatedPaths) { 197 nbAllocatedPaths += 5; 198 paths = (char**) realloc(paths, sizeof(char*) * nbAllocatedPaths); 199 /* reset the cursor in case paths pointer was moved */ 200 pathsCrsr = paths + (nbPaths - 1); 201 } 202 *pathsCrsr++ = crsr + 1; 203 } 204 if (theChar == '\\') { 205 /* escape character. test next char */ 206 char nextChar = crsr[1]; 207 if (nextChar == '\\') { 208 /* rewrite the string */ 209 char* rewriteCrsr = crsr + 1; 210 do { 211 char theChar = *rewriteCrsr; 212 rewriteCrsr[-1] = theChar; 213 rewriteCrsr++; 214 } while (theChar != 0); 215 } else if (nextChar == ':') { 216 crsr++; 217 } 218 /* otherwise, ignore (keep the backslash) */ 219 } 220 221 /* next char */ 222 crsr++; 223 } while (1); 224 /* null terminate the array */ 225 *pathsCrsr = 0; 226 /* resize and save it */ 227 __darwintrace_sandbox_bounds = (char**) realloc(paths, sizeof(char*) * (nbPaths + 1)); 228 } 136 229 } 137 230 } … … 258 351 mode = va_arg(args, int); 259 352 va_end(args); 353 #if DARWINTRACE_SANDBOX 354 result = 0; 355 if (flags & (O_CREAT | O_APPEND | O_RDWR | O_WRONLY | O_TRUNC)) { 356 __darwintrace_setup(); 357 if (__darwintrace_sandbox_bounds != NULL) { 358 /* check the path */ 359 char** basePathsCrsr = __darwintrace_sandbox_bounds; 360 char* basepath = *basePathsCrsr++; 361 /* normalize the path */ 362 char createpath[MAXPATHLEN]; 363 if (realpath(path, createpath) != NULL) { 364 __darwintrace_cleanup_path(createpath); 365 /* forbid unless allowed */ 366 result = -1; 367 while (basepath != NULL) { 368 if (__darwintrace_strbeginswith(createpath, basepath)) { 369 result = 0; 370 break; 371 } 372 basepath = *basePathsCrsr++;; 373 } 374 } /* otherwise, open will fail anyway */ 375 } 376 if (result == 0) { 377 dprintf("darwintrace: creation/writing was allowed at %s\n", path); 378 } 379 } 380 if (result == 0) { 381 result = open(path, flags, mode); 382 } else { 383 dprintf("darwintrace: creation/writing was forbidden at %s\n", path); 384 __darwintrace_log_op("sandbox_violation", NULL, path, result); 385 errno = EACCES; 386 } 387 #else 260 388 result = open(path, flags, mode); 389 #endif 261 390 if (result >= 0) { 262 391 /* check that it's a file */ -
trunk/base/src/port1.0/porttrace.tcl
r18687 r18709 2 2 # porttrace.tcl 3 3 # 4 # $Id: porttrace.tcl,v 1.1 6 2006/07/22 09:16:10pguyot Exp $5 # 6 # Copyright (c) 2005 Paul Guyot <pguyot@kallisys.net>,4 # $Id: porttrace.tcl,v 1.17 2006/07/24 05:55:44 pguyot Exp $ 5 # 6 # Copyright (c) 2005-2006 Paul Guyot <pguyot@kallisys.net>, 7 7 # All rights reserved. 8 8 # … … 42 42 ui_warn "trace requires Tcl Thread package ($error)" 43 43 } else { 44 global env trace_fifo 44 global env trace_fifo trace_sandboxbounds 45 45 # Create a fifo. 46 46 set trace_fifo "$workpath/trace_fifo" … … 57 57 set env(DYLD_FORCE_FLAT_NAMESPACE) 1 58 58 set env(DARWINTRACE_LOG) "$trace_fifo" 59 } 59 # The sandbox is limited to: 60 # workpath 61 # /tmp 62 # /var/tmp 63 # $TMPDIR 64 # /dev/null 65 # /dev/tty 66 set trace_sandboxbounds "/tmp:/var/tmp:/dev/null:/dev/tty:${workpath}" 67 if {[info exists env(TMPDIR)]} { 68 set trace_sandboxbounds "${trace_sandboxbounds}:$env(TMPDIR)" 69 } 70 } 71 } 72 } 73 74 # Enable the fence. 75 # Only done for targets that should only happen in the sandbox. 76 proc trace_enable_fence {} { 77 global env trace_sandboxbounds 78 set env(DARWINTRACE_SANDBOX_BOUNDS) $trace_sandboxbounds 79 } 80 81 # Disable the fence. 82 # Unused yet. 83 proc trace_disable_fence {} { 84 global env 85 if [info exists env(DARWINTRACE_SANDBOX_BOUNDS)] { 86 unset env(DARWINTRACE_SANDBOX_BOUNDS) 60 87 } 61 88 } … … 83 110 } 84 111 85 # Check that no file were created outside workpath.86 # Output a warning for every created filethe trace revealed.112 # Check that no violation happened. 113 # Output a warning for every sandbox violation the trace revealed. 87 114 # This method must be called after trace_start 88 proc trace_check_ create{} {89 # Get the list of created files.90 set created [slave_send slave_get_created]115 proc trace_check_violations {} { 116 # Get the list of violations. 117 set violations [slave_send slave_get_sandbox_violations] 91 118 92 # Compare with portslist 93 set created [lsort $created] 94 foreach created_file $created { 95 ui_warn "A file was created outside \${workpath}: $created_file" 119 foreach violation [lsort $violations] { 120 ui_warn "A file creation/writing was attempted outside sandbox: $violation" 96 121 } 97 122 } … … 106 131 unset env(DYLD_FORCE_FLAT_NAMESPACE) 107 132 unset env(DARWINTRACE_LOG) 133 if [info exists env(DARWINTRACE_SANDBOX_BOUNDS)] { 134 unset env(DARWINTRACE_SANDBOX_BOUNDS) 135 } 108 136 109 137 # Clean up. … … 162 190 # Slave method to read a line from the trace. 163 191 proc slave_read_line {chan} { 164 global ports_list trace_filemap created_list workpath192 global ports_list trace_filemap sandbox_violation_list workpath 165 193 global env 166 194 … … 213 241 } 214 242 } 215 } elseif {$op == "create"} { 216 # Only keep entries not under workpath, under /tmp/, under 217 # /var/tmp/, $TMPDIR and /dev/null 218 if {![string equal -length [string length "/tmp/"] "/tmp/" $path] 219 && ![string equal -length [string length "/var/tmp/"] "/var/tmp/" $path] 220 && (![info exists env(TMPDIR)] 221 || ![string equal -length [string length $env(TMPDIR)] $env(TMPDIR) $path]) 222 && ![string equal "/dev/null" $path] 223 && ![string equal -length [string length $workpath] $workpath $path]} { 224 lappend created_list $path 225 } 243 } elseif {$op == "sandbox_violation"} { 244 lappend sandbox_violation_list $path 226 245 } 227 246 } … … 232 251 # Slave init method. 233 252 proc slave_start {fifo p_workpath} { 234 global ports_list trace_filemap created_list trace_fifo_r_chan \253 global ports_list trace_filemap sandbox_violation_list trace_fifo_r_chan \ 235 254 trace_fifo_w_chan workpath 236 255 # Save the workpath. … … 239 258 filemap create trace_filemap 240 259 set ports_list {} 241 set created_list {}260 set sandbox_violation_list {} 242 261 set trace_fifo_r_chan [open $fifo {RDONLY NONBLOCK}] 243 262 # To prevent EOF when darwintrace closes the file, I also open the pipe … … 271 290 272 291 # Private. 273 # Slave createdexport method.274 proc slave_get_ created{} {275 global created_list276 return $ created_list277 } 292 # Slave sandbox violations export method. 293 proc slave_get_sandbox_violations {} { 294 global sandbox_violation_list 295 return $sandbox_violation_list 296 } -
trunk/base/src/port1.0/portutil.tcl
r18144 r18709 1 1 # et:ts=4 2 2 # portutil.tcl 3 # $Id: portutil.tcl,v 1.19 2 2006/05/29 16:57:03 mwwExp $3 # $Id: portutil.tcl,v 1.193 2006/07/24 05:55:44 pguyot Exp $ 4 4 # 5 5 # Copyright (c) 2004 Robert Shaw <rshaw@opendarwin.org> … … 636 636 && $target != "clean")} { 637 637 trace_start $workpath 638 639 # Enable the fence to prevent any creation/modification 640 # outside the sandbox. 641 if {$target != "activate" 642 && $target != "archive" 643 && $target != "fetch" 644 && $target != "install"} { 645 trace_enable_fence 646 } 638 647 } 639 648 … … 709 718 } 710 719 trace_check_deps $target $depsPorts 720 trace_check_violations 711 721 712 # Check files that were created.713 if {$target != "activate"714 && $target != "archive"715 && $target != "fetch"716 && $target != "install"} {717 trace_check_create718 }719 720 722 # End of trace. 721 723 trace_stop -
trunk/base/tests/Makefile
r18681 r18709 34 34 PORTSRC=$(PWD)/test-ports.conf $(bindir)/port test > output 2>&1 \ 35 35 || (cat output; exit 1) && \ 36 diff output master 2>&1 | tee difference && \ 36 sed -e "s|${PWD}|PWD|g" < output > output.sed && \ 37 diff output.sed master 2>&1 | tee difference && \ 37 38 if [ -s difference ]; then \ 38 39 exit 1; \ -
trunk/base/tests/trace/Makefile
r13743 r18709 10 10 @PORTSRC=$(PORTSRC) $(bindir)/port clean > /dev/null 11 11 @PORTSRC=$(PORTSRC) $(bindir)/port -t test > output 2>&1 || (cat output; exit 1) 12 @diff output master 2>&1 | tee difference 12 @sed -e "s|${PWD}|PWD|g" < output > output.sed 13 @diff output.sed master 2>&1 | tee difference 13 14 @if [ -s difference ]; then \ 14 15 exit 1; \ -
trunk/base/tests/trace/Portfile
r13743 r18709 1 # $Id: Portfile,v 1. 1 2005/08/27 07:24:35pguyot Exp $1 # $Id: Portfile,v 1.2 2006/07/24 05:55:44 pguyot Exp $ 2 2 3 3 PortSystem 1.0 … … 20 20 21 21 test { 22 system "rm -f hello-trace" 23 system "touch hello-trace" 24 system "rm hello-trace" 22 catch {system "rm -f hello-trace && touch hello-trace && rm hello-trace"} 23 catch {system "rm -f /tmp/hello-trace && /tmp/hello-trace && rm /tmp/hello-trace"} 25 24 } -
trunk/base/tests/trace/master
r13743 r18709 5 5 ---> Building trace with target all 6 6 ---> Testing trace 7 Warning: A file was created outside ${workpath}: /Junk/src/opendarwin/darwinports/base/tests/trace/hello-trace7 Warning: A file creation/writing was attempted outside sandbox: PWD/hello-trace
Note: See TracChangeset
for help on using the changeset viewer.