aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/crypt_ops/compat_openssl.h22
-rw-r--r--src/lib/crypt_ops/crypto_openssl_mgt.h3
-rw-r--r--src/lib/crypt_ops/crypto_rsa_openssl.c8
-rw-r--r--src/lib/dispatch/dispatch_cfg_st.h4
-rw-r--r--src/lib/geoip/geoip.c4
-rw-r--r--src/lib/geoip/geoip.h6
-rw-r--r--src/lib/malloc/malloc.h4
-rw-r--r--src/lib/sandbox/sandbox.c128
8 files changed, 142 insertions, 37 deletions
diff --git a/src/lib/crypt_ops/compat_openssl.h b/src/lib/crypt_ops/compat_openssl.h
index 0f56f338b5..c5eccdb015 100644
--- a/src/lib/crypt_ops/compat_openssl.h
+++ b/src/lib/crypt_ops/compat_openssl.h
@@ -20,32 +20,36 @@
* \brief compatibility definitions for working with different openssl forks
**/
-#if !defined(LIBRESSL_VERSION_NUMBER) && \
- OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,0,1)
+#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,0,1)
#error "We require OpenSSL >= 1.0.1"
#endif
-#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) && \
- ! defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
/* We define this macro if we're trying to build with the majorly refactored
* API in OpenSSL 1.1 */
#define OPENSSL_1_1_API
#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) && ... */
-#ifndef OPENSSL_1_1_API
-#define OpenSSL_version(v) SSLeay_version(v)
-#define tor_OpenSSL_version_num() SSLeay()
+/* LibreSSL claims to be OpenSSL 2.0 but lacks these OpenSSL 1.1 APIs */
+#if !defined(OPENSSL_1_1_API) || defined(LIBRESSL_VERSION_NUMBER)
#define RAND_OpenSSL() RAND_SSLeay()
#define STATE_IS_SW_SERVER_HELLO(st) \
(((st) == SSL3_ST_SW_SRVR_HELLO_A) || \
((st) == SSL3_ST_SW_SRVR_HELLO_B))
#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()
+#else
#define STATE_IS_SW_SERVER_HELLO(st) \
((st) == TLS_ST_SW_SRVR_HELLO)
#define CONST_IF_OPENSSL_1_1_API const
+#endif
+
+/* OpenSSL 1.1 and LibreSSL both have these APIs */
+#ifndef OPENSSL_1_1_API
+#define OpenSSL_version(v) SSLeay_version(v)
+#define tor_OpenSSL_version_num() SSLeay()
+#else /* defined(OPENSSL_1_1_API) */
+#define tor_OpenSSL_version_num() OpenSSL_version_num()
#endif /* !defined(OPENSSL_1_1_API) */
#endif /* defined(ENABLE_OPENSSL) */
diff --git a/src/lib/crypt_ops/crypto_openssl_mgt.h b/src/lib/crypt_ops/crypto_openssl_mgt.h
index c6f63ffa08..96a37721dd 100644
--- a/src/lib/crypt_ops/crypto_openssl_mgt.h
+++ b/src/lib/crypt_ops/crypto_openssl_mgt.h
@@ -54,8 +54,7 @@
#define DISABLE_ENGINES
#endif
-#if OPENSSL_VERSION_NUMBER >= OPENSSL_VER(1,1,0,0,5) && \
- !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_VER(1,1,0,0,5)
/* OpenSSL as of 1.1.0pre4 has an "new" thread API, which doesn't require
* setting up various callbacks.
*
diff --git a/src/lib/crypt_ops/crypto_rsa_openssl.c b/src/lib/crypt_ops/crypto_rsa_openssl.c
index a21c4a65cf..544d72e6ca 100644
--- a/src/lib/crypt_ops/crypto_rsa_openssl.c
+++ b/src/lib/crypt_ops/crypto_rsa_openssl.c
@@ -572,7 +572,9 @@ static bool
rsa_private_key_too_long(RSA *rsa, int max_bits)
{
const BIGNUM *n, *e, *p, *q, *d, *dmp1, *dmq1, *iqmp;
-#ifdef OPENSSL_1_1_API
+#if defined(OPENSSL_1_1_API) && \
+ (!defined(LIBRESSL_VERSION_NUMBER) || \
+ LIBRESSL_VERSION_NUMBER >= OPENSSL_V_SERIES(3,5,0))
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,1)
n = RSA_get0_n(rsa);
@@ -591,7 +593,7 @@ rsa_private_key_too_long(RSA *rsa, int max_bits)
if (RSA_bits(rsa) > max_bits)
return true;
-#else /* !defined(OPENSSL_1_1_API) */
+#else /* !defined(OPENSSL_1_1_API) && ... */
n = rsa->n;
e = rsa->e;
p = rsa->p;
@@ -600,7 +602,7 @@ rsa_private_key_too_long(RSA *rsa, int max_bits)
dmp1 = rsa->dmp1;
dmq1 = rsa->dmq1;
iqmp = rsa->iqmp;
-#endif /* defined(OPENSSL_1_1_API) */
+#endif /* defined(OPENSSL_1_1_API) && ... */
if (n && BN_num_bits(n) > max_bits)
return true;
diff --git a/src/lib/dispatch/dispatch_cfg_st.h b/src/lib/dispatch/dispatch_cfg_st.h
index 636f2e6df5..503d13e010 100644
--- a/src/lib/dispatch/dispatch_cfg_st.h
+++ b/src/lib/dispatch/dispatch_cfg_st.h
@@ -24,9 +24,9 @@ struct dispatch_cfg_t {
struct smartlist_t *type_by_msg;
/** A list of channel_id_t (cast to void*), indexed by msg_t. */
struct smartlist_t *chan_by_msg;
- /** A list of dispatch_rcv_t, indexed by msg_type_id_t. */
+ /** A list of dispatch_typefns_t, indexed by msg_type_id_t. */
struct smartlist_t *fns_by_type;
- /** A list of dispatch_typefns_t, indexed by msg_t. */
+ /** A list of dispatch_rcv_t, indexed by msg_t. */
struct smartlist_t *recv_by_msg;
};
diff --git a/src/lib/geoip/geoip.c b/src/lib/geoip/geoip.c
index 686040613d..f13354dbe1 100644
--- a/src/lib/geoip/geoip.c
+++ b/src/lib/geoip/geoip.c
@@ -387,7 +387,7 @@ geoip_load_file(sa_family_t family, const char *filename, int severity)
* be less than geoip_get_n_countries(). To decode it, call
* geoip_get_country_name().
*/
-int
+STATIC int
geoip_get_country_by_ipv4(uint32_t ipaddr)
{
geoip_ipv4_entry_t *ent;
@@ -403,7 +403,7 @@ geoip_get_country_by_ipv4(uint32_t ipaddr)
* 0 for the 'unknown country'. The return value will always be less than
* geoip_get_n_countries(). To decode it, call geoip_get_country_name().
*/
-int
+STATIC int
geoip_get_country_by_ipv6(const struct in6_addr *addr)
{
geoip_ipv6_entry_t *ent;
diff --git a/src/lib/geoip/geoip.h b/src/lib/geoip/geoip.h
index 764ed1d5a5..e68573fd1a 100644
--- a/src/lib/geoip/geoip.h
+++ b/src/lib/geoip/geoip.h
@@ -21,14 +21,14 @@
#ifdef GEOIP_PRIVATE
STATIC int geoip_parse_entry(const char *line, sa_family_t family);
STATIC void clear_geoip_db(void);
+
+STATIC int geoip_get_country_by_ipv4(uint32_t ipaddr);
+STATIC int geoip_get_country_by_ipv6(const struct in6_addr *addr);
#endif /* defined(GEOIP_PRIVATE) */
struct in6_addr;
struct tor_addr_t;
-int geoip_get_country_by_ipv4(uint32_t ipaddr);
-int geoip_get_country_by_ipv6(const struct in6_addr *addr);
-
/** A per-country GeoIP record. */
typedef struct geoip_country_t {
/** A nul-terminated two-letter country-code. */
diff --git a/src/lib/malloc/malloc.h b/src/lib/malloc/malloc.h
index cc031f843a..48a3ac32cf 100644
--- a/src/lib/malloc/malloc.h
+++ b/src/lib/malloc/malloc.h
@@ -11,6 +11,7 @@
#ifndef TOR_UTIL_MALLOC_H
#define TOR_UTIL_MALLOC_H
+#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include "lib/cc/compat_compiler.h"
@@ -45,6 +46,9 @@ void tor_free_(void *mem);
#ifdef __GNUC__
#define tor_free(p) STMT_BEGIN \
typeof(&(p)) tor_free__tmpvar = &(p); \
+ _Static_assert(!__builtin_types_compatible_p(typeof(*tor_free__tmpvar), \
+ struct event *), \
+ "use tor_event_free for struct event *"); \
raw_free(*tor_free__tmpvar); \
*tor_free__tmpvar=NULL; \
STMT_END
diff --git a/src/lib/sandbox/sandbox.c b/src/lib/sandbox/sandbox.c
index cc00d2048f..7c024d7e37 100644
--- a/src/lib/sandbox/sandbox.c
+++ b/src/lib/sandbox/sandbox.c
@@ -141,10 +141,12 @@ static sandbox_cfg_t *filter_dynamic = NULL;
* the high bits of the value might get masked out improperly. */
#define SCMP_CMP_MASKED(a,b,c) \
SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, ~(scmp_datum_t)(b), (c))
-/* For negative constants, the rule to add depends on the glibc version. */
-#define SCMP_CMP_NEG(a,op,b) (libc_negative_constant_needs_cast() ? \
- (SCMP_CMP((a), (op), (unsigned int)(b))) : \
- (SCMP_CMP_STR((a), (op), (b))))
+/* Negative constants aren't consistently sign extended or zero extended.
+ * Different compilers, libc, and architectures behave differently. For cases
+ * where the kernel ABI uses a 32 bit integer, this macro can be used to
+ * mask-compare only the lower 32 bits of the value. */
+#define SCMP_CMP_LOWER32_EQ(a,b) \
+ SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, 0xFFFFFFFF, (unsigned int)(b))
/** Variable used for storing all syscall numbers that will be allowed with the
* stage 1 general Tor sandbox.
@@ -516,14 +518,6 @@ libc_uses_openat_for_opendir(void)
(is_libc_at_least(2, 15) && !is_libc_at_least(2, 22));
}
-/* Return true if we think we're running with a libc that needs to cast
- * negative arguments like AT_FDCWD for seccomp rules. */
-static int
-libc_negative_constant_needs_cast(void)
-{
- return is_libc_at_least(2, 27);
-}
-
/** Allow a single file to be opened. If <b>use_openat</b> is true,
* we're using a libc that remaps all the opens into openats. */
static int
@@ -531,7 +525,7 @@ allow_file_open(scmp_filter_ctx ctx, int use_openat, const char *file)
{
if (use_openat) {
return seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
- SCMP_CMP_NEG(0, SCMP_CMP_EQ, AT_FDCWD),
+ SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
SCMP_CMP_STR(1, SCMP_CMP_EQ, file));
} else {
return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open),
@@ -612,6 +606,32 @@ sb_chmod(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
return 0;
}
+static int
+sb_fchmodat(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(fchmodat)) {
+ rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchmodat),
+ SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
+ SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value));
+ if (rc != 0) {
+ log_err(LD_BUG,"(Sandbox) failed to add fchmodat syscall, received "
+ "libseccomp error %d", rc);
+ return rc;
+ }
+ }
+ }
+
+ return 0;
+}
+
#ifdef __i386__
static int
sb_chown32(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
@@ -664,6 +684,32 @@ sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
}
#endif /* defined(__i386__) */
+static int
+sb_fchownat(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(fchownat)) {
+ rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchownat),
+ SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
+ SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value));
+ if (rc != 0) {
+ log_err(LD_BUG,"(Sandbox) failed to add fchownat syscall, received "
+ "libseccomp error %d", rc);
+ return rc;
+ }
+ }
+ }
+
+ return 0;
+}
+
/**
* Function responsible for setting up the rename syscall for
* the seccomp filter sandbox.
@@ -696,6 +742,39 @@ sb_rename(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
}
/**
+ * Function responsible for setting up the renameat syscall for
+ * the seccomp filter sandbox.
+ */
+static int
+sb_renameat(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(renameat)) {
+
+ rc = seccomp_rule_add_4(ctx, SCMP_ACT_ALLOW, SCMP_SYS(renameat),
+ SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
+ SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
+ SCMP_CMP_LOWER32_EQ(2, AT_FDCWD),
+ SCMP_CMP_STR(3, SCMP_CMP_EQ, param->value2));
+ if (rc != 0) {
+ log_err(LD_BUG,"(Sandbox) failed to add renameat syscall, received "
+ "libseccomp error %d", rc);
+ return rc;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
* Function responsible for setting up the openat syscall for
* the seccomp filter sandbox.
*/
@@ -712,7 +791,7 @@ sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
if (param != NULL && param->prot == 1 && param->syscall
== SCMP_SYS(openat)) {
rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
- SCMP_CMP_NEG(0, SCMP_CMP_EQ, AT_FDCWD),
+ SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|
O_CLOEXEC));
@@ -1315,7 +1394,9 @@ static sandbox_filter_func_t filter_func[] = {
#else
sb_chown,
#endif
+ sb_fchownat,
sb_chmod,
+ sb_fchmodat,
sb_open,
sb_openat,
sb_opendir,
@@ -1323,6 +1404,7 @@ static sandbox_filter_func_t filter_func[] = {
sb_ptrace,
#endif
sb_rename,
+ sb_renameat,
#ifdef __NR_fcntl64
sb_fcntl64,
#endif
@@ -1590,10 +1672,24 @@ new_element(int syscall, char *value)
#ifdef __i386__
#define SCMP_chown SCMP_SYS(chown32)
+#elif defined(__aarch64__) && defined(__LP64__)
+#define SCMP_chown SCMP_SYS(fchownat)
#else
#define SCMP_chown SCMP_SYS(chown)
#endif
+#if defined(__aarch64__) && defined(__LP64__)
+#define SCMP_chmod SCMP_SYS(fchmodat)
+#else
+#define SCMP_chmod SCMP_SYS(chmod)
+#endif
+
+#if defined(__aarch64__) && defined(__LP64__)
+#define SCMP_rename SCMP_SYS(renameat)
+#else
+#define SCMP_rename SCMP_SYS(rename)
+#endif
+
#ifdef __NR_stat64
#define SCMP_stat SCMP_SYS(stat64)
#else
@@ -1631,7 +1727,7 @@ sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
{
sandbox_cfg_t *elem = NULL;
- elem = new_element(SCMP_SYS(chmod), file);
+ elem = new_element(SCMP_chmod, file);
elem->next = *cfg;
*cfg = elem;
@@ -1657,7 +1753,7 @@ sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
{
sandbox_cfg_t *elem = NULL;
- elem = new_element2(SCMP_SYS(rename), file1, file2);
+ elem = new_element2(SCMP_rename, file1, file2);
elem->next = *cfg;
*cfg = elem;