From 70ab0c67fc915eccf3fb068cbeb02c54cdc5d032 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 15 May 2024 08:36:02 +0000 Subject: [PATCH] Import from AlmaLinux stable repository --- .gitignore | 2 +- .passt.metadata | 2 +- ...op-user_namespace-create-allow-rules.patch | 52 ++++ ...-host-resolver-to-forward-DNS-querie.patch | 47 ---- ...onf-Split-add_dns-4-6-out-of-get_dns.patch | 129 ---------- ...ny-loopback-address-to-be-used-as-re.patch | 119 --------- ...et-rid-of-false-positive-CWE-394-Cov.patch | 130 ---------- ...but-convoluted-positive-Coverity-CWE.patch | 39 --- ...tical-resource-leak-CWE-772-Coverity.patch | 35 --- ...initions-of-SOCKET_MAX-TCP_MAX_CONNS.patch | 84 ------ ...Fix-and-suppress-ShellCheck-warnings.patch | 44 ---- ...Drop-duplicate-init_daemon_domain-ru.patch | 29 --- ...Let-passt-write-to-stdout-and-stderr.patch | 33 --- ...Allow-binding-and-connecting-to-all-.patch | 78 ------ ...Let-interface-users-set-paths-for-lo.patch | 65 ----- ...s-socket-creation-errors-all-the-way.patch | 243 ------------------ ...ial-success-return-codes-in-tcp-udp-.patch | 139 ---------- ...n-EMFILE-or-ENFILE-on-sockets-for-po.patch | 112 -------- ...lue-when-queueing-data-to-tap-also-f.patch | 129 ---------- ...Drop-example-from-headers-this-is-th.patch | 98 ------- ...Drop-unused-passt_read_data-interfac.patch | 34 --- ...x-Split-interfaces-into-smaller-bits.patch | 120 --------- SPECS/passt.spec | 70 +++-- 23 files changed, 98 insertions(+), 1735 deletions(-) create mode 100644 SOURCES/0001-selinux-Drop-user_namespace-create-allow-rules.patch delete mode 100644 SOURCES/0001-udp-Actually-use-host-resolver-to-forward-DNS-querie.patch delete mode 100644 SOURCES/0002-conf-Split-add_dns-4-6-out-of-get_dns.patch delete mode 100644 SOURCES/0003-conf-udp-Allow-any-loopback-address-to-be-used-as-re.patch delete mode 100644 SOURCES/0004-tcp-tcp_splice-Get-rid-of-false-positive-CWE-394-Cov.patch delete mode 100644 SOURCES/0005-tcp-Avoid-false-but-convoluted-positive-Coverity-CWE.patch delete mode 100644 SOURCES/0006-tcp-Avoid-theoretical-resource-leak-CWE-772-Coverity.patch delete mode 100644 SOURCES/0007-Fix-definitions-of-SOCKET_MAX-TCP_MAX_CONNS.patch delete mode 100644 SOURCES/0008-doc-demo-Fix-and-suppress-ShellCheck-warnings.patch delete mode 100644 SOURCES/0009-contrib-selinux-Drop-duplicate-init_daemon_domain-ru.patch delete mode 100644 SOURCES/0010-contrib-selinux-Let-passt-write-to-stdout-and-stderr.patch delete mode 100644 SOURCES/0011-contrib-selinux-Allow-binding-and-connecting-to-all-.patch delete mode 100644 SOURCES/0012-contrib-selinux-Let-interface-users-set-paths-for-lo.patch delete mode 100644 SOURCES/0013-tcp-udp-util-Pass-socket-creation-errors-all-the-way.patch delete mode 100644 SOURCES/0014-tcp-udp-Fix-partial-success-return-codes-in-tcp-udp-.patch delete mode 100644 SOURCES/0015-conf-Terminate-on-EMFILE-or-ENFILE-on-sockets-for-po.patch delete mode 100644 SOURCES/0016-tcp-Clamp-MSS-value-when-queueing-data-to-tap-also-f.patch delete mode 100644 SOURCES/0017-contrib-selinux-Drop-example-from-headers-this-is-th.patch delete mode 100644 SOURCES/0018-contrib-selinux-Drop-unused-passt_read_data-interfac.patch delete mode 100644 SOURCES/0019-contrib-selinux-Split-interfaces-into-smaller-bits.patch diff --git a/.gitignore b/.gitignore index 58e8109..4e7f596 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/passt-4ddbcb9c0c555838b123c018a9ebc9b7e14a87e5.tar.xz +SOURCES/passt-b86afe3559c0bd3d24bc6fed7c60466cf141224c.tar.xz diff --git a/.passt.metadata b/.passt.metadata index 2092824..cca99da 100644 --- a/.passt.metadata +++ b/.passt.metadata @@ -1 +1 @@ -f0d7edae2c421217fd15a72ce7b552656ce4ed16 SOURCES/passt-4ddbcb9c0c555838b123c018a9ebc9b7e14a87e5.tar.xz +833dc4cee84bf49eb54354f5da5ae07748ce2969 SOURCES/passt-b86afe3559c0bd3d24bc6fed7c60466cf141224c.tar.xz diff --git a/SOURCES/0001-selinux-Drop-user_namespace-create-allow-rules.patch b/SOURCES/0001-selinux-Drop-user_namespace-create-allow-rules.patch new file mode 100644 index 0000000..4cac1f7 --- /dev/null +++ b/SOURCES/0001-selinux-Drop-user_namespace-create-allow-rules.patch @@ -0,0 +1,52 @@ +From 6977619743bbc602a865f79562b59a80921d6063 Mon Sep 17 00:00:00 2001 +From: Stefano Brivio +Date: Mon, 21 Aug 2023 17:52:28 +0200 +Subject: [PATCH] selinux: Drop user_namespace create allow rules + +Those are incompatible with current el9 kernels. I introduced them +upstream with commit 62059058cf24 ("selinux: Fix user namespace +creation after breaking kernel change"), in turn as a result of +kernel commit ed5d44d42c95 ("selinux: Implement userns_create hook"), +but on current el9 kernels (which lack the hook) they result in +failures such as: + + Failed to resolve allow statement at /var/lib/selinux/targeted/tmp/modules/200/passt/cil:103 + Failed to resolve AST + /usr/sbin/semodule: Failed! + Failed to resolve allow statement at /var/lib/selinux/targeted/tmp/modules/200/pasta/cil:104 + Failed to resolve AST + /usr/sbin/semodule: Failed! + +Signed-off-by: Stefano Brivio +--- + contrib/selinux/passt.te | 1 - + contrib/selinux/pasta.te | 1 - + 2 files changed, 2 deletions(-) + +diff --git a/contrib/selinux/passt.te b/contrib/selinux/passt.te +index facc2d1..de10f45 100644 +--- a/contrib/selinux/passt.te ++++ b/contrib/selinux/passt.te +@@ -93,7 +93,6 @@ allow syslogd_t self:cap_userns sys_ptrace; + allow passt_t self:process setcap; + allow passt_t self:capability { sys_tty_config setpcap net_bind_service setuid setgid}; + allow passt_t self:cap_userns { setpcap sys_admin sys_ptrace }; +-allow passt_t self:user_namespace create; + + allow passt_t passwd_file_t:file read_file_perms; + sssd_search_lib(passt_t) +diff --git a/contrib/selinux/pasta.te b/contrib/selinux/pasta.te +index ed70c5f..3226e37 100644 +--- a/contrib/selinux/pasta.te ++++ b/contrib/selinux/pasta.te +@@ -113,7 +113,6 @@ init_daemon_domain(pasta_t, pasta_exec_t) + + allow pasta_t self:capability { setpcap net_bind_service sys_tty_config dac_read_search net_admin sys_resource setuid setgid }; + allow pasta_t self:cap_userns { setpcap sys_admin sys_ptrace net_admin net_bind_service }; +-allow pasta_t self:user_namespace create; + + allow pasta_t passwd_file_t:file read_file_perms; + sssd_search_lib(pasta_t) +-- +2.39.2 + diff --git a/SOURCES/0001-udp-Actually-use-host-resolver-to-forward-DNS-querie.patch b/SOURCES/0001-udp-Actually-use-host-resolver-to-forward-DNS-querie.patch deleted file mode 100644 index ced20f9..0000000 --- a/SOURCES/0001-udp-Actually-use-host-resolver-to-forward-DNS-querie.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0dfc25b917f7e94ac56ea4285a5d394305787b06 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Thu, 23 Feb 2023 12:21:29 +0000 -Subject: [PATCH 01/20] udp: Actually use host resolver to forward DNS queries - -Instead of the address of the first resolver we advertise to -the guest or namespace. - -This was one of the intentions behind commit 3a2afde87dd1 ("conf, -udp: Drop mostly duplicated dns_send arrays, rename related fields"), -but I forgot to implement this part. In practice, they are usually -the same thing, unless /etc/resolv.conf points to a loopback address. - -Fixes: 3a2afde87dd1 ("conf, udp: Drop mostly duplicated dns_send arrays, rename related fields") -Signed-off-by: Stefano Brivio -Tested-by: Andrea Bolognani -Reviewed-by: David Gibson -(cherry picked from commit ddf7097a718095e879428667f2d56ec7d4f027e5) ---- - udp.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/udp.c b/udp.c -index c913d27..1d65559 100644 ---- a/udp.c -+++ b/udp.c -@@ -867,7 +867,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, - } else if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, - &c->ip4.dns_match) && - ntohs(s_in.sin_port) == 53) { -- s_in.sin_addr = c->ip4.dns[0]; -+ s_in.sin_addr = c->ip4.dns_host; - } - } else { - s_in6 = (struct sockaddr_in6) { -@@ -890,7 +890,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, - s_in6.sin6_addr = c->ip6.addr_seen; - } else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_match) && - ntohs(s_in6.sin6_port) == 53) { -- s_in6.sin6_addr = c->ip6.dns[0]; -+ s_in6.sin6_addr = c->ip6.dns_host; - } else if (IN6_IS_ADDR_LINKLOCAL(&s_in6.sin6_addr)) { - bind_addr = &c->ip6.addr_ll; - } --- -2.39.2 - diff --git a/SOURCES/0002-conf-Split-add_dns-4-6-out-of-get_dns.patch b/SOURCES/0002-conf-Split-add_dns-4-6-out-of-get_dns.patch deleted file mode 100644 index 9b0d1c4..0000000 --- a/SOURCES/0002-conf-Split-add_dns-4-6-out-of-get_dns.patch +++ /dev/null @@ -1,129 +0,0 @@ -From bf19154051b6c920f702c8394cd6821bb00f531a Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Thu, 23 Feb 2023 13:32:30 +0000 -Subject: [PATCH 02/20] conf: Split add_dns{4,6}() out of get_dns() - -The logic handling which resolvers we add, and whether to add them, -is getting rather cramped in get_dns(): split it into separate -functions. - -No functional changes intended. - -Signed-off-by: Stefano Brivio -Tested-by: Andrea Bolognani -Reviewed-by: David Gibson -(cherry picked from commit 8ca907a3f0a095691cdaf56ad610fd802df88146) ---- - conf.c | 86 ++++++++++++++++++++++++++++++++++------------------------ - 1 file changed, 51 insertions(+), 35 deletions(-) - -diff --git a/conf.c b/conf.c -index 4dc0660..ed25e35 100644 ---- a/conf.c -+++ b/conf.c -@@ -382,6 +382,53 @@ bind_fail: - die("Failed to bind any port for '-%c %s', exiting", optname, optarg); - } - -+/** -+ * add_dns4() - Possibly add the IPv4 address of a DNS resolver to configuration -+ * @c: Execution context -+ * @addr: Address found in /etc/resolv.conf -+ * @conf: Pointer to reference of current entry in array of IPv4 resolvers -+ */ -+static void add_dns4(struct ctx *c, struct in_addr *addr, struct in_addr **conf) -+{ -+ /* Guest or container can only access local addresses via redirect */ -+ if (IN4_IS_ADDR_LOOPBACK(addr)) { -+ if (!c->no_map_gw) { -+ **conf = c->ip4.gw; -+ (*conf)++; -+ } -+ } else { -+ **conf = *addr; -+ (*conf)++; -+ } -+ -+ if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_host)) -+ c->ip4.dns_host = *addr; -+} -+ -+/** -+ * add_dns6() - Possibly add the IPv6 address of a DNS resolver to configuration -+ * @c: Execution context -+ * @addr: Address found in /etc/resolv.conf -+ * @conf: Pointer to reference of current entry in array of IPv6 resolvers -+ */ -+static void add_dns6(struct ctx *c, -+ struct in6_addr *addr, struct in6_addr **conf) -+{ -+ /* Guest or container can only access local addresses via redirect */ -+ if (IN6_IS_ADDR_LOOPBACK(addr)) { -+ if (!c->no_map_gw) { -+ memcpy(*conf, &c->ip6.gw, sizeof(**conf)); -+ (*conf)++; -+ } -+ } else { -+ memcpy(*conf, addr, sizeof(**conf)); -+ (*conf)++; -+ } -+ -+ if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_host)) -+ c->ip6.dns_host = *addr; -+} -+ - /** - * get_dns() - Get nameserver addresses from local /etc/resolv.conf - * @c: Execution context -@@ -420,44 +467,13 @@ static void get_dns(struct ctx *c) - - if (!dns4_set && - dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) - 1 -- && inet_pton(AF_INET, p + 1, &dns4_tmp)) { -- /* Guest or container can only access local -- * addresses via local redirect -- */ -- if (IN4_IS_ADDR_LOOPBACK(&dns4_tmp)) { -- if (!c->no_map_gw) { -- *dns4 = c->ip4.gw; -- dns4++; -- } -- } else { -- *dns4 = dns4_tmp; -- dns4++; -- } -- -- if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_host)) -- c->ip4.dns_host = dns4_tmp; -- } -+ && inet_pton(AF_INET, p + 1, &dns4_tmp)) -+ add_dns4(c, &dns4_tmp, &dns4); - - if (!dns6_set && - dns6 - &c->ip6.dns[0] < ARRAY_SIZE(c->ip6.dns) - 1 -- && inet_pton(AF_INET6, p + 1, &dns6_tmp)) { -- /* Guest or container can only access local -- * addresses via local redirect -- */ -- if (IN6_IS_ADDR_LOOPBACK(&dns6_tmp)) { -- if (!c->no_map_gw) { -- memcpy(dns6, &c->ip6.gw, -- sizeof(*dns6)); -- dns6++; -- } -- } else { -- memcpy(dns6, &dns6_tmp, sizeof(*dns6)); -- dns6++; -- } -- -- if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_host)) -- c->ip6.dns_host = dns6_tmp; -- } -+ && inet_pton(AF_INET6, p + 1, &dns6_tmp)) -+ add_dns6(c, &dns6_tmp, &dns6); - } else if (!dnss_set && strstr(line, "search ") == line && - s == c->dns_search) { - end = strpbrk(line, "\n"); --- -2.39.2 - diff --git a/SOURCES/0003-conf-udp-Allow-any-loopback-address-to-be-used-as-re.patch b/SOURCES/0003-conf-udp-Allow-any-loopback-address-to-be-used-as-re.patch deleted file mode 100644 index a98f0ac..0000000 --- a/SOURCES/0003-conf-udp-Allow-any-loopback-address-to-be-used-as-re.patch +++ /dev/null @@ -1,119 +0,0 @@ -From ae0004f591d816f1b6e78c57c3d9530098f123b0 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Thu, 23 Feb 2023 16:41:47 +0000 -Subject: [PATCH 03/20] conf, udp: Allow any loopback address to be used as - resolver - -Andrea reports that with a Fedora 37 guest running on a Fedora 37 -host, both using systemd-resolved, with passt connecting them, -running with default options, DNS queries don't work. - -systemd-resolved on the host is reachable only at the loopback -address 127.0.0.53. - -We advertise the default gateway address to the guest as resolver, -because our local address is of course unreachable from there, which -means we see DNS queries directed to the default gateway, and we -redirect them to 127.0.0.1. However, systemd-resolved doesn't answer -on 127.0.0.1. - -To fix this, set @dns_match to the address of the default gateway, -unless a different resolver address is explicitly configured, so that -we know we explicitly have to map DNS queries, in this case, to the -address of the local resolver. - -This means that in udp_tap_handler() we need to check, first, if -the destination address of packets matches @dns_match: even if it's -the address of the local gateway, we want to map that to a specific -address, which isn't necessarily 127.0.0.1. - -Do the same for IPv6 for consistency, even though IPv6 defines a -single loopback address. - -Reported-by: Andrea Bolognani -Signed-off-by: Stefano Brivio -Tested-by: Andrea Bolognani -Reviewed-by: David Gibson -(cherry picked from commit bad252687271c0255f6a077f19cbc19aa0427f8d) ---- - conf.c | 6 ++++++ - udp.c | 20 ++++++++++---------- - 2 files changed, 16 insertions(+), 10 deletions(-) - -diff --git a/conf.c b/conf.c -index ed25e35..37f25d6 100644 ---- a/conf.c -+++ b/conf.c -@@ -395,6 +395,9 @@ static void add_dns4(struct ctx *c, struct in_addr *addr, struct in_addr **conf) - if (!c->no_map_gw) { - **conf = c->ip4.gw; - (*conf)++; -+ -+ if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match)) -+ c->ip4.dns_match = c->ip4.gw; - } - } else { - **conf = *addr; -@@ -419,6 +422,9 @@ static void add_dns6(struct ctx *c, - if (!c->no_map_gw) { - memcpy(*conf, &c->ip6.gw, sizeof(**conf)); - (*conf)++; -+ -+ if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match)) -+ memcpy(&c->ip6.dns_match, addr, sizeof(*addr)); - } - } else { - memcpy(*conf, addr, sizeof(**conf)); -diff --git a/udp.c b/udp.c -index 1d65559..20a9ea0 100644 ---- a/udp.c -+++ b/udp.c -@@ -857,17 +857,16 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, - - udp_tap_map[V4][src].ts = now->tv_sec; - -- if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.gw) && -- !c->no_map_gw) { -+ if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.dns_match) && -+ ntohs(s_in.sin_port) == 53) { -+ s_in.sin_addr = c->ip4.dns_host; -+ } else if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.gw) && -+ !c->no_map_gw) { - if (!(udp_tap_map[V4][dst].flags & PORT_LOCAL) || - (udp_tap_map[V4][dst].flags & PORT_LOOPBACK)) - s_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - else - s_in.sin_addr = c->ip4.addr_seen; -- } else if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, -- &c->ip4.dns_match) && -- ntohs(s_in.sin_port) == 53) { -- s_in.sin_addr = c->ip4.dns_host; - } - } else { - s_in6 = (struct sockaddr_in6) { -@@ -880,7 +879,11 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, - sa = (struct sockaddr *)&s_in6; - sl = sizeof(s_in6); - -- if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.gw) && !c->no_map_gw) { -+ if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_match) && -+ ntohs(s_in6.sin6_port) == 53) { -+ s_in6.sin6_addr = c->ip6.dns_host; -+ } else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.gw) && -+ !c->no_map_gw) { - if (!(udp_tap_map[V6][dst].flags & PORT_LOCAL) || - (udp_tap_map[V6][dst].flags & PORT_LOOPBACK)) - s_in6.sin6_addr = in6addr_loopback; -@@ -888,9 +891,6 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, - s_in6.sin6_addr = c->ip6.addr; - else - s_in6.sin6_addr = c->ip6.addr_seen; -- } else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_match) && -- ntohs(s_in6.sin6_port) == 53) { -- s_in6.sin6_addr = c->ip6.dns_host; - } else if (IN6_IS_ADDR_LINKLOCAL(&s_in6.sin6_addr)) { - bind_addr = &c->ip6.addr_ll; - } --- -2.39.2 - diff --git a/SOURCES/0004-tcp-tcp_splice-Get-rid-of-false-positive-CWE-394-Cov.patch b/SOURCES/0004-tcp-tcp_splice-Get-rid-of-false-positive-CWE-394-Cov.patch deleted file mode 100644 index 5ab1eab..0000000 --- a/SOURCES/0004-tcp-tcp_splice-Get-rid-of-false-positive-CWE-394-Cov.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 850bb9c15d39dcbefb0849955f4f09382f587c20 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Mon, 27 Feb 2023 02:45:42 +0100 -Subject: [PATCH 04/20] tcp, tcp_splice: Get rid of false positive CWE-394 - Coverity warning from fls() - -We use the return value of fls() as array index for debug strings. - -While fls() can return -1 (if no bit is set), Coverity Scan doesn't -see that we're first checking the return value of another fls() call -with the same bitmask, before using it. - -Call fls() once, store its return value, check it, and use the stored -value as array index. - -Signed-off-by: Stefano Brivio -Reviewed-by: David Gibson -(cherry picked from commit 5474bc5485d814acae19961f9a9cd4b541722a5e) ---- - tcp.c | 12 ++++++++---- - tcp_splice.c | 24 ++++++++++++++++-------- - 2 files changed, 24 insertions(+), 12 deletions(-) - -diff --git a/tcp.c b/tcp.c -index 803c2c4..c62fe44 100644 ---- a/tcp.c -+++ b/tcp.c -@@ -743,15 +743,19 @@ static void conn_flag_do(const struct ctx *c, struct tcp_tap_conn *conn, - unsigned long flag) - { - if (flag & (flag - 1)) { -+ int flag_index = fls(~flag); -+ - if (!(conn->flags & ~flag)) - return; - - conn->flags &= flag; -- if (fls(~flag) >= 0) { -+ if (flag_index >= 0) { - debug("TCP: index %li: %s dropped", CONN_IDX(conn), -- tcp_flag_str[fls(~flag)]); -+ tcp_flag_str[flag_index]); - } - } else { -+ int flag_index = fls(~flag); -+ - if (conn->flags & flag) { - /* Special case: setting ACK_FROM_TAP_DUE on a - * connection where it's already set is used to -@@ -766,9 +770,9 @@ static void conn_flag_do(const struct ctx *c, struct tcp_tap_conn *conn, - } - - conn->flags |= flag; -- if (fls(flag) >= 0) { -+ if (flag_index >= 0) { - debug("TCP: index %li: %s", CONN_IDX(conn), -- tcp_flag_str[fls(flag)]); -+ tcp_flag_str[flag_index]); - } - } - -diff --git a/tcp_splice.c b/tcp_splice.c -index 84f855e..67af46b 100644 ---- a/tcp_splice.c -+++ b/tcp_splice.c -@@ -127,22 +127,26 @@ static void conn_flag_do(const struct ctx *c, struct tcp_splice_conn *conn, - unsigned long flag) - { - if (flag & (flag - 1)) { -+ int flag_index = fls(~flag); -+ - if (!(conn->flags & ~flag)) - return; - - conn->flags &= flag; -- if (fls(~flag) >= 0) { -+ if (flag_index >= 0) { - debug("TCP (spliced): index %li: %s dropped", CONN_IDX(conn), -- tcp_splice_flag_str[fls(~flag)]); -+ tcp_splice_flag_str[flag_index]); - } - } else { -+ int flag_index = fls(flag); -+ - if (conn->flags & flag) - return; - - conn->flags |= flag; -- if (fls(flag) >= 0) { -+ if (flag_index >= 0) { - debug("TCP (spliced): index %li: %s", CONN_IDX(conn), -- tcp_splice_flag_str[fls(flag)]); -+ tcp_splice_flag_str[flag_index]); - } - } - -@@ -207,22 +211,26 @@ static void conn_event_do(const struct ctx *c, struct tcp_splice_conn *conn, - unsigned long event) - { - if (event & (event - 1)) { -+ int flag_index = fls(~event); -+ - if (!(conn->events & ~event)) - return; - - conn->events &= event; -- if (fls(~event) >= 0) { -+ if (flag_index >= 0) { - debug("TCP (spliced): index %li, ~%s", CONN_IDX(conn), -- tcp_splice_event_str[fls(~event)]); -+ tcp_splice_event_str[flag_index]); - } - } else { -+ int flag_index = fls(event); -+ - if (conn->events & event) - return; - - conn->events |= event; -- if (fls(event) >= 0) { -+ if (flag_index >= 0) { - debug("TCP (spliced): index %li, %s", CONN_IDX(conn), -- tcp_splice_event_str[fls(event)]); -+ tcp_splice_event_str[flag_index]); - } - } - --- -2.39.2 - diff --git a/SOURCES/0005-tcp-Avoid-false-but-convoluted-positive-Coverity-CWE.patch b/SOURCES/0005-tcp-Avoid-false-but-convoluted-positive-Coverity-CWE.patch deleted file mode 100644 index f474163..0000000 --- a/SOURCES/0005-tcp-Avoid-false-but-convoluted-positive-Coverity-CWE.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 65d8d329620973319b577e9a1b0ffad528a4df1f Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Mon, 27 Feb 2023 03:05:26 +0100 -Subject: [PATCH 05/20] tcp: Avoid false (but convoluted) positive Coverity - CWE-476 warning - -If there are no TCP options in the header, tcp_tap_handler() will -pass the corresponding pointer, fetched via packet_get(), as NULL to -tcp_conn_from_sock_finish(), which in turn indirectly calls -tcp_opt_get(). - -If there are no options, tcp_opt_get() will stop right away because -the option length is indicated as zero. However, if the logic is -complicated enough to follow for static checkers, adding an explicit -check against NULL in tcp_opt_get() is probably a good idea. - -Signed-off-by: Stefano Brivio -Reviewed-by: David Gibson -(cherry picked from commit a1d5537741679c117b4c1a9b736ea2540a976eee) ---- - tcp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tcp.c b/tcp.c -index c62fe44..a811b5e 100644 ---- a/tcp.c -+++ b/tcp.c -@@ -1114,7 +1114,7 @@ static int tcp_opt_get(const char *opts, size_t len, uint8_t type_find, - { - uint8_t type, optlen; - -- if (!len) -+ if (!opts || !len) - return -1; - - for (; len >= 2; opts += optlen, len -= optlen) { --- -2.39.2 - diff --git a/SOURCES/0006-tcp-Avoid-theoretical-resource-leak-CWE-772-Coverity.patch b/SOURCES/0006-tcp-Avoid-theoretical-resource-leak-CWE-772-Coverity.patch deleted file mode 100644 index a258843..0000000 --- a/SOURCES/0006-tcp-Avoid-theoretical-resource-leak-CWE-772-Coverity.patch +++ /dev/null @@ -1,35 +0,0 @@ -From cd950e6b7f85f4f8f80284ba79a027dee57bfa61 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Mon, 27 Feb 2023 03:13:31 +0100 -Subject: [PATCH 06/20] tcp: Avoid (theoretical) resource leak (CWE-772) - Coverity warning - -If tcp_timer_ctl() gets a socket number greater than SOCKET_MAX -(2 ^ 24), we return error but we don't close the socket. This is a -rather formal issue given that, at least on Linux, socket numbers are -monotonic and we're in general not allowed to open so many sockets. - -Signed-off-by: Stefano Brivio -Reviewed-by: David Gibson -(cherry picked from commit 4f523c3276741781346478328f863e60f30cba8e) ---- - tcp.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/tcp.c b/tcp.c -index a811b5e..fe6e458 100644 ---- a/tcp.c -+++ b/tcp.c -@@ -702,6 +702,9 @@ static void tcp_timer_ctl(const struct ctx *c, struct tcp_tap_conn *conn) - fd = timerfd_create(CLOCK_MONOTONIC, 0); - if (fd == -1 || fd > SOCKET_MAX) { - debug("TCP: failed to get timer: %s", strerror(errno)); -+ if (fd > -1) -+ close(fd); -+ conn->timer = -1; - return; - } - conn->timer = fd; --- -2.39.2 - diff --git a/SOURCES/0007-Fix-definitions-of-SOCKET_MAX-TCP_MAX_CONNS.patch b/SOURCES/0007-Fix-definitions-of-SOCKET_MAX-TCP_MAX_CONNS.patch deleted file mode 100644 index e0fa3e0..0000000 --- a/SOURCES/0007-Fix-definitions-of-SOCKET_MAX-TCP_MAX_CONNS.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 44d35498a98da3d3234b0084033f6dcd6450e22b Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Mon, 27 Feb 2023 03:30:01 +0100 -Subject: [PATCH 07/20] Fix definitions of SOCKET_MAX, TCP_MAX_CONNS - -...and, given that I keep getting this wrong, add a convenience -macro, MAX_FROM_BITS(). - -Signed-off-by: Stefano Brivio -Reviewed-by: David Gibson -(cherry picked from commit 26a0e4d6ee17fa174a401d8e8d9a4c189f11f258) ---- - passt.h | 4 ++-- - tcp.h | 4 ++-- - tcp_conn.h | 2 +- - util.h | 2 ++ - 4 files changed, 7 insertions(+), 5 deletions(-) - -diff --git a/passt.h b/passt.h -index 3d7e567..e0383eb 100644 ---- a/passt.h -+++ b/passt.h -@@ -42,7 +42,7 @@ union epoll_ref; - /** - * union epoll_ref - Breakdown of reference for epoll socket bookkeeping - * @proto: IP protocol number -- * @s: Socket number (implies 2^24 limit on number of descriptors) -+ * @s: Socket number (implies 2^24-1 limit on number of descriptors) - * @tcp: TCP-specific reference part - * @udp: UDP-specific reference part - * @icmp: ICMP-specific reference part -@@ -53,7 +53,7 @@ union epoll_ref { - struct { - int32_t proto:8, - #define SOCKET_REF_BITS 24 --#define SOCKET_MAX (1 << SOCKET_REF_BITS) -+#define SOCKET_MAX MAX_FROM_BITS(SOCKET_REF_BITS) - s:SOCKET_REF_BITS; - union { - union tcp_epoll_ref tcp; -diff --git a/tcp.h b/tcp.h -index 5527c5b..36e5391 100644 ---- a/tcp.h -+++ b/tcp.h -@@ -8,8 +8,8 @@ - - #define TCP_TIMER_INTERVAL 1000 /* ms */ - --#define TCP_CONN_INDEX_BITS 17 /* 128k */ --#define TCP_MAX_CONNS (1 << TCP_CONN_INDEX_BITS) -+#define TCP_CONN_INDEX_BITS 17 /* 128k - 1 */ -+#define TCP_MAX_CONNS MAX_FROM_BITS(TCP_CONN_INDEX_BITS) - - struct ctx; - -diff --git a/tcp_conn.h b/tcp_conn.h -index a499f34..c22632b 100644 ---- a/tcp_conn.h -+++ b/tcp_conn.h -@@ -54,7 +54,7 @@ struct tcp_tap_conn { - - #define TCP_RETRANS_BITS 3 - unsigned int retrans :TCP_RETRANS_BITS; --#define TCP_MAX_RETRANS ((1U << TCP_RETRANS_BITS) - 1) -+#define TCP_MAX_RETRANS MAX_FROM_BITS(TCP_RETRANS_BITS) - - #define TCP_WS_BITS 4 /* RFC 7323 */ - #define TCP_WS_MAX 14 -diff --git a/util.h b/util.h -index 6303c17..570094c 100644 ---- a/util.h -+++ b/util.h -@@ -40,6 +40,8 @@ - #define ROUND_DOWN(x, y) ((x) & ~((y) - 1)) - #define ROUND_UP(x, y) (((x) + (y) - 1) & ~((y) - 1)) - -+#define MAX_FROM_BITS(n) ((int)((1U << (n)) - 1)) -+ - #define BIT(n) (1UL << (n)) - #define BITMAP_BIT(n) (BIT((n) % (sizeof(long) * 8))) - #define BITMAP_WORD(n) (n / (sizeof(long) * 8)) --- -2.39.2 - diff --git a/SOURCES/0008-doc-demo-Fix-and-suppress-ShellCheck-warnings.patch b/SOURCES/0008-doc-demo-Fix-and-suppress-ShellCheck-warnings.patch deleted file mode 100644 index 0f87d21..0000000 --- a/SOURCES/0008-doc-demo-Fix-and-suppress-ShellCheck-warnings.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 8d631f17e11d6c9f1c01eb0dc1cb104ac45e63ac Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Mon, 27 Feb 2023 03:44:25 +0100 -Subject: [PATCH 08/20] doc/demo: Fix and suppress ShellCheck warnings - -ShellCheck reports (SC2034) that __qemu_arch is not used. Use it, -and silence the resulting SC2086 warning as we want word splitting on -options we pass with it. - -While at it, silence SC2317 warnings for commands in cleanup() that -appear to be unreachable: cleanup() is only called as trap. - -Signed-off-by: Stefano Brivio -Reviewed-by: David Gibson -(cherry picked from commit fb05a713789fd9c20d0432f023ce26f3c5b94251) ---- - doc/demo.sh | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/doc/demo.sh b/doc/demo.sh -index ed71ffb..5b05ddf 100755 ---- a/doc/demo.sh -+++ b/doc/demo.sh -@@ -110,6 +110,7 @@ next() { - } - - # cleanup() - Terminate pasta and passt, clean up, restore TTY settings -+# shellcheck disable=SC2317 - cleanup() { - [ -f "${DEMO_DIR}/pasta.pid" ] && kill "$(cat "${DEMO_DIR}/pasta.pid")" - [ -f "${DEMO_DIR}/passt.pid" ] && kill "$(cat "${DEMO_DIR}/passt.pid")" -@@ -223,7 +224,8 @@ into_ns() { - echo "Use ^C to terminate it." - next - -- cmd qrap 5 qemu-system-x86_64 -M pc,accel=kvm:tcg \ -+ # shellcheck disable=SC2086 -+ cmd qrap 5 ${__qemu_arch} \ - -smp "$(nproc)" -m 1024 \ - -nographic -serial stdio -nodefaults -no-reboot -vga none \ - -initrd "${DEMO_DIR}/demo.img" \ --- -2.39.2 - diff --git a/SOURCES/0009-contrib-selinux-Drop-duplicate-init_daemon_domain-ru.patch b/SOURCES/0009-contrib-selinux-Drop-duplicate-init_daemon_domain-ru.patch deleted file mode 100644 index 5f7e274..0000000 --- a/SOURCES/0009-contrib-selinux-Drop-duplicate-init_daemon_domain-ru.patch +++ /dev/null @@ -1,29 +0,0 @@ -From bbeecf78cf598f24bd2f1434dfbb3fad7b549f59 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Mon, 6 Mar 2023 22:48:21 +0000 -Subject: [PATCH 09/20] contrib/selinux: Drop duplicate init_daemon_domain() - rule - -Signed-off-by: Stefano Brivio -Tested-by: Laine Stump -Reviewed-by: Laine Stump -(cherry picked from commit 009af75e450aae1d4e9e031a9e42a0e74ce1adf7) ---- - contrib/selinux/passt.te | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/contrib/selinux/passt.te b/contrib/selinux/passt.te -index 7fa4fb9..593b346 100644 ---- a/contrib/selinux/passt.te -+++ b/contrib/selinux/passt.te -@@ -57,7 +57,6 @@ type passt_t; - domain_type(passt_t); - type passt_exec_t; - files_type(passt_exec_t); --init_daemon_domain(passt_t, passt_exec_t) - type passt_log_t; - logging_log_file(passt_log_t); - type passt_etc_t; --- -2.39.2 - diff --git a/SOURCES/0010-contrib-selinux-Let-passt-write-to-stdout-and-stderr.patch b/SOURCES/0010-contrib-selinux-Let-passt-write-to-stdout-and-stderr.patch deleted file mode 100644 index 9f04dd4..0000000 --- a/SOURCES/0010-contrib-selinux-Let-passt-write-to-stdout-and-stderr.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 2fcc8f2b519facb139df5e412379f991d8322bf4 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Mon, 6 Mar 2023 22:49:39 +0000 -Subject: [PATCH 10/20] contrib/selinux: Let passt write to stdout and stderr - when it starts - -Otherwise, it's unusable as stand-alone tool, or in foreground mode, -and it's also impossible to get output from --help or --version, -because for SELinux it's just a daemon. - -Signed-off-by: Stefano Brivio -Tested-by: Laine Stump -Reviewed-by: Laine Stump -(cherry picked from commit 41bc669866b9e408d8d4966ee06e01784949b98d) ---- - contrib/selinux/passt.te | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/contrib/selinux/passt.te b/contrib/selinux/passt.te -index 593b346..6cd61f1 100644 ---- a/contrib/selinux/passt.te -+++ b/contrib/selinux/passt.te -@@ -72,6 +72,7 @@ type_transition unconfined_t passt_exec_t : process passt_t; - allow unconfined_t passt_t : process transition ; - - init_daemon_domain(passt_t, passt_exec_t) -+term_use_all_inherited_terms(passt_t) - - allow passt_t bin_t:file { execute execute_no_trans map }; - allow passt_t user_home_dir_t:dir { search add_name write }; --- -2.39.2 - diff --git a/SOURCES/0011-contrib-selinux-Allow-binding-and-connecting-to-all-.patch b/SOURCES/0011-contrib-selinux-Allow-binding-and-connecting-to-all-.patch deleted file mode 100644 index 36f68aa..0000000 --- a/SOURCES/0011-contrib-selinux-Allow-binding-and-connecting-to-all-.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 8cb64a237ed6183c492dea04da7c8d3ca064a155 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Mon, 6 Mar 2023 23:05:36 +0000 -Subject: [PATCH 11/20] contrib/selinux: Allow binding and connecting to all - UDP and TCP ports - -Laine reports that with a simple: - - - - - -in libvirt's domain XML, passt won't start as it fails to bind -arbitrary ports. That was actually the intention behind passt_port_t: -the user or system administrator should have explicitly configured -allowed ports on a given machine. But it's probably not realistic, so -just allow any port to be bound and forwarded. - -Also fix up some missing operations on sockets. - -Reported-by: Laine Stump -Signed-off-by: Stefano Brivio -Tested-by: Laine Stump -Reviewed-by: Laine Stump -(cherry picked from commit de9b0cb5fee2ea00ed7e7877ef9be8c446bca134) ---- - contrib/selinux/passt.te | 27 +++++++++++++++------------ - 1 file changed, 15 insertions(+), 12 deletions(-) - -diff --git a/contrib/selinux/passt.te b/contrib/selinux/passt.te -index 6cd61f1..438155d 100644 ---- a/contrib/selinux/passt.te -+++ b/contrib/selinux/passt.te -@@ -62,9 +62,6 @@ logging_log_file(passt_log_t); - type passt_etc_t; - files_config_file(passt_etc_t); - --type passt_port_t; --typeattribute passt_port_t port_type; -- - role unconfined_r types passt_t; - - allow passt_t passt_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ; -@@ -100,16 +97,22 @@ allow passt_t net_conf_t:lnk_file read; - allow passt_t tmp_t:sock_file { create unlink write }; - allow passt_t self:netlink_route_socket { bind create nlmsg_read read write setopt }; - --allow passt_t self:tcp_socket create_stream_socket_perms; --corenet_tcp_sendrecv_generic_node(passt_t) --corenet_tcp_bind_generic_node(passt_t) --allow passt_t passt_port_t:tcp_socket { name_bind name_connect }; --allow passt_t http_port_t:tcp_socket { name_bind name_connect }; --allow passt_t self:udp_socket create_stream_socket_perms; --corenet_udp_sendrecv_generic_node(passt_t) --corenet_udp_bind_generic_node(passt_t) --allow passt_t passt_port_t:udp_socket { name_bind }; -+corenet_tcp_bind_all_nodes(passt_t) -+corenet_udp_bind_all_nodes(passt_t) -+ -+corenet_tcp_bind_all_ports(passt_t) -+corenet_udp_bind_all_ports(passt_t) -+ -+corenet_tcp_connect_all_ports(passt_t) -+ -+corenet_tcp_sendrecv_all_ports(passt_t) -+corenet_udp_sendrecv_all_ports(passt_t) -+ - allow passt_t node_t:icmp_socket { name_bind node_bind }; -+allow passt_t port_t:icmp_socket name_bind; -+ -+allow passt_t self:tcp_socket { create getopt setopt connect bind listen accept shutdown read write }; -+allow passt_t self:udp_socket { create getopt setopt connect bind read write }; - allow passt_t self:icmp_socket { bind create setopt read write }; - - allow passt_t user_tmp_t:dir { add_name write }; --- -2.39.2 - diff --git a/SOURCES/0012-contrib-selinux-Let-interface-users-set-paths-for-lo.patch b/SOURCES/0012-contrib-selinux-Let-interface-users-set-paths-for-lo.patch deleted file mode 100644 index ee43f22..0000000 --- a/SOURCES/0012-contrib-selinux-Let-interface-users-set-paths-for-lo.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 7c01aa69bcd52197af708b9e08ce3067624288ef Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Mon, 6 Mar 2023 23:19:18 +0000 -Subject: [PATCH 12/20] contrib/selinux: Let interface users set paths for log, - PID, socket files - -Even libvirt itself will configure passt to write log, PID and socket -files to different locations depending on whether the domain is -started as root (/var/log/libvirt/...) or as a regular user -(/var/log//libvirt/...), and user_tmp_t would only cover the -latter. - -Create interfaces for log and PID files, so that callers can specify -different file contexts for those, and modify the interface for the -UNIX socket file to allow different paths as well. - -Signed-off-by: Stefano Brivio -Tested-by: Laine Stump -Reviewed-by: Laine Stump -(cherry picked from commit d361fe6e809bdf3539d764cfa5058f46ce51bcbf) ---- - contrib/selinux/passt.if | 26 +++++++++++++++++++++++++- - 1 file changed, 25 insertions(+), 1 deletion(-) - -diff --git a/contrib/selinux/passt.if b/contrib/selinux/passt.if -index 893395b..6a6105c 100644 ---- a/contrib/selinux/passt.if -+++ b/contrib/selinux/passt.if -@@ -30,8 +30,32 @@ interface(`passt_socket',` - type passt_t; - ') - -- allow $1 user_tmp_t:sock_file write; -+ allow $1 $2:sock_file write; - allow $1 passt_t:unix_stream_socket connectto; -+ -+ allow passt_t $2:sock_file { create read write unlink }; -+') -+ -+interface(`passt_logfile',` -+ gen_require(` -+ type passt_t; -+ ') -+ -+ logging_log_file($1); -+ allow passt_t $1:dir { search write add_name }; -+ allow passt_t $1:file { create open read write }; -+') -+ -+interface(`passt_pidfile',` -+ gen_require(` -+ type passt_t; -+ ') -+ -+ allow $1 $2:file { open read unlink }; -+ -+ files_pid_file($2); -+ allow passt_t $2:dir { search write add_name }; -+ allow passt_t $2:file { create open write }; - ') - - interface(`passt_kill',` --- -2.39.2 - diff --git a/SOURCES/0013-tcp-udp-util-Pass-socket-creation-errors-all-the-way.patch b/SOURCES/0013-tcp-udp-util-Pass-socket-creation-errors-all-the-way.patch deleted file mode 100644 index 71b7819..0000000 --- a/SOURCES/0013-tcp-udp-util-Pass-socket-creation-errors-all-the-way.patch +++ /dev/null @@ -1,243 +0,0 @@ -From 812d24c91aecff78369f32f6593045f24d578d38 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Wed, 8 Mar 2023 12:14:29 +0100 -Subject: [PATCH 13/20] tcp, udp, util: Pass socket creation errors all the way - up - -...starting from sock_l4(), pass negative error (errno) codes instead -of -1. They will only be used in two commits from now, no functional -changes intended here. - -Signed-off-by: Stefano Brivio -Reviewed-by: David Gibson -(cherry picked from commit 73992c42cea0df56f6ba0a3bef0f4a939f26ebad) ---- - tcp.c | 22 ++++++++++++---------- - udp.c | 18 +++++++++--------- - util.c | 31 ++++++++++++++++++------------- - 3 files changed, 39 insertions(+), 32 deletions(-) - -diff --git a/tcp.c b/tcp.c -index fe6e458..482c2f9 100644 ---- a/tcp.c -+++ b/tcp.c -@@ -2891,7 +2891,7 @@ void tcp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, - * @addr: Pointer to address for binding, NULL if not configured - * @ifname: Name of interface to bind to, NULL if not configured - * -- * Return: fd for the new listening socket, or -1 on failure -+ * Return: fd for the new listening socket, negative error code on failure - */ - static int tcp_sock_init_af(const struct ctx *c, int af, in_port_t port, - const struct in_addr *addr, const char *ifname) -@@ -2904,13 +2904,13 @@ static int tcp_sock_init_af(const struct ctx *c, int af, in_port_t port, - - if (c->tcp.fwd_in.mode == FWD_AUTO) { - if (af == AF_INET || af == AF_UNSPEC) -- tcp_sock_init_ext[port][V4] = s; -+ tcp_sock_init_ext[port][V4] = s < 0 ? -1 : s; - if (af == AF_INET6 || af == AF_UNSPEC) -- tcp_sock_init_ext[port][V6] = s; -+ tcp_sock_init_ext[port][V6] = s < 0 ? -1 : s; - } - - if (s < 0) -- return -1; -+ return s; - - tcp_sock_set_bufsize(c, s); - return s; -@@ -2924,12 +2924,12 @@ static int tcp_sock_init_af(const struct ctx *c, int af, in_port_t port, - * @ifname: Name of interface to bind to, NULL if not configured - * @port: Port, host order - * -- * Return: 0 on (partial) success, -1 on (complete) failure -+ * Return: 0 on (partial) success, negative error code on (complete) failure - */ - int tcp_sock_init(const struct ctx *c, sa_family_t af, const void *addr, - const char *ifname, in_port_t port) - { -- int ret = 0; -+ int ret = 0, af_ret; - - if (af == AF_UNSPEC && c->ifi4 && c->ifi6) - /* Attempt to get a dual stack socket */ -@@ -2938,13 +2938,15 @@ int tcp_sock_init(const struct ctx *c, sa_family_t af, const void *addr, - - /* Otherwise create a socket per IP version */ - if ((af == AF_INET || af == AF_UNSPEC) && c->ifi4) { -- if (tcp_sock_init_af(c, AF_INET, port, addr, ifname) < 0) -- ret = -1; -+ af_ret = tcp_sock_init_af(c, AF_INET, port, addr, ifname); -+ if (af_ret < 0) -+ ret = af_ret; - } - - if ((af == AF_INET6 || af == AF_UNSPEC) && c->ifi6) { -- if (tcp_sock_init_af(c, AF_INET6, port, addr, ifname) < 0) -- ret = -1; -+ af_ret = tcp_sock_init_af(c, AF_INET6, port, addr, ifname); -+ if (af_ret < 0) -+ ret = af_ret; - } - - return ret; -diff --git a/udp.c b/udp.c -index 20a9ea0..9a43835 100644 ---- a/udp.c -+++ b/udp.c -@@ -956,7 +956,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, - * @ifname: Name of interface to bind to, NULL if not configured - * @port: Port, host order - * -- * Return: 0 on (partial) success, -1 on (complete) failure -+ * Return: 0 on (partial) success, negative error code on (complete) failure - */ - int udp_sock_init(const struct ctx *c, int ns, sa_family_t af, - const void *addr, const char *ifname, in_port_t port) -@@ -981,19 +981,19 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af, - s = sock_l4(c, AF_INET, IPPROTO_UDP, addr, ifname, - port, uref.u32); - -- udp_tap_map[V4][uref.udp.port].sock = s; -- udp_splice_init[V4][port].sock = s; -+ udp_tap_map[V4][uref.udp.port].sock = s < 0 ? -1 : s; -+ udp_splice_init[V4][port].sock = s < 0 ? -1 : s; - } else { - struct in_addr loopback = { htonl(INADDR_LOOPBACK) }; - uref.udp.ns = true; - - s = sock_l4(c, AF_INET, IPPROTO_UDP, &loopback, - ifname, port, uref.u32); -- udp_splice_ns[V4][port].sock = s; -+ udp_splice_ns[V4][port].sock = s < 0 ? -1 : s; - } - - if (s < 0) -- ret = -1; -+ ret = s; - } - - if ((af == AF_INET6 || af == AF_UNSPEC) && c->ifi6) { -@@ -1005,18 +1005,18 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af, - s = sock_l4(c, AF_INET6, IPPROTO_UDP, addr, ifname, - port, uref.u32); - -- udp_tap_map[V6][uref.udp.port].sock = s; -- udp_splice_init[V6][port].sock = s; -+ udp_tap_map[V6][uref.udp.port].sock = s < 0 ? -1 : s; -+ udp_splice_init[V6][port].sock = s < 0 ? -1 : s; - } else { - uref.udp.ns = true; - - s = sock_l4(c, AF_INET6, IPPROTO_UDP, &in6addr_loopback, - ifname, port, uref.u32); -- udp_splice_ns[V6][port].sock = s; -+ udp_splice_ns[V6][port].sock = s < 0 ? -1 : s; - } - - if (s < 0) -- ret = -1; -+ ret = s; - } - - return ret; -diff --git a/util.c b/util.c -index c5ee1c0..13f8fab 100644 ---- a/util.c -+++ b/util.c -@@ -95,7 +95,7 @@ found: - * @port: Port, host order - * @data: epoll reference portion for protocol handlers - * -- * Return: newly created socket, -1 on error -+ * Return: newly created socket, negative error code on failure - */ - int sock_l4(const struct ctx *c, int af, uint8_t proto, - const void *bind_addr, const char *ifname, uint16_t port, -@@ -114,16 +114,16 @@ int sock_l4(const struct ctx *c, int af, uint8_t proto, - }; - const struct sockaddr *sa; - bool dual_stack = false; -+ int fd, sl, y = 1, ret; - struct epoll_event ev; -- int fd, sl, y = 1; - - if (proto != IPPROTO_TCP && proto != IPPROTO_UDP && - proto != IPPROTO_ICMP && proto != IPPROTO_ICMPV6) -- return -1; /* Not implemented. */ -+ return -EPFNOSUPPORT; /* Not implemented. */ - - if (af == AF_UNSPEC) { - if (!DUAL_STACK_SOCKETS || bind_addr) -- return -1; -+ return -EINVAL; - dual_stack = true; - af = AF_INET6; - } -@@ -133,14 +133,15 @@ int sock_l4(const struct ctx *c, int af, uint8_t proto, - else - fd = socket(af, SOCK_DGRAM | SOCK_NONBLOCK, proto); - -+ ret = -errno; - if (fd < 0) { -- warn("L4 socket: %s", strerror(errno)); -- return -1; -+ warn("L4 socket: %s", strerror(-ret)); -+ return ret; - } - - if (fd > SOCKET_MAX) { - close(fd); -- return -1; -+ return -EBADF; - } - - ref.r.s = fd; -@@ -185,10 +186,11 @@ int sock_l4(const struct ctx *c, int af, uint8_t proto, - */ - if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, - ifname, strlen(ifname))) { -+ ret = -errno; - warn("Can't bind socket for %s port %u to %s, closing", - ip_proto_str[proto], port, ifname); - close(fd); -- return -1; -+ return ret; - } - } - -@@ -199,22 +201,25 @@ int sock_l4(const struct ctx *c, int af, uint8_t proto, - * broken SELinux policy, see icmp_tap_handler(). - */ - if (proto != IPPROTO_ICMP && proto != IPPROTO_ICMPV6) { -+ ret = -errno; - close(fd); -- return -1; -+ return ret; - } - } - - if (proto == IPPROTO_TCP && listen(fd, 128) < 0) { -- warn("TCP socket listen: %s", strerror(errno)); -+ ret = -errno; -+ warn("TCP socket listen: %s", strerror(-ret)); - close(fd); -- return -1; -+ return ret; - } - - ev.events = EPOLLIN; - ev.data.u64 = ref.u64; - if (epoll_ctl(c->epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { -- warn("L4 epoll_ctl: %s", strerror(errno)); -- return -1; -+ ret = -errno; -+ warn("L4 epoll_ctl: %s", strerror(-ret)); -+ return ret; - } - - return fd; --- -2.39.2 - diff --git a/SOURCES/0014-tcp-udp-Fix-partial-success-return-codes-in-tcp-udp-.patch b/SOURCES/0014-tcp-udp-Fix-partial-success-return-codes-in-tcp-udp-.patch deleted file mode 100644 index 4e83621..0000000 --- a/SOURCES/0014-tcp-udp-Fix-partial-success-return-codes-in-tcp-udp-.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 8f71f17cc087fc80f1cbe9b71852b95916a9afbc Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Wed, 8 Mar 2023 12:38:39 +0100 -Subject: [PATCH 14/20] tcp, udp: Fix partial success return codes in - {tcp,udp}_sock_init() - -The comments say we should return 0 on partial success, and an error -code on complete failure. Rationale: if the user configures a port -forwarding, and we succeed to bind that port for IPv4 or IPv6 only, -that might actually be what the user intended. - -Adjust the two functions to reflect the comments. - -Signed-off-by: Stefano Brivio -Reviewed-by: David Gibson -(cherry picked from commit 5aea2f88ab5f63f01885109a4afb1271607fc06b) ---- - tcp.c | 21 +++++++++------------ - udp.c | 30 ++++++++++++++---------------- - 2 files changed, 23 insertions(+), 28 deletions(-) - -diff --git a/tcp.c b/tcp.c -index 482c2f9..001fa50 100644 ---- a/tcp.c -+++ b/tcp.c -@@ -2929,7 +2929,7 @@ static int tcp_sock_init_af(const struct ctx *c, int af, in_port_t port, - int tcp_sock_init(const struct ctx *c, sa_family_t af, const void *addr, - const char *ifname, in_port_t port) - { -- int ret = 0, af_ret; -+ int r4 = SOCKET_MAX + 1, r6 = SOCKET_MAX + 1; - - if (af == AF_UNSPEC && c->ifi4 && c->ifi6) - /* Attempt to get a dual stack socket */ -@@ -2937,19 +2937,16 @@ int tcp_sock_init(const struct ctx *c, sa_family_t af, const void *addr, - return 0; - - /* Otherwise create a socket per IP version */ -- if ((af == AF_INET || af == AF_UNSPEC) && c->ifi4) { -- af_ret = tcp_sock_init_af(c, AF_INET, port, addr, ifname); -- if (af_ret < 0) -- ret = af_ret; -- } -+ if ((af == AF_INET || af == AF_UNSPEC) && c->ifi4) -+ r4 = tcp_sock_init_af(c, AF_INET, port, addr, ifname); - -- if ((af == AF_INET6 || af == AF_UNSPEC) && c->ifi6) { -- af_ret = tcp_sock_init_af(c, AF_INET6, port, addr, ifname); -- if (af_ret < 0) -- ret = af_ret; -- } -+ if ((af == AF_INET6 || af == AF_UNSPEC) && c->ifi6) -+ r6 = tcp_sock_init_af(c, AF_INET6, port, addr, ifname); - -- return ret; -+ if (IN_INTERVAL(0, SOCKET_MAX, r4) || IN_INTERVAL(0, SOCKET_MAX, r6)) -+ return 0; -+ -+ return r4 < 0 ? r4 : r6; - } - - /** -diff --git a/udp.c b/udp.c -index 9a43835..20ee0f2 100644 ---- a/udp.c -+++ b/udp.c -@@ -962,7 +962,7 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af, - const void *addr, const char *ifname, in_port_t port) - { - union udp_epoll_ref uref = { .u32 = 0 }; -- int s, ret = 0; -+ int s, r4 = SOCKET_MAX + 1, r6 = SOCKET_MAX + 1; - - if (ns) { - uref.udp.port = (in_port_t)(port + -@@ -978,8 +978,8 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af, - uref.udp.orig = true; - - if (!ns) { -- s = sock_l4(c, AF_INET, IPPROTO_UDP, addr, ifname, -- port, uref.u32); -+ r4 = s = sock_l4(c, AF_INET, IPPROTO_UDP, addr, -+ ifname, port, uref.u32); - - udp_tap_map[V4][uref.udp.port].sock = s < 0 ? -1 : s; - udp_splice_init[V4][port].sock = s < 0 ? -1 : s; -@@ -987,13 +987,10 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af, - struct in_addr loopback = { htonl(INADDR_LOOPBACK) }; - uref.udp.ns = true; - -- s = sock_l4(c, AF_INET, IPPROTO_UDP, &loopback, -- ifname, port, uref.u32); -+ r4 = s = sock_l4(c, AF_INET, IPPROTO_UDP, &loopback, -+ ifname, port, uref.u32); - udp_splice_ns[V4][port].sock = s < 0 ? -1 : s; - } -- -- if (s < 0) -- ret = s; - } - - if ((af == AF_INET6 || af == AF_UNSPEC) && c->ifi6) { -@@ -1002,24 +999,25 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af, - uref.udp.orig = true; - - if (!ns) { -- s = sock_l4(c, AF_INET6, IPPROTO_UDP, addr, ifname, -- port, uref.u32); -+ r6 = s = sock_l4(c, AF_INET6, IPPROTO_UDP, addr, -+ ifname, port, uref.u32); - - udp_tap_map[V6][uref.udp.port].sock = s < 0 ? -1 : s; - udp_splice_init[V6][port].sock = s < 0 ? -1 : s; - } else { - uref.udp.ns = true; - -- s = sock_l4(c, AF_INET6, IPPROTO_UDP, &in6addr_loopback, -- ifname, port, uref.u32); -+ r6 = s = sock_l4(c, AF_INET6, IPPROTO_UDP, -+ &in6addr_loopback, -+ ifname, port, uref.u32); - udp_splice_ns[V6][port].sock = s < 0 ? -1 : s; - } -- -- if (s < 0) -- ret = s; - } - -- return ret; -+ if (IN_INTERVAL(0, SOCKET_MAX, r4) || IN_INTERVAL(0, SOCKET_MAX, r6)) -+ return 0; -+ -+ return r4 < 0 ? r4 : r6; - } - - /** --- -2.39.2 - diff --git a/SOURCES/0015-conf-Terminate-on-EMFILE-or-ENFILE-on-sockets-for-po.patch b/SOURCES/0015-conf-Terminate-on-EMFILE-or-ENFILE-on-sockets-for-po.patch deleted file mode 100644 index 1ffcb68..0000000 --- a/SOURCES/0015-conf-Terminate-on-EMFILE-or-ENFILE-on-sockets-for-po.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 1df417752faf52f17d8ec14578ffde89ced32772 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Wed, 8 Mar 2023 13:21:19 +0100 -Subject: [PATCH 15/20] conf: Terminate on EMFILE or ENFILE on sockets for port - mapping - -In general, we don't terminate or report failures if we fail to bind -to some ports out of a given port range specifier, to allow users to -conveniently specify big port ranges (or "all") without having to -care about ports that might already be in use. - -However, running out of the open file descriptors quota is a -different story: we can't do what the user requested in a very -substantial way. - -For example, if the user specifies '-t all' and we can only bind -1024 sockets, the behaviour is rather unexpected. - -Fail whenever socket creation returns -ENFILE or -EMFILE. - -Link: https://bugs.passt.top/show_bug.cgi?id=27 -Signed-off-by: Stefano Brivio -Reviewed-by: David Gibson -(cherry picked from commit bb2b67cb3549ea2509f5b7b88790e08d2e362351) ---- - conf.c | 36 +++++++++++++++++++++++++++++------- - 1 file changed, 29 insertions(+), 7 deletions(-) - -diff --git a/conf.c b/conf.c -index 37f25d6..7f25a22 100644 ---- a/conf.c -+++ b/conf.c -@@ -182,6 +182,7 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, - bool exclude_only = true, bound_one = false; - uint8_t exclude[PORT_BITMAP_SIZE] = { 0 }; - sa_family_t af = AF_UNSPEC; -+ int ret; - - if (!strcmp(optarg, "none")) { - if (fwd->mode) -@@ -216,11 +217,18 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, - - for (i = 0; i < PORT_EPHEMERAL_MIN; i++) { - if (optname == 't') { -- if (!tcp_sock_init(c, AF_UNSPEC, NULL, NULL, i)) -+ ret = tcp_sock_init(c, AF_UNSPEC, NULL, NULL, -+ i); -+ if (ret == -ENFILE || ret == -EMFILE) -+ goto enfile; -+ if (!ret) - bound_one = true; - } else if (optname == 'u') { -- if (!udp_sock_init(c, 0, AF_UNSPEC, NULL, NULL, -- i)) -+ ret = udp_sock_init(c, 0, AF_UNSPEC, NULL, NULL, -+ i); -+ if (ret == -ENFILE || ret == -EMFILE) -+ goto enfile; -+ if (!ret) - bound_one = true; - } - } -@@ -301,10 +309,16 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, - bitmap_set(fwd->map, i); - - if (optname == 't') { -- if (!tcp_sock_init(c, af, addr, ifname, i)) -+ ret = tcp_sock_init(c, af, addr, ifname, i); -+ if (ret == -ENFILE || ret == -EMFILE) -+ goto enfile; -+ if (!ret) - bound_one = true; - } else if (optname == 'u') { -- if (!udp_sock_init(c, 0, af, addr, ifname, i)) -+ ret = udp_sock_init(c, 0, af, addr, ifname, i); -+ if (ret == -ENFILE || ret == -EMFILE) -+ goto enfile; -+ if (!ret) - bound_one = true; - } else { - /* No way to check in advance for -T and -U */ -@@ -356,10 +370,16 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, - fwd->delta[i] = mapped_range.first - orig_range.first; - - if (optname == 't') { -- if (!tcp_sock_init(c, af, addr, ifname, i)) -+ ret = tcp_sock_init(c, af, addr, ifname, i); -+ if (ret == -ENFILE || ret == -EMFILE) -+ goto enfile; -+ if (!ret) - bound_one = true; - } else if (optname == 'u') { -- if (!udp_sock_init(c, 0, af, addr, ifname, i)) -+ ret = udp_sock_init(c, 0, af, addr, ifname, i); -+ if (ret == -ENFILE || ret == -EMFILE) -+ goto enfile; -+ if (!ret) - bound_one = true; - } else { - /* No way to check in advance for -T and -U */ -@@ -372,6 +392,8 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, - goto bind_fail; - - return; -+enfile: -+ die("Can't open enough sockets for port specifier: %s", optarg); - bad: - die("Invalid port specifier %s", optarg); - overlap: --- -2.39.2 - diff --git a/SOURCES/0016-tcp-Clamp-MSS-value-when-queueing-data-to-tap-also-f.patch b/SOURCES/0016-tcp-Clamp-MSS-value-when-queueing-data-to-tap-also-f.patch deleted file mode 100644 index 02c6c0a..0000000 --- a/SOURCES/0016-tcp-Clamp-MSS-value-when-queueing-data-to-tap-also-f.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 96bf75e8ebffe06d33b5dee20c44e16ce53ea663 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Wed, 8 Mar 2023 18:07:42 +0100 -Subject: [PATCH 16/20] tcp: Clamp MSS value when queueing data to tap, also - for pasta - -Tom reports that a pattern of repated ~1 MiB chunks downloads over -NNTP over TLS, on Podman 4.4 using pasta as network back-end, results -in pasta taking one full CPU thread after a while, and the download -never succeeds. - -On that setup, we end up re-sending the same frame over and over, -with a consistent 65 534 bytes size, and never get an -acknowledgement from the tap-side client. This only happens for the -default MTU value (65 520 bytes) or for values that are slightly -smaller than that (down to 64 499 bytes). - -We hit this condition because the MSS value we use in -tcp_data_from_sock(), only in pasta mode, is simply clamped to -USHRT_MAX, and not to the actual size of the buffers we pre-cooked -for sending, which is a bit less than that. - -It looks like we got away with it until commit 0fb7b2b9080a ("tap: -Use different io vector bases depending on tap type") fixed the -setting of iov_len. - -Luckily, since it's pasta, we're queueing up to two frames at a time, -so the worst that can happen is a badly segmented TCP stream: we -always have some space at the tail of the buffer. - -Clamp the MSS value to the appropriate maximum given by struct -tcp{4,6}_buf_data_t, no matter if we're running in pasta or passt -mode. - -While at it, fix the comments to those structs to reflect the current -struct size. This is not really relevant for any further calculation -or consideration, but it's convenient to know while debugging this -kind of issues. - -Thanks to Tom for reporting the issue in a very detailed way and for -providing a test setup. - -Reported-by: Tom Mombourquette -Link: https://github.com/containers/podman/issues/17703 -Signed-off-by: Stefano Brivio -Reviewed-by: David Gibson -(cherry picked from commit d7272f1df89c099a7e98ae43d1ef9b936c7e46f7) ---- - tcp.c | 23 +++++++++-------------- - 1 file changed, 9 insertions(+), 14 deletions(-) - -diff --git a/tcp.c b/tcp.c -index 001fa50..1355b0e 100644 ---- a/tcp.c -+++ b/tcp.c -@@ -460,7 +460,7 @@ static struct tcp4_l2_buf_t { - struct iphdr iph; /* 44 28 */ - struct tcphdr th; /* 64 48 */ - uint8_t data[MSS4]; /* 84 68 */ -- /* 65541 65525 */ -+ /* 65536 65532 */ - #ifdef __AVX2__ - } __attribute__ ((packed, aligned(32))) - #else -@@ -488,7 +488,7 @@ struct tcp6_l2_buf_t { - struct ipv6hdr ip6h; /* 32 20 */ - struct tcphdr th; /* 72 60 */ - uint8_t data[MSS6]; /* 92 80 */ -- /* 65639 65627 */ -+ /* 65536 65532 */ - #ifdef __AVX2__ - } __attribute__ ((packed, aligned(32))) - #else -@@ -1913,15 +1913,13 @@ int tcp_conn_new_sock(const struct ctx *c, sa_family_t af) - - /** - * tcp_conn_tap_mss() - Get MSS value advertised by tap/guest -- * @c: Execution context - * @conn: Connection pointer - * @opts: Pointer to start of TCP options - * @optlen: Bytes in options: caller MUST ensure available length - * - * Return: clamped MSS value - */ --static uint16_t tcp_conn_tap_mss(const struct ctx *c, -- const struct tcp_tap_conn *conn, -+static uint16_t tcp_conn_tap_mss(const struct tcp_tap_conn *conn, - const char *opts, size_t optlen) - { - unsigned int mss; -@@ -1932,13 +1930,10 @@ static uint16_t tcp_conn_tap_mss(const struct ctx *c, - else - mss = ret; - -- /* Don't upset qemu */ -- if (c->mode == MODE_PASST) { -- if (CONN_V4(conn)) -- mss = MIN(MSS4, mss); -- else -- mss = MIN(MSS6, mss); -- } -+ if (CONN_V4(conn)) -+ mss = MIN(MSS4, mss); -+ else -+ mss = MIN(MSS6, mss); - - return MIN(mss, USHRT_MAX); - } -@@ -2007,7 +2002,7 @@ static void tcp_conn_from_tap(struct ctx *c, int af, const void *addr, - - conn->wnd_to_tap = WINDOW_DEFAULT; - -- mss = tcp_conn_tap_mss(c, conn, opts, optlen); -+ mss = tcp_conn_tap_mss(conn, opts, optlen); - if (setsockopt(s, SOL_TCP, TCP_MAXSEG, &mss, sizeof(mss))) - trace("TCP: failed to set TCP_MAXSEG on socket %i", s); - MSS_SET(conn, mss); -@@ -2469,7 +2464,7 @@ static void tcp_conn_from_sock_finish(struct ctx *c, struct tcp_tap_conn *conn, - if (!(conn->wnd_from_tap >>= conn->ws_from_tap)) - conn->wnd_from_tap = 1; - -- MSS_SET(conn, tcp_conn_tap_mss(c, conn, opts, optlen)); -+ MSS_SET(conn, tcp_conn_tap_mss(conn, opts, optlen)); - - conn->seq_init_from_tap = ntohl(th->seq) + 1; - conn->seq_from_tap = conn->seq_init_from_tap; --- -2.39.2 - diff --git a/SOURCES/0017-contrib-selinux-Drop-example-from-headers-this-is-th.patch b/SOURCES/0017-contrib-selinux-Drop-example-from-headers-this-is-th.patch deleted file mode 100644 index 933de64..0000000 --- a/SOURCES/0017-contrib-selinux-Drop-example-from-headers-this-is-th.patch +++ /dev/null @@ -1,98 +0,0 @@ -From def7d05a8babf5ea227f688f1f3a8bce286f97a3 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Fri, 10 Mar 2023 14:53:14 +0000 -Subject: [PATCH 17/20] contrib/selinux: Drop "example" from headers: this is - the actual policy - -Signed-off-by: Stefano Brivio -(cherry picked from commit 9f35cf0b11891e9dfb12eeb5d52f728881f84967) ---- - contrib/selinux/passt.fc | 2 +- - contrib/selinux/passt.if | 2 +- - contrib/selinux/passt.te | 2 +- - contrib/selinux/pasta.fc | 2 +- - contrib/selinux/pasta.if | 2 +- - contrib/selinux/pasta.te | 2 +- - 6 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/contrib/selinux/passt.fc b/contrib/selinux/passt.fc -index 286c868..88e388e 100644 ---- a/contrib/selinux/passt.fc -+++ b/contrib/selinux/passt.fc -@@ -3,7 +3,7 @@ - # PASST - Plug A Simple Socket Transport - # for qemu/UNIX domain socket mode - # --# contrib/selinux/passt.fc - SELinux profile example: File Context for passt -+# contrib/selinux/passt.fc - SELinux profile: File Context for passt - # - # Copyright (c) 2022 Red Hat GmbH - # Author: Stefano Brivio -diff --git a/contrib/selinux/passt.if b/contrib/selinux/passt.if -index 6a6105c..a79a8ec 100644 ---- a/contrib/selinux/passt.if -+++ b/contrib/selinux/passt.if -@@ -3,7 +3,7 @@ - # PASST - Plug A Simple Socket Transport - # for qemu/UNIX domain socket mode - # --# contrib/selinux/passt.if - SELinux profile example: Interface File for passt -+# contrib/selinux/passt.if - SELinux profile: Interface File for passt - # - # Copyright (c) 2022 Red Hat GmbH - # Author: Stefano Brivio -diff --git a/contrib/selinux/passt.te b/contrib/selinux/passt.te -index 438155d..590ad40 100644 ---- a/contrib/selinux/passt.te -+++ b/contrib/selinux/passt.te -@@ -3,7 +3,7 @@ - # PASST - Plug A Simple Socket Transport - # for qemu/UNIX domain socket mode - # --# contrib/selinux/passt.te - SELinux profile example: Type Enforcement for passt -+# contrib/selinux/passt.te - SELinux profile: Type Enforcement for passt - # - # Copyright (c) 2022 Red Hat GmbH - # Author: Stefano Brivio -diff --git a/contrib/selinux/pasta.fc b/contrib/selinux/pasta.fc -index f8fa0fa..e72b4ac 100644 ---- a/contrib/selinux/pasta.fc -+++ b/contrib/selinux/pasta.fc -@@ -3,7 +3,7 @@ - # PASTA - Pack A Subtle Tap Abstraction - # for network namespace/tap device mode - # --# contrib/selinux/pasta.fc - SELinux profile example: File Context for pasta -+# contrib/selinux/pasta.fc - SELinux profile: File Context for pasta - # - # Copyright (c) 2022 Red Hat GmbH - # Author: Stefano Brivio -diff --git a/contrib/selinux/pasta.if b/contrib/selinux/pasta.if -index a42bfcd..149045a 100644 ---- a/contrib/selinux/pasta.if -+++ b/contrib/selinux/pasta.if -@@ -3,7 +3,7 @@ - # PASTA - Pack A Subtle Tap Abstraction - # for network namespace/tap device mode - # --# contrib/selinux/pasta.if - SELinux profile example: Interface File for pasta -+# contrib/selinux/pasta.if - SELinux profile: Interface File for pasta - # - # Copyright (c) 2022 Red Hat GmbH - # Author: Stefano Brivio -diff --git a/contrib/selinux/pasta.te b/contrib/selinux/pasta.te -index 8986c0c..7856019 100644 ---- a/contrib/selinux/pasta.te -+++ b/contrib/selinux/pasta.te -@@ -3,7 +3,7 @@ - # PASTA - Pack A Subtle Tap Abstraction - # for network namespace/tap device mode - # --# contrib/selinux/pasta.te - SELinux profile example: Type Enforcement for pasta -+# contrib/selinux/pasta.te - SELinux profile: Type Enforcement for pasta - # - # Copyright (c) 2022 Red Hat GmbH - # Author: Stefano Brivio --- -2.39.2 - diff --git a/SOURCES/0018-contrib-selinux-Drop-unused-passt_read_data-interfac.patch b/SOURCES/0018-contrib-selinux-Drop-unused-passt_read_data-interfac.patch deleted file mode 100644 index 7d71b8c..0000000 --- a/SOURCES/0018-contrib-selinux-Drop-unused-passt_read_data-interfac.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 6b5f382f342ad4a0a46e30b5ba165713768e363a Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Fri, 10 Mar 2023 14:53:37 +0000 -Subject: [PATCH 18/20] contrib/selinux: Drop unused passt_read_data() - interface - -Signed-off-by: Stefano Brivio -(cherry picked from commit dcdc50fc2251339d6e929f708fad114e61b60627) ---- - contrib/selinux/passt.if | 8 -------- - 1 file changed, 8 deletions(-) - -diff --git a/contrib/selinux/passt.if b/contrib/selinux/passt.if -index a79a8ec..3e37c5b 100644 ---- a/contrib/selinux/passt.if -+++ b/contrib/selinux/passt.if -@@ -8,14 +8,6 @@ - # Copyright (c) 2022 Red Hat GmbH - # Author: Stefano Brivio - --interface(`passt_read_data',` -- gen_require(` -- type passt_data_t; -- ') -- allow $1 passt_t:dir { search add_name }; -- allow $1 passt_t:file { open read getattr }; --') -- - interface(`passt_domtrans',` - gen_require(` - type passt_t, passt_exec_t; --- -2.39.2 - diff --git a/SOURCES/0019-contrib-selinux-Split-interfaces-into-smaller-bits.patch b/SOURCES/0019-contrib-selinux-Split-interfaces-into-smaller-bits.patch deleted file mode 100644 index 456f04f..0000000 --- a/SOURCES/0019-contrib-selinux-Split-interfaces-into-smaller-bits.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 80978901354b17cf3460d5d4451b48b59a9204ae Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Fri, 10 Mar 2023 17:00:31 +0000 -Subject: [PATCH 19/20] contrib/selinux: Split interfaces into smaller bits - -...to fit accepted Fedora practices. - -Link: https://github.com/fedora-selinux/selinux-policy/pull/1613 -Signed-off-by: Stefano Brivio -(cherry picked from commit 93105ea06619d4c199f8140f4b75ae359757dc6d) ---- - contrib/selinux/passt.if | 71 ++++++++++++++++++++++++++++++++++------ - 1 file changed, 61 insertions(+), 10 deletions(-) - -diff --git a/contrib/selinux/passt.if b/contrib/selinux/passt.if -index 3e37c5b..f7560a7 100644 ---- a/contrib/selinux/passt.if -+++ b/contrib/selinux/passt.if -@@ -17,37 +17,88 @@ interface(`passt_domtrans',` - domtrans_pattern($1, passt_exec_t, passt_t) - ') - --interface(`passt_socket',` -+interface(`passt_socket_dir',` -+ gen_require(` -+ type passt_t; -+ ') -+ -+ allow passt_t $1:dir add_entry_dir_perms; -+') -+ -+interface(`passt_socket_create',` -+ gen_require(` -+ type passt_t; -+ ') -+ -+ allow passt_t $1:sock_file create; -+') -+ -+interface(`passt_socket_use',` - gen_require(` - type passt_t; - ') - -- allow $1 $2:sock_file write; - allow $1 passt_t:unix_stream_socket connectto; -+ allow $1 $2:sock_file { read write }; -+ allow passt_t $2:sock_file { read write }; -+') -+ -+interface(`passt_socket_delete',` -+ gen_require(` -+ type passt_t; -+ ') -+ -+ allow $1 $2:sock_file unlink; -+') -+ -+interface(`passt_logfile_dir',` -+ gen_require(` -+ type passt_t; -+ ') - -- allow passt_t $2:sock_file { create read write unlink }; -+ allow passt_t $1:dir add_entry_dir_perms; - ') - --interface(`passt_logfile',` -+interface(`passt_logfile_use',` - gen_require(` - type passt_t; - ') - - logging_log_file($1); -- allow passt_t $1:dir { search write add_name }; - allow passt_t $1:file { create open read write }; - ') - --interface(`passt_pidfile',` -+interface(`passt_pidfile_dir',` -+ gen_require(` -+ type passt_t; -+ ') -+ -+ allow passt_t $1:dir add_entry_dir_perms; -+') -+ -+interface(`passt_pidfile_write',` -+ gen_require(` -+ type passt_t; -+ ') -+ -+ files_pid_file($1); -+ allow passt_t $1:file { create open write }; -+') -+ -+interface(`passt_pidfile_read',` - gen_require(` - type passt_t; - ') - -- allow $1 $2:file { open read unlink }; -+ allow $1 $2:file { open read }; -+') -+ -+interface(`passt_pidfile_delete',` -+ gen_require(` -+ type passt_t; -+ ') - -- files_pid_file($2); -- allow passt_t $2:dir { search write add_name }; -- allow passt_t $2:file { create open write }; -+ allow $1 $2:file unlink; - ') - - interface(`passt_kill',` --- -2.39.2 - diff --git a/SPECS/passt.spec b/SPECS/passt.spec index 04a0fc7..b6b9eb8 100644 --- a/SPECS/passt.spec +++ b/SPECS/passt.spec @@ -7,40 +7,22 @@ # Copyright (c) 2022 Red Hat GmbH # Author: Stefano Brivio -%global git_hash 4ddbcb9c0c555838b123c018a9ebc9b7e14a87e5 +%global git_hash b86afe3559c0bd3d24bc6fed7c60466cf141224c %global selinuxtype targeted Name: passt -Version: 0^20230222.g4ddbcb9 -Release: 4%{?dist} +Version: 0^20231204.gb86afe3 +Release: 1%{?dist} Summary: User-mode networking daemons for virtual machines and namespaces -License: AGPLv3+ and BSD +License: GPLv2+ and BSD Group: System Environment/Daemons URL: https://passt.top/ Source: https://passt.top/passt/snapshot/passt-%{git_hash}.tar.xz -Patch1: 0001-udp-Actually-use-host-resolver-to-forward-DNS-querie.patch -Patch2: 0002-conf-Split-add_dns-4-6-out-of-get_dns.patch -Patch3: 0003-conf-udp-Allow-any-loopback-address-to-be-used-as-re.patch -Patch4: 0004-tcp-tcp_splice-Get-rid-of-false-positive-CWE-394-Cov.patch -Patch5: 0005-tcp-Avoid-false-but-convoluted-positive-Coverity-CWE.patch -Patch6: 0006-tcp-Avoid-theoretical-resource-leak-CWE-772-Coverity.patch -Patch7: 0007-Fix-definitions-of-SOCKET_MAX-TCP_MAX_CONNS.patch -Patch8: 0008-doc-demo-Fix-and-suppress-ShellCheck-warnings.patch -Patch9: 0009-contrib-selinux-Drop-duplicate-init_daemon_domain-ru.patch -Patch10: 0010-contrib-selinux-Let-passt-write-to-stdout-and-stderr.patch -Patch11: 0011-contrib-selinux-Allow-binding-and-connecting-to-all-.patch -Patch12: 0012-contrib-selinux-Let-interface-users-set-paths-for-lo.patch -Patch13: 0013-tcp-udp-util-Pass-socket-creation-errors-all-the-way.patch -Patch14: 0014-tcp-udp-Fix-partial-success-return-codes-in-tcp-udp-.patch -Patch15: 0015-conf-Terminate-on-EMFILE-or-ENFILE-on-sockets-for-po.patch -Patch16: 0016-tcp-Clamp-MSS-value-when-queueing-data-to-tap-also-f.patch -Patch17: 0017-contrib-selinux-Drop-example-from-headers-this-is-th.patch -Patch18: 0018-contrib-selinux-Drop-unused-passt_read_data-interfac.patch -Patch19: 0019-contrib-selinux-Split-interfaces-into-smaller-bits.patch +Patch1: 0001-selinux-Drop-user_namespace-create-allow-rules.patch BuildRequires: gcc, make, git, checkpolicy, selinux-policy-devel -Requires: (%{name}-selinux = %{version}-%{release} if selinux-policy-%{selinuxtype}) +Requires: (%{name}-selinux = %{version}-%{release} if selinux-policy-%{selinuxtype}) %description passt implements a translation layer between a Layer-2 network interface and @@ -71,13 +53,30 @@ This package adds SELinux enforcement to passt(1) and pasta(1). %build %set_build_flags -%make_build VERSION="%{version}-%{release}.%{_arch}" +# The Makefile creates symbolic links for pasta, but we need actual copies for +# SELinux file contexts to work as intended. Same with pasta.avx2 if present. +# Build twice, changing the version string, to avoid duplicate Build-IDs. +%make_build VERSION="%{version}-%{release}.%{_arch}-pasta" +mv -f passt pasta +%ifarch x86_64 +mv -f passt.avx2 pasta.avx2 +%make_build passt passt.avx2 VERSION="%{version}-%{release}.%{_arch}" +%else +%make_build passt VERSION="%{version}-%{release}.%{_arch}" +%endif %install +# Already built (not as symbolic links), see above +touch pasta +%ifarch x86_64 +touch pasta.avx2 +%endif + %make_install DESTDIR=%{buildroot} prefix=%{_prefix} bindir=%{_bindir} mandir=%{_mandir} docdir=%{_docdir}/%{name} %ifarch x86_64 ln -sr %{buildroot}%{_mandir}/man1/passt.1 %{buildroot}%{_mandir}/man1/passt.avx2.1 ln -sr %{buildroot}%{_mandir}/man1/pasta.1 %{buildroot}%{_mandir}/man1/pasta.avx2.1 +install -p -m 755 %{buildroot}%{_bindir}/passt.avx2 %{buildroot}%{_bindir}/pasta.avx2 %endif pushd contrib/selinux @@ -104,7 +103,7 @@ fi %selinux_relabel_post -s %{selinuxtype} %files -%license LICENSES/{AGPL-3.0-or-later.txt,BSD-3-Clause.txt} +%license LICENSES/{GPL-2.0-or-later.txt,BSD-3-Clause.txt} %dir %{_docdir}/%{name} %doc %{_docdir}/%{name}/README.md %doc %{_docdir}/%{name}/demo.sh @@ -127,6 +126,25 @@ fi %{_datadir}/selinux/packages/%{selinuxtype}/pasta.pp %changelog +* Fri Dec 15 2023 Stefano Brivio - 0^20231204.gb86afe3-1 +- Resolves: RHEL-19590 + +* Tue Aug 22 2023 Stefano Brivio - 0^20230818.g0af928e-4 +- Switch to copies instead of links for pasta: previous workaround unreliable +- Resolves: RHELPLAN-155811 + +* Tue Aug 22 2023 Stefano Brivio - 0^20230818.g0af928e-3 +- Explicit restorecon in scriptlet as rpm(8) mix up contexts with hard links +- Resolves: RHELPLAN-155811 + +* Mon Aug 21 2023 Stefano Brivio - 0^20230818.g0af928e-2 +- Drop user_namespace create allow rule, incompatible with current el9 kernel +- Resolves: RHELPLAN-155811 + +* Sat Aug 19 2023 Stefano Brivio - 0^20230818.g0af928e-1 +- Rebase from Fedora 39 +- Resolves: RHELPLAN-155811 + * Sun Jun 11 2023 Stefano Brivio - 0^20230222.g4ddbcb9-4 - Drop (pointless) patches 20, 21, 22, actually apply changes to the spec file! - Refresh SELinux labels in scriptlets, require -selinux package (rhbz#2183089)