From 645b709a383a475fae434acb0b4eb0558ecd2b15 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sat, 15 Nov 2025 00:52:51 +0800 Subject: [PATCH 01/16] network: Support interface-bound ECMP routes in MultiPathRoute= MultiPathRoute= can now specify device-only nexthops without a gateway address, e.g. MultiPathRoute=@wg0. This enables ECMP configurations over interfaces that don't use gateway addresses, such as WireGuard tunnels. The syntax is extended from "address[@device] [weight]" to "[address]@device [weight]". The address is now optional, but at least one of gateway or device must be specified. The @ symbol must still be present for device-only routes, making the syntax unambiguous: @wg0 specifies a device, while a bare IP address specifies a gateway. Device-only nexthops are only available for IPv4 routes. Device-only multipath routes for IPv6 are not supported by the kernel's netlink interface and will be rejected with a warning. This change is fully backwards compatible. All existing configurations continue to work unchanged, as they always included a gateway address. Closes #39699. --- man/systemd.network.xml | 17 ++++-- src/network/networkd-route-nexthop.c | 78 ++++++++++++++++------------ 2 files changed, 57 insertions(+), 38 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index b9f49a43a804a..b00c2c6795702 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2325,13 +2325,20 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix - MultiPathRoute=address[@name] [weight] + MultiPathRoute= Configures multipath route. Multipath routing is the technique of using multiple - alternative paths through a network. Takes gateway address. Optionally, takes a network - interface name or index separated with @, and a weight in 1..256 for this - multipath route separated with whitespace. This setting can be specified multiple times. If - an empty string is assigned, then the all previous assignments are cleared. + alternative paths through a network. Takes a gateway address and/or a network interface + name or index (prefixed with @). At least one of these must be specified. + Optionally, a weight in 1..256 can be specified, separated with whitespace. This setting + can be specified multiple times. If an empty string is assigned, then all previous + assignments are cleared. + + Examples: + MultiPathRoute=10.0.0.1@eth0 20 +MultiPathRoute=192.168.1.1 50 +MultiPathRoute=@wg0 15 +MultiPathRoute=2001:db8::1@eth0 diff --git a/src/network/networkd-route-nexthop.c b/src/network/networkd-route-nexthop.c index 5ad8cd4c6485f..7eb1a79424758 100644 --- a/src/network/networkd-route-nexthop.c +++ b/src/network/networkd-route-nexthop.c @@ -94,10 +94,12 @@ static void route_nexthop_hash_func_full(const RouteNextHop *nh, struct siphash /* See nh_comp() in net/ipv4/fib_semantics.c of the kernel. */ siphash24_compress_typesafe(nh->family, state); - if (!IN_SET(nh->family, AF_INET, AF_INET6)) - return; - in_addr_hash_func(&nh->gw, nh->family, state); + /* For device-only nexthops parsed from config, family is AF_UNSPEC until verification. + * We still need to hash weight/ifindex/ifname to distinguish different device-only entries. */ + if (IN_SET(nh->family, AF_INET, AF_INET6)) + in_addr_hash_func(&nh->gw, nh->family, state); + if (with_weight) siphash24_compress_typesafe(nh->weight, state); siphash24_compress_typesafe(nh->ifindex, state); @@ -115,12 +117,13 @@ static int route_nexthop_compare_func_full(const RouteNextHop *a, const RouteNex if (r != 0) return r; - if (!IN_SET(a->family, AF_INET, AF_INET6)) - return 0; - - r = memcmp(&a->gw, &b->gw, FAMILY_ADDRESS_SIZE(a->family)); - if (r != 0) - return r; + /* For device-only nexthops parsed from config, family is AF_UNSPEC until verification. + * We still need to compare weight/ifindex/ifname to distinguish different device-only entries. */ + if (IN_SET(a->family, AF_INET, AF_INET6)) { + r = memcmp(&a->gw, &b->gw, FAMILY_ADDRESS_SIZE(a->family)); + if (r != 0) + return r; + } if (with_weight) { r = CMP(a->weight, b->weight); @@ -553,30 +556,34 @@ static int append_nexthop_one(const Route *route, const RouteNextHop *nh, struct (*rta)->rta_len += sizeof(struct rtnexthop); - if (nh->family == route->family) { - r = rtattr_append_attribute(rta, RTA_GATEWAY, &nh->gw, FAMILY_ADDRESS_SIZE(nh->family)); - if (r < 0) - goto clear; + /* For device-only nexthops, skip RTA_GATEWAY entirely. The kernel will use the + * interface specified in rtnh_ifindex without requiring a gateway address. */ + if (in_addr_is_set(nh->family, &nh->gw)) { + if (nh->family == route->family) { + r = rtattr_append_attribute(rta, RTA_GATEWAY, &nh->gw, FAMILY_ADDRESS_SIZE(nh->family)); + if (r < 0) + goto clear; - rtnh = (struct rtnexthop *)((uint8_t *) *rta + offset); - rtnh->rtnh_len += RTA_SPACE(FAMILY_ADDRESS_SIZE(nh->family)); + rtnh = (struct rtnexthop *)((uint8_t *) *rta + offset); + rtnh->rtnh_len += RTA_SPACE(FAMILY_ADDRESS_SIZE(nh->family)); - } else if (nh->family == AF_INET6) { - assert(route->family == AF_INET); + } else if (nh->family == AF_INET6) { + assert(route->family == AF_INET); - r = rtattr_append_attribute(rta, RTA_VIA, - &(RouteVia) { - .family = nh->family, - .address = nh->gw, - }, sizeof(RouteVia)); - if (r < 0) - goto clear; + r = rtattr_append_attribute(rta, RTA_VIA, + &(RouteVia) { + .family = nh->family, + .address = nh->gw, + }, sizeof(RouteVia)); + if (r < 0) + goto clear; - rtnh = (struct rtnexthop *)((uint8_t *) *rta + offset); - rtnh->rtnh_len += RTA_SPACE(sizeof(RouteVia)); + rtnh = (struct rtnexthop *)((uint8_t *) *rta + offset); + rtnh->rtnh_len += RTA_SPACE(sizeof(RouteVia)); - } else if (nh->family == AF_INET) - assert_not_reached(); + } else if (nh->family == AF_INET) + assert_not_reached(); + } return 0; @@ -1080,11 +1087,16 @@ int config_parse_multipath_route( } } - r = in_addr_from_string_auto(word, &nh->family, &nh->gw); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Invalid multipath route gateway '%s', ignoring assignment: %m", rvalue); - return 0; + if (isempty(word)) { + if (!dev) + return log_syntax_parse_error(unit, filename, line, SYNTHETIC_ERRNO(EINVAL), lvalue, rvalue); + } else { + r = in_addr_from_string_auto(word, &nh->family, &nh->gw); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Invalid multipath route gateway '%s', ignoring assignment: %m", rvalue); + return 0; + } } if (!isempty(p)) { From 23d02f63277c44137fa03af498c4976262df38d2 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 16 Nov 2025 01:15:47 +0800 Subject: [PATCH 02/16] test: Add comprehensive tests for MultiPathRoute device-only syntax Add unit tests for config_parse_multipath_route() covering the new device-only nexthop syntax (@device). Tests verify basic parsing of device-only routes, gateway with device routes, gateway-only routes, interface index handling, etc. Also some checks on new hash/duplicate semantics. Also add an integration test to verify device-only multipath routes are correctly installed in the kernel routing table. --- src/network/test-networkd-conf.c | 161 ++++++++++++++++++ .../test-network/conf/25-route-static.network | 5 + test/test-network/systemd-networkd-tests.py | 7 + 3 files changed, 173 insertions(+) diff --git a/src/network/test-networkd-conf.c b/src/network/test-networkd-conf.c index e4533737bfc95..8120e04f4239c 100644 --- a/src/network/test-networkd-conf.c +++ b/src/network/test-networkd-conf.c @@ -6,6 +6,8 @@ #include "networkd-address.h" #include "networkd-manager.h" #include "networkd-network.h" +#include "networkd-route-nexthop.h" +#include "ordered-set.h" #include "set.h" #include "strv.h" #include "tests.h" @@ -263,4 +265,163 @@ TEST(config_parse_match_strv) { "KEY3=val with \\quotation\\"))); } +static int parse_mpr(const char *rvalue, OrderedSet **nexthops) { + return config_parse_multipath_route( + "network", "filename", 1, "section", 1, "MultiPathRoute", 0, rvalue, nexthops, NULL); +} + +static void test_config_parse_multipath_route_one(const char *rvalue, int expected_ret, size_t expected_size) { + _cleanup_ordered_set_free_ OrderedSet *nexthops = NULL; + + ASSERT_OK_EQ(parse_mpr(rvalue, &nexthops), expected_ret); + ASSERT_EQ(ordered_set_size(nexthops), expected_size); +} + +static void test_config_parse_multipath_route_verify( + const char *rvalue, + int expected_family, + const char *expected_gw, + const char *expected_ifname, + int expected_ifindex, + uint32_t expected_weight) { + + _cleanup_ordered_set_free_ OrderedSet *nexthops = NULL; + RouteNextHop *nh; + + ASSERT_OK_EQ(parse_mpr(rvalue, &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 1u); + + ASSERT_NOT_NULL(nh = ordered_set_first(nexthops)); + ASSERT_EQ(nh->family, expected_family); + + if (expected_gw) { + union in_addr_union gw; + ASSERT_OK(in_addr_from_string(expected_family, expected_gw, &gw)); + ASSERT_EQ(memcmp(&nh->gw, &gw, FAMILY_ADDRESS_SIZE(expected_family)), 0); + } else + ASSERT_FALSE(in_addr_is_set(nh->family, &nh->gw)); + + ASSERT_STREQ(nh->ifname, expected_ifname); + + ASSERT_EQ(nh->ifindex, expected_ifindex); + ASSERT_EQ(nh->weight, expected_weight); +} + +TEST(config_parse_multipath_route) { + _cleanup_ordered_set_free_ OrderedSet *nexthops = NULL; + + /* Device only routes */ + test_config_parse_multipath_route_verify("@wg0", AF_UNSPEC, NULL, "wg0", 0, 0); + test_config_parse_multipath_route_verify("@wg0 10", AF_UNSPEC, NULL, "wg0", 0, 9); + test_config_parse_multipath_route_verify("@eth0 255", AF_UNSPEC, NULL, "eth0", 0, 254); + test_config_parse_multipath_route_verify("@1 15", AF_UNSPEC, NULL, NULL, 1, 14); + + /* Gateway with device */ + test_config_parse_multipath_route_verify("10.0.0.1@eth0", AF_INET, "10.0.0.1", "eth0", 0, 0); + test_config_parse_multipath_route_verify("10.0.0.1@eth0 20", AF_INET, "10.0.0.1", "eth0", 0, 19); + test_config_parse_multipath_route_verify("2001:db8::1@wg0 15", AF_INET6, "2001:db8::1", "wg0", 0, 14); + + /* Gateway without device */ + test_config_parse_multipath_route_verify("192.168.1.1", AF_INET, "192.168.1.1", NULL, 0, 0); + test_config_parse_multipath_route_verify("192.168.1.1 100", AF_INET, "192.168.1.1", NULL, 0, 99); + test_config_parse_multipath_route_verify("fe80::1", AF_INET6, "fe80::1", NULL, 0, 0); + + /* Interface index instead of name */ + test_config_parse_multipath_route_verify("10.0.0.1@5", AF_INET, "10.0.0.1", NULL, 5, 0); + test_config_parse_multipath_route_verify("@10", AF_UNSPEC, NULL, NULL, 10, 0); + test_config_parse_multipath_route_verify("@10 50", AF_UNSPEC, NULL, NULL, 10, 49); + + /* Empty value clears nexthops */ + ASSERT_OK_EQ(parse_mpr("@wg0 15", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 1u); + ASSERT_OK_EQ(parse_mpr("", &nexthops), 1); + ASSERT_NULL(nexthops); + + /* Make sure device-only/AF_UNSPEC routes do not collapse into a single entry. */ + + /* Different interfaces, same weight */ + ASSERT_OK_EQ(parse_mpr("@wg0 15", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 1u); + ASSERT_OK_EQ(parse_mpr("@wg1 15", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 2u); + /* Same interface, different weights */ + ASSERT_OK_EQ(parse_mpr("@eth0 10", &nexthops), 1); + ASSERT_OK_EQ(parse_mpr("@eth0 20", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 4u); + /* Interface name vs interface index */ + ASSERT_OK_EQ(parse_mpr("@5 15", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 5u); + /* Mixing device-only and gateway routes */ + ASSERT_OK_EQ(parse_mpr("10.0.0.1@eth0 20", &nexthops), 1); + ASSERT_OK_EQ(parse_mpr("192.168.1.1 30", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 7u); + /* Large interface index */ + ASSERT_OK_EQ(parse_mpr("@999999 10", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 8u); + /* IPv4 and IPv6 mixing */ + ASSERT_OK_EQ(parse_mpr("2001:db8::1@eth0 20", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 9u); + /* Default weight handling */ + ASSERT_OK_EQ(parse_mpr("@wg2", &nexthops), 1); + ASSERT_OK_EQ(parse_mpr("@wg3", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 11u); + + nexthops = ordered_set_free(nexthops); + + /* Insertion order does not affect deduplication */ + _cleanup_ordered_set_free_ OrderedSet *nexthops2 = NULL; + ASSERT_OK_EQ(parse_mpr("@wg0 10", &nexthops), 1); + ASSERT_OK_EQ(parse_mpr("@wg1 20", &nexthops), 1); + ASSERT_OK_EQ(parse_mpr("@wg1 20", &nexthops2), 1); + ASSERT_OK_EQ(parse_mpr("@wg0 10", &nexthops2), 1); + ASSERT_EQ(ordered_set_size(nexthops), 2u); + ASSERT_EQ(ordered_set_size(nexthops2), 2u); + + nexthops = ordered_set_free(nexthops); + + /* Duplicate routes should be detected and rejected with a warning. */ + + /* Exact duplicates are rejected */ + ASSERT_OK_EQ(parse_mpr("@wg0 15", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 1u); + ASSERT_OK_EQ(parse_mpr("@wg0 15", &nexthops), 0); + ASSERT_EQ(ordered_set_size(nexthops), 1u); + + nexthops = ordered_set_free(nexthops); + + /* Default weight vs explicit weight=1 are treated as identical */ + ASSERT_OK_EQ(parse_mpr("@eth0", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 1u); + ASSERT_OK_EQ(parse_mpr("@eth0 1", &nexthops), 0); + ASSERT_EQ(ordered_set_size(nexthops), 1u); + + nexthops = ordered_set_free(nexthops); + + /* Weight=1 then default weight (reverse order), still detected as duplicate */ + ASSERT_OK_EQ(parse_mpr("@wg0 1", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 1u); + ASSERT_OK_EQ(parse_mpr("@wg0", &nexthops), 0); + ASSERT_EQ(ordered_set_size(nexthops), 1u); + + nexthops = ordered_set_free(nexthops); + + /* Device-only vs gateway with device are semantically distinct, both accepted */ + ASSERT_OK_EQ(parse_mpr("@eth0 10", &nexthops), 1); + ASSERT_OK_EQ(parse_mpr("10.0.0.1@eth0 10", &nexthops), 1); + ASSERT_EQ(ordered_set_size(nexthops), 2u); + + /* Invalid input should be rejected */ + + /* Invalid gateway addresses */ + test_config_parse_multipath_route_one("999.999.999.999", 0, 0); + test_config_parse_multipath_route_one("not-an-ip", 0, 0); + test_config_parse_multipath_route_one("10", 0, 0); + + /* Invalid weights */ + test_config_parse_multipath_route_one("@wg0 0", 0, 0); /* Weight 0 */ + test_config_parse_multipath_route_one("@wg0 257", 0, 0); /* Weight > 256 */ + test_config_parse_multipath_route_one("@wg0 -1", 0, 0); /* Negative */ + test_config_parse_multipath_route_one("@wg0 abc", 0, 0); /* Non-numeric */ +} + DEFINE_TEST_MAIN(LOG_INFO); diff --git a/test/test-network/conf/25-route-static.network b/test/test-network/conf/25-route-static.network index 5ddd7de61a5b1..8e0578f0584dc 100644 --- a/test/test-network/conf/25-route-static.network +++ b/test/test-network/conf/25-route-static.network @@ -115,3 +115,8 @@ Peer=1.1.8.104/31 [Route] Gateway=1.1.8.104 + +[Route] +Destination=192.168.20.0/24 +MultiPathRoute=@test1 15 +MultiPathRoute=@dummy98 25 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index beaefbdc89572..61bc8b75bf8f5 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -4391,6 +4391,13 @@ def _check_route_static(self, test1_is_managed: bool): self.assertIn('via 2001:1234:5:8fff:ff:ff:ff:ff dev dummy98', output) self.assertIn('via 2001:1234:5:9fff:ff:ff:ff:ff dev dummy98', output) + print('### ip route show 192.168.20.0/24') + output = check_output('ip route show 192.168.20.0/24') + print(output) + self.assertIn('192.168.20.0/24 proto static', output) + self.assertIn('nexthop dev test1 weight 15', output) + self.assertIn('nexthop dev dummy98 weight 25', output) + check_json(networkctl_json()) def _check_unreachable_routes_removed(self): From 19d7ce2f7b8c74ffd81acafb3205e3184bef5d01 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 31 Dec 2025 10:58:26 -0500 Subject: [PATCH 03/16] docs/PASSWORD_AGENTS: note that the user directory may be created --- docs/PASSWORD_AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/PASSWORD_AGENTS.md b/docs/PASSWORD_AGENTS.md index b6c0f051c21c5..5609f48bf26cf 100644 --- a/docs/PASSWORD_AGENTS.md +++ b/docs/PASSWORD_AGENTS.md @@ -100,4 +100,4 @@ now available, with the same protocol as the system-wide counterpart. Unprivileged, per-directory agents should watch this directory in parallel to the system-wide one. Unprivileged queriers (i.e. clients to these agents) should pick the per-user directory to place their password request -files in. +files in. If the directory does not exist, agents may create it. From dc08cb1eb83072666a4ff21e1db8d35712e29121 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 31 Dec 2025 10:58:53 -0500 Subject: [PATCH 04/16] docs/PASSWORD_AGENTS: clarify that `Echo=0` may obscure --- docs/PASSWORD_AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/PASSWORD_AGENTS.md b/docs/PASSWORD_AGENTS.md index 5609f48bf26cf..3bf4138ad0fd8 100644 --- a/docs/PASSWORD_AGENTS.md +++ b/docs/PASSWORD_AGENTS.md @@ -40,7 +40,7 @@ It is easy to write additional agents. The basic algorithm to follow looks like * You'll find the PID of the client asking the question in the `PID=` field in the `[Ask]` section (Before asking your question use `kill(PID, 0)` and ignore the file if this returns `ESRCH`; there's no need to show the data of this field but if you want to you may) -* `Echo=` specifies whether the input should be obscured. If this field is missing or is `Echo=0`, the input should not be shown. +* `Echo=` specifies whether the input should be obscured. If this field is missing or is `Echo=0`, the input should not be shown as-is. * The socket to send the response to is configured via `Socket=` in the `[Ask]` section. It is a `AF_UNIX`/`SOCK_DGRAM` socket in the file system. * Ignore files where the time specified in the `NotAfter=` field in the `[Ask]` section is in the past. The time is specified in usecs, and refers to the `CLOCK_MONOTONIC` clock. If `NotAfter=` is `0`, no such check should take place. From 9f4606c3617bf47015c7bf9f63f5c44d9866ec1f Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 31 Dec 2025 10:59:25 -0500 Subject: [PATCH 05/16] docs/PASSWORD_AGENTS: document the `Silent=` field --- docs/PASSWORD_AGENTS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/PASSWORD_AGENTS.md b/docs/PASSWORD_AGENTS.md index 3bf4138ad0fd8..4badd8a5793d5 100644 --- a/docs/PASSWORD_AGENTS.md +++ b/docs/PASSWORD_AGENTS.md @@ -41,6 +41,7 @@ It is easy to write additional agents. The basic algorithm to follow looks like (Before asking your question use `kill(PID, 0)` and ignore the file if this returns `ESRCH`; there's no need to show the data of this field but if you want to you may) * `Echo=` specifies whether the input should be obscured. If this field is missing or is `Echo=0`, the input should not be shown as-is. +* `Silent=` specifies whether the input should have any indication. If this field is `Silent=1`, nothing should be printed for any input. * The socket to send the response to is configured via `Socket=` in the `[Ask]` section. It is a `AF_UNIX`/`SOCK_DGRAM` socket in the file system. * Ignore files where the time specified in the `NotAfter=` field in the `[Ask]` section is in the past. The time is specified in usecs, and refers to the `CLOCK_MONOTONIC` clock. If `NotAfter=` is `0`, no such check should take place. From 0d15b2304bd76459d338429e6a6ef1b08e8c1b0d Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 31 Dec 2025 10:59:41 -0500 Subject: [PATCH 06/16] docs/PASSWORD_AGENTS: document the `AcceptCached=` field --- docs/PASSWORD_AGENTS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/PASSWORD_AGENTS.md b/docs/PASSWORD_AGENTS.md index 4badd8a5793d5..7460409d1f4bb 100644 --- a/docs/PASSWORD_AGENTS.md +++ b/docs/PASSWORD_AGENTS.md @@ -42,6 +42,7 @@ It is easy to write additional agents. The basic algorithm to follow looks like there's no need to show the data of this field but if you want to you may) * `Echo=` specifies whether the input should be obscured. If this field is missing or is `Echo=0`, the input should not be shown as-is. * `Silent=` specifies whether the input should have any indication. If this field is `Silent=1`, nothing should be printed for any input. +* `AcceptCached=` specifies whether a cached password is acceptable or not. If this field is missing or is `AcceptCached=0`, the password should not be provided from a cache. * The socket to send the response to is configured via `Socket=` in the `[Ask]` section. It is a `AF_UNIX`/`SOCK_DGRAM` socket in the file system. * Ignore files where the time specified in the `NotAfter=` field in the `[Ask]` section is in the past. The time is specified in usecs, and refers to the `CLOCK_MONOTONIC` clock. If `NotAfter=` is `0`, no such check should take place. From ded0f85f7bbfae64c63865fcf71b6c8179605ed3 Mon Sep 17 00:00:00 2001 From: DaanDeMeyer Date: Thu, 25 Dec 2025 19:24:17 +0100 Subject: [PATCH 07/16] openssl-util: Make ret_user_interface required output argument To avoid the argument accidentally not getting passed anymore during refactoring, let's make it a required output argument so that callers are required to provide it. See 11f47cb70014894a9f09c730ee7aedcac89cf73e and 875b568f56e3a8a23edd9f20463c9019ec098900. --- src/shared/openssl-util.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/shared/openssl-util.c b/src/shared/openssl-util.c index 0e54ae527af00..47c64fd7d4cb8 100644 --- a/src/shared/openssl-util.c +++ b/src/shared/openssl-util.c @@ -1712,17 +1712,20 @@ int openssl_load_private_key( int r; + /* The caller must keep the OpenSSLAskPasswordUI object alive as long as the EVP_PKEY object so that + * the user can enter any needed hardware token pin to unlock the private key when needed. */ + assert(private_key); assert(request); assert(ret_private_key); + assert(ret_user_interface); if (private_key_source_type == OPENSSL_KEY_SOURCE_FILE) { r = openssl_load_private_key_from_file(private_key, ret_private_key); if (r < 0) return r; - if (ret_user_interface) - *ret_user_interface = NULL; + *ret_user_interface = NULL; } else { _cleanup_(openssl_ask_password_ui_freep) OpenSSLAskPasswordUI *ui = NULL; r = openssl_ask_password_ui_new(request, &ui); @@ -1747,8 +1750,7 @@ int openssl_load_private_key( private_key, private_key_source); - if (ret_user_interface) - *ret_user_interface = TAKE_PTR(ui); + *ret_user_interface = TAKE_PTR(ui); } return 0; From 47d22e41e4a679c3e65d6cc09f21f294e37826b1 Mon Sep 17 00:00:00 2001 From: DaanDeMeyer Date: Thu, 1 Jan 2026 20:38:25 +0100 Subject: [PATCH 08/16] unit-def: Clean up whitespace --- src/basic/unit-def.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/basic/unit-def.h b/src/basic/unit-def.h index d346174d56fcf..0324dc5a37433 100644 --- a/src/basic/unit-def.h +++ b/src/basic/unit-def.h @@ -317,7 +317,6 @@ DECLARE_STRING_TABLE_LOOKUP(unit_type, UnitType); void unit_types_list(void); DECLARE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState); - DECLARE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState); DECLARE_STRING_TABLE_LOOKUP(freezer_state, FreezerState); @@ -325,35 +324,20 @@ FreezerState freezer_state_finish(FreezerState state) _const_; FreezerState freezer_state_objective(FreezerState state) _const_; DECLARE_STRING_TABLE_LOOKUP(unit_marker, UnitMarker); - DECLARE_STRING_TABLE_LOOKUP(automount_state, AutomountState); - DECLARE_STRING_TABLE_LOOKUP(device_state, DeviceState); - DECLARE_STRING_TABLE_LOOKUP(mount_state, MountState); - DECLARE_STRING_TABLE_LOOKUP(path_state, PathState); - DECLARE_STRING_TABLE_LOOKUP(scope_state, ScopeState); - DECLARE_STRING_TABLE_LOOKUP(service_state, ServiceState); - DECLARE_STRING_TABLE_LOOKUP(slice_state, SliceState); - DECLARE_STRING_TABLE_LOOKUP(socket_state, SocketState); - DECLARE_STRING_TABLE_LOOKUP(swap_state, SwapState); - DECLARE_STRING_TABLE_LOOKUP(target_state, TargetState); - DECLARE_STRING_TABLE_LOOKUP(timer_state, TimerState); - DECLARE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency); - DECLARE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess); - DECLARE_STRING_TABLE_LOOKUP(job_mode, JobMode); - DECLARE_STRING_TABLE_LOOKUP(exec_directory_type, ExecDirectoryType); Glyph unit_active_state_to_glyph(UnitActiveState state); From ca6b65991ce38d73eb785eb187da8adcec8ad1d1 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Thu, 1 Jan 2026 20:10:45 +0100 Subject: [PATCH 09/16] udev,sysupdated: fix pidfd leak Follow-up for 179dcf924f7d0ac9398f54baeb39b47abd23aeaf After the mentioned commit, event_add_child_pidref() duplicates the pidfd internally, hence the original pidfd would be leaked with TAKE_PIDREF. --- src/sysupdate/sysupdated.c | 2 +- src/udev/udev-watch.c | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/sysupdate/sysupdated.c b/src/sysupdate/sysupdated.c index a9740ee854237..4eeaf3a706213 100644 --- a/src/sysupdate/sysupdated.c +++ b/src/sysupdate/sysupdated.c @@ -543,7 +543,7 @@ static int job_start(Job *j) { r = sd_event_source_set_child_process_own(j->child, true); if (r < 0) return log_error_errno(r, "Event loop failed to take ownership of child process: %m"); - TAKE_PIDREF(pid); + pidref_done(&pid); /* disarm sigkill_wait */ j->stdout_fd = TAKE_FD(stdout_fd); diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c index 76de67733f458..10cbc848460db 100644 --- a/src/udev/udev-watch.c +++ b/src/udev/udev-watch.c @@ -208,11 +208,6 @@ static int synthesize_change(Manager *manager, sd_device *dev) { return 0; } - r = sd_event_source_set_child_pidfd_own(s, true); - if (r < 0) - return r; - TAKE_PIDREF(pidref); - r = set_ensure_put(&manager->synthesize_change_child_event_sources, &event_source_hash_ops, s); if (r < 0) return r; From 4e805ec1522a8b58ae946ad69ec4a6d35f2b1d0c Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 22 Dec 2025 15:11:18 +0100 Subject: [PATCH 10/16] vmspawn: Add --user/--system and support user session machined registration The UX of registering with the user session machined instance is much better as there won't be an authorization prompt. To make that available for users, let's add --user and --system switches for vmspawn. For backwards compat, we'll still try to register with the system machined instance if the user machined instance is not available. --- man/systemd-vmspawn.xml | 12 ++++ shell-completion/bash/systemd-vmspawn | 2 +- src/vmspawn/vmspawn-register.c | 17 ++++-- src/vmspawn/vmspawn-register.h | 3 +- src/vmspawn/vmspawn.c | 80 +++++++++++++++++++++------ 5 files changed, 89 insertions(+), 25 deletions(-) diff --git a/man/systemd-vmspawn.xml b/man/systemd-vmspawn.xml index 7fd19671cbcc4..e51b7e8b6934b 100644 --- a/man/systemd-vmspawn.xml +++ b/man/systemd-vmspawn.xml @@ -69,6 +69,18 @@ + + + + + Specify whether to interact with the user manager or the system manager and whether + to register with the user machined instance or the system machined instance. If + unspecified, the system manager and machined instance will be used when running as root, otherwise + the user manager and machined instance will be used. + + + + diff --git a/shell-completion/bash/systemd-vmspawn b/shell-completion/bash/systemd-vmspawn index 7043ce2c89a47..52c3a84e36c07 100644 --- a/shell-completion/bash/systemd-vmspawn +++ b/shell-completion/bash/systemd-vmspawn @@ -29,7 +29,7 @@ _systemd_vmspawn() { local i verb comps local -A OPTS=( - [STANDALONE]='-h --help --version -q --quiet --no-pager -n --network-tap --network-user-mode' + [STANDALONE]='-h --help --version -q --quiet --no-pager -n --network-tap --network-user-mode --user --system' [PATH]='-D --directory -i --image --linux --initrd --extra-drive --forward-journal' [BOOL]='--kvm --vsock --tpm --secure-boot --discard-disk --register --pass-ssh-key' [FIRMWARE]='--firmware' diff --git a/src/vmspawn/vmspawn-register.c b/src/vmspawn/vmspawn-register.c index b33f86becf094..46f292ce49525 100644 --- a/src/vmspawn/vmspawn-register.c +++ b/src/vmspawn/vmspawn-register.c @@ -12,6 +12,7 @@ #include "errno-util.h" #include "json-util.h" #include "log.h" +#include "path-lookup.h" #include "pidref.h" #include "socket-util.h" #include "string-util.h" @@ -29,7 +30,8 @@ int register_machine( unsigned cid, const char *address, const char *key_path, - bool keep_unit) { + bool allocate_unit, + RuntimeScope scope) { _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; int r; @@ -38,7 +40,12 @@ int register_machine( assert(service); /* First try to use varlink, as it provides more features (such as SSH support). */ - r = sd_varlink_connect_address(&vl, "/run/systemd/machine/io.systemd.Machine"); + _cleanup_free_ char *p = NULL; + r = runtime_directory_generic(scope, "systemd/machine/io.systemd.Machine", &p); + if (r < 0) + return r; + + r = sd_varlink_connect_address(&vl, p); if (r == -ENOENT || ERRNO_IS_DISCONNECT(r)) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -59,12 +66,12 @@ int register_machine( (uint32_t) (pidref_is_set(pidref) ? pidref->pid : 0), strempty(directory)); if (r < 0) - return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r)); + return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r)); return 0; } if (r < 0) - return log_error_errno(r, "Failed to connect to machined on /run/systemd/machine/io.systemd.Machine: %m"); + return log_error_errno(r, "Failed to connect to machined on %p: %m", p); return varlink_callbo_and_log( vl, @@ -79,7 +86,7 @@ int register_machine( SD_JSON_BUILD_PAIR_CONDITION(!!address, "sshAddress", SD_JSON_BUILD_STRING(address)), SD_JSON_BUILD_PAIR_CONDITION(!!key_path, "sshPrivateKeyPath", SD_JSON_BUILD_STRING(key_path)), SD_JSON_BUILD_PAIR_CONDITION(isatty_safe(STDIN_FILENO), "allowInteractiveAuthentication", SD_JSON_BUILD_BOOLEAN(true)), - SD_JSON_BUILD_PAIR_CONDITION(!keep_unit, "allocateUnit", SD_JSON_BUILD_BOOLEAN(true)), + SD_JSON_BUILD_PAIR_CONDITION(allocate_unit, "allocateUnit", SD_JSON_BUILD_BOOLEAN(true)), SD_JSON_BUILD_PAIR_CONDITION(pidref_is_set(pidref), "leaderProcessId", JSON_BUILD_PIDREF(pidref))); } diff --git a/src/vmspawn/vmspawn-register.h b/src/vmspawn/vmspawn-register.h index eeee16f701156..de118b7492fa2 100644 --- a/src/vmspawn/vmspawn-register.h +++ b/src/vmspawn/vmspawn-register.h @@ -13,6 +13,7 @@ int register_machine( unsigned cid, const char *address, const char *key_path, - bool keep_unit); + bool allocate_unit, + RuntimeScope scope); int unregister_machine(sd_bus *bus, const char *machine_name); diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c index 291cac3be1525..8951e19704a77 100644 --- a/src/vmspawn/vmspawn.c +++ b/src/vmspawn/vmspawn.c @@ -123,7 +123,6 @@ static uid_t arg_uid_shift = UID_INVALID, arg_uid_range = 0x10000U; static RuntimeMountContext arg_runtime_mounts = {}; static char *arg_firmware = NULL; static char *arg_forward_journal = NULL; -static bool arg_privileged = false; static bool arg_register = true; static bool arg_keep_unit = false; static sd_id128_t arg_uuid = {}; @@ -144,6 +143,7 @@ static char **arg_bind_user = NULL; static char *arg_bind_user_shell = NULL; static bool arg_bind_user_shell_copy = false; static char **arg_bind_user_groups = NULL; +static RuntimeScope arg_runtime_scope = _RUNTIME_SCOPE_INVALID; STATIC_DESTRUCTOR_REGISTER(arg_directory, freep); STATIC_DESTRUCTOR_REGISTER(arg_image, freep); @@ -184,6 +184,8 @@ static int help(void) { " -q --quiet Do not show status information\n" " --no-pager Do not pipe output into a pager\n" " --no-ask-password Do not prompt for password\n" + " --user Interact with user manager\n" + " --system Interact with system manager\n" "\n%3$sImage:%4$s\n" " -D --directory=PATH Root directory for the VM\n" " -i --image=FILE|DEVICE Root file system disk image or device for the VM\n" @@ -308,6 +310,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_BIND_USER, ARG_BIND_USER_SHELL, ARG_BIND_USER_GROUP, + ARG_SYSTEM, + ARG_USER, }; static const struct option options[] = { @@ -360,6 +364,8 @@ static int parse_argv(int argc, char *argv[]) { { "bind-user", required_argument, NULL, ARG_BIND_USER }, { "bind-user-shell", required_argument, NULL, ARG_BIND_USER_SHELL }, { "bind-user-group", required_argument, NULL, ARG_BIND_USER_GROUP }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "user", no_argument, NULL, ARG_USER }, {} }; @@ -730,6 +736,14 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_SYSTEM: + arg_runtime_scope = RUNTIME_SCOPE_SYSTEM; + break; + + case ARG_USER: + arg_runtime_scope = RUNTIME_SCOPE_USER; + break; + case '?': return -EINVAL; @@ -1808,7 +1822,7 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { /* Registration always happens on the system bus */ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *system_bus = NULL; - if (arg_register || arg_privileged) { + if (arg_register || arg_runtime_scope == RUNTIME_SCOPE_SYSTEM) { r = sd_bus_default_system(&system_bus); if (r < 0) return log_error_errno(r, "Failed to open system bus: %m"); @@ -1823,7 +1837,7 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { /* Scope allocation happens on the user bus if we are unpriv, otherwise system bus. */ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *user_bus = NULL; _cleanup_(sd_bus_unrefp) sd_bus *runtime_bus = NULL; - if (arg_privileged) + if (arg_runtime_scope == RUNTIME_SCOPE_SYSTEM) runtime_bus = sd_bus_ref(system_bus); else { r = sd_bus_default_user(&user_bus); @@ -1949,10 +1963,7 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { if (asprintf(&subdir, "systemd/vmspawn.%" PRIx64, random_u64()) < 0) return log_oom(); - r = runtime_directory( - arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER, - subdir, - &runtime_dir); + r = runtime_directory(arg_runtime_scope, subdir, &runtime_dir); if (r < 0) return log_error_errno(r, "Failed to lookup runtime directory: %m"); if (r > 0) { /* We need to create our own runtime dir */ @@ -2762,7 +2773,7 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { } bool scope_allocated = false; - if (!arg_keep_unit && (!arg_register || !arg_privileged)) { + if (!arg_keep_unit && (!arg_register || arg_runtime_scope != RUNTIME_SCOPE_SYSTEM)) { r = allocate_scope( runtime_bus, arg_machine, @@ -2778,7 +2789,7 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { scope_allocated = true; } else { - if (arg_privileged) + if (arg_runtime_scope == RUNTIME_SCOPE_SYSTEM) r = cg_pid_get_unit(0, &unit); else r = cg_pid_get_user_unit(0, &unit); @@ -2786,7 +2797,7 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { return log_error_errno(r, "Failed to get our own unit: %m"); } - bool registered = false; + bool registered_system = false, registered_runtime = false; if (arg_register) { char vm_address[STRLEN("vsock/") + DECIMAL_STR_MAX(unsigned)]; xsprintf(vm_address, "vsock/%u", child_cid); @@ -2800,11 +2811,38 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { child_cid, child_cid != VMADDR_CID_ANY ? vm_address : NULL, ssh_private_key_path, - arg_keep_unit || !arg_privileged); - if (r < 0) - return r; + !arg_keep_unit && arg_runtime_scope == RUNTIME_SCOPE_SYSTEM, + RUNTIME_SCOPE_SYSTEM); + if (r < 0) { + /* if privileged the request to register definitely failed */ + if (arg_runtime_scope == RUNTIME_SCOPE_SYSTEM) + return r; + + log_notice_errno(r, "Failed to register machine in system context, will try in user context."); + } else + registered_system = true; + + if (arg_runtime_scope == RUNTIME_SCOPE_USER) { + r = register_machine( + runtime_bus, + arg_machine, + arg_uuid, + "systemd-vmspawn", + &child_pidref, + arg_directory, + child_cid, + child_cid != VMADDR_CID_ANY ? vm_address : NULL, + ssh_private_key_path, + !arg_keep_unit, + RUNTIME_SCOPE_USER); + if (r < 0) { + if (!registered_system) /* neither registration worked: fail */ + return r; - registered = true; + log_notice_errno(r, "Failed to register machine in user context, but succeeded in system context, will proceed."); + } else + registered_runtime = true; + } } /* Report that the VM is now set up */ @@ -2905,8 +2943,10 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { if (scope_allocated) terminate_scope(runtime_bus, arg_machine); - if (registered) + if (registered_system) (void) unregister_machine(system_bus, arg_machine); + if (registered_runtime) + (void) unregister_machine(runtime_bus, arg_machine); if (use_vsock) { if (exit_status == INT_MAX) { @@ -2928,8 +2968,12 @@ static int determine_names(void) { if (arg_machine) { _cleanup_(image_unrefp) Image *i = NULL; - r = image_find(arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER, - IMAGE_MACHINE, arg_machine, NULL, &i); + /* Use both user and system images in user mode, use only system images in system mode. */ + r = image_find(arg_runtime_scope == RUNTIME_SCOPE_USER ? _RUNTIME_SCOPE_INVALID : arg_runtime_scope, + IMAGE_MACHINE, + arg_machine, + /* root= */ NULL, + &i); if (r == -ENOENT) return log_error_errno(r, "No image for machine '%s'.", arg_machine); if (r < 0) @@ -2993,7 +3037,7 @@ static int run(int argc, char *argv[]) { log_setup(); - arg_privileged = getuid() == 0; + arg_runtime_scope = getuid() == 0 ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER; r = parse_environment(); if (r < 0) From b671f193e31bf9b80c36c7a7a64ab160f19c0f4a Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Mon, 17 Nov 2025 14:35:11 -0800 Subject: [PATCH 11/16] Enable systemd-coredump for offline updates If a crash occurs during an offline update, we do not get a coredump, because systemd-coredump is not enabled. This of course complicates debugging. Signed-off-by: Adam Williamson --- units/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/units/meson.build b/units/meson.build index 2e04c4aa2b2c8..ddaefc56e8cc5 100644 --- a/units/meson.build +++ b/units/meson.build @@ -310,7 +310,7 @@ units = [ { 'file' : 'systemd-coredump.socket', 'conditions' : ['ENABLE_COREDUMP'], - 'symlinks' : ['sockets.target.wants/'], + 'symlinks' : ['sockets.target.wants/', 'system-update-pre.target.wants/'], }, { 'file' : 'systemd-coredump@.service.in', From 33340fbe445cd58eec1eaac0f3297059e2fae9ed Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 2 Jan 2026 09:52:28 +0900 Subject: [PATCH 12/16] man: drop redundant 'and' Also swap the order of entries, to make it consistent for other unit types. Follow-up for 79dd24cf14adc809620479d45a7b469cf3e82892. --- man/org.freedesktop.systemd1.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml index 466e98aa519f3..708793d7d1bed 100644 --- a/man/org.freedesktop.systemd1.xml +++ b/man/org.freedesktop.systemd1.xml @@ -12664,8 +12664,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \ LogsDirectoryQuotaUsage, LogsDirectoryAccounting, and KillSubgroup() were added in version 258. - OOMKills, and - UserNamespacePath, and + UserNamespacePath, + OOMKills, and ManagedOOMKills were added in 259. BindNetworkInterface was added in version 260. From 99d0a9fdb08d0291dcd06a279bf6e2597f651244 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 17 Aug 2025 21:41:22 +0900 Subject: [PATCH 13/16] Bump required minimum version of OpenSSL to 3.0.0 All major distributions have switched to OpenSSL version 3.x. Let's drop support of OpenSSL version 1.x. Note, OpenSSL 3.0 was released on 2021-09-07 (and will be EOL on 2026-09-07). See also #38608. --- README | 2 +- meson.build | 2 +- src/resolve/resolved-dns-dnssec.c | 2 +- src/shared/openssl-util.c | 205 +----------------------------- src/shared/openssl-util.h | 43 +++---- src/shared/pkcs11-util.c | 26 ---- src/shared/tpm2-util.c | 9 +- src/test/test-openssl.c | 14 -- src/test/test-tpm2.c | 6 +- 9 files changed, 26 insertions(+), 283 deletions(-) diff --git a/README b/README index 84f2b3ae41f25..4fcd111777129 100644 --- a/README +++ b/README @@ -243,7 +243,7 @@ REQUIREMENTS: libcurl >= 7.32.0 (optional) libidn2 or libidn (optional) gnutls >= 3.1.4 (optional) - openssl >= 1.1.0 (optional, required to support DNS-over-TLS) + openssl >= 3.0.0 (optional, required to support DNS-over-TLS) p11-kit >= 0.23.3 (optional) libfido2 (optional) tpm2-tss (optional) diff --git a/meson.build b/meson.build index bcf1ff2df592d..3b179d64e09f6 100644 --- a/meson.build +++ b/meson.build @@ -1355,7 +1355,7 @@ libgnutls = dependency('gnutls', conf.set10('HAVE_GNUTLS', libgnutls.found()) libopenssl = dependency('openssl', - version : '>= 1.1.0', + version : '>= 3.0.0', required : get_option('openssl')) conf.set10('HAVE_OPENSSL', libopenssl.found()) diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c index 537370f0a9c87..ced874e2ba9f2 100644 --- a/src/resolve/resolved-dns-dnssec.c +++ b/src/resolve/resolved-dns-dnssec.c @@ -17,7 +17,7 @@ #include "string-util.h" #include "time-util.h" -#if HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3 +#if HAVE_OPENSSL DISABLE_WARNING_DEPRECATED_DECLARATIONS; DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(RSA*, RSA_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_KEY*, EC_KEY_free, NULL); diff --git a/src/shared/openssl-util.c b/src/shared/openssl-util.c index 47c64fd7d4cb8..e564c2cb7b4e7 100644 --- a/src/shared/openssl-util.c +++ b/src/shared/openssl-util.c @@ -97,21 +97,12 @@ int openssl_digest_size(const char *digest_alg, size_t *ret_digest_size) { assert(digest_alg); assert(ret_digest_size); -#if OPENSSL_VERSION_MAJOR >= 3 _cleanup_(EVP_MD_freep) EVP_MD *md = EVP_MD_fetch(NULL, digest_alg, NULL); -#else - const EVP_MD *md = EVP_get_digestbyname(digest_alg); -#endif if (!md) return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Digest algorithm '%s' not supported.", digest_alg); - size_t digest_size; -#if OPENSSL_VERSION_MAJOR >= 3 - digest_size = EVP_MD_get_size(md); -#else - digest_size = EVP_MD_size(md); -#endif + size_t digest_size = EVP_MD_get_size(md); if (digest_size == 0) return log_openssl_errors("Failed to get Digest size"); @@ -136,11 +127,7 @@ int openssl_digest_many( assert(ret_digest); /* ret_digest_size is optional, as caller may already know the digest size */ -#if OPENSSL_VERSION_MAJOR >= 3 _cleanup_(EVP_MD_freep) EVP_MD *md = EVP_MD_fetch(NULL, digest_alg, NULL); -#else - const EVP_MD *md = EVP_get_digestbyname(digest_alg); -#endif if (!md) return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Digest algorithm '%s' not supported.", digest_alg); @@ -196,16 +183,11 @@ int openssl_hmac_many( assert(ret_digest); /* ret_digest_size is optional, as caller may already know the digest size */ -#if OPENSSL_VERSION_MAJOR >= 3 _cleanup_(EVP_MD_freep) EVP_MD *md = EVP_MD_fetch(NULL, digest_alg, NULL); -#else - const EVP_MD *md = EVP_get_digestbyname(digest_alg); -#endif if (!md) return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Digest algorithm '%s' not supported.", digest_alg); -#if OPENSSL_VERSION_MAJOR >= 3 _cleanup_(EVP_MAC_freep) EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL); if (!mac) return log_openssl_errors("Failed to create new EVP_MAC"); @@ -227,29 +209,12 @@ int openssl_hmac_many( if (!EVP_MAC_init(ctx, key, key_size, params)) return log_openssl_errors("Failed to initialize EVP_MAC_CTX"); -#else - _cleanup_(HMAC_CTX_freep) HMAC_CTX *ctx = HMAC_CTX_new(); - if (!ctx) - return log_openssl_errors("Failed to create new HMAC_CTX"); - - if (!HMAC_Init_ex(ctx, key, key_size, md, NULL)) - return log_openssl_errors("Failed to initialize HMAC_CTX"); -#endif for (size_t i = 0; i < n_data; i++) -#if OPENSSL_VERSION_MAJOR >= 3 if (!EVP_MAC_update(ctx, data[i].iov_base, data[i].iov_len)) -#else - if (!HMAC_Update(ctx, data[i].iov_base, data[i].iov_len)) -#endif return log_openssl_errors("Failed to update HMAC"); - size_t digest_size; -#if OPENSSL_VERSION_MAJOR >= 3 - digest_size = EVP_MAC_CTX_get_mac_size(ctx); -#else - digest_size = HMAC_size(ctx); -#endif + size_t digest_size = EVP_MAC_CTX_get_mac_size(ctx); if (digest_size == 0) return log_openssl_errors("Failed to get HMAC digest size"); @@ -257,13 +222,8 @@ int openssl_hmac_many( if (!buf) return log_oom_debug(); -#if OPENSSL_VERSION_MAJOR >= 3 size_t size; if (!EVP_MAC_final(ctx, buf, &size, digest_size)) -#else - unsigned size; - if (!HMAC_Final(ctx, buf, &size)) -#endif return log_openssl_errors("Failed to finalize HMAC"); assert(size == digest_size); @@ -306,11 +266,7 @@ int openssl_cipher_many( if (asprintf(&cipher_alg, "%s-%zu-%s", alg, bits, mode) < 0) return log_oom_debug(); -#if OPENSSL_VERSION_MAJOR >= 3 _cleanup_(EVP_CIPHER_freep) EVP_CIPHER *cipher = EVP_CIPHER_fetch(NULL, cipher_alg, NULL); -#else - const EVP_CIPHER *cipher = EVP_get_cipherbyname(cipher_alg); -#endif if (!cipher) return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Cipher algorithm '%s' not supported.", cipher_alg); @@ -391,7 +347,6 @@ int kdf_ss_derive( size_t derive_size, void **ret) { -#if OPENSSL_VERSION_MAJOR >= 3 assert(digest); assert(key); assert(derive_size > 0); @@ -437,9 +392,6 @@ int kdf_ss_derive( *ret = TAKE_PTR(buf); return 0; -#else - return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "KDF-SS requires OpenSSL >= 3."); -#endif } /* Perform Key-Based HMAC KDF. The mode must be "COUNTER" or "FEEDBACK". The parameter naming is from the @@ -461,7 +413,6 @@ int kdf_kb_hmac_derive( size_t derive_size, void **ret) { -#if OPENSSL_VERSION_MAJOR >= 3 assert(mode); assert(strcaseeq(mode, "COUNTER") || strcaseeq(mode, "FEEDBACK")); assert(digest); @@ -523,9 +474,6 @@ int kdf_kb_hmac_derive( *ret = TAKE_PTR(buf); return 0; -#else - return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "KDF-KB requires OpenSSL >= 3."); -#endif } int rsa_encrypt_bytes( @@ -583,11 +531,7 @@ int rsa_oaep_encrypt_bytes( assert(ret_encrypt_key); assert(ret_encrypt_key_size); -#if OPENSSL_VERSION_MAJOR >= 3 _cleanup_(EVP_MD_freep) EVP_MD *md = EVP_MD_fetch(NULL, digest_alg, NULL); -#else - const EVP_MD *md = EVP_get_digestbyname(digest_alg); -#endif if (!md) return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Digest algorithm '%s' not supported.", digest_alg); @@ -672,7 +616,6 @@ int rsa_pkey_from_n_e(const void *n, size_t n_size, const void *e, size_t e_size assert(e_size != 0); assert(ret); -#if OPENSSL_VERSION_MAJOR >= 3 _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); if (!ctx) return log_openssl_errors("Failed to create new EVP_PKEY_CTX"); @@ -701,34 +644,6 @@ int rsa_pkey_from_n_e(const void *n, size_t n_size, const void *e, size_t e_size if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0) return log_openssl_errors("Failed to create RSA EVP_PKEY"); -#else - _cleanup_(BN_freep) BIGNUM *bn_n = BN_bin2bn(n, n_size, NULL); - if (!bn_n) - return log_openssl_errors("Failed to create BIGNUM for RSA n"); - - _cleanup_(BN_freep) BIGNUM *bn_e = BN_bin2bn(e, e_size, NULL); - if (!bn_e) - return log_openssl_errors("Failed to create BIGNUM for RSA e"); - - _cleanup_(RSA_freep) RSA *rsa_key = RSA_new(); - if (!rsa_key) - return log_openssl_errors("Failed to create new RSA"); - - if (!RSA_set0_key(rsa_key, bn_n, bn_e, NULL)) - return log_openssl_errors("Failed to set RSA n/e"); - /* rsa_key owns these now, don't free */ - TAKE_PTR(bn_n); - TAKE_PTR(bn_e); - - pkey = EVP_PKEY_new(); - if (!pkey) - return log_openssl_errors("Failed to create new EVP_PKEY"); - - if (!EVP_PKEY_assign_RSA(pkey, rsa_key)) - return log_openssl_errors("Failed to assign RSA key"); - /* pkey owns this now, don't free */ - TAKE_PTR(rsa_key); -#endif *ret = TAKE_PTR(pkey); @@ -749,7 +664,6 @@ int rsa_pkey_to_n_e( assert(ret_e); assert(ret_e_size); -#if OPENSSL_VERSION_MAJOR >= 3 _cleanup_(BN_freep) BIGNUM *bn_n = NULL; if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bn_n)) return log_openssl_errors("Failed to get RSA n"); @@ -757,19 +671,6 @@ int rsa_pkey_to_n_e( _cleanup_(BN_freep) BIGNUM *bn_e = NULL; if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &bn_e)) return log_openssl_errors("Failed to get RSA e"); -#else - const RSA *rsa = EVP_PKEY_get0_RSA((EVP_PKEY*) pkey); - if (!rsa) - return log_openssl_errors("Failed to get RSA key from public key"); - - const BIGNUM *bn_n = RSA_get0_n(rsa); - if (!bn_n) - return log_openssl_errors("Failed to get RSA n"); - - const BIGNUM *bn_e = RSA_get0_e(rsa); - if (!bn_e) - return log_openssl_errors("Failed to get RSA e"); -#endif size_t n_size = BN_num_bytes(bn_n), e_size = BN_num_bytes(bn_e); _cleanup_free_ void *n = malloc(n_size), *e = malloc(e_size); @@ -823,7 +724,6 @@ int ecc_pkey_from_curve_x_y( if (!EC_POINT_set_affine_coordinates(group, point, bn_x, bn_y, NULL)) return log_openssl_errors("Failed to set ECC coordinates"); -#if OPENSSL_VERSION_MAJOR >= 3 if (EVP_PKEY_fromdata_init(ctx) <= 0) return log_openssl_errors("Failed to initialize EVP_PKEY_CTX"); @@ -850,26 +750,6 @@ int ecc_pkey_from_curve_x_y( _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL; if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0) return log_openssl_errors("Failed to create ECC EVP_PKEY"); -#else - _cleanup_(EC_KEY_freep) EC_KEY *eckey = EC_KEY_new(); - if (!eckey) - return log_openssl_errors("Failed to create new EC_KEY"); - - if (!EC_KEY_set_group(eckey, group)) - return log_openssl_errors("Failed to set ECC group"); - - if (!EC_KEY_set_public_key(eckey, point)) - return log_openssl_errors("Failed to set ECC point"); - - _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = EVP_PKEY_new(); - if (!pkey) - return log_openssl_errors("Failed to create new EVP_PKEY"); - - if (!EVP_PKEY_assign_EC_KEY(pkey, eckey)) - return log_openssl_errors("Failed to assign ECC key"); - /* pkey owns this now, don't free */ - TAKE_PTR(eckey); -#endif *ret = TAKE_PTR(pkey); return 0; @@ -888,7 +768,6 @@ int ecc_pkey_to_curve_x_y( assert(pkey); -#if OPENSSL_VERSION_MAJOR >= 3 size_t name_size; if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0, &name_size)) return log_openssl_errors("Failed to get ECC group name size"); @@ -909,31 +788,6 @@ int ecc_pkey_to_curve_x_y( if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &bn_y)) return log_openssl_errors("Failed to get ECC point y"); -#else - const EC_KEY *eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY*) pkey); - if (!eckey) - return log_openssl_errors("Failed to get EC_KEY"); - - const EC_GROUP *group = EC_KEY_get0_group(eckey); - if (!group) - return log_openssl_errors("Failed to get EC_GROUP"); - - curve_id = EC_GROUP_get_curve_name(group); - if (curve_id == NID_undef) - return log_openssl_errors("Failed to get ECC curve id"); - - const EC_POINT *point = EC_KEY_get0_public_key(eckey); - if (!point) - return log_openssl_errors("Failed to get EC_POINT"); - - bn_x = BN_new(); - bn_y = BN_new(); - if (!bn_x || !bn_y) - return log_openssl_errors("Failed to create new BIGNUM"); - - if (!EC_POINT_get_affine_coordinates(group, point, bn_x, bn_y, NULL)) - return log_openssl_errors("Failed to get ECC x/y."); -#endif size_t x_size = BN_num_bytes(bn_x), y_size = BN_num_bytes(bn_y); _cleanup_free_ void *x = malloc(x_size), *y = malloc(y_size); @@ -1247,10 +1101,8 @@ static int ecc_pkey_generate_volume_keys( _cleanup_(erase_and_freep) void *decrypted_key = NULL; _cleanup_free_ unsigned char *saved_key = NULL; size_t decrypted_key_size, saved_key_size; - int nid = NID_undef; int r; -#if OPENSSL_VERSION_MAJOR >= 3 _cleanup_free_ char *curve_name = NULL; size_t len = 0; @@ -1265,19 +1117,7 @@ static int ecc_pkey_generate_volume_keys( if (EVP_PKEY_get_group_name(pkey, curve_name, len, &len) != 1) return log_openssl_errors("Failed to get PKEY group name"); - nid = OBJ_sn2nid(curve_name); -#else - EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); - if (!ec_key) - return log_openssl_errors("PKEY doesn't have EC_KEY associated"); - - if (EC_KEY_check_key(ec_key) != 1) - return log_openssl_errors("EC_KEY associated with PKEY is not valid"); - - nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); -#endif - - r = ecc_pkey_new(nid, &pkey_new); + r = ecc_pkey_new(OBJ_sn2nid(curve_name), &pkey_new); if (r < 0) return log_debug_errno(r, "Failed to generate a new EC keypair: %m"); @@ -1285,38 +1125,11 @@ static int ecc_pkey_generate_volume_keys( if (r < 0) return log_debug_errno(r, "Failed to derive shared secret: %m"); -#if OPENSSL_VERSION_MAJOR >= 3 /* EVP_PKEY_get1_encoded_public_key() always returns uncompressed format of EC points. See https://github.com/openssl/openssl/discussions/22835 */ saved_key_size = EVP_PKEY_get1_encoded_public_key(pkey_new, &saved_key); if (saved_key_size == 0) return log_openssl_errors("Failed to convert the generated public key to SEC1 format"); -#else - EC_KEY *ec_key_new = EVP_PKEY_get0_EC_KEY(pkey_new); - if (!ec_key_new) - return log_openssl_errors("The generated key doesn't have associated EC_KEY"); - - if (EC_KEY_check_key(ec_key_new) != 1) - return log_openssl_errors("EC_KEY associated with the generated key is not valid"); - - saved_key_size = EC_POINT_point2oct(EC_KEY_get0_group(ec_key_new), - EC_KEY_get0_public_key(ec_key_new), - POINT_CONVERSION_UNCOMPRESSED, - NULL, 0, NULL); - if (saved_key_size == 0) - return log_openssl_errors("Failed to determine size of the generated public key"); - - saved_key = malloc(saved_key_size); - if (!saved_key) - return log_oom_debug(); - - saved_key_size = EC_POINT_point2oct(EC_KEY_get0_group(ec_key_new), - EC_KEY_get0_public_key(ec_key_new), - POINT_CONVERSION_UNCOMPRESSED, - saved_key, saved_key_size, NULL); - if (saved_key_size == 0) - return log_openssl_errors("Failed to convert the generated public key to SEC1 format"); -#endif *ret_decrypted_key = TAKE_PTR(decrypted_key); *ret_decrypted_key_size = decrypted_key_size; @@ -1375,11 +1188,7 @@ int pkey_generate_volume_keys( assert(ret_saved_key); assert(ret_saved_key_size); -#if OPENSSL_VERSION_MAJOR >= 3 int type = EVP_PKEY_get_base_id(pkey); -#else - int type = EVP_PKEY_base_id(pkey); -#endif switch (type) { case EVP_PKEY_RSA: @@ -1405,7 +1214,6 @@ static int load_key_from_provider( assert(private_key_uri); assert(ret); -#if OPENSSL_VERSION_MAJOR >= 3 /* Load the provider so that this can work without any custom written configuration in /etc/. * Also load the 'default' as that seems to be the recommendation. */ if (!OSSL_PROVIDER_try_load(/* ctx= */ NULL, provider, /* retain_fallbacks= */ true)) @@ -1436,9 +1244,6 @@ static int load_key_from_provider( *ret = TAKE_PTR(private_key); return 0; -#else - return -EOPNOTSUPP; -#endif } static int load_key_from_engine(const char *engine, const char *private_key_uri, EVP_PKEY **ret) { @@ -1609,7 +1414,6 @@ static int load_x509_certificate_from_provider(const char *provider, const char assert(certificate_uri); assert(ret); -#if OPENSSL_VERSION_MAJOR >= 3 /* Load the provider so that this can work without any custom written configuration in /etc/. * Also load the 'default' as that seems to be the recommendation. */ if (!OSSL_PROVIDER_try_load(/* ctx= */ NULL, provider, /* retain_fallbacks= */ true)) @@ -1640,9 +1444,6 @@ static int load_x509_certificate_from_provider(const char *provider, const char *ret = TAKE_PTR(cert); return 0; -#else - return -EOPNOTSUPP; -#endif } OpenSSLAskPasswordUI* openssl_ask_password_ui_free(OpenSSLAskPasswordUI *ui) { diff --git a/src/shared/openssl-util.h b/src/shared/openssl-util.h index cb48ea8bfd320..218641e06fe61 100644 --- a/src/shared/openssl-util.h +++ b/src/shared/openssl-util.h @@ -32,27 +32,21 @@ int parse_openssl_key_source_argument(const char *argument, char **private_key_s #if HAVE_OPENSSL # include /* IWYU pragma: export */ # include /* IWYU pragma: export */ +# include /* IWYU pragma: export */ # include /* IWYU pragma: export */ # include /* IWYU pragma: export */ # include /* IWYU pragma: export */ +# include /* IWYU pragma: export */ # include /* IWYU pragma: export */ +# include /* IWYU pragma: export */ # include /* IWYU pragma: export */ +# include /* IWYU pragma: export */ # include /* IWYU pragma: export */ +# include /* IWYU pragma: export */ # ifndef OPENSSL_NO_UI_CONSOLE # include /* IWYU pragma: export */ # endif # include /* IWYU pragma: export */ -# ifndef OPENSSL_VERSION_MAJOR -/* OPENSSL_VERSION_MAJOR macro was added in OpenSSL 3. Thus, if it doesn't exist, we must be before OpenSSL 3. */ -# define OPENSSL_VERSION_MAJOR 1 -# endif -# if OPENSSL_VERSION_MAJOR >= 3 -# include /* IWYU pragma: export */ -# include /* IWYU pragma: export */ -# include /* IWYU pragma: export */ -# include /* IWYU pragma: export */ -# include /* IWYU pragma: export */ -# endif DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_MACRO(void*, OPENSSL_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(ASN1_OCTET_STRING*, ASN1_OCTET_STRING_free, NULL); @@ -64,10 +58,20 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(BN_CTX*, BN_CTX_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_GROUP*, EC_GROUP_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_POINT*, EC_POINT_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(ECDSA_SIG*, ECDSA_SIG_free, NULL); +DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_CIPHER*, EVP_CIPHER_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_CIPHER_CTX*, EVP_CIPHER_CTX_free, NULL); +DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_KDF*, EVP_KDF_free, NULL); +DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_KDF_CTX*, EVP_KDF_CTX_free, NULL); +DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MAC*, EVP_MAC_free, NULL); +DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MAC_CTX*, EVP_MAC_CTX_free, NULL); +DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MD*, EVP_MD_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MD_CTX*, EVP_MD_CTX_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_PKEY*, EVP_PKEY_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_PKEY_CTX*, EVP_PKEY_CTX_free, NULL); +DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_PARAM*, OSSL_PARAM_free, NULL); +DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_PARAM_BLD*, OSSL_PARAM_BLD_free, NULL); +DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_STORE_CTX*, OSSL_STORE_close, NULL); +DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_STORE_INFO*, OSSL_STORE_INFO_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(PKCS7*, PKCS7_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(PKCS7_SIGNER_INFO*, PKCS7_SIGNER_INFO_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SSL*, SSL_free, NULL); @@ -94,23 +98,6 @@ static inline STACK_OF(X509_ATTRIBUTE) *x509_attribute_free_many(STACK_OF(X509_A DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(STACK_OF(X509_ATTRIBUTE)*, x509_attribute_free_many, NULL); -#if OPENSSL_VERSION_MAJOR >= 3 -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_CIPHER*, EVP_CIPHER_free, NULL); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_KDF*, EVP_KDF_free, NULL); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_KDF_CTX*, EVP_KDF_CTX_free, NULL); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MAC*, EVP_MAC_free, NULL); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MAC_CTX*, EVP_MAC_CTX_free, NULL); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MD*, EVP_MD_free, NULL); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_PARAM*, OSSL_PARAM_free, NULL); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_PARAM_BLD*, OSSL_PARAM_BLD_free, NULL); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_STORE_CTX*, OSSL_STORE_close, NULL); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_STORE_INFO*, OSSL_STORE_INFO_free, NULL); -#else -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_KEY*, EC_KEY_free, NULL); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(HMAC_CTX*, HMAC_CTX_free, NULL); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(RSA*, RSA_free, NULL); -#endif - static inline void sk_X509_free_allp(STACK_OF(X509) **sk) { if (!sk || !*sk) return; diff --git a/src/shared/pkcs11-util.c b/src/shared/pkcs11-util.c index 2111e4b966c47..3062bcc554196 100644 --- a/src/shared/pkcs11-util.c +++ b/src/shared/pkcs11-util.c @@ -546,7 +546,6 @@ int pkcs11_token_read_public_key( if (!os) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unable to decode CKA_EC_POINT."); -#if OPENSSL_VERSION_MAJOR >= 3 _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); if (!ctx) return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to create an EVP_PKEY_CTX for EC."); @@ -642,31 +641,6 @@ int pkcs11_token_read_public_key( if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, ec_params) != 1) return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to create EVP_PKEY from EC parameters."); -#else - _cleanup_(EC_POINT_freep) EC_POINT *point = EC_POINT_new(group); - if (!point) - return log_oom_debug(); - - if (EC_POINT_oct2point(group, point, os->data, os->length, NULL) != 1) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unable to decode CKA_EC_POINT."); - - _cleanup_(EC_KEY_freep) EC_KEY *ec_key = EC_KEY_new(); - if (!ec_key) - return log_oom_debug(); - - if (EC_KEY_set_group(ec_key, group) != 1) - return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set group for EC_KEY."); - - if (EC_KEY_set_public_key(ec_key, point) != 1) - return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set public key for EC_KEY."); - - pkey = EVP_PKEY_new(); - if (!pkey) - return log_oom_debug(); - - if (EVP_PKEY_set1_EC_KEY(pkey, ec_key) != 1) - return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to assign EC_KEY to EVP_PKEY."); -#endif break; } default: diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index e089cfbc5eaff..4ba83a47ae0dc 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -4354,7 +4354,7 @@ int tpm2_tpm2b_public_to_openssl_pkey(const TPM2B_PUBLIC *public, EVP_PKEY **ret * "name", because it would break unsealing of previously-sealed objects that used (for example) * tpm2_calculate_policy_authorize(). See bug #30546. */ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) { - int key_id, r; + int r; assert(pkey); assert(ret); @@ -4368,12 +4368,7 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) }, }; -#if OPENSSL_VERSION_MAJOR >= 3 - key_id = EVP_PKEY_get_id(pkey); -#else - key_id = EVP_PKEY_id(pkey); -#endif - + int key_id = EVP_PKEY_get_id(pkey); switch (key_id) { case EVP_PKEY_EC: { public.type = TPM2_ALG_ECC; diff --git a/src/test/test-openssl.c b/src/test/test-openssl.c index d4c254e50ad8a..a09484a2ba8ad 100644 --- a/src/test/test-openssl.c +++ b/src/test/test-openssl.c @@ -103,15 +103,12 @@ static const struct { } digest_size_table[] = { /* SHA1 "family" */ { "sha1", 20, }, -#if OPENSSL_VERSION_MAJOR >= 3 { "sha-1", 20, }, -#endif /* SHA2 family */ { "sha224", 28, }, { "sha256", 32, }, { "sha384", 48, }, { "sha512", 64, }, -#if OPENSSL_VERSION_MAJOR >= 3 { "sha-224", 28, }, { "sha2-224", 28, }, { "sha-256", 32, }, @@ -120,7 +117,6 @@ static const struct { { "sha2-384", 48, }, { "sha-512", 64, }, { "sha2-512", 64, }, -#endif /* SHA3 family */ { "sha3-224", 28, }, { "sha3-256", 32, }, @@ -296,7 +292,6 @@ TEST(hmac_many) { } TEST(kdf_kb_hmac_derive) { -#if OPENSSL_VERSION_MAJOR >= 3 _cleanup_free_ void *derived_key = NULL; DEFINE_HEX_PTR(key, "d7ac57124f28371eacaec475b74869d26b4cd64586412a607ce0a9e0c63d468c"); @@ -306,12 +301,8 @@ TEST(kdf_kb_hmac_derive) { assert_se(kdf_kb_hmac_derive("COUNTER", "SHA256", key, key_len, salt, strlen(salt), info, info_len, /* seed= */ NULL, /* seed_size= */ 0, 64, &derived_key) >= 0); assert_se(memcmp_nn(derived_key, 64, expected_derived_key, expected_derived_key_len) == 0); -#else - log_tests_skipped("KDF-KB requires OpenSSL >= 3"); -#endif } -#if OPENSSL_VERSION_MAJOR >= 3 static void check_ss_derive(const char *hex_key, const char *hex_salt, const char *hex_info, const char *hex_expected) { DEFINE_HEX_PTR(key, hex_key); DEFINE_HEX_PTR(salt, hex_salt); @@ -322,10 +313,8 @@ static void check_ss_derive(const char *hex_key, const char *hex_salt, const cha assert_se(kdf_ss_derive("SHA256", key, key_len, salt, salt_len, info, info_len, expected_len, &derived_key) >= 0); assert_se(memcmp_nn(derived_key, expected_len, expected, expected_len) == 0); } -#endif TEST(kdf_ss_derive) { -#if OPENSSL_VERSION_MAJOR >= 3 check_ss_derive( "01166ad6b05d1fad8cdb50d1902170e9", "feea805789dc8d0b57da5d4d61886b1a", @@ -343,9 +332,6 @@ TEST(kdf_ss_derive) { "b75e3b65d1bb845dee581c7e14cfebc6e882946e90273b77ebe289faaf7de248", "ed25a0043d6c1eb28296da1f9ab138dafee18f4c937bfc43601d4ee6e7634199", "30EB1A1E9DEA7DE4DDB8F3FDF50A01E30581D606C1228D98AFF691DF743AC2EE9D99EFD2AE1946C079AA18C9524877FA65D5065F0DAED058AB3416AF80EB2B73"); -#else - log_tests_skipped("KDF-SS requires OpenSSL >= 3"); -#endif } static void check_cipher( diff --git a/src/test/test-tpm2.c b/src/test/test-tpm2.c index 94a92fd2c6e96..a6164f2677d52 100644 --- a/src/test/test-tpm2.c +++ b/src/test/test-tpm2.c @@ -1144,7 +1144,7 @@ static void check_get_or_create_srk(Tpm2Context *c) { assert_se(memcmp_nn(qname->name, qname->size, qname2->name, qname2->size) == 0); } -#if HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3 +#if HAVE_OPENSSL static void calculate_seal_and_unseal( Tpm2Context *c, TPM2_HANDLE parent_index, @@ -1228,7 +1228,7 @@ static int check_calculate_seal(Tpm2Context *c) { return 0; } -#endif /* HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3 */ +#endif /* HAVE_OPENSSL */ static void check_seal_unseal_for_handle(Tpm2Context *c, TPM2_HANDLE handle) { TPM2B_DIGEST policy = TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE); @@ -1330,7 +1330,7 @@ TEST_RET(tests_which_require_tpm) { check_get_or_create_srk(c); check_seal_unseal(c); -#if HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3 /* calculating sealed object requires openssl >= 3 */ +#if HAVE_OPENSSL r = check_calculate_seal(c); #endif From e4fd21a77722a27c5b073184acd79b28edb8aa30 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 17 Aug 2025 22:05:53 +0900 Subject: [PATCH 14/16] Bump required minimum version of blkid to 2.37 Major distributions already have blkid >= 2.37. Let's bump the minimal required version. Note, util-linux (which provides blkid) 2.37 was released on 2021-06-01. See also #38608. --- README | 2 +- meson.build | 3 +-- src/udev/udev-builtin-blkid.c | 12 +----------- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/README b/README index 4fcd111777129..2985d5c4fa512 100644 --- a/README +++ b/README @@ -216,7 +216,7 @@ REQUIREMENTS: libmount >= 2.30 (from util-linux) (util-linux *must* be built without --enable-libmount-support-mtab) libseccomp >= 2.3.1 (optional) - libblkid >= 2.24 (from util-linux) (optional) + libblkid >= 2.37 (from util-linux) (optional) libkmod >= 15 (optional) PAM >= 1.1.2 (optional) libcryptsetup >= 2.0.1 (optional), diff --git a/meson.build b/meson.build index 3b179d64e09f6..90604e41910fd 100644 --- a/meson.build +++ b/meson.build @@ -1229,10 +1229,9 @@ conf.set10('HAVE_AUDIT', libaudit.found()) libaudit_cflags = libaudit.partial_dependency(includes: true, compile_args: true) libblkid = dependency('blkid', + version : '>=2.37.0', required : get_option('blkid')) conf.set10('HAVE_BLKID', libblkid.found()) -conf.set10('HAVE_BLKID_PROBE_SET_HINT', - libblkid.found() and cc.has_function('blkid_probe_set_hint', dependencies : libblkid)) libblkid_cflags = libblkid.partial_dependency(includes: true, compile_args: true) libkmod = dependency('libkmod', diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c index 5e7f78eebced8..6ec02674b9fd6 100644 --- a/src/udev/udev-builtin-blkid.c +++ b/src/udev/udev-builtin-blkid.c @@ -458,21 +458,11 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[]) { switch (option) { case 'H': -#if HAVE_BLKID_PROBE_SET_HINT errno = 0; r = sym_blkid_probe_set_hint(pr, optarg, 0); if (r < 0) return log_device_error_errno(dev, errno_or_else(ENOMEM), "Failed to use '%s' probing hint: %m", optarg); break; -#else - /* Use the hint = as probing offset for old versions */ - optarg = strchr(optarg, '='); - if (!optarg) - /* no value means 0, do nothing for old versions */ - break; - ++optarg; - _fallthrough_; -#endif case 'o': r = safe_atoi64(optarg, &offset); if (r < 0) @@ -489,7 +479,7 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[]) { sym_blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE | -#ifdef BLKID_SUBLKS_FSINFO +#ifdef BLKID_SUBLKS_FSINFO /* since util-linux 2.39 */ BLKID_SUBLKS_FSINFO | #endif BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION); From 9ba0e5674b97291aa975b6f137d8b92199f25606 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 17 Aug 2025 22:19:50 +0900 Subject: [PATCH 15/16] Bump required minimum version of elfutils to 0.177 Major distributions already have elfutils >= 0.190. Let's bump the required minimum version. Note, elfutils 0.177 was released on 2019-08-14. See also #38608. --- README | 2 +- meson.build | 5 +---- src/shared/elf-util.c | 6 ------ 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/README b/README index 2985d5c4fa512..a75f4175e90e7 100644 --- a/README +++ b/README @@ -247,7 +247,7 @@ REQUIREMENTS: p11-kit >= 0.23.3 (optional) libfido2 (optional) tpm2-tss (optional) - elfutils >= 158 (optional) + elfutils >= 177 (optional) polkit (optional) tzdata >= 2014f (optional) pkg-config diff --git a/meson.build b/meson.build index 90604e41910fd..96197002d1c05 100644 --- a/meson.build +++ b/meson.build @@ -1380,6 +1380,7 @@ conf.set10('HAVE_TSS2_ESYS3', tpm2.found() and tpm2.version().version_compare('> conf.set('TPM2_NVPCR_BASE', get_option('tpm2-nvpcr-base')) libdw = dependency('libdw', + version : '>=0.177', required : get_option('elfutils')) libdw_cflags = libdw.partial_dependency(includes: true, compile_args: true) libelf = dependency('libelf', @@ -1387,10 +1388,6 @@ libelf = dependency('libelf', libelf_cflags = libelf.partial_dependency(includes: true, compile_args: true) conf.set10('HAVE_ELFUTILS', libdw.found() and libelf.found()) -# New in elfutils 0.177 -conf.set10('HAVE_DWELF_ELF_E_MACHINE_STRING', - libdw.found() and cc.has_function('dwelf_elf_e_machine_string', dependencies : libdw)) - # New in elfutils 0.192 conf.set10('HAVE_DWFL_SET_SYSROOT', libdw.found() and cc.has_function('dwfl_set_sysroot', dependencies : libdw)) diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c index a8cfb8cd22cb4..9a09352ca7fea 100644 --- a/src/shared/elf-util.c +++ b/src/shared/elf-util.c @@ -47,9 +47,7 @@ static DLSYM_PROTOTYPE(dwarf_formstring) = NULL; static DLSYM_PROTOTYPE(dwarf_getscopes) = NULL; static DLSYM_PROTOTYPE(dwarf_getscopes_die) = NULL; static DLSYM_PROTOTYPE(dwelf_elf_begin) = NULL; -#if HAVE_DWELF_ELF_E_MACHINE_STRING static DLSYM_PROTOTYPE(dwelf_elf_e_machine_string) = NULL; -#endif static DLSYM_PROTOTYPE(dwelf_elf_gnu_build_id) = NULL; static DLSYM_PROTOTYPE(dwarf_tag) = NULL; static DLSYM_PROTOTYPE(dwfl_addrmodule) = NULL; @@ -111,9 +109,7 @@ int dlopen_dw(void) { DLSYM_ARG(dwarf_diename), DLSYM_ARG(dwelf_elf_gnu_build_id), DLSYM_ARG(dwelf_elf_begin), -#if HAVE_DWELF_ELF_E_MACHINE_STRING DLSYM_ARG(dwelf_elf_e_machine_string), -#endif DLSYM_ARG(dwfl_addrmodule), DLSYM_ARG(dwfl_frame_pc), DLSYM_ARG(dwfl_module_addrdie), @@ -773,7 +769,6 @@ static int parse_elf( if (r < 0) return log_warning_errno(r, "Failed to build JSON object: %m"); -#if HAVE_DWELF_ELF_E_MACHINE_STRING const char *elf_architecture = sym_dwelf_elf_e_machine_string(elf_header.e_machine); if (elf_architecture) { r = sd_json_variant_merge_objectbo( @@ -785,7 +780,6 @@ static int parse_elf( if (ret) fprintf(c.m.f, "ELF object binary architecture: %s\n", elf_architecture); } -#endif /* We always at least have the ELF type, so merge that (and possibly the arch). */ r = sd_json_variant_merge_object(&elf_metadata, package_metadata); From 23c82484e7f91c7088bfa29581ed42f851bfdc57 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 17 Aug 2025 21:22:16 +0900 Subject: [PATCH 16/16] Bump required minimum version of cryptsetup to 2.4.0 Major distributions already have cryptsetup newer than 2.4.0. Let's bump the minimal required version. Note, cryptsetup 2.4.0 was released on 2021-08-18. See also #38608. --- README | 3 +-- meson.build | 15 +++------------ src/cryptsetup/cryptsetup.c | 8 -------- src/repart/repart.c | 6 +----- src/shared/cryptsetup-util.c | 18 ------------------ src/shared/cryptsetup-util.h | 18 ------------------ src/veritysetup/veritysetup.c | 4 ---- 7 files changed, 5 insertions(+), 67 deletions(-) diff --git a/README b/README index a75f4175e90e7..9492d717dec06 100644 --- a/README +++ b/README @@ -219,8 +219,7 @@ REQUIREMENTS: libblkid >= 2.37 (from util-linux) (optional) libkmod >= 15 (optional) PAM >= 1.1.2 (optional) - libcryptsetup >= 2.0.1 (optional), - >= 2.3.0 is required for signed Verity images support + libcryptsetup >= 2.4.0 (optional), libaudit (optional) libacl (optional) libbpf >= 0.1.0 (optional), diff --git a/meson.build b/meson.build index 96197002d1c05..26b6fea22ca50 100644 --- a/meson.build +++ b/meson.build @@ -1276,19 +1276,16 @@ if libcryptsetup_plugins.enabled() endif libcryptsetup = dependency('libcryptsetup', - version : libcryptsetup_plugins.enabled() ? '>= 2.4.0' : '>= 2.0.1', + version : '>= 2.4.0', required : libcryptsetup) libcryptsetup_cflags = libcryptsetup.partial_dependency(includes: true, compile_args: true) have = libcryptsetup.found() conf.set10('HAVE_LIBCRYPTSETUP', have) +conf.set10('HAVE_LIBCRYPTSETUP_PLUGINS', + libcryptsetup_plugins.allowed() and have) foreach ident : [ - 'crypt_activate_by_token_pin', # 2.4 - 'crypt_logf', # 2.4 - 'crypt_reencrypt_run', # 2.4 - 'crypt_token_external_path', # 2.4 - 'crypt_token_max', # 2.4 'crypt_set_keyring_to_link', # 2.7 'crypt_token_set_external_path', # 2.7 ] @@ -1300,12 +1297,6 @@ foreach ident : [ conf.set10('HAVE_' + ident.to_upper(), have_ident) endforeach -conf.set10('HAVE_LIBCRYPTSETUP_PLUGINS', - libcryptsetup_plugins.allowed() and - conf.get('HAVE_CRYPT_ACTIVATE_BY_TOKEN_PIN') == 1 and - conf.get('HAVE_CRYPT_LOGF') == 1 and - conf.get('HAVE_CRYPT_TOKEN_EXTERNAL_PATH') == 1) - libcurl = dependency('libcurl', version : '>= 7.32.0', required : get_option('libcurl')) diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index eb545fd0234ff..e61f4b4606ac5 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -331,11 +331,8 @@ static int parse_one_option(const char *option) { arg_no_write_workqueue = true; else if (streq(option, "luks")) arg_type = ANY_LUKS; -/* since cryptsetup 2.3.0 (Feb 2020) */ -#ifdef CRYPT_BITLK else if (streq(option, "bitlk")) arg_type = CRYPT_BITLK; -#endif else if (streq(option, "tcrypt")) arg_type = CRYPT_TCRYPT; else if (STR_IN_SET(option, "tcrypt-hidden", "tcrypthidden")) { @@ -2492,11 +2489,9 @@ static uint32_t determine_flags(void) { if (arg_no_write_workqueue) flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE; -#ifdef CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF /* Try to decrease the risk of OOM event if memory hard key derivation function is in use */ /* https://gitlab.com/cryptsetup/cryptsetup/issues/446/ */ flags |= CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF; -#endif return flags; } @@ -2672,14 +2667,11 @@ static int verb_attach(int argc, char *argv[], void *userdata) { } } -/* since cryptsetup 2.3.0 (Feb 2020) */ -#ifdef CRYPT_BITLK if (streq_ptr(arg_type, CRYPT_BITLK)) { r = crypt_load(cd, CRYPT_BITLK, NULL); if (r < 0) return log_error_errno(r, "Failed to load Bitlocker superblock on device %s: %m", crypt_get_device_name(cd)); } -#endif bool use_cached_passphrase = true, try_discover_key = !key_file; const char *discovered_key_fn = strjoina(volume, ".key"); diff --git a/src/repart/repart.c b/src/repart/repart.c index e3a6e7efafe8b..706349a2cf4e1 100644 --- a/src/repart/repart.c +++ b/src/repart/repart.c @@ -5442,11 +5442,7 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta if (r < 0) return log_error_errno(r, "Failed to load reencryption context: %m"); -#if HAVE_CRYPT_REENCRYPT_RUN r = sym_crypt_reencrypt_run(cd, NULL, NULL); -#else - r = sym_crypt_reencrypt(cd, NULL); -#endif if (r < 0) return log_error_errno(r, "Failed to encrypt %s: %m", node); } else { @@ -5507,7 +5503,7 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta return 0; #else return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "libcryptsetup is not supported or is missing required symbols, cannot encrypt."); + "libcryptsetup is not supported, cannot encrypt."); #endif } diff --git a/src/shared/cryptsetup-util.c b/src/shared/cryptsetup-util.c index 90e98c1b8370e..5d99edd52d106 100644 --- a/src/shared/cryptsetup-util.c +++ b/src/shared/cryptsetup-util.c @@ -39,11 +39,7 @@ DLSYM_PROTOTYPE(crypt_keyslot_max) = NULL; DLSYM_PROTOTYPE(crypt_load) = NULL; DLSYM_PROTOTYPE(crypt_metadata_locking) = NULL; DLSYM_PROTOTYPE(crypt_reencrypt_init_by_passphrase) = NULL; -#if HAVE_CRYPT_REENCRYPT_RUN DLSYM_PROTOTYPE(crypt_reencrypt_run); -#else -DLSYM_PROTOTYPE(crypt_reencrypt); -#endif DLSYM_PROTOTYPE(crypt_resize) = NULL; DLSYM_PROTOTYPE(crypt_resume_by_volume_key) = NULL; DLSYM_PROTOTYPE(crypt_set_data_device) = NULL; @@ -55,15 +51,7 @@ DLSYM_PROTOTYPE(crypt_set_pbkdf_type) = NULL; DLSYM_PROTOTYPE(crypt_suspend) = NULL; DLSYM_PROTOTYPE(crypt_token_json_get) = NULL; DLSYM_PROTOTYPE(crypt_token_json_set) = NULL; -#if HAVE_CRYPT_TOKEN_MAX DLSYM_PROTOTYPE(crypt_token_max) = NULL; -#else -int crypt_token_max(_unused_ const char *type) { - assert(streq(type, CRYPT_LUKS2)); - - return 32; -} -#endif #if HAVE_CRYPT_TOKEN_SET_EXTERNAL_PATH DLSYM_PROTOTYPE(crypt_token_set_external_path) = NULL; #endif @@ -252,11 +240,7 @@ int dlopen_cryptsetup(void) { DLSYM_ARG(crypt_load), DLSYM_ARG(crypt_metadata_locking), DLSYM_ARG(crypt_reencrypt_init_by_passphrase), -#if HAVE_CRYPT_REENCRYPT_RUN DLSYM_ARG(crypt_reencrypt_run), -#else - DLSYM_ARG(crypt_reencrypt), -#endif DLSYM_ARG(crypt_resize), DLSYM_ARG(crypt_resume_by_volume_key), DLSYM_ARG(crypt_set_data_device), @@ -268,9 +252,7 @@ int dlopen_cryptsetup(void) { DLSYM_ARG(crypt_suspend), DLSYM_ARG(crypt_token_json_get), DLSYM_ARG(crypt_token_json_set), -#if HAVE_CRYPT_TOKEN_MAX DLSYM_ARG(crypt_token_max), -#endif #if HAVE_CRYPT_TOKEN_SET_EXTERNAL_PATH DLSYM_ARG(crypt_token_set_external_path), #endif diff --git a/src/shared/cryptsetup-util.h b/src/shared/cryptsetup-util.h index 7c520497967c2..e42debeeb464f 100644 --- a/src/shared/cryptsetup-util.h +++ b/src/shared/cryptsetup-util.h @@ -7,14 +7,6 @@ #if HAVE_LIBCRYPTSETUP #include /* IWYU pragma: export */ -/* These next two are defined in libcryptsetup.h from cryptsetup version 2.3.4 forwards. */ -#ifndef CRYPT_ACTIVATE_NO_READ_WORKQUEUE -#define CRYPT_ACTIVATE_NO_READ_WORKQUEUE (1 << 24) -#endif -#ifndef CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE -#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (1 << 25) -#endif - extern DLSYM_PROTOTYPE(crypt_activate_by_passphrase); extern DLSYM_PROTOTYPE(crypt_activate_by_signed_key); extern DLSYM_PROTOTYPE(crypt_activate_by_volume_key); @@ -39,11 +31,7 @@ extern DLSYM_PROTOTYPE(crypt_keyslot_max); extern DLSYM_PROTOTYPE(crypt_load); extern DLSYM_PROTOTYPE(crypt_metadata_locking); extern DLSYM_PROTOTYPE(crypt_reencrypt_init_by_passphrase); -#if HAVE_CRYPT_REENCRYPT_RUN extern DLSYM_PROTOTYPE(crypt_reencrypt_run); -#else -extern DLSYM_PROTOTYPE(crypt_reencrypt); -#endif extern DLSYM_PROTOTYPE(crypt_resize); extern DLSYM_PROTOTYPE(crypt_resume_by_volume_key); extern DLSYM_PROTOTYPE(crypt_set_data_device); @@ -55,13 +43,7 @@ extern DLSYM_PROTOTYPE(crypt_set_pbkdf_type); extern DLSYM_PROTOTYPE(crypt_suspend); extern DLSYM_PROTOTYPE(crypt_token_json_get); extern DLSYM_PROTOTYPE(crypt_token_json_set); -#if HAVE_CRYPT_TOKEN_MAX extern DLSYM_PROTOTYPE(crypt_token_max); -#else -/* As a fallback, use the same hard-coded value libcryptsetup uses internally. */ -int crypt_token_max(_unused_ const char *type); -#define sym_crypt_token_max(type) crypt_token_max(type) -#endif #if HAVE_CRYPT_TOKEN_SET_EXTERNAL_PATH extern DLSYM_PROTOTYPE(crypt_token_set_external_path); #endif diff --git a/src/veritysetup/veritysetup.c b/src/veritysetup/veritysetup.c index 586af5c62383f..91b5bcaaa28d3 100644 --- a/src/veritysetup/veritysetup.c +++ b/src/veritysetup/veritysetup.c @@ -161,14 +161,10 @@ static int parse_options(const char *options) { arg_activate_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION; else if (streq(word, "ignore-zero-blocks")) arg_activate_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS; -#ifdef CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE else if (streq(word, "check-at-most-once")) arg_activate_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE; -#endif -#ifdef CRYPT_ACTIVATE_PANIC_ON_CORRUPTION else if (streq(word, "panic-on-corruption")) arg_activate_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION; -#endif else if ((val = startswith(word, "superblock="))) { r = parse_boolean(val);