aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libsandbox')
-rw-r--r--libsandbox/Makefile.am2
-rwxr-xr-xlibsandbox/moo/usr/lib/libsandbox.sobin0 -> 192531 bytes
-rw-r--r--libsandbox/trace.c145
-rw-r--r--libsandbox/wrapper-funcs/__64_post.h1
-rw-r--r--libsandbox/wrapper-funcs/__64_pre.h1
-rw-r--r--libsandbox/wrapper-funcs/__openat_2.c38
-rw-r--r--libsandbox/wrapper-funcs/fopen.c28
-rw-r--r--libsandbox/wrapper-funcs/fopen64.c6
-rw-r--r--libsandbox/wrapper-funcs/fopen64_pre_check.c12
-rw-r--r--libsandbox/wrapper-funcs/fopen_pre_check.c26
-rw-r--r--libsandbox/wrapper-funcs/mkdir.c4
-rw-r--r--libsandbox/wrapper-funcs/mkdirat.c42
-rw-r--r--libsandbox/wrapper-funcs/mkdirat_pre_check.c42
-rw-r--r--libsandbox/wrapper-funcs/openat.c40
-rw-r--r--libsandbox/wrapper-funcs/openat64_pre_check.c12
-rw-r--r--libsandbox/wrapper-funcs/openat_pre_check.c28
-rw-r--r--libsandbox/wrapper-funcs/unlink.c4
-rw-r--r--libsandbox/wrapper-funcs/unlinkat.c38
-rw-r--r--libsandbox/wrapper-funcs/unlinkat_pre_check.c38
-rw-r--r--libsandbox/wrappers.h9
20 files changed, 297 insertions, 219 deletions
diff --git a/libsandbox/Makefile.am b/libsandbox/Makefile.am
index c470f2e..9e1b775 100644
--- a/libsandbox/Makefile.am
+++ b/libsandbox/Makefile.am
@@ -51,7 +51,7 @@ SYMBOLS_WRAPPERS = $(wildcard $(srcdir)/wrapper-funcs/*.[ch])
GEN_VERSION_MAP_SCRIPT = $(SCRIPT_DIR)/gen_symbol_version_map.awk
GEN_HEADER_SCRIPT = $(SCRIPT_DIR)/gen_symbol_header.awk
GEN_TRACE_SCRIPT = $(SCRIPT_DIR)/gen_trace_header.awk
-SB_AWK = LC_ALL=C $(AWK) -v SYMBOLS_LIST="$(SYMBOLS_LIST)" -f
+SB_AWK = LC_ALL=C $(AWK) -v SYMBOLS_LIST="$(SYMBOLS_LIST)" -v srcdir="$(srcdir)" -f
SB_V = $(SB_V_$(V))
SB_V_ = @echo " GEN" $@;
diff --git a/libsandbox/moo/usr/lib/libsandbox.so b/libsandbox/moo/usr/lib/libsandbox.so
new file mode 100755
index 0000000..2641d01
--- /dev/null
+++ b/libsandbox/moo/usr/lib/libsandbox.so
Binary files differ
diff --git a/libsandbox/trace.c b/libsandbox/trace.c
index 7c5ec17..acbda70 100644
--- a/libsandbox/trace.c
+++ b/libsandbox/trace.c
@@ -15,6 +15,10 @@ pid_t trace_pid;
#ifndef SB_NO_TRACE
+#ifdef HAVE_OPEN64
+# define sb_openat_pre_check sb_openat64_pre_check
+#endif
+
#ifdef DEBUG
# define SBDEBUG 1
#else
@@ -43,9 +47,10 @@ static long _do_ptrace(enum __ptrace_request request, const char *srequest, void
/* Child hasn't gotten to the next marker yet ? */
if (errno == ESRCH) {
int status;
- if (waitpid(trace_pid, &status, 0) == -1)
+ if (waitpid(trace_pid, &status, 0) == -1) {
/* nah, it's dead ... should we whine though ? */
trace_exit(0);
+ }
sched_yield();
goto try_again;
} else if (!errno)
@@ -194,49 +199,73 @@ static const struct syscall_entry *lookup_syscall(int nr)
return lookup_syscall_in_tbl(trace_check_personality(), nr);
}
-static bool _trace_check_syscall_C(void *regs, int sb_nr, const char *func, int ibase)
+struct syscall_state {
+ void *regs;
+ int nr;
+ const char *func;
+ bool (*pre_check)(const char *func, const char *pathname, int dirfd);
+};
+
+static bool _trace_check_syscall_C(struct syscall_state *state, int ibase)
{
- char *path = do_peekstr(trace_arg(regs, ibase));
+ char *path = do_peekstr(trace_arg(state->regs, ibase));
__SB_DEBUG("(\"%s\")", path);
- bool ret = _SB_SAFE(sb_nr, func, path);
+ bool pre_ret, ret;
+ if (state->pre_check)
+ pre_ret = state->pre_check(state->func, path, AT_FDCWD);
+ else
+ pre_ret = true;
+ if (pre_ret)
+ ret = _SB_SAFE(state->nr, state->func, path);
+ else
+ ret = true;
free(path);
return ret;
}
-static bool trace_check_syscall_C(void *regs, int sb_nr, const char *func)
+static bool trace_check_syscall_C(struct syscall_state *state)
{
- return _trace_check_syscall_C(regs, sb_nr, func, 1);
+ return _trace_check_syscall_C(state, 1);
}
-static bool __trace_check_syscall_DCF(void *regs, int sb_nr, const char *func, int ibase, int flags)
+static bool __trace_check_syscall_DCF(struct syscall_state *state, int ibase, int flags)
{
- int dirfd = trace_arg(regs, ibase);
- char *path = do_peekstr(trace_arg(regs, ibase + 1));
+ int dirfd = trace_arg(state->regs, ibase);
+ char *path = do_peekstr(trace_arg(state->regs, ibase + 1));
__SB_DEBUG("(%i, \"%s\", %x)", dirfd, path, flags);
- bool ret = _SB_SAFE_AT(sb_nr, func, dirfd, path, flags);
+ bool pre_ret, ret;
+ if (state->pre_check)
+ pre_ret = state->pre_check(state->func, path, dirfd);
+ else
+ pre_ret = true;
+ if (pre_ret)
+ ret = _SB_SAFE_AT(state->nr, state->func, dirfd, path, flags);
+ else
+ ret = true;
free(path);
return ret;
}
-static bool _trace_check_syscall_DCF(void *regs, int sb_nr, const char *func, int ibase)
+static bool _trace_check_syscall_DCF(struct syscall_state *state, int ibase)
{
- int flags = trace_arg(regs, ibase + 2);
- return __trace_check_syscall_DCF(regs, sb_nr, func, ibase, flags);
+ int flags = trace_arg(state->regs, ibase + 2);
+ return __trace_check_syscall_DCF(state, ibase, flags);
}
-static bool trace_check_syscall_DCF(void *regs, int sb_nr, const char *func)
+static bool trace_check_syscall_DCF(struct syscall_state *state)
{
- return _trace_check_syscall_DCF(regs, sb_nr, func, 1);
+ return _trace_check_syscall_DCF(state, 1);
}
-static bool _trace_check_syscall_DC(void *regs, int sb_nr, const char *func, int ibase)
+static bool _trace_check_syscall_DC(struct syscall_state *state, int ibase)
{
- return __trace_check_syscall_DCF(regs, sb_nr, func, ibase, 0);
+ return __trace_check_syscall_DCF(state, ibase, 0);
}
-static bool trace_check_syscall_DC(void *regs, int sb_nr, const char *func)
+static bool trace_check_syscall_DC(struct syscall_state *state)
{
- return _trace_check_syscall_DC(regs, sb_nr, func, 1);
+ return _trace_check_syscall_DC(state, 1);
}
static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
{
+ struct syscall_state state;
bool ret = true;
int nr;
const char *name;
@@ -256,37 +285,45 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
if (!se)
goto done;
- nr = se->sys;
- name = se->name;
+ state.regs = regs;
+ state.nr = nr = se->sys;
+ state.func = name = se->name;
+ if (nr == SB_NR_UNDEF) goto done;
+ else if (nr == SB_NR_MKDIR) state.pre_check = sb_mkdirat_pre_check;
+ else if (nr == SB_NR_MKDIRAT) state.pre_check = sb_mkdirat_pre_check;
+ else if (nr == SB_NR_UNLINK) state.pre_check = sb_unlinkat_pre_check;
+ else if (nr == SB_NR_UNLINKAT) state.pre_check = sb_unlinkat_pre_check;
+ else state.pre_check = NULL;
+
/* Hmm, add these functions to the syscall table and avoid this if() ? */
if (nr == SB_NR_UNDEF) goto done;
- else if (nr == SB_NR_CHMOD) return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_CHOWN) return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_CREAT) return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_FCHMODAT) return trace_check_syscall_DCF(regs, nr, name);
- else if (nr == SB_NR_FCHOWNAT) return trace_check_syscall_DCF(regs, nr, name);
- else if (nr == SB_NR_FUTIMESAT) return trace_check_syscall_DC (regs, nr, name);
- else if (nr == SB_NR_LCHOWN) return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_LINK) return _trace_check_syscall_C (regs, nr, name, 2);
- else if (nr == SB_NR_LINKAT) return _trace_check_syscall_DCF(regs, nr, name, 3);
- else if (nr == SB_NR_MKDIR) return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_MKDIRAT) return trace_check_syscall_DC (regs, nr, name);
- else if (nr == SB_NR_MKNOD) return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_MKNODAT) return trace_check_syscall_DC (regs, nr, name);
- else if (nr == SB_NR_RENAME) return trace_check_syscall_C (regs, nr, name) &&
- _trace_check_syscall_C (regs, nr, name, 2);
- else if (nr == SB_NR_RENAMEAT) return trace_check_syscall_DC (regs, nr, name) &&
- _trace_check_syscall_DC (regs, nr, name, 3);
- else if (nr == SB_NR_RMDIR) return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_SYMLINK) return _trace_check_syscall_C (regs, nr, name, 2);
- else if (nr == SB_NR_SYMLINKAT) return _trace_check_syscall_DC (regs, nr, name, 2);
- else if (nr == SB_NR_TRUNCATE) return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_TRUNCATE64)return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_UNLINK) return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_UNLINKAT) return trace_check_syscall_DCF(regs, nr, name);
- else if (nr == SB_NR_UTIME) return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_UTIMES) return trace_check_syscall_C (regs, nr, name);
- else if (nr == SB_NR_UTIMENSAT) return trace_check_syscall_DCF(regs, nr, name);
+ else if (nr == SB_NR_CHMOD) return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_CHOWN) return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_CREAT) return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_FCHMODAT) return trace_check_syscall_DCF(&state);
+ else if (nr == SB_NR_FCHOWNAT) return trace_check_syscall_DCF(&state);
+ else if (nr == SB_NR_FUTIMESAT) return trace_check_syscall_DC (&state);
+ else if (nr == SB_NR_LCHOWN) return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_LINK) return _trace_check_syscall_C (&state, 2);
+ else if (nr == SB_NR_LINKAT) return _trace_check_syscall_DCF(&state, 3);
+ else if (nr == SB_NR_MKDIR) return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_MKDIRAT) return trace_check_syscall_DC (&state);
+ else if (nr == SB_NR_MKNOD) return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_MKNODAT) return trace_check_syscall_DC (&state);
+ else if (nr == SB_NR_RENAME) return trace_check_syscall_C (&state) &&
+ _trace_check_syscall_C (&state, 2);
+ else if (nr == SB_NR_RENAMEAT) return trace_check_syscall_DC (&state) &&
+ _trace_check_syscall_DC (&state, 3);
+ else if (nr == SB_NR_RMDIR) return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_SYMLINK) return _trace_check_syscall_C (&state, 2);
+ else if (nr == SB_NR_SYMLINKAT) return _trace_check_syscall_DC (&state, 2);
+ else if (nr == SB_NR_TRUNCATE) return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_TRUNCATE64)return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_UNLINK) return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_UNLINKAT) return trace_check_syscall_DCF(&state);
+ else if (nr == SB_NR_UTIME) return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_UTIMES) return trace_check_syscall_C (&state);
+ else if (nr == SB_NR_UTIMENSAT) return trace_check_syscall_DCF(&state);
else if (nr == SB_NR_ACCESS) {
char *path = do_peekstr(trace_arg(regs, 1));
@@ -309,7 +346,10 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
char *path = do_peekstr(trace_arg(regs, 1));
int flags = trace_arg(regs, 2);
__SB_DEBUG("(\"%s\", %x)", path, flags);
- ret = _SB_SAFE_OPEN_INT(nr, name, path, flags);
+ if (sb_openat_pre_check(name, path, AT_FDCWD, flags))
+ ret = _SB_SAFE_OPEN_INT(nr, name, path, flags);
+ else
+ ret = 1;
free(path);
return ret;
@@ -318,7 +358,10 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
char *path = do_peekstr(trace_arg(regs, 2));
int flags = trace_arg(regs, 3);
__SB_DEBUG("(%i, \"%s\", %x)", dirfd, path, flags);
- ret = _SB_SAFE_OPEN_INT_AT(nr, name, dirfd, path, flags);
+ if (sb_openat_pre_check(name, path, dirfd, flags))
+ ret = _SB_SAFE_OPEN_INT_AT(nr, name, dirfd, path, flags);
+ else
+ ret = 1;
free(path);
return ret;
}
@@ -369,6 +412,8 @@ static void trace_loop(void)
if (before_syscall) {
_SB_DEBUG("%s:%i", se ? se->name : "IDK", nr);
if (!trace_check_syscall(se, &regs)) {
+ if (is_env_on(ENV_SANDBOX_DEBUG))
+ SB_EINFO("trace_loop", " destroying\n");
do_ptrace(PTRACE_KILL, NULL, NULL);
exit(1);
}
diff --git a/libsandbox/wrapper-funcs/__64_post.h b/libsandbox/wrapper-funcs/__64_post.h
index 33ea3b2..2fd2182 100644
--- a/libsandbox/wrapper-funcs/__64_post.h
+++ b/libsandbox/wrapper-funcs/__64_post.h
@@ -1,2 +1,3 @@
+#undef SB64
#undef stat
#undef off_t
diff --git a/libsandbox/wrapper-funcs/__64_pre.h b/libsandbox/wrapper-funcs/__64_pre.h
index 1e836f4..2132110 100644
--- a/libsandbox/wrapper-funcs/__64_pre.h
+++ b/libsandbox/wrapper-funcs/__64_pre.h
@@ -1,2 +1,3 @@
+#define SB64
#define stat stat64
#define off_t off64_t
diff --git a/libsandbox/wrapper-funcs/__openat_2.c b/libsandbox/wrapper-funcs/__openat_2.c
index b7a6e09..4549a23 100644
--- a/libsandbox/wrapper-funcs/__openat_2.c
+++ b/libsandbox/wrapper-funcs/__openat_2.c
@@ -9,40 +9,16 @@
# define WRAPPER_ARGS_PROTO int dirfd, const char *pathname, int flags
# define WRAPPER_ARGS dirfd, pathname, flags
# define WRAPPER_SAFE() SB_SAFE_OPEN_INT_AT(dirfd, pathname, flags)
-# define USE_AT 1
#else
-# define USE_AT 0
+# define dirfd AT_FDCWD
#endif
-#ifndef PRE_CHECK_FUNC
-# define _PRE_CHECK_FUNC(x) sb_##x##_pre_check
-# define PRE_CHECK_FUNC(x) _PRE_CHECK_FUNC(x)
-#endif
-static inline bool PRE_CHECK_FUNC(WRAPPER_NAME)(WRAPPER_ARGS_PROTO)
-{
- if (!(flags & O_CREAT)) {
- /* If we're not trying to create, fail normally if
- * file does not stat
- */
-#if USE_AT
- if (dirfd == AT_FDCWD || pathname[0] == '/')
+#ifdef SB64
+# define WRAPPER_PRE_CHECKS() sb_openat64_pre_check(STRING_NAME, pathname, dirfd, flags)
+#else
+# define WRAPPER_PRE_CHECKS() sb_openat_pre_check(STRING_NAME, pathname, dirfd, flags)
#endif
-#undef USE_AT
- {
- struct stat st;
- save_errno();
- if (-1 == stat(pathname, &st)) {
- if (is_env_on(ENV_SANDBOX_DEBUG))
- SB_EINFO("EARLY FAIL", " %s(%s): %s\n",
- STRING_NAME, pathname, strerror(errno));
- return false;
- }
- restore_errno();
- }
- }
-
- return true;
-}
-#define WRAPPER_PRE_CHECKS() PRE_CHECK_FUNC(WRAPPER_NAME)(WRAPPER_ARGS)
#include "__wrapper_simple.c"
+
+#undef dirfd
diff --git a/libsandbox/wrapper-funcs/fopen.c b/libsandbox/wrapper-funcs/fopen.c
index 57e7dba..ce2fdf3 100644
--- a/libsandbox/wrapper-funcs/fopen.c
+++ b/libsandbox/wrapper-funcs/fopen.c
@@ -11,30 +11,10 @@
#define WRAPPER_RET_TYPE FILE *
#define WRAPPER_RET_DEFAULT NULL
-#ifndef SB_FOPEN_PRE_CHECK
-#define SB_FOPEN_PRE_CHECK
-static inline bool sb_fopen_pre_check(WRAPPER_ARGS_PROTO)
-{
- if ((NULL != mode) && (mode[0] == 'r')) {
- save_errno();
-
- /* If we're trying to read, fail normally if file does not stat */
- struct stat st;
- if (-1 == stat(pathname, &st)) {
- if (is_env_on(ENV_SANDBOX_DEBUG))
- SB_EINFO("EARLY FAIL", " %s(%s): %s\n",
- STRING_NAME, pathname, strerror(errno));
- return false;
- }
-
- restore_errno();
- }
-
- return true;
-}
-#endif
-#ifndef WRAPPER_PRE_CHECKS
-# define WRAPPER_PRE_CHECKS() sb_fopen_pre_check(WRAPPER_ARGS)
+#ifdef SB64
+# define WRAPPER_PRE_CHECKS() sb_fopen64_pre_check(STRING_NAME, pathname, mode)
+#else
+# define WRAPPER_PRE_CHECKS() sb_fopen_pre_check(STRING_NAME, pathname, mode)
#endif
#include "__wrapper_simple.c"
diff --git a/libsandbox/wrapper-funcs/fopen64.c b/libsandbox/wrapper-funcs/fopen64.c
index 60116fe..8e0cdb0 100644
--- a/libsandbox/wrapper-funcs/fopen64.c
+++ b/libsandbox/wrapper-funcs/fopen64.c
@@ -1,14 +1,10 @@
/*
* fopen64() wrapper.
*
- * Copyright 1999-2008 Gentoo Foundation
+ * Copyright 1999-2009 Gentoo Foundation
* Licensed under the GPL-2
*/
#include "__64_pre.h"
-#undef SB_FOPEN_PRE_CHECK
-#define sb_fopen_pre_check sb_fopen64_pre_check
-#define WRAPPER_PRE_CHECKS() sb_fopen64_pre_check(WRAPPER_ARGS)
#include "fopen.c"
-#undef sb_fopen_pre_check
#include "__64_post.h"
diff --git a/libsandbox/wrapper-funcs/fopen64_pre_check.c b/libsandbox/wrapper-funcs/fopen64_pre_check.c
new file mode 100644
index 0000000..3f7a737
--- /dev/null
+++ b/libsandbox/wrapper-funcs/fopen64_pre_check.c
@@ -0,0 +1,12 @@
+/*
+ * fopen64() pre-check.
+ *
+ * Copyright 1999-2009 Gentoo Foundation
+ * Licensed under the GPL-2
+ */
+
+#include "__64_pre.h"
+#define sb_fopen_pre_check sb_fopen64_pre_check
+#include "fopen_pre_check.c"
+#undef sb_fopen_pre_check
+#include "__64_post.h"
diff --git a/libsandbox/wrapper-funcs/fopen_pre_check.c b/libsandbox/wrapper-funcs/fopen_pre_check.c
new file mode 100644
index 0000000..9ee3b60
--- /dev/null
+++ b/libsandbox/wrapper-funcs/fopen_pre_check.c
@@ -0,0 +1,26 @@
+/*
+ * fopen() pre-check.
+ *
+ * Copyright 1999-2009 Gentoo Foundation
+ * Licensed under the GPL-2
+ */
+
+bool sb_fopen_pre_check(const char *func, const char *pathname, const char *mode)
+{
+ if ((NULL != mode) && (mode[0] == 'r')) {
+ save_errno();
+
+ /* If we're trying to read, fail normally if file does not stat */
+ struct stat st;
+ if (-1 == stat(pathname, &st)) {
+ if (is_env_on(ENV_SANDBOX_DEBUG))
+ SB_EINFO("EARLY FAIL", " %s(%s): %s\n",
+ func, pathname, strerror(errno));
+ return false;
+ }
+
+ restore_errno();
+ }
+
+ return true;
+}
diff --git a/libsandbox/wrapper-funcs/mkdir.c b/libsandbox/wrapper-funcs/mkdir.c
index cc4cbee..4962490 100644
--- a/libsandbox/wrapper-funcs/mkdir.c
+++ b/libsandbox/wrapper-funcs/mkdir.c
@@ -1,13 +1,11 @@
/*
* mkdir() wrapper.
*
- * Copyright 1999-2008 Gentoo Foundation
+ * Copyright 1999-2009 Gentoo Foundation
* Licensed under the GPL-2
*/
#define WRAPPER_ARGS_PROTO const char *pathname, mode_t mode
#define WRAPPER_ARGS pathname, mode
#define WRAPPER_SAFE() SB_SAFE(pathname)
-#define sb_mkdirat_pre_check sb_mkdir_pre_check
#include "mkdirat.c"
-#undef sb_mkdirat_pre_check
diff --git a/libsandbox/wrapper-funcs/mkdirat.c b/libsandbox/wrapper-funcs/mkdirat.c
index f809c9f..4445356 100644
--- a/libsandbox/wrapper-funcs/mkdirat.c
+++ b/libsandbox/wrapper-funcs/mkdirat.c
@@ -1,7 +1,7 @@
/*
* mkdirat() wrapper.
*
- * Copyright 1999-2008 Gentoo Foundation
+ * Copyright 1999-2009 Gentoo Foundation
* Licensed under the GPL-2
*/
@@ -9,42 +9,12 @@
# define WRAPPER_ARGS_PROTO int dirfd, const char *pathname, mode_t mode
# define WRAPPER_ARGS dirfd, pathname, mode
# define WRAPPER_SAFE() SB_SAFE_AT(dirfd, pathname, 0)
+#else
+# define dirfd AT_FDCWD
#endif
-static inline bool sb_mkdirat_pre_check(WRAPPER_ARGS_PROTO)
-{
- char canonic[SB_PATH_MAX];
-
- save_errno();
-
- if (-1 == canonicalize(pathname, canonic))
- /* see comments in check_syscall() */
- if (ENAMETOOLONG != errno) {
- if (is_env_on(ENV_SANDBOX_DEBUG))
- SB_EINFO("EARLY FAIL", " %s(%s) @ canonicalize: %s\n",
- STRING_NAME, pathname, strerror(errno));
- return false;
- }
-
- /* XXX: Hack to prevent errors if the directory exist, and are
- * not writable - we rather return EEXIST than fail. This can
- * occur if doing something like `mkdir -p /`. We certainly do
- * not want to pass this attempt up to the higher levels as those
- * will trigger a sandbox violation.
- */
- struct stat st;
- if (0 == lstat(canonic, &st)) {
- if (is_env_on(ENV_SANDBOX_DEBUG))
- SB_EINFO("EARLY FAIL", " %s(%s) @ lstat: %s\n",
- STRING_NAME, pathname, strerror(errno));
- errno = EEXIST;
- return false;
- }
-
- restore_errno();
-
- return true;
-}
-#define WRAPPER_PRE_CHECKS() sb_mkdirat_pre_check(WRAPPER_ARGS)
+#define WRAPPER_PRE_CHECKS() sb_mkdirat_pre_check(STRING_NAME, pathname, dirfd)
#include "__wrapper_simple.c"
+
+#undef dirfd
diff --git a/libsandbox/wrapper-funcs/mkdirat_pre_check.c b/libsandbox/wrapper-funcs/mkdirat_pre_check.c
new file mode 100644
index 0000000..ea9ff9a
--- /dev/null
+++ b/libsandbox/wrapper-funcs/mkdirat_pre_check.c
@@ -0,0 +1,42 @@
+/*
+ * mkdir*() pre-check.
+ *
+ * Copyright 1999-2009 Gentoo Foundation
+ * Licensed under the GPL-2
+ */
+
+bool sb_mkdirat_pre_check(const char *func, const char *pathname, int dirfd)
+{
+ char canonic[SB_PATH_MAX];
+
+ save_errno();
+
+ /* XXX: need to check pathname with dirfd */
+ if (-1 == canonicalize(pathname, canonic))
+ /* see comments in check_syscall() */
+ if (ENAMETOOLONG != errno) {
+ if (is_env_on(ENV_SANDBOX_DEBUG))
+ SB_EINFO("EARLY FAIL", " %s(%s) @ canonicalize: %s\n",
+ func, pathname, strerror(errno));
+ return false;
+ }
+
+ /* XXX: Hack to prevent errors if the directory exist, and are
+ * not writable - we rather return EEXIST than fail. This can
+ * occur if doing something like `mkdir -p /`. We certainly do
+ * not want to pass this attempt up to the higher levels as those
+ * will trigger a sandbox violation.
+ */
+ struct stat st;
+ if (0 == lstat(canonic, &st)) {
+ if (is_env_on(ENV_SANDBOX_DEBUG))
+ SB_EINFO("EARLY FAIL", " %s(%s[%s]) @ lstat: %s\n",
+ func, pathname, canonic, strerror(errno));
+ errno = EEXIST;
+ return false;
+ }
+
+ restore_errno();
+
+ return true;
+}
diff --git a/libsandbox/wrapper-funcs/openat.c b/libsandbox/wrapper-funcs/openat.c
index 123b7c2..3e46ad5 100644
--- a/libsandbox/wrapper-funcs/openat.c
+++ b/libsandbox/wrapper-funcs/openat.c
@@ -1,7 +1,7 @@
/*
* openat() wrapper.
*
- * Copyright 1999-2008 Gentoo Foundation
+ * Copyright 1999-2009 Gentoo Foundation
* Licensed under the GPL-2
*/
@@ -12,42 +12,15 @@
# define WRAPPER_ARGS dirfd, pathname, flags
# define WRAPPER_ARGS_FULL WRAPPER_ARGS, mode
# define WRAPPER_SAFE() SB_SAFE_OPEN_INT_AT(dirfd, pathname, flags)
-# define USE_AT 1
#else
-# define USE_AT 0
+# define dirfd AT_FDCWD
#endif
-#ifndef PRE_CHECK_FUNC
-# define _PRE_CHECK_FUNC(x) sb_##x##_pre_check
-# define PRE_CHECK_FUNC(x) _PRE_CHECK_FUNC(x)
-#endif
-
-static inline bool PRE_CHECK_FUNC(WRAPPER_NAME)(_WRAPPER_ARGS_PROTO)
-{
- if (!(flags & O_CREAT)) {
- /* If we're not trying to create, fail normally if
- * file does not stat
- */
-#if USE_AT
- if (dirfd == AT_FDCWD || pathname[0] == '/')
+#ifdef SB64
+# define WRAPPER_PRE_CHECKS() sb_openat64_pre_check(STRING_NAME, pathname, dirfd, flags)
+#else
+# define WRAPPER_PRE_CHECKS() sb_openat_pre_check(STRING_NAME, pathname, dirfd, flags)
#endif
-#undef USE_AT
- {
- struct stat st;
- save_errno();
- if (-1 == stat(pathname, &st)) {
- if (is_env_on(ENV_SANDBOX_DEBUG))
- SB_EINFO("EARLY FAIL", " %s(%s): %s\n",
- STRING_NAME, pathname, strerror(errno));
- return false;
- }
- restore_errno();
- }
- }
-
- return true;
-}
-#define WRAPPER_PRE_CHECKS() PRE_CHECK_FUNC(WRAPPER_NAME)(WRAPPER_ARGS)
#define WRAPPER_SAFE_POST_EXPAND \
int mode = 0; \
@@ -60,4 +33,5 @@ static inline bool PRE_CHECK_FUNC(WRAPPER_NAME)(_WRAPPER_ARGS_PROTO)
#include "__wrapper_simple.c"
+#undef dirfd
#undef _WRAPPER_ARGS_PROTO
diff --git a/libsandbox/wrapper-funcs/openat64_pre_check.c b/libsandbox/wrapper-funcs/openat64_pre_check.c
new file mode 100644
index 0000000..67dc0dc
--- /dev/null
+++ b/libsandbox/wrapper-funcs/openat64_pre_check.c
@@ -0,0 +1,12 @@
+/*
+ * open*64*() pre-check.
+ *
+ * Copyright 1999-2009 Gentoo Foundation
+ * Licensed under the GPL-2
+ */
+
+#include "__64_pre.h"
+#define sb_openat_pre_check sb_openat64_pre_check
+#include "openat_pre_check.c"
+#undef sb_openat_pre_check
+#include "__64_post.h"
diff --git a/libsandbox/wrapper-funcs/openat_pre_check.c b/libsandbox/wrapper-funcs/openat_pre_check.c
new file mode 100644
index 0000000..7f5e823
--- /dev/null
+++ b/libsandbox/wrapper-funcs/openat_pre_check.c
@@ -0,0 +1,28 @@
+/*
+ * open*() pre-check.
+ *
+ * Copyright 1999-2009 Gentoo Foundation
+ * Licensed under the GPL-2
+ */
+
+bool sb_openat_pre_check(const char *func, const char *pathname, int dirfd, int flags)
+{
+ if (!(flags & O_CREAT)) {
+ /* If we're not trying to create, fail normally if
+ * file does not stat
+ */
+ if (dirfd == AT_FDCWD || pathname[0] == '/') {
+ struct stat st;
+ save_errno();
+ if (-1 == stat(pathname, &st)) {
+ if (is_env_on(ENV_SANDBOX_DEBUG))
+ SB_EINFO("EARLY FAIL", " %s(%s): %s\n",
+ func, pathname, strerror(errno));
+ return false;
+ }
+ restore_errno();
+ }
+ }
+
+ return true;
+}
diff --git a/libsandbox/wrapper-funcs/unlink.c b/libsandbox/wrapper-funcs/unlink.c
index 79cab10..4f26de1 100644
--- a/libsandbox/wrapper-funcs/unlink.c
+++ b/libsandbox/wrapper-funcs/unlink.c
@@ -1,13 +1,11 @@
/*
* unlink() wrapper.
*
- * Copyright 1999-2008 Gentoo Foundation
+ * Copyright 1999-2009 Gentoo Foundation
* Licensed under the GPL-2
*/
#define WRAPPER_ARGS_PROTO const char *pathname
#define WRAPPER_ARGS pathname
#define WRAPPER_SAFE() SB_SAFE(pathname)
-#define sb_unlinkat_pre_check sb_unlink_pre_check
#include "unlinkat.c"
-#undef sb_unlinkat_pre_check
diff --git a/libsandbox/wrapper-funcs/unlinkat.c b/libsandbox/wrapper-funcs/unlinkat.c
index 4ef4a3b..34bce72 100644
--- a/libsandbox/wrapper-funcs/unlinkat.c
+++ b/libsandbox/wrapper-funcs/unlinkat.c
@@ -1,7 +1,7 @@
/*
* unlinkat() wrapper.
*
- * Copyright 1999-2008 Gentoo Foundation
+ * Copyright 1999-2009 Gentoo Foundation
* Licensed under the GPL-2
*/
@@ -9,38 +9,12 @@
# define WRAPPER_ARGS_PROTO int dirfd, const char *pathname, int flags
# define WRAPPER_ARGS dirfd, pathname, flags
# define WRAPPER_SAFE() SB_SAFE_AT(dirfd, pathname, flags)
+#else
+# define dirfd AT_FDCWD
#endif
-static inline bool sb_unlinkat_pre_check(WRAPPER_ARGS_PROTO)
-{
- char canonic[SB_PATH_MAX];
-
- save_errno();
-
- if (-1 == canonicalize(pathname, canonic))
- /* see comments in check_syscall() */
- if (ENAMETOOLONG != errno)
- goto error;
-
- /* XXX: Hack to make sure sandboxed process cannot remove
- * a device node, bug #79836. */
- if (0 == strcmp(canonic, "/dev/null") ||
- 0 == strcmp(canonic, "/dev/zero"))
- {
- errno = EACCES;
- goto error;
- }
-
- restore_errno();
-
- return true;
-
- error:
- if (is_env_on(ENV_SANDBOX_DEBUG))
- SB_EINFO("EARLY FAIL", " %s(%s): %s\n",
- STRING_NAME, pathname, strerror(errno));
- return false;
-}
-#define WRAPPER_PRE_CHECKS() sb_unlinkat_pre_check(WRAPPER_ARGS)
+#define WRAPPER_PRE_CHECKS() sb_unlinkat_pre_check(STRING_NAME, pathname, dirfd)
#include "__wrapper_simple.c"
+
+#undef dirfd
diff --git a/libsandbox/wrapper-funcs/unlinkat_pre_check.c b/libsandbox/wrapper-funcs/unlinkat_pre_check.c
new file mode 100644
index 0000000..961c31f
--- /dev/null
+++ b/libsandbox/wrapper-funcs/unlinkat_pre_check.c
@@ -0,0 +1,38 @@
+/*
+ * unlink*() pre-check.
+ *
+ * Copyright 1999-2009 Gentoo Foundation
+ * Licensed under the GPL-2
+ */
+
+bool sb_unlinkat_pre_check(const char *func, const char *pathname, int dirfd)
+{
+ char canonic[SB_PATH_MAX];
+
+ save_errno();
+
+ /* XXX: need to check pathname with dirfd */
+ if (-1 == canonicalize(pathname, canonic))
+ /* see comments in check_syscall() */
+ if (ENAMETOOLONG != errno)
+ goto error;
+
+ /* XXX: Hack to make sure sandboxed process cannot remove
+ * a device node, bug #79836. */
+ if (0 == strcmp(canonic, "/dev/null") ||
+ 0 == strcmp(canonic, "/dev/zero"))
+ {
+ errno = EACCES;
+ goto error;
+ }
+
+ restore_errno();
+
+ return true;
+
+ error:
+ if (is_env_on(ENV_SANDBOX_DEBUG))
+ SB_EINFO("EARLY FAIL", " %s(%s): %s\n",
+ func, pathname, strerror(errno));
+ return false;
+}
diff --git a/libsandbox/wrappers.h b/libsandbox/wrappers.h
index fddbe1b..5b97787 100644
--- a/libsandbox/wrappers.h
+++ b/libsandbox/wrappers.h
@@ -3,7 +3,7 @@
*
* Function wrapping functions.
*
- * Copyright 1999-2008 Gentoo Foundation
+ * Copyright 1999-2009 Gentoo Foundation
* Licensed under the GPL-2
*/
@@ -22,4 +22,11 @@ attribute_hidden int sb_unwrapped_open (const char *, int, mode_t);
#define sb_unwrapped_popen sb_unwrapped_popen_DEFAULT
attribute_hidden FILE *sb_unwrapped_popen (const char *, const char *);
+attribute_hidden bool sb_fopen_pre_check (const char *func, const char *pathname, const char *mode);
+attribute_hidden bool sb_fopen64_pre_check (const char *func, const char *pathname, const char *mode);
+attribute_hidden bool sb_mkdirat_pre_check (const char *func, const char *pathname, int dirfd);
+attribute_hidden bool sb_openat_pre_check (const char *func, const char *pathname, int dirfd, int flags);
+attribute_hidden bool sb_openat64_pre_check (const char *func, const char *pathname, int dirfd, int flags);
+attribute_hidden bool sb_unlinkat_pre_check (const char *func, const char *pathname, int dirfd);
+
#endif