Merge branch 'tor-gitlab/mr/292_squashed' into maint-0.4.4

This commit is contained in:
Alexander Færøy 2021-02-05 16:04:53 +00:00
commit 6578a3e865

View File

@ -31,7 +31,47 @@ static const struct {
{ NULL, 0 } { NULL, 0 }
}; };
/* Returns the first port that we think we can bind to without special
* permissions. Usually this function returns 1024. */
static uint16_t
unprivileged_port_range_start(void)
{
uint16_t result = 1024;
#if defined(__linux__)
char *content = NULL;
content = read_file_to_str(
"/proc/sys/net/ipv4/ip_unprivileged_port_start",
0,
NULL);
if (content != NULL) {
int ok = 1;
uint16_t tmp_result;
tmp_result = (uint16_t)tor_parse_long(content, 10, 0, 65535, &ok, NULL);
if (ok) {
result = tmp_result;
} else {
fprintf(stderr,
"Unable to convert ip_unprivileged_port_start to integer: %s\n",
content);
}
}
tor_free(content);
#endif /* defined(__linux__) */
return result;
}
#if !defined(_WIN32) #if !defined(_WIN32)
#define PORT_TEST_RANGE_START 600
#define PORT_TEST_RANGE_END 1024
/* 0 on no, 1 on yes, -1 on failure. */ /* 0 on no, 1 on yes, -1 on failure. */
static int static int
check_can_bind_low_ports(void) check_can_bind_low_ports(void)
@ -41,7 +81,7 @@ check_can_bind_low_ports(void)
memset(&sin, 0, sizeof(sin)); memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
for (port = 600; port < 1024; ++port) { for (port = PORT_TEST_RANGE_START; port < PORT_TEST_RANGE_END; ++port) {
sin.sin_port = htons(port); sin.sin_port = htons(port);
tor_socket_t fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); tor_socket_t fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (! SOCKET_OK(fd)) { if (! SOCKET_OK(fd)) {
@ -149,10 +189,24 @@ main(int argc, char **argv)
/* Succeed if we can do a setuid with capability retention, and doing so /* Succeed if we can do a setuid with capability retention, and doing so
* does not make us lose the ability to bind low ports */ * does not make us lose the ability to bind low ports */
{ {
int keepcaps = (test_id == TEST_SETUID_KEEPCAPS); const int keepcaps = (test_id == TEST_SETUID_KEEPCAPS);
okay = switch_id(username, keepcaps ? SWITCH_ID_KEEP_BINDLOW : 0) == 0; okay = switch_id(username, keepcaps ? SWITCH_ID_KEEP_BINDLOW : 0) == 0;
if (okay) { if (okay) {
okay = check_can_bind_low_ports() == keepcaps; /* Only run this check if there are ports we may not be able to bind
* to. */
const uint16_t min_port = unprivileged_port_range_start();
if (min_port >= PORT_TEST_RANGE_START &&
min_port < PORT_TEST_RANGE_END) {
okay = check_can_bind_low_ports() == keepcaps;
} else {
fprintf(stderr,
"Skipping check for whether we can bind to any "
"privileged ports as the user system seems to "
"allow us to bind to ports even without any "
"capabilities set.\n");
}
} }
break; break;
} }