mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
Merge remote-tracking branch 'public/bug18253'
This commit is contained in:
commit
ca8423a703
3
changes/bug18253
Normal file
3
changes/bug18253
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
o Minor bugfixes (linux seccomp2 sandbox):
|
||||||
|
- Fix the sandbox's interoprability with unix sockets under setuid.
|
||||||
|
Fixes bug 18253; bugfix on 0.2.8.1-alpha.
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2001 Matej Pfajfar.
|
/* Copyright (c) 2001 Matej Pfajfar.
|
||||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
* Copyright (c) 2007-2016, The Tor Project, Inc. */
|
* Copyright (c) 2007-2016, The Tor Project, Inc. */
|
||||||
@ -447,6 +447,56 @@ sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sb_chmod(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
sandbox_cfg_t *elem = NULL;
|
||||||
|
|
||||||
|
// for each dynamic parameter filters
|
||||||
|
for (elem = filter; elem != NULL; elem = elem->next) {
|
||||||
|
smp_param_t *param = elem->param;
|
||||||
|
|
||||||
|
if (param != NULL && param->prot == 1 && param->syscall
|
||||||
|
== SCMP_SYS(chmod)) {
|
||||||
|
rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chmod),
|
||||||
|
SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
|
||||||
|
if (rc != 0) {
|
||||||
|
log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
|
||||||
|
"libseccomp error %d", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
sandbox_cfg_t *elem = NULL;
|
||||||
|
|
||||||
|
// for each dynamic parameter filters
|
||||||
|
for (elem = filter; elem != NULL; elem = elem->next) {
|
||||||
|
smp_param_t *param = elem->param;
|
||||||
|
|
||||||
|
if (param != NULL && param->prot == 1 && param->syscall
|
||||||
|
== SCMP_SYS(chown)) {
|
||||||
|
rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown),
|
||||||
|
SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
|
||||||
|
if (rc != 0) {
|
||||||
|
log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
|
||||||
|
"libseccomp error %d", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sb__sysctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
|
sb__sysctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
|
||||||
{
|
{
|
||||||
@ -980,6 +1030,8 @@ static sandbox_filter_func_t filter_func[] = {
|
|||||||
#ifdef __NR_mmap2
|
#ifdef __NR_mmap2
|
||||||
sb_mmap2,
|
sb_mmap2,
|
||||||
#endif
|
#endif
|
||||||
|
sb_chown,
|
||||||
|
sb_chmod,
|
||||||
sb_open,
|
sb_open,
|
||||||
sb_openat,
|
sb_openat,
|
||||||
sb__sysctl,
|
sb__sysctl,
|
||||||
@ -1255,6 +1307,40 @@ sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
|
||||||
|
{
|
||||||
|
sandbox_cfg_t *elem = NULL;
|
||||||
|
|
||||||
|
elem = new_element(SCMP_SYS(chmod), file);
|
||||||
|
if (!elem) {
|
||||||
|
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
elem->next = *cfg;
|
||||||
|
*cfg = elem;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
|
||||||
|
{
|
||||||
|
sandbox_cfg_t *elem = NULL;
|
||||||
|
|
||||||
|
elem = new_element(SCMP_SYS(chown), file);
|
||||||
|
if (!elem) {
|
||||||
|
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
elem->next = *cfg;
|
||||||
|
*cfg = elem;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
|
sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
|
||||||
{
|
{
|
||||||
|
@ -149,6 +149,9 @@ sandbox_cfg_t * sandbox_cfg_new(void);
|
|||||||
*/
|
*/
|
||||||
int sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file);
|
int sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file);
|
||||||
|
|
||||||
|
int sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file);
|
||||||
|
int sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file);
|
||||||
|
|
||||||
/**DOCDOC*/
|
/**DOCDOC*/
|
||||||
int sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2);
|
int sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2);
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "routerlist.h"
|
#include "routerlist.h"
|
||||||
#include "transports.h"
|
#include "transports.h"
|
||||||
#include "routerparse.h"
|
#include "routerparse.h"
|
||||||
|
#include "sandbox.h"
|
||||||
#include "transports.h"
|
#include "transports.h"
|
||||||
|
|
||||||
#ifdef USE_BUFFEREVENTS
|
#ifdef USE_BUFFEREVENTS
|
||||||
@ -1287,11 +1288,16 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
|||||||
#ifdef HAVE_PWD_H
|
#ifdef HAVE_PWD_H
|
||||||
if (options->User) {
|
if (options->User) {
|
||||||
pw = tor_getpwnam(options->User);
|
pw = tor_getpwnam(options->User);
|
||||||
|
struct stat st;
|
||||||
if (pw == NULL) {
|
if (pw == NULL) {
|
||||||
log_warn(LD_NET,"Unable to chown() %s socket: user %s not found.",
|
log_warn(LD_NET,"Unable to chown() %s socket: user %s not found.",
|
||||||
address, options->User);
|
address, options->User);
|
||||||
goto err;
|
goto err;
|
||||||
} else if (chown(address, pw->pw_uid, pw->pw_gid) < 0) {
|
} else if (fstat(s, &st) == 0 &&
|
||||||
|
st.st_uid == pw->pw_uid && st.st_gid == pw->pw_gid) {
|
||||||
|
/* No change needed */
|
||||||
|
} else if (chown(sandbox_intern_string(address),
|
||||||
|
pw->pw_uid, pw->pw_gid) < 0) {
|
||||||
log_warn(LD_NET,"Unable to chown() %s socket: %s.",
|
log_warn(LD_NET,"Unable to chown() %s socket: %s.",
|
||||||
address, strerror(errno));
|
address, strerror(errno));
|
||||||
goto err;
|
goto err;
|
||||||
@ -1302,6 +1308,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
|||||||
{
|
{
|
||||||
unsigned mode;
|
unsigned mode;
|
||||||
const char *status;
|
const char *status;
|
||||||
|
struct stat st;
|
||||||
if (port_cfg->is_world_writable) {
|
if (port_cfg->is_world_writable) {
|
||||||
mode = 0666;
|
mode = 0666;
|
||||||
status = "world-writable";
|
status = "world-writable";
|
||||||
@ -1314,7 +1321,9 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
|||||||
}
|
}
|
||||||
/* We need to use chmod; fchmod doesn't work on sockets on all
|
/* We need to use chmod; fchmod doesn't work on sockets on all
|
||||||
* platforms. */
|
* platforms. */
|
||||||
if (chmod(address, mode) < 0) {
|
if (fstat(s, &st) == 0 && (st.st_mode & 0777) == mode) {
|
||||||
|
/* no change needed */
|
||||||
|
} else if (chmod(sandbox_intern_string(address), mode) < 0) {
|
||||||
log_warn(LD_FS,"Unable to make %s %s.", address, status);
|
log_warn(LD_FS,"Unable to make %s %s.", address, status);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -3482,6 +3482,20 @@ sandbox_init_filter(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMARTLIST_FOREACH_BEGIN(get_configured_ports(), port_cfg_t *, port) {
|
||||||
|
if (!port->is_unix_addr)
|
||||||
|
continue;
|
||||||
|
/* When we open an AF_UNIX address, we want permission to open the
|
||||||
|
* directory that holds it. */
|
||||||
|
char *dirname = tor_strdup(port->unix_addr);
|
||||||
|
if (get_parent_directory(dirname) == 0) {
|
||||||
|
OPEN(dirname);
|
||||||
|
}
|
||||||
|
tor_free(dirname);
|
||||||
|
sandbox_cfg_allow_chmod_filename(&cfg, tor_strdup(port->unix_addr));
|
||||||
|
sandbox_cfg_allow_chown_filename(&cfg, tor_strdup(port->unix_addr));
|
||||||
|
} SMARTLIST_FOREACH_END(port);
|
||||||
|
|
||||||
if (options->DirPortFrontPage) {
|
if (options->DirPortFrontPage) {
|
||||||
sandbox_cfg_allow_open_filename(&cfg,
|
sandbox_cfg_allow_open_filename(&cfg,
|
||||||
tor_strdup(options->DirPortFrontPage));
|
tor_strdup(options->DirPortFrontPage));
|
||||||
|
Loading…
Reference in New Issue
Block a user