Changeset 19004


Ignore:
Timestamp:
Aug 4, 2006, 6:40:42 AM (11 years ago)
Author:
pguyot
Message:

Changes to strengthen the trace mode:

  • the values of the global variables are noted when the library is loaded and not when the first trapped function is called.
  • when a process calls exec[ve], the environment variables are restored.

Both changes aim at preventing processes to (inadvertantly) bypass of trace
mode.

Several holes remain (syscall, setuid binaries owned by a different user, kernel
modules), but this should prevent all inadvertant methods to bypass the trace
mode.

Location:
trunk/base
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/base/src/darwintracelib1.0/darwintrace.c

    r18988 r19004  
    44 * All rights reserved.
    55 *
    6  * $Id: darwintrace.c,v 1.20 2006/08/02 00:48:28 pguyot Exp $
     6 * $Id: darwintrace.c,v 1.21 2006/08/04 06:40:41 pguyot Exp $
    77 *
    88 * @APPLE_BSD_LICENSE_HEADER_START@
     
    121121inline int __darwintrace_strbeginswith(const char* str, const char* prefix);
    122122inline void __darwintrace_log_op(const char* op, const char* procname, const char* path, int fd);
     123void __darwintrace_copy_env() __attribute__((constructor));
     124inline char* __darwintrace_alloc_env(const char* varName, const char* varValue);
     125inline char* const* __darwintrace_restore_env(char* const envp[]);
    123126inline void __darwintrace_setup();
    124127inline void __darwintrace_cleanup_path(char *path);
     
    133136#if DARWINTRACE_SANDBOX
    134137static char** __darwintrace_sandbox_bounds = NULL;
     138#endif
     139
     140/* copy of the global variables */
     141static char* __env_dyld_insert_libraries;
     142static char* __env_dyld_force_flat_namespace;
     143static char* __env_darwintrace_log;
     144#if DARWINTRACE_SANDBOX
     145static char* __env_darwintrace_sandbox_bounds;
    135146#endif
    136147
     
    162173}
    163174
     175/*
     176 * Copy the environment variables, if they're defined.
     177 */
     178void __darwintrace_copy_env() {
     179        char* theValue;
     180        theValue = getenv("DYLD_INSERT_LIBRARIES");
     181        if (theValue != NULL) {
     182                __env_dyld_insert_libraries = strdup(theValue);
     183        } else {
     184                __env_dyld_insert_libraries = NULL;
     185        }
     186        theValue = getenv("DYLD_FORCE_FLAT_NAMESPACE");
     187        if (theValue != NULL) {
     188                __env_dyld_force_flat_namespace = strdup(theValue);
     189        } else {
     190                __env_dyld_force_flat_namespace = NULL;
     191        }
     192        theValue = getenv("DARWINTRACE_LOG");
     193        if (theValue != NULL) {
     194                __env_darwintrace_log = strdup(theValue);
     195        } else {
     196                __env_darwintrace_log = NULL;
     197        }
     198#if DARWINTRACE_SANDBOX
     199        theValue = getenv("DARWINTRACE_SANDBOX_BOUNDS");
     200        if (theValue != NULL) {
     201                __env_darwintrace_sandbox_bounds = strdup(theValue);
     202        } else {
     203                __env_darwintrace_sandbox_bounds = NULL;
     204        }
     205#endif
     206}
     207
     208/*
     209 * Allocate a X=Y string where X is the variable name and Y its value.
     210 * Return the new string.
     211 *
     212 * If the value is NULL, return NULL.
     213 */
     214inline char* __darwintrace_alloc_env(const char* varName, const char* varValue) {
     215        char* theResult = NULL;
     216        if (varValue) {
     217                int theSize = strlen(varName) + strlen(varValue) + 2;
     218                theResult = (char*) malloc(theSize);
     219                sprintf(theResult, "%s=%s", varName, varValue);
     220                theResult[theSize - 1] = 0;
     221        }
     222       
     223        return theResult;
     224}
     225
     226/*
     227 * This function checks that envp contains the global variables we had when the
     228 * library was loaded and modifies it if it doesn't.
     229 */
     230inline char* const* __darwintrace_restore_env(char* const envp[]) {
     231        /* allocate the strings. */
     232        /* we don't care about the leak here because we're going to call execve,
     233     * which, if it succeeds, will get rid of our heap */
     234        char* dyld_insert_libraries_ptr =       
     235                __darwintrace_alloc_env(
     236                        "DYLD_INSERT_LIBRARIES",
     237                        __env_dyld_insert_libraries);
     238        char* dyld_force_flat_namespace_ptr =   
     239                __darwintrace_alloc_env(
     240                        "DYLD_FORCE_FLAT_NAMESPACE",
     241                        __env_dyld_force_flat_namespace);
     242        char* darwintrace_log_ptr =     
     243                __darwintrace_alloc_env(
     244                        "DARWINTRACE_LOG",
     245                        __env_darwintrace_log);
     246#if DARWINTRACE_SANDBOX
     247        char* darwintrace_sandbox_bounds_ptr = 
     248                __darwintrace_alloc_env(
     249                        "DARWINTRACE_SANDBOX_BOUNDS",
     250                        __env_darwintrace_sandbox_bounds);
     251#endif
     252
     253        char* const * theEnvIter = envp;
     254        int theEnvLength = 0;
     255        char** theCopy;
     256        char** theCopyIter;
     257
     258        while (*theEnvIter != NULL) {
     259                theEnvLength++;
     260                theEnvIter++;
     261        }
     262
     263        /* 5 is sufficient for the four variables we copy and the terminator */
     264        theCopy = (char**) malloc(sizeof(char*) * (theEnvLength + 5));
     265        theEnvIter = envp;
     266        theCopyIter = theCopy;
     267
     268        while (*theEnvIter != NULL) {
     269                char* theValue = *theEnvIter;
     270                if (__darwintrace_strbeginswith(theValue, "DYLD_INSERT_LIBRARIES=")) {
     271                        theValue = dyld_insert_libraries_ptr;
     272                        dyld_insert_libraries_ptr = NULL;
     273                } else if (__darwintrace_strbeginswith(theValue, "DYLD_FORCE_FLAT_NAMESPACE=")) {
     274                        theValue = dyld_force_flat_namespace_ptr;
     275                        dyld_force_flat_namespace_ptr = NULL;
     276                } else if (__darwintrace_strbeginswith(theValue, "DARWINTRACE_LOG=")) {
     277                        theValue = darwintrace_log_ptr;
     278                        darwintrace_log_ptr = NULL;
     279#if DARWINTRACE_SANDBOX
     280                } else if (__darwintrace_strbeginswith(theValue, "DARWINTRACE_SANDBOX_BOUNDS=")) {
     281                        theValue = darwintrace_sandbox_bounds_ptr;
     282                        darwintrace_sandbox_bounds_ptr = NULL;
     283#endif
     284                }
     285               
     286                if (theValue) {
     287                        *theCopyIter++ = theValue;
     288                }
     289
     290                theEnvIter++;
     291        }
     292       
     293        if (dyld_insert_libraries_ptr) {
     294                *theCopyIter++ = dyld_insert_libraries_ptr;
     295        }
     296        if (dyld_force_flat_namespace_ptr) {
     297                *theCopyIter++ = dyld_force_flat_namespace_ptr;
     298        }
     299        if (darwintrace_log_ptr) {
     300                *theCopyIter++ = darwintrace_log_ptr;
     301        }
     302#if DARWINTRACE_SANDBOX
     303        if (darwintrace_sandbox_bounds_ptr) {
     304                *theCopyIter++ = darwintrace_sandbox_bounds_ptr;
     305        }
     306#endif
     307
     308        *theCopyIter = 0;
     309       
     310        return theCopy;
     311}
     312
    164313inline void __darwintrace_setup() {
    165314#define open(x,y,z) syscall(SYS_open, (x), (y), (z))
    166315#define close(x) syscall(SYS_close, (x))
    167316        if (__darwintrace_fd == -2) {
    168                 char* path = getenv("DARWINTRACE_LOG");
    169                 if (path != NULL) {
     317                if (__env_darwintrace_log != NULL) {
    170318                        int olderrno = errno;
    171                         int fd = open(path, O_CREAT | O_WRONLY | O_APPEND, DEFFILEMODE);
     319                        int fd = open(__env_darwintrace_log, O_CREAT | O_WRONLY | O_APPEND, DEFFILEMODE);
    172320                        int newfd;
    173321                        for(newfd = START_FD; newfd < START_FD + 21; newfd++) {
     
    195343#if DARWINTRACE_SANDBOX
    196344        if (__darwintrace_sandbox_bounds == NULL) {
    197                 char* paths = getenv("DARWINTRACE_SANDBOX_BOUNDS");
    198                 if (paths != NULL) {
     345                if (__env_darwintrace_sandbox_bounds != NULL) {
    199346                        /* copy the string */
    200                         char* copy = strdup(paths);
     347                        char* copy = strdup(__env_darwintrace_sandbox_bounds);
    201348                        if (copy != NULL) {
    202349                                int nbPaths = 1;
     
    483630
    484631int execve(const char* path, char* const argv[], char* const envp[]) {
    485 #define execve(x,y,z) syscall(SYS_execve, (x), (y), (z))
     632#define __execve(x,y,z) syscall(SYS_execve, (x), (y), (z))
    486633#define open(x,y,z) syscall(SYS_open, (x), (y), (z))
    487634#define close(x) syscall(SYS_close, (x))
     
    553700        }
    554701       
    555         result = execve(path, argv, envp);
     702        /* call the original execve function, but fix the environment if required. */
     703        result = __execve(path, argv, __darwintrace_restore_env(envp));
    556704        return result;
    557705#undef close
  • trunk/base/tests/trace/Makefile

    r18988 r19004  
    1111        @touch delete-trace
    1212        @touch rename-trace
    13         @mkdir rmdir-trace
     13        @mkdir -p rmdir-trace
    1414        @rm -f create-trace
     15        @rm -f create-trace-modenv
    1516        @rm -rf mkdir-trace
    1617        @rm -f /tmp/hello-trace
     
    2021        @rm -f rename-new-trace
    2122        @rm -f create-trace
     23        @rm -f create-trace-modenv
    2224        @rm -rf mkdir-trace
    2325        @rm -rf rmdir-trace
  • trunk/base/tests/trace/Portfile

    r18988 r19004  
    1 # $Id: Portfile,v 1.6 2006/08/02 00:48:29 pguyot Exp $
     1# $Id: Portfile,v 1.7 2006/08/04 06:40:42 pguyot Exp $
    22
    33PortSystem 1.0
     
    1919destroot        {}
    2020
    21 test { 
     21test {
    2222        catch {system "touch create-trace"}
    2323        catch {system "rm delete-trace"}
     
    2727        catch {system "rmdir rmdir-trace"}
    2828        catch {system "mv rename-trace rename-new-trace"}
     29        catch {system "DYLD_INSERT_LIBRARIES= touch create-trace-modenv"}
    2930        system "mkdir -p /usr/bin"
    3031}
  • trunk/base/tests/trace/master

    r18988 r19004  
    66--->  Testing trace
    77Warning: A creation/deletion/modification was attempted outside sandbox: PWD/create-trace
     8Warning: A creation/deletion/modification was attempted outside sandbox: PWD/create-trace-modenv
    89Warning: A creation/deletion/modification was attempted outside sandbox: PWD/delete-trace
    910Warning: A creation/deletion/modification was attempted outside sandbox: PWD/mkdir-trace
Note: See TracChangeset for help on using the changeset viewer.