diff options
author | Cristian Toader <cristian.matei.toader@gmail.com> | 2013-08-19 13:56:50 +0300 |
---|---|---|
committer | Cristian Toader <cristian.matei.toader@gmail.com> | 2013-08-19 13:56:50 +0300 |
commit | 36aeca0ecf5f6e724a4d5da1795c9c9d76410290 (patch) | |
tree | 71c027df5f5a4ab48c2b5bed43a19af98108ae68 /src | |
parent | a9910d89f170933a7730798c98ebbb1d743a1c46 (diff) | |
download | tor-36aeca0ecf5f6e724a4d5da1795c9c9d76410290.tar.gz tor-36aeca0ecf5f6e724a4d5da1795c9c9d76410290.zip |
fix for getaddrinfo open syscall
Diffstat (limited to 'src')
-rw-r--r-- | src/common/address.c | 3 | ||||
-rw-r--r-- | src/common/sandbox.c | 72 | ||||
-rw-r--r-- | src/common/sandbox.h | 4 |
3 files changed, 69 insertions, 10 deletions
diff --git a/src/common/address.c b/src/common/address.c index 227b4fbaee..5c8603ee20 100644 --- a/src/common/address.c +++ b/src/common/address.c @@ -14,6 +14,7 @@ #include "address.h" #include "torlog.h" #include "container.h" +#include "sandbox.h" #ifdef _WIN32 #include <process.h> @@ -234,7 +235,7 @@ tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr) memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; - err = getaddrinfo(name, NULL, &hints, &res); + err = sandbox_getaddrinfo(name, &res); if (!err) { best = NULL; for (res_p = res; res_p; res_p = res_p->ai_next) { diff --git a/src/common/sandbox.c b/src/common/sandbox.c index 210aa7c860..c71efb02da 100644 --- a/src/common/sandbox.c +++ b/src/common/sandbox.c @@ -55,6 +55,8 @@ static sandbox_cfg_t *filter_dynamic = NULL; +static struct addrinfo *sb_addr_info= NULL; + /** Variable used for storing all syscall numbers that will be allowed with the * stage 1 general Tor sandbox. */ @@ -262,13 +264,13 @@ sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter) } // problem: required by getaddrinfo - rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1, - SCMP_CMP(1, SCMP_CMP_EQ, O_RDONLY|O_CLOEXEC)); - if (rc != 0) { - log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp " - "error %d", rc); - return rc; - } +// rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1, +// SCMP_CMP(1, SCMP_CMP_EQ, O_RDONLY|O_CLOEXEC)); +// if (rc != 0) { +// log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp " +// "error %d", rc); +// return rc; +// } return 0; } @@ -288,8 +290,8 @@ sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY| O_CLOEXEC)); if (rc != 0) { - log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received libseccomp " - "error %d", rc); + log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received " + "libseccomp error %d", rc); return rc; } } @@ -862,6 +864,54 @@ sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, int num, ...) return 0; } +int sandbox_getaddrinfo(const char *name, struct addrinfo **res) +{ + char hname[256]; + + if (!res) { + return -2; + } + *res = NULL; + + if (gethostname(hname, sizeof(hname)) < 0) { + return -1; + } + + if (strncmp(name, hname, sizeof(hname)) || sb_addr_info == NULL) { + log_err(LD_BUG,"(Sandbox) failed for hname %s!", name); + return -1; + } + + *res = sb_addr_info; + return 0; +} + +static int +init_addrinfo(void) +{ + int ret; + struct addrinfo hints; + char hname[256]; + + sb_addr_info = NULL; + + if (gethostname(hname, sizeof(hname)) < 0) { + return -1; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + ret = getaddrinfo(hname, NULL, &hints, &sb_addr_info); + if(ret) { + sb_addr_info = NULL; + return -2; + } + + return 0; +} + static int add_param_filter(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) { @@ -1047,6 +1097,10 @@ initialise_libseccomp_sandbox(sandbox_cfg_t* cfg) if (install_sigsys_debugging()) return -1; + if (init_addrinfo()) { + return -4; + } + if (install_syscall_filter(cfg)) return -2; diff --git a/src/common/sandbox.h b/src/common/sandbox.h index ad31e54100..6cb827e268 100644 --- a/src/common/sandbox.h +++ b/src/common/sandbox.h @@ -34,6 +34,7 @@ #endif #include <sys/ucontext.h> #include <seccomp.h> +#include <netdb.h> /** Security measure for filter string parameter lengths*/ #define MAX_PARAM_LEN 64 @@ -91,6 +92,9 @@ typedef struct { #endif // __linux__ +/** Replacement for getaddrinfo(), using pre-recorded results. */ +int sandbox_getaddrinfo(const char *name, struct addrinfo **res); + /** Use <b>fd</b> to log non-survivable sandbox violations. */ void sandbox_set_debugging_fd(int fd); |