Skip to content
Permalink
Browse files

darwintrace: use modern interposing, avoid DYLD_FORCE_FLAT_NAMESPACE …

…that's no longer necessary with interposing, https://trac.macports.org/ticket/29228, patch by gauravb7090

git-svn-id: https://svn.macports.org/repository/macports/trunk/base@117751 d073be05-634f-4543-b044-5fe20cf6d1d6
  • Loading branch information
neverpanic committed Mar 10, 2014
1 parent 8ca8ee5 commit 7aa2869ef1ff2283b2e40eb7516e5b155f2b674f
@@ -41,7 +41,7 @@
#include <sys/syscall.h>
#include <unistd.h>

int access(const char *path, int amode) {
int _dt_access(const char *path, int amode) {
#define access(x, y) syscall(SYS_access, (x), (y))
__darwintrace_setup();

@@ -59,3 +59,5 @@ int access(const char *path, int amode) {
return result;
#undef access
}

DARWINTRACE_INTERPOSE(_dt_access, access);
@@ -50,7 +50,7 @@
* need to. This possibility is the \c __darwintrace_close_sock variable, which
* will be set to the FD to be closed when closing should be allowed.
*/
int close(int fd) {
int _dt_close(int fd) {
#define close(x) syscall(SYS_close, (x))
__darwintrace_setup();

@@ -66,3 +66,5 @@ int close(int fd) {
return close(fd);
#undef close
}

DARWINTRACE_INTERPOSE(_dt_close, close);
@@ -43,6 +43,22 @@
#include <stdbool.h>
#include <stdio.h>

/**
* DARWINTRACE_INTERPOSE: provides a way to override standard library functions
* with your own implementations.
*/
#ifndef DARWINTRACE_INTERPOSE
#define DARWINTRACE_INTERPOSE(_replacement, _replacee) \
__attribute__((used)) static struct { \
const void *replacement; \
const void *replacee; \
} _interpose_##_replacee \
__attribute__((section ("__DATA,__interpose"))) = { \
(const void *) (unsigned long) &_replacement, \
(const void *) (unsigned long) &_replacee \
}
#endif

/**
* DARWINTRACE_DEBUG: verbose output of operations to debug darwintrace
*/
@@ -48,7 +48,7 @@
* attempts to overwrite it using \c dup(2). Shells tend to do that a lot when
* FDs are numbered in ascending order.
*/
int dup2(int filedes, int filedes2) {
int _dt_dup2(int filedes, int filedes2) {
#define dup2(x, y) syscall(SYS_dup2, (x), (y))
__darwintrace_setup();

@@ -75,3 +75,5 @@ int dup2(int filedes, int filedes2) {
return dup2(filedes, filedes2);
#undef dup2
}

DARWINTRACE_INTERPOSE(_dt_dup2, dup2);
@@ -53,7 +53,7 @@
* the sandbox. Will silently do nothing and return success for directories
* outside the sandbox that already exist.
*/
int mkdir(const char *path, mode_t mode) {
int _dt_mkdir(const char *path, mode_t mode) {
#define mkdir(x,y) syscall(SYS_mkdir, (x), (y))
#define lstat(x,y) syscall(LSTATSYSNUM, (x), (y))
__darwintrace_setup();
@@ -78,3 +78,5 @@ int mkdir(const char *path, mode_t mode) {
#undef lstat
#undef mkdir
}

DARWINTRACE_INTERPOSE(_dt_mkdir, mkdir);
@@ -48,7 +48,7 @@
* Indicates the file does not exist on sandbox violation, or permission denied
* when attempting to create a file, i.e., when \c O_CREAT is set.
*/
int open(const char *path, int flags, ...) {
int _dt_open(const char *path, int flags, ...) {
#define open(x,y,z) syscall(SYS_open, (x), (y), (z))
__darwintrace_setup();
int result = 0;
@@ -70,3 +70,5 @@ int open(const char *path, int flags, ...) {
return result;
#undef open
}

DARWINTRACE_INTERPOSE(_dt_open, open);
@@ -254,7 +254,7 @@ static inline int check_interpreter(const char *restrict path) {
* exist, if it's outside the sandbox. Also checks for potential interpreters
* using \c check_interpreter.
*/
int execve(const char *path, char *const argv[], char *const envp[]) {
int _dt_execve(const char *path, char *const argv[], char *const envp[]) {
#define execve(x,y,z) syscall(SYS_execve, (x), (y), (z))
__darwintrace_setup();

@@ -289,6 +289,8 @@ int execve(const char *path, char *const argv[], char *const envp[]) {
#undef execve
}

DARWINTRACE_INTERPOSE(_dt_execve, execve);

#if defined(HAVE_SPAWN_H) && defined(HAVE_POSIX_SPAWN)
// Let's save some typing work...
typedef int (*posix_spawn_t)(
@@ -303,11 +305,10 @@ typedef int (*posix_spawn_t)(
* exist, if it's outside the sandbox. Also checks for potential interpreters
* using \c check_interpreter.
*/
int posix_spawn(pid_t *restrict pid, const char *restrict path, const posix_spawn_file_actions_t *file_actions,
int _dt_posix_spawn(pid_t *restrict pid, const char *restrict path, const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *restrict attrp, char *const argv[restrict], char *const envp[restrict]) {
__darwintrace_setup();

static posix_spawn_t prev_posix_spawn = NULL;
int result = 0;

if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
@@ -339,13 +340,9 @@ int posix_spawn(pid_t *restrict pid, const char *restrict path, const posix_spaw
* We cannot override posix_spawn and call __posix_spawn from it
* either, because that will fail with an invalid argument. Thus,
* we need to call the original posix_spawn from here. */
// retrieve the original posix_spawn function
if (prev_posix_spawn == NULL) {
prev_posix_spawn = (posix_spawn_t) dlsym(RTLD_NEXT, "posix_spawn");
}
// call the original posix_spawn function, but restore environment
char **newenv = restore_env(envp);
result = prev_posix_spawn(pid, path, file_actions, attrp, argv, newenv);
result = posix_spawn(pid, path, file_actions, attrp, argv, newenv);
free(newenv);
}
}
@@ -354,4 +351,6 @@ int posix_spawn(pid_t *restrict pid, const char *restrict path, const posix_spaw

return result;
}

DARWINTRACE_INTERPOSE(_dt_posix_spawn, posix_spawn);
#endif
@@ -66,7 +66,7 @@ struct dirent64 {
char d_name[__DARWIN_MAXPATHLEN]; /* entry name (up to MAXPATHLEN bytes) */
};

size_t __getdirentries64(int fd, void *buf, size_t bufsize, __darwin_off_t *basep) {
size_t _dt_getdirentries64(int fd, void *buf, size_t bufsize, __darwin_off_t *basep) {
#define __getdirentries64(w,x,y,z) syscall(SYS_getdirentries64, (w), (x), (y), (z))
__darwintrace_setup();

@@ -105,6 +105,10 @@ size_t __getdirentries64(int fd, void *buf, size_t bufsize, __darwin_off_t *base
#undef __getdirentries64
}

// __getdirentries64(2) is private API. There's no header for it.
size_t __getdirentries64(int fd, void *buf, size_t bufsize, __darwin_off_t *basep);
DARWINTRACE_INTERPOSE(_dt_getdirentries64, __getdirentries64);

#endif /* defined(__DARWIN_64_BIT_INO_T) */

#pragma pack(4)
@@ -117,7 +121,7 @@ struct dirent32 {
};
#pragma pack()

int getdirentries(int fd, char *buf, int nbytes, long *basep) {
int _dt_getdirentries(int fd, char *buf, int nbytes, long *basep) {
#define getdirentries(w,x,y,z) syscall(SYS_getdirentries, (w), (x), (y), (z))
__darwintrace_setup();

@@ -154,3 +158,6 @@ int getdirentries(int fd, char *buf, int nbytes, long *basep) {
return sz;
#undef getdirentries
}

int getdirentries(int fd, char *buf, int nbytes, long *basep);
DARWINTRACE_INTERPOSE(_dt_getdirentries, getdirentries);
@@ -46,9 +46,9 @@
* Deny \c readlink(2) if the file is not within the sandbox bounds.
*/
#ifdef READLINK_IS_NOT_P1003_1A
int readlink(const char *path, char *buf, int bufsiz) {
int _dt_readlink(const char *path, char *buf, int bufsiz) {
#else
ssize_t readlink(const char *path, char *buf, size_t bufsiz) {
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();
@@ -69,3 +69,5 @@ ssize_t readlink(const char *path, char *buf, size_t bufsiz) {
return result;
#undef readlink
}

DARWINTRACE_INTERPOSE(_dt_readlink, readlink);
@@ -46,7 +46,7 @@
* Wrapper around \c rename(2) to prevent moving a file outside, or out of the
* sandbox.
*/
int rename(const char *from, const char *to) {
int _dt_rename(const char *from, const char *to) {
#define rename(x,y) syscall(SYS_rename, (x), (y))
__darwintrace_setup();

@@ -67,3 +67,5 @@ int rename(const char *from, const char *to) {
return result;
#undef rename
}

DARWINTRACE_INTERPOSE(_dt_rename, rename);
@@ -46,7 +46,7 @@
* Wrapper around \c rmdir(2) to deny deleting directories outside of the
* sandbox.
*/
int rmdir(const char *path) {
int _dt_rmdir(const char *path) {
#define rmdir(x) syscall(SYS_rmdir, (x))
__darwintrace_setup();

@@ -64,3 +64,5 @@ int rmdir(const char *path) {
return result;
#undef rmdir
}

DARWINTRACE_INTERPOSE(_dt_rmdir, rmdir);
@@ -47,7 +47,7 @@
* Wrapper around \c stat(2) to hide information about files outside the
* sandbox.
*/
int stat(const char *path, void *sb) {
int _dt_stat(const char *path, void *sb) {
#define stat(path, sb) syscall(SYS_stat, path, sb)
__darwintrace_setup();

@@ -66,9 +66,14 @@ int stat(const char *path, void *sb) {
#undef stat
}

// We don't include sys/stat.h because it would rewrite all stat function
// calls, but we need the declaration of stat here.
int stat(const char *path, void *sb);
DARWINTRACE_INTERPOSE(_dt_stat, stat);

// Don't provide stat64 on systems that have no stat64 syscall
#ifdef SYS_stat64
int stat64(const char *path, void *sb) {
int _dt_stat64(const char *path, void *sb) {
#define stat64(path, sb) syscall(SYS_stat64, path, sb)
__darwintrace_setup();

@@ -86,13 +91,15 @@ int stat64(const char *path, void *sb) {
return result;
#undef stat64
}
int stat64(const char *path, void *sb);
DARWINTRACE_INTERPOSE(_dt_stat64, stat64);

int stat$INODE64(const char *path, void *sb);
DARWINTRACE_INTERPOSE(_dt_stat64, stat$INODE64);

int stat$INODE64(const char *path, void *sb) {
return stat64(path, sb);
}
#endif /* defined(SYS_stat64) */

int lstat(const char *path, void *sb) {
int _dt_lstat(const char *path, void *sb) {
#define lstat(path, sb) syscall(SYS_lstat, path, sb)
__darwintrace_setup();

@@ -112,9 +119,12 @@ int lstat(const char *path, void *sb) {
#undef lstat
}

int lstat(const char *path, void *sb);
DARWINTRACE_INTERPOSE(_dt_lstat, lstat);

// Don't provide lstat64 on systems that have no lstat64 syscall
#ifdef SYS_lstat64
int lstat64(const char *path, void *sb) {
int _dt_lstat64(const char *path, void *sb) {
#define lstat64(path, sb) syscall(SYS_lstat64, path, sb)
__darwintrace_setup();

@@ -134,7 +144,10 @@ int lstat64(const char *path, void *sb) {
#undef lstat64
}

int lstat$INODE64(const char *path, void *sb) {
return lstat64(path, sb);
}
int lstat64(const char *path, void *sb);
DARWINTRACE_INTERPOSE(_dt_lstat64, lstat64);

int lstat$INODE64(const char *path, void *sb);
DARWINTRACE_INTERPOSE(_dt_lstat64, lstat$INODE64);

#endif /* defined(SYS_lstat64) */
@@ -46,7 +46,7 @@
* Wrapper around \c unlink(2) that will deny attempts to delete files outside
* of the sandbox and simulate non-existence of the file instead.
*/
int unlink(const char *path) {
int _dt_unlink(const char *path) {
#define unlink(x) syscall(SYS_unlink, (x))
__darwintrace_setup();

@@ -64,3 +64,5 @@ int unlink(const char *path) {
return result;
#undef unlink
}

DARWINTRACE_INTERPOSE(_dt_unlink, unlink);
@@ -66,7 +66,6 @@ proc porttrace::trace_start {workpath} {
} else {
set env(DYLD_INSERT_LIBRARIES) ${tracelib_path}
}
set env(DYLD_FORCE_FLAT_NAMESPACE) 1
set env(DARWINTRACE_LOG) "$trace_fifo"
# The sandbox is limited to:
# workpath
@@ -170,7 +169,7 @@ proc porttrace::trace_stop {} {
global os.platform
if {${os.platform} == "darwin"} {
global env trace_fifo macosx_version
foreach var {DYLD_INSERT_LIBRARIES DYLD_FORCE_FLAT_NAMESPACE DARWINTRACE_LOG DARWINTRACE_SANDBOX_BOUNDS} {
foreach var {DYLD_INSERT_LIBRARIES DARWINTRACE_LOG} {
array unset env $var
if {$macosx_version eq "10.5"} {
unsetenv $var

0 comments on commit 7aa2869

Please sign in to comment.
You can’t perform that action at this time.