fragment: add ip protocol to SocketBind{Allow|Deny}=

Add ip protocol token to SocketBind{Allow|Deny}= property parser.

Use parse_socket_bind_item helper.

Replace int32_t with int in cgroup item for socket-bind as it was
requested in [0].

Update tests.

[0] https://github.com/systemd/systemd/pull/19942#discussion_r652150024
This commit is contained in:
Julia Kartseva
2021-06-30 00:36:33 -07:00
parent 8bd095aa9a
commit 5587ce7f6c
4 changed files with 25 additions and 44 deletions
+12 -5
View File
@@ -20,6 +20,7 @@
#include "fileio.h"
#include "fs-util.h"
#include "io-util.h"
#include "ip-protocol-list.h"
#include "limits-util.h"
#include "nulstr-util.h"
#include "parse-util.h"
@@ -593,18 +594,24 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
}
void cgroup_context_dump_socket_bind_item(const CGroupSocketBindItem *item, FILE *f) {
const char *family, *colon;
const char *family, *colon1, *protocol = "", *colon2 = "";
family = strempty(af_to_ipv4_ipv6(item->address_family));
colon = isempty(family) ? "" : ":";
colon1 = isempty(family) ? "" : ":";
if (item->ip_protocol != 0) {
protocol = ip_protocol_to_tcp_udp(item->ip_protocol);
colon2 = ":";
}
if (item->nr_ports == 0)
fprintf(f, " %s%sany", family, colon);
fprintf(f, " %s%s%s%sany", family, colon1, protocol, colon2);
else if (item->nr_ports == 1)
fprintf(f, " %s%s%" PRIu16, family, colon, item->port_min);
fprintf(f, " %s%s%s%s%" PRIu16, family, colon1, protocol, colon2, item->port_min);
else {
uint16_t port_max = item->port_min + item->nr_ports - 1;
fprintf(f, " %s%s%" PRIu16 "-%" PRIu16, family, colon, item->port_min, port_max);
fprintf(f, " %s%s%s%s%" PRIu16 "-%" PRIu16, family, colon1, protocol, colon2,
item->port_min, port_max);
}
}
+2 -2
View File
@@ -104,8 +104,8 @@ struct CGroupBPFForeignProgram {
struct CGroupSocketBindItem {
LIST_FIELDS(CGroupSocketBindItem, socket_bind_items);
int32_t address_family;
int32_t ip_protocol;
int address_family;
int ip_protocol;
uint16_t nr_ports;
uint16_t port_min;
};
+6 -37
View File
@@ -47,6 +47,7 @@
#include "log.h"
#include "mountpoint-util.h"
#include "nulstr-util.h"
#include "parse-socket-bind-item.h"
#include "parse-util.h"
#include "path-util.h"
#include "percent-util.h"
@@ -5633,62 +5634,30 @@ int config_parse_cgroup_socket_bind(
void *data,
void *userdata) {
_cleanup_free_ CGroupSocketBindItem *item = NULL;
const char *user_port;
uint16_t nr_ports = 0, port_min = 0;
CGroupSocketBindItem **head = data;
_cleanup_free_ char *word = NULL;
int af, r;
uint16_t nr_ports, port_min;
int af, ip_protocol, r;
if (isempty(rvalue)) {
cgroup_context_remove_socket_bind(head);
return 0;
}
r = extract_first_word(&rvalue, &word, ":", 0);
r = parse_socket_bind_item(rvalue, &af, &ip_protocol, &nr_ports, &port_min);
if (r == -ENOMEM)
return log_oom();
if (r <= 0) {
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Unable to parse %s= assignment, ignoring: %s", lvalue, rvalue);
return 0;
}
if (rvalue) {
af = af_from_ipv4_ipv6(word);
if (af == AF_UNSPEC) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Only \"ipv4\" and \"ipv6\" protocols are supported, ignoring.");
return 0;
}
user_port = rvalue;
} else {
af = AF_UNSPEC;
user_port = word;
}
if (!streq(user_port, "any")) {
uint16_t port_max;
r = parse_ip_port_range(user_port, &port_min, &port_max);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid port or port range, ignoring: %m");
return 0;
}
nr_ports = 1 + port_max - port_min;
}
item = new(CGroupSocketBindItem, 1);
if (!item)
return log_oom();
*item = (CGroupSocketBindItem) {
.address_family = af,
/* No ip protocol specified for now. */
.ip_protocol = 0,
.ip_protocol = ip_protocol,
.nr_ports = nr_ports,
.port_min = port_min,
};
+5
View File
@@ -146,6 +146,11 @@ int main(int argc, char *argv[]) {
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "6666", STRV_MAKE("6667", "6668", ""), STRV_MAKE("any")) >= 0);
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "7777", STRV_MAKE_EMPTY, STRV_MAKE_EMPTY) >= 0);
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "8888", STRV_MAKE("any"), STRV_MAKE("any")) >= 0);
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "8888", STRV_MAKE("ipv6:tcp:8888-8889"), STRV_MAKE("any")) >= 0);
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "10000", STRV_MAKE("ipv6:udp:9999-10000"), STRV_MAKE("any")) >= 0);
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "6666", STRV_MAKE("ipv4:tcp:6666"), STRV_MAKE("any")) >= 0);
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "6666", STRV_MAKE("ipv4:udp:6666"), STRV_MAKE("any")) >= 0);
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "6666", STRV_MAKE("tcp:6666"), STRV_MAKE("any")) >= 0);
return 0;
}