Exemple #1
0
/* Trap attempts to rename files/directories outside the sandbox.
 */
int rename(const char* from, const char* to) {
#define __rename(x,y) syscall(SYS_rename, (x), (y))
	int result = 0;
	int isInSandbox = __darwintrace_is_in_sandbox(from, 0);
	if (isInSandbox == 1) {
		debug_printf("darwintrace: rename was allowed at %s\n", from);
	} else if (isInSandbox == 0) {
		/* outside sandbox, but sandbox is defined: forbid */
		debug_printf("darwintrace: renaming from %s was forbidden\n", from);
		errno = EACCES;
		result = -1;
	}

	if (result == 0) {
		isInSandbox = __darwintrace_is_in_sandbox(to, 0);
		if (isInSandbox == 1) {
			debug_printf("darwintrace: rename was allowed at %s\n", to);
		} else if (isInSandbox == 0) {
			/* outside sandbox, but sandbox is defined: forbid */
			debug_printf("darwintrace: renaming to %s was forbidden\n", to);
			errno = EACCES;
			result = -1;
		}
	}
	
	if (result == 0) {
		result = __rename(from, to);
	}
	
	return result;
}
Exemple #2
0
/* Trap attempts to create directories outside the sandbox.
 */
int mkdir(const char* path, mode_t mode) {
#define __mkdir(x,y) syscall(SYS_mkdir, (x), (y))
	int result = 0;
	int isInSandbox = __darwintrace_is_in_sandbox(path, 0);
	if (isInSandbox == 1) {
		debug_printf("darwintrace: mkdir was allowed at %s\n", path);
	} else if (isInSandbox == 0) {
		/* outside sandbox, but sandbox is defined: forbid */
		/* only consider directories that do not exist. */
		struct stat theInfo;
		int err;
		err = lstat(path, &theInfo);
		if ((err == -1) && (errno == ENOENT))
		{
			debug_printf("darwintrace: mkdir was forbidden at %s\n", path);
			errno = EACCES;
			result = -1;
		} /* otherwise, mkdir will do nothing (directory exists) or fail
		     (another error) */
	}
	
	if (result == 0) {
		result = __mkdir(path, mode);
	}
	
	return result;
}
Exemple #3
0
int open(const char* path, int flags, ...) {
#define open(x,y,z) syscall(SYS_open, (x), (y), (z))
	mode_t mode;
	int result;
	va_list args;
	struct stat sb;
	char newpath[MAXPATHLEN];
	int isInSandbox;	

	/* Why mode here ? */
	va_start(args, flags);
	mode = va_arg(args, int);
	va_end(args);
	
	result = 0;
	
	if((stat(path, &sb)!=-1 && !(sb.st_mode&S_IFDIR)) || flags & O_CREAT )
	{
		*newpath=0;
		__darwintrace_setup();
		isInSandbox = __darwintrace_is_in_sandbox(path, newpath);
		if (isInSandbox == 0) {
			debug_printf("darwintrace: creation/writing was forbidden at %s\n", path);
			errno = EACCES;
			result = -1;
		}
		if(*newpath)
			path=newpath;
	}
	if (result == 0) {
		result = open(path, flags, mode);
	}
	return result;
#undef open
}
Exemple #4
0
/**
 * Wrapper around \c rmdir(2) to deny deleting directories outside of the
 * sandbox.
 */
static int _dt_rmdir(const char *path) {
#define rmdir(x) syscall(SYS_rmdir, (x))
	__darwintrace_setup();

	int result = 0;

	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_FOLLOWSYMS)) {
		errno = ENOENT;
		result = -1;
	} else {
		result = rmdir(path);
	}

	debug_printf("rmdir(%s) = %d\n", path, result);

	return result;
#undef rmdir
}
Exemple #5
0
static int _dt_access(const char *path, int amode) {
#define access(x, y) syscall(SYS_access, (x), (y))
	__darwintrace_setup();

	int result = 0;

	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
		errno = ENOENT;
		result = -1;
	} else {
		result = access(path, amode);
	}

	debug_printf("access(%s) = %d\n", path, result);

	return result;
#undef access
}
Exemple #6
0
/* Trap attempts to remove directories outside the sandbox.
 */
int rmdir(const char* path) {
#define __rmdir(x) syscall(SYS_rmdir, (x))
	int result = 0;
	int isInSandbox = __darwintrace_is_in_sandbox(path, 0);
	if (isInSandbox == 1) {
		debug_printf("darwintrace: rmdir was allowed at %s\n", path);
	} else if (isInSandbox == 0) {
		/* outside sandbox, but sandbox is defined: forbid */
		debug_printf("darwintrace: removing directory %s was forbidden\n", path);
		errno = EACCES;
		result = -1;
	}
	
	if (result == 0) {
		result = __rmdir(path);
	}
	
	return result;
}
Exemple #7
0
/* Trap attempts to unlink a file outside the sandbox.
 */
int unlink(const char* path) {
#define __unlink(x) syscall(SYS_unlink, (x))
	int result = 0;
	int isInSandbox = __darwintrace_is_in_sandbox(path, 0);
	if (isInSandbox == 1) {
		debug_printf("darwintrace: unlink was allowed at %s\n", path);
	} else if (isInSandbox == 0) {
		/* outside sandbox, but sandbox is defined: forbid */
		debug_printf("darwintrace: unlink was forbidden at %s\n", path);
		errno = EACCES;
		result = -1;
	}
	
	if (result == 0) {
		result = __unlink(path);
	}
	
	return result;
}
Exemple #8
0
int  readlink(const char * path, char * buf, int bufsiz) {
#else
ssize_t  readlink(const char * path, char * buf, size_t bufsiz) {
#endif
#define readlink(x,y,z) syscall(SYS_readlink, (x), (y), (z))
	ssize_t result;
	int isInSandbox;

	result = readlink(path, buf, bufsiz);
	if (result >= 0) {
		__darwintrace_setup();
		isInSandbox = __darwintrace_is_in_sandbox(path, 0);
		if (!isInSandbox)
		{
			errno=EACCES;
			result=-1;
		}
	}
	return result;
#undef readlink
}
Exemple #9
0
int lstat64(const char * path, struct stat64 * sb)
{
#define lstat64(path, sb) syscall(SYS_lstat64, path, sb)
	int result=0;
	char newpath[260];
	
	*newpath=0;
	if(!is_directory(path)&&__darwintrace_is_in_sandbox(path, newpath)==0)
	{
		errno=ENOENT;
		result=-1;
	}else
	{
		if(*newpath)
			path=newpath;
			
		result=lstat64(path, sb);
	}
	
	return result;
#undef lstat64
}
Exemple #10
0
static int _dt_readlink(const char *path, char *buf, int bufsiz) {
#else
static ssize_t _dt_readlink(const char *path, char *buf, size_t bufsiz) {
#endif
#define readlink(x,y,z) syscall(SYS_readlink, (x), (y), (z))
	__darwintrace_setup();

	int result = 0;

	// don't follow symlinks here; whether access to the link target is allowed
	// or not does not matter for reading the symlink
	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
		errno = ENOENT;
		result = -1;
	} else {
		result = readlink(path, buf, bufsiz);
	}

	debug_printf("readlink(%s) = %d\n", path, result);

	return result;
#undef readlink
}
Exemple #11
0
int execve(const char* path, char* const argv[], char* const envp[]) {
#define __execve(x,y,z) syscall(SYS_execve, (x), (y), (z))
#define open(x,y,z) syscall(SYS_open, (x), (y), (z))
#define close(x) syscall(SYS_close, (x))
#define lstat(x, y) syscall(SYS_lstat, (x), (y))
	int result;
	__darwintrace_setup();
	if (__darwintrace_fd >= 0) {
	  struct stat sb;
	  /* for symlinks, we want to capture
	   * both the original path and the modified one,
	   * since for /usr/bin/gcc -> gcc-4.0,
	   * both "gcc_select" and "gcc" are contributors
	   */
	  if (lstat(path, &sb) == 0) {
	  	int fd;

	    if(S_ISLNK(sb.st_mode)) {
	      /* for symlinks, print both */
		  __darwintrace_log_op("execve", path, 0);
	    }
		
		fd = open(path, O_RDONLY, 0);
		if (fd > 0) {
		  char buffer[MAXPATHLEN+1], newpath[MAXPATHLEN+1];
		  ssize_t bytes_read;
		
		  *newpath=0;
		  if(__darwintrace_is_in_sandbox(path, newpath)==0)
		  {
			close(fd);
			errno=ENOENT;
		    return -1;
		  }
		  if(*newpath)
		    path=newpath;
	
		  /* once we have an open fd, if a full path was requested, do it */
		  __darwintrace_log_op("execve", path, fd);

		  /* read the file for the interpreter */
		  bytes_read = read(fd, buffer, MAXPATHLEN);
		  buffer[bytes_read] = 0;
		  if (bytes_read > 2 &&
			buffer[0] == '#' && buffer[1] == '!') {
			const char* interp = &buffer[2];
			int i;
			/* skip past leading whitespace */
			for (i = 2; i < bytes_read; ++i) {
			  if (buffer[i] != ' ' && buffer[i] != '\t') {
				interp = &buffer[i];
				break;
			  }
			}
			/* found interpreter (or ran out of data)
			   skip until next whitespace, then terminate the string */
			for (; i < bytes_read; ++i) {
			  if (buffer[i] == ' ' || buffer[i] == '\t' || buffer[i] == '\n') {
				buffer[i] = 0;
				break;
			  }
			}
			/* we have liftoff */
			if (interp && interp[0] != '\0') {
			  __darwintrace_log_op("execve", interp, 0);
			}
		  }
		  close(fd);
		}
	  }
	close(__darwintrace_fd);
	__darwintrace_fd=-1;
	}
	
	/* call the original execve function, but fix the environment if required. */
	result = __execve(path, argv, __darwintrace_restore_env(envp));
	return result;
#undef lstat
#undef close
#undef open
#undef execve
}