From: Julia Kartseva Date: Tue, 15 Jun 2021 02:14:14 +0000 (-0700) Subject: fragment: add ip protocol to SocketBind{Allow|Deny}= X-Git-Tag: v249-rc3~23^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5587ce7f6ca83b5ae08ad2a73a2b96392b261e9a;p=thirdparty%2Fsystemd.git 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 --- diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 3cec8a57863..1dc5a5b0349 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -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); } } diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 526f056d1e8..ea929368cbd 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -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; }; diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index b0f24695409..87dfe5d1b0f 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -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, }; diff --git a/src/test/test-socket-bind.c b/src/test/test-socket-bind.c index 996aeebbcc5..989172eee3b 100644 --- a/src/test/test-socket-bind.c +++ b/src/test/test-socket-bind.c @@ -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; }