aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/crypt_ops/compat_openssl.h3
-rw-r--r--src/lib/crypt_ops/crypto_openssl_mgt.c2
-rw-r--r--src/lib/fs/conffile.c41
-rw-r--r--src/lib/fs/path.c15
-rw-r--r--src/lib/sandbox/sandbox.c39
-rw-r--r--src/lib/sandbox/sandbox.h5
-rw-r--r--src/lib/tls/tortls_openssl.c2
7 files changed, 87 insertions, 20 deletions
diff --git a/src/lib/crypt_ops/compat_openssl.h b/src/lib/crypt_ops/compat_openssl.h
index c2e1459078..aa66e0c3fa 100644
--- a/src/lib/crypt_ops/compat_openssl.h
+++ b/src/lib/crypt_ops/compat_openssl.h
@@ -34,7 +34,7 @@
#ifndef OPENSSL_1_1_API
#define OpenSSL_version(v) SSLeay_version(v)
-#define OpenSSL_version_num() SSLeay()
+#define tor_OpenSSL_version_num() SSLeay()
#define RAND_OpenSSL() RAND_SSLeay()
#define STATE_IS_SW_SERVER_HELLO(st) \
(((st) == SSL3_ST_SW_SRVR_HELLO_A) || \
@@ -42,6 +42,7 @@
#define OSSL_HANDSHAKE_STATE int
#define CONST_IF_OPENSSL_1_1_API
#else /* defined(OPENSSL_1_1_API) */
+#define tor_OpenSSL_version_num() OpenSSL_version_num()
#define STATE_IS_SW_SERVER_HELLO(st) \
((st) == TLS_ST_SW_SRVR_HELLO)
#define CONST_IF_OPENSSL_1_1_API const
diff --git a/src/lib/crypt_ops/crypto_openssl_mgt.c b/src/lib/crypt_ops/crypto_openssl_mgt.c
index 065cbca1cc..e763491a11 100644
--- a/src/lib/crypt_ops/crypto_openssl_mgt.c
+++ b/src/lib/crypt_ops/crypto_openssl_mgt.c
@@ -222,7 +222,7 @@ crypto_openssl_early_init(void)
setup_openssl_threading();
- unsigned long version_num = OpenSSL_version_num();
+ unsigned long version_num = tor_OpenSSL_version_num();
const char *version_str = crypto_openssl_get_version_str();
if (version_num == OPENSSL_VERSION_NUMBER &&
!strcmp(version_str, OPENSSL_VERSION_TEXT)) {
diff --git a/src/lib/fs/conffile.c b/src/lib/fs/conffile.c
index f1f6d8ae5f..0d0bdf09a6 100644
--- a/src/lib/fs/conffile.c
+++ b/src/lib/fs/conffile.c
@@ -19,9 +19,11 @@
#include "lib/fs/path.h"
#include "lib/log/log.h"
#include "lib/malloc/malloc.h"
+#include "lib/sandbox/sandbox.h"
#include "lib/string/printf.h"
#include <stdbool.h>
+#include <errno.h>
static smartlist_t *config_get_file_list(const char *path,
smartlist_t *opened_files);
@@ -52,21 +54,26 @@ config_get_lines_include(const char *string, config_line_t **result,
opened_lst, 1, NULL, config_process_include);
}
-/** Returns a list of paths obtained when expading globs in <b>pattern</b>. If
- * <b>pattern</b> has no globs, returns a list with <b>pattern</b> if it is an
- * existing path or NULL otherwise. If <b>opened_files</b> is provided, adds
- * paths opened by glob to it. Returns NULL on failure. */
+/** Return a list of paths obtained when expading globs in <b>pattern</b>.
+ * If <b>pattern</b> has no globs, return a list with <b>pattern</b> in it.
+ * If <b>opened_files</b> is provided, add paths opened by glob to it.
+ * Return NULL on failure. */
static smartlist_t *
expand_glob(const char *pattern, smartlist_t *opened_files)
{
- smartlist_t *matches = tor_glob(pattern);
- if (!matches) {
- return NULL;
+ if (! has_glob(pattern)) {
+ smartlist_t *matches = smartlist_new();
+ smartlist_add_strdup(matches, pattern);
+ return matches;
}
- // if it is not a glob, return error when the path is missing
- if (!has_glob(pattern) && smartlist_len(matches) == 0) {
- smartlist_free(matches);
+ smartlist_t *matches = tor_glob(pattern);
+ if (!matches) {
+ if (errno == EPERM) {
+ log_err(LD_CONFIG, "Sandbox is active, but the configuration pattern "
+ "\"%s\" listed with %%include would access files or folders not "
+ "allowed by it. Cannot proceed.", pattern);
+ }
return NULL;
}
@@ -107,6 +114,13 @@ config_get_file_list(const char *pattern, smartlist_t *opened_files)
if (opened_files) {
smartlist_add_strdup(opened_files, path);
}
+ if (sandbox_interned_string_is_missing(path)) {
+ log_err(LD_CONFIG, "Sandbox is active, but a new configuration "
+ "file \"%s\" has been listed with %%include. Cannot proceed.",
+ path);
+ error_found = true;
+ break;
+ }
file_status_t file_type = file_status(path);
if (file_type == FN_FILE) {
@@ -201,6 +215,13 @@ config_process_include(const char *pattern, int recursion_level, int extended,
int rv = -1;
SMARTLIST_FOREACH_BEGIN(config_files, const char *, config_file) {
+ if (sandbox_interned_string_is_missing(config_file)) {
+ log_err(LD_CONFIG, "Sandbox is active, but a new configuration "
+ "file \"%s\" has been listed with %%include. Cannot proceed.",
+ config_file);
+ goto done;
+ }
+
log_notice(LD_CONFIG, "Including configuration file \"%s\".", config_file);
config_line_t *included_config = NULL;
config_line_t *included_config_last = NULL;
diff --git a/src/lib/fs/path.c b/src/lib/fs/path.c
index fc759f6169..c2fdddb9db 100644
--- a/src/lib/fs/path.c
+++ b/src/lib/fs/path.c
@@ -537,6 +537,10 @@ unglob_win32(const char *pattern, int prev_sep, int next_sep)
static DIR *
prot_opendir(const char *name)
{
+ if (sandbox_interned_string_is_missing(name)) {
+ errno = EPERM;
+ return NULL;
+ }
return opendir(sandbox_intern_string(name));
}
@@ -544,6 +548,10 @@ prot_opendir(const char *name)
static int
prot_stat(const char *pathname, struct stat *buf)
{
+ if (sandbox_interned_string_is_missing(pathname)) {
+ errno = EPERM;
+ return -1;
+ }
return stat(sandbox_intern_string(pathname), buf);
}
@@ -551,6 +559,10 @@ prot_stat(const char *pathname, struct stat *buf)
static int
prot_lstat(const char *pathname, struct stat *buf)
{
+ if (sandbox_interned_string_is_missing(pathname)) {
+ errno = EPERM;
+ return -1;
+ }
return lstat(sandbox_intern_string(pathname), buf);
}
/** As closedir, but has the right type for gl_closedir */
@@ -563,7 +575,8 @@ wrap_closedir(void *arg)
/** Return a new list containing the paths that match the pattern
* <b>pattern</b>. Return NULL on error. On POSIX systems, errno is set by the
- * glob function.
+ * glob function or is set to EPERM if glob tried to access a file not allowed
+ * by the seccomp sandbox.
*/
struct smartlist_t *
tor_glob(const char *pattern)
diff --git a/src/lib/sandbox/sandbox.c b/src/lib/sandbox/sandbox.c
index 8d467c516e..168dfd943c 100644
--- a/src/lib/sandbox/sandbox.c
+++ b/src/lib/sandbox/sandbox.c
@@ -310,6 +310,8 @@ static int filter_nopar_gen[] = {
#define seccomp_rule_add_4(ctx,act,call,f1,f2,f3,f4) \
seccomp_rule_add((ctx),(act),(call),4,(f1),(f2),(f3),(f4))
+static const char *sandbox_get_interned_string(const char *str);
+
/**
* Function responsible for setting up the rt_sigaction syscall for
* the seccomp filter sandbox.
@@ -1224,9 +1226,42 @@ static sandbox_filter_func_t filter_func[] = {
sb_kill
};
+/**
+ * Return the interned (and hopefully sandbox-permitted) string equal
+ * to @a str.
+ *
+ * Return NULL if `str` is NULL, or `str` is not an interned string.
+ **/
const char *
sandbox_intern_string(const char *str)
{
+ const char *interned = sandbox_get_interned_string(str);
+
+ if (sandbox_active && str != NULL && interned == NULL) {
+ log_warn(LD_BUG, "No interned sandbox parameter found for %s", str);
+ }
+
+ return interned ? interned : str;
+}
+
+/**
+ * Return true if the sandbox is running and we are missing an interned string
+ * equal to @a str.
+ */
+bool
+sandbox_interned_string_is_missing(const char *str)
+{
+ return sandbox_active && sandbox_get_interned_string(str) == NULL;
+}
+
+/**
+ * Try to find and return the interned string equal to @a str.
+ *
+ * If there is no such string, return NULL.
+ **/
+static const char *
+sandbox_get_interned_string(const char *str)
+{
sandbox_cfg_t *elem;
if (str == NULL)
@@ -1245,9 +1280,7 @@ sandbox_intern_string(const char *str)
}
}
- if (sandbox_active)
- log_warn(LD_BUG, "No interned sandbox parameter found for %s", str);
- return str;
+ return NULL;
}
/* DOCDOC */
diff --git a/src/lib/sandbox/sandbox.h b/src/lib/sandbox/sandbox.h
index a2b3227b90..eba99afbde 100644
--- a/src/lib/sandbox/sandbox.h
+++ b/src/lib/sandbox/sandbox.h
@@ -104,12 +104,11 @@ typedef struct {
#endif /* defined(USE_LIBSECCOMP) */
#ifdef USE_LIBSECCOMP
-/** Returns a registered protected string used with the sandbox, given that
- * it matches the parameter.
- */
const char* sandbox_intern_string(const char *param);
+bool sandbox_interned_string_is_missing(const char *s);
#else /* !defined(USE_LIBSECCOMP) */
#define sandbox_intern_string(s) (s)
+#define sandbox_interned_string_is_missing(s) (false)
#endif /* defined(USE_LIBSECCOMP) */
/** Creates an empty sandbox configuration file.*/
diff --git a/src/lib/tls/tortls_openssl.c b/src/lib/tls/tortls_openssl.c
index 2269714141..ad9b49ab4f 100644
--- a/src/lib/tls/tortls_openssl.c
+++ b/src/lib/tls/tortls_openssl.c
@@ -342,7 +342,7 @@ tor_tls_init(void)
#if (SIZEOF_VOID_P >= 8 && \
OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,1))
- long version = OpenSSL_version_num();
+ long version = tor_OpenSSL_version_num();
/* LCOV_EXCL_START : we can't test these lines on the same machine */
if (version >= OPENSSL_V_SERIES(1,0,1)) {