mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
parse-helpers: allow port 0 for socket bind items
This patch adds a new parameter to parse_ip_port_range, giving callers the option to allow ranges to have their min be 0 instead of 1. This is then used by parse_ip_ports_token, intern used by parse_socket_bind_item to allow port 0 when restricting bind system calls with SocketBindDeny / SocketBindAllow. With this, users running server software written using the golang standard library will be able to effectively sandbox their software, albeit with a small loss in security protections by allowing the process to bind on a random port in the /proc/sys/net/ipv4/ip_local_port_range.
This commit is contained in:
committed by
Yu Watanabe
parent
9807ee19b0
commit
dcfac3a3f9
@@ -691,7 +691,7 @@ int parse_ip_port(const char *s, uint16_t *ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high) {
|
||||
int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high, bool allow_zero) {
|
||||
unsigned l, h;
|
||||
int r;
|
||||
|
||||
@@ -699,7 +699,10 @@ int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (l <= 0 || l > 65535 || h <= 0 || h > 65535)
|
||||
if (l > 65535 || h > 65535)
|
||||
return -EINVAL;
|
||||
|
||||
if (!allow_zero && (l == 0 || h == 0))
|
||||
return -EINVAL;
|
||||
|
||||
if (h < l)
|
||||
|
||||
@@ -139,7 +139,7 @@ int parse_fractional_part_u(const char **s, size_t digits, unsigned *res);
|
||||
int parse_nice(const char *p, int *ret);
|
||||
|
||||
int parse_ip_port(const char *s, uint16_t *ret);
|
||||
int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high);
|
||||
int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high, bool allow_zero);
|
||||
|
||||
int parse_ip_prefix_length(const char *s, int *ret);
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ int config_parse_port_range(
|
||||
VxLan *v = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
r = parse_ip_port_range(rvalue, &v->port_range.low, &v->port_range.high);
|
||||
r = parse_ip_port_range(rvalue, &v->port_range.low, &v->port_range.high, /* allow_zero = */ false);
|
||||
if (r < 0)
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse VXLAN port range '%s'. Port should be greater than 0 and less than 65535.", rvalue);
|
||||
|
||||
@@ -1408,7 +1408,7 @@ int config_parse_routing_policy_rule_port_range(
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = parse_ip_port_range(rvalue, &low, &high);
|
||||
r = parse_ip_port_range(rvalue, &low, &high, /* allow_zero = */ false);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse routing policy rule port range '%s'", rvalue);
|
||||
return 0;
|
||||
|
||||
@@ -102,6 +102,8 @@ static int parse_ip_ports_token(
|
||||
uint16_t *nr_ports,
|
||||
uint16_t *port_min) {
|
||||
|
||||
int r;
|
||||
|
||||
assert(token);
|
||||
assert(nr_ports);
|
||||
assert(port_min);
|
||||
@@ -110,7 +112,7 @@ static int parse_ip_ports_token(
|
||||
*nr_ports = *port_min = 0;
|
||||
else {
|
||||
uint16_t mn = 0, mx = 0;
|
||||
int r = parse_ip_port_range(token, &mn, &mx);
|
||||
r = parse_ip_port_range(token, &mn, &mx, /* allow_zero = */ true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -194,6 +196,7 @@ int parse_socket_bind_item(
|
||||
*ip_protocol = proto;
|
||||
*nr_ports = nr;
|
||||
*port_min = mn;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ static void test_invalid_item(const char *str) {
|
||||
|
||||
TEST(valid_items) {
|
||||
test_valid_item("any", AF_UNSPEC, 0, 0, 0);
|
||||
test_valid_item("0-65535", AF_UNSPEC, 0, 0, 0);
|
||||
test_valid_item("ipv4", AF_INET, 0, 0, 0);
|
||||
test_valid_item("ipv6", AF_INET6, 0, 0, 0);
|
||||
test_valid_item("ipv4:any", AF_INET, 0, 0, 0);
|
||||
@@ -45,6 +46,7 @@ TEST(valid_items) {
|
||||
test_valid_item("udp", AF_UNSPEC, IPPROTO_UDP, 0, 0);
|
||||
test_valid_item("tcp:any", AF_UNSPEC, IPPROTO_TCP, 0, 0);
|
||||
test_valid_item("udp:any", AF_UNSPEC, IPPROTO_UDP, 0, 0);
|
||||
test_valid_item("0", AF_UNSPEC, 0, 1, 0);
|
||||
test_valid_item("6666", AF_UNSPEC, 0, 1, 6666);
|
||||
test_valid_item("6666-6667", AF_UNSPEC, 0, 2, 6666);
|
||||
test_valid_item("65535", AF_UNSPEC, 0, 1, 65535);
|
||||
@@ -61,6 +63,7 @@ TEST(valid_items) {
|
||||
test_valid_item("ipv6:tcp:6666", AF_INET6, IPPROTO_TCP, 1, 6666);
|
||||
test_valid_item("ipv6:udp:6666-6667", AF_INET6, IPPROTO_UDP, 2, 6666);
|
||||
test_valid_item("ipv6:tcp:any", AF_INET6, IPPROTO_TCP, 0, 0);
|
||||
test_valid_item("ipv6:tcp:0", AF_INET6, IPPROTO_TCP, 1, 0);
|
||||
}
|
||||
|
||||
TEST(invalid_items) {
|
||||
@@ -77,9 +80,7 @@ TEST(invalid_items) {
|
||||
test_invalid_item("ipv6::");
|
||||
test_invalid_item("ipv6:ipv6");
|
||||
test_invalid_item("ipv6:icmp");
|
||||
test_invalid_item("ipv6:tcp:0");
|
||||
test_invalid_item("65536");
|
||||
test_invalid_item("0-65535");
|
||||
test_invalid_item("ipv6:tcp:6666-6665");
|
||||
test_invalid_item("ipv6:tcp:6666-100000");
|
||||
test_invalid_item("ipv6::6666");
|
||||
|
||||
Reference in New Issue
Block a user