diff -Nru systemd-246.6/debian/changelog systemd-246.6/debian/changelog --- systemd-246.6/debian/changelog 2021-03-10 21:03:13.000000000 +0000 +++ systemd-246.6/debian/changelog 2021-05-27 15:13:07.000000000 +0000 @@ -1,3 +1,38 @@ +systemd (246.6-1ubuntu1.4) groovy; urgency=medium + + [ Andy Chi ] + * debian/patches/lp1926547-hwdb-60-keyboard-Update-Dell-Privacy-Local-Mic-Mute-.patch + - Apply upstream patch to correct key and device mapping. + (LP: #1926547) + https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=a4c14d1c8370445e315ffa59b0a7ce593a79fbf4 + + [ Dan Streetman ] + * d/p/lp1921696/0001-rfkill-improve-error-logging.patch, + d/p/lp1921696/0002-rfkill-use-short-writes-and-accept-long-reads.patch: + Handle rfkill api change in kernel 5.10 (LP: #1921696) + https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=b683c842c74b5f193555fd79bc76e574a025f5b1 + * d/p/lp1929560-network-move-set-MAC-and-set-nomaster-operations-out.patch: + Move link mac and master config out of link_up() (LP: #1929560) + https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=a90963d52a70c0ed1b429b1025b95f8c0fa6e7aa + * d/p/lp1902891-core-mount-mount-command-may-fail-after-adding-the-c.patch: + Handle failed mount command (LP: #1902891) + https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=d83f3bce38e04395c6406c3c45efbc9977ae1138 + * d/p/debian/UBUNTU-resolved-Mitigate-DVE-2018-0001-by-retrying-NXDOMAIN-with.patch, + d/p/lp1880258-log-nxdomain-as-debug.patch, + d/p/lp1785383-resolved-address-DVE-2018-0001.patch: + - Use upstream patch for DVE-2018-0001 handling (LP: #1785383) + https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=eb311ad89c5fd570bf3af362d8a2af1b357be3dd + + [ Ɓukasz 'sil2100' Zemczak ] + * d/p/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch, + d/p/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch, + d/p/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch: + - add support for configuring the activation policy for an interface + (LP: #1664844) + https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=0b0a9202964b24fb8d9fb4b28bdb22c6aadd25b7 + + -- Dan Streetman Thu, 27 May 2021 11:13:07 -0400 + systemd (246.6-1ubuntu1.3) groovy; urgency=medium * d/p/lp1918696-shared-seccomp-util-address-family-filtering-is-brok.patch: diff -Nru systemd-246.6/debian/patches/debian/UBUNTU-resolved-Mitigate-DVE-2018-0001-by-retrying-NXDOMAIN-with.patch systemd-246.6/debian/patches/debian/UBUNTU-resolved-Mitigate-DVE-2018-0001-by-retrying-NXDOMAIN-with.patch --- systemd-246.6/debian/patches/debian/UBUNTU-resolved-Mitigate-DVE-2018-0001-by-retrying-NXDOMAIN-with.patch 2021-03-10 21:03:13.000000000 +0000 +++ systemd-246.6/debian/patches/debian/UBUNTU-resolved-Mitigate-DVE-2018-0001-by-retrying-NXDOMAIN-with.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -From: Dimitri John Ledkov -Date: Wed, 28 Mar 2018 23:05:17 +0100 -Subject: resolved: Mitigate DVE-2018-0001, - by retrying NXDOMAIN without EDNS0. - -Some captive portals, lie and do not respond with the captive portal IP -address, if the query is with EDNS0 enabled and DO bit set to zero. Thus retry -all domain name look ups with less secure methods, upon NXDOMAIN. Unless strict -DNSSEC validation is enabled. - -Refreshed patch from new upstream patch from xnox. - -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/bionic/+source/systemd/+bug/1766969 -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/bionic/+source/systemd/+bug/1727237 -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1796501 -Bug-DNS: https://github.com/dns-violations/dns-violations/blob/master/2018/DVE-2018-0001.md -(cherry picked from commit cc0a0eb1a9379a81256d68d65f8450a487c0ab12) ---- - src/resolve/resolved-dns-transaction.c | 38 +++++++++++++++++++++++++++++----- - 1 file changed, 33 insertions(+), 5 deletions(-) - -diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c -index 016ff01..fd7cbe0 100644 ---- a/src/resolve/resolved-dns-transaction.c -+++ b/src/resolve/resolved-dns-transaction.c -@@ -384,12 +384,12 @@ static int dns_transaction_pick_server(DnsTransaction *t) { - if (!server) - return -ESRCH; - -- /* If we changed the server invalidate the feature level clamping, as the new server might have completely -- * different properties. */ -- if (server != t->server) -+ /* If we changed the server invalidate the current & clamp feature levels, as the new server might have -+ * completely different properties. */ -+ if (server != t->server) { - t->clamp_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID; -- -- t->current_feature_level = dns_server_possible_feature_level(server); -+ t->current_feature_level = dns_server_possible_feature_level(server); -+ } - - /* Clamp the feature level if that is requested. */ - if (t->clamp_feature_level != _DNS_SERVER_FEATURE_LEVEL_INVALID && -@@ -1028,6 +1028,34 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) { - return; - } - -+ /* Some captive portals are special in that the Aruba/Datavalet hardware will miss replacing the -+ * packets with the local server IP to point to the authenticated side of the network if EDNS0 is -+ * enabled. Instead they return NXDOMAIN, with DO bit set to zero... nothing to see here, yet respond -+ * with the captive portal IP, when using the more simple UDP level. -+ * -+ * Common portal names that fail like so are: -+ * secure.datavalet.io -+ * securelogin.arubanetworks.com -+ * securelogin.networks.mycompany.com -+ * -+ * Thus retry NXDOMAIN RCODES with a lower feature level. -+ * -+ * Do not "clamp" the feature level down, as the captive portal should not be lying for the wider -+ * internet (e.g. _other_ queries were observed fine with EDNS0 on these networks, post auth) -+ * -+ * This is reported as https://github.com/dns-violations/dns-violations/blob/master/2018/DVE-2018-0001.md -+ */ -+ if (DNS_PACKET_RCODE(p) == DNS_RCODE_NXDOMAIN && t->current_feature_level >= DNS_SERVER_FEATURE_LEVEL_EDNS0 && t->scope->dnssec_mode != DNSSEC_YES) { -+ char key_str[DNS_RESOURCE_KEY_STRING_MAX]; -+ dns_resource_key_to_string(t->key, key_str, sizeof key_str); -+ t->current_feature_level = DNS_SERVER_FEATURE_LEVEL_UDP; -+ log_warning("Server returned error %s, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level %s.", -+ dns_rcode_to_string(DNS_PACKET_RCODE(p)), -+ dns_server_feature_level_to_string(t->current_feature_level)); -+ dns_transaction_retry(t, false /* use the same server */); -+ return; -+ } -+ - if (DNS_PACKET_RCODE(p) == DNS_RCODE_REFUSED) { - /* This server refused our request? If so, try again, use a different server */ - log_debug("Server returned REFUSED, switching servers, and retrying."); diff -Nru systemd-246.6/debian/patches/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch systemd-246.6/debian/patches/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch --- systemd-246.6/debian/patches/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-246.6/debian/patches/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch 2021-05-27 15:12:21.000000000 +0000 @@ -0,0 +1,344 @@ +From 61135582e0b2e847e49c96af05e4d101323ce00c Mon Sep 17 00:00:00 2001 +From: Dan Streetman +Date: Thu, 18 Jun 2020 16:09:40 -0400 +Subject: [PATCH 1/3] network: add ActivationPolicy= configuration parameter +Origin: upstream, https://github.com/systemd/systemd/pull/16228 +Bug-Ubuntu: https://bugs.launchpad.net/netplan/+bug/1664844 + +This parameter allows configuring the activation policy for an interface, +meaning how it manages the interface's administrative state (IFF_UP flag). +The policy can be configured to bring the interface either up or down when +the interface is (re)configured, to always force the interface either up or +down, or to never change the interface administrative state. + +If the interface is bound with BindCarrier=, its administrative state is +controlled by the interface(s) it's bound to, and this parameter is forced +to 'bound'. + +This changes the default behavior of how systemd-networkd sets the IFF_UP +flag; previously, it was set up (if not already up) every time the +link_joined() function was called. Now, with the default ActivationPolicy= +setting of 'up', it will only set the IFF_UP flag once, the first time +link_joined() is called, during an interface's configuration; and on +the first link_joined() call each time the interface is reconfigured. + +Fixes: #3031 +Fixes: #17437 +--- + man/systemd.network.xml | 39 ++++++++++++- + src/network/networkd-link.c | 58 ++++++++++++++++++- + src/network/networkd-link.h | 1 + + src/network/networkd-network-gperf.gperf | 1 + + src/network/networkd-network.c | 40 ++++++++++++- + src/network/networkd-network.h | 16 +++++ + .../fuzz-network-parser/directives.network | 1 + + 7 files changed, 148 insertions(+), 8 deletions(-) + +--- a/man/systemd.network.xml ++++ b/man/systemd.network.xml +@@ -228,6 +228,36 @@ + if RequiredForOnline=no. + + ++ ++ ActivationPolicy= ++ ++ Specifies the policy for systemd-networkd managing the link ++ administrative state. Specifically, this controls how systemd-networkd ++ changes the network device's IFF_UP flag, which is sometimes ++ controlled by system administrators by running e.g., ip set dev eth0 up ++ or ip set dev eth0 down, and can also be changed with ++ networkctl up eth0 or networkctl down eth0. ++ ++ Takes one of up, always-up, ++ manual, always-down, down, ++ or bound. When manual, systemd-networkd ++ will not change the link's admin state automatically; the system administrator must bring the ++ interface up or down manually, as desired. When up (the default) or ++ always-up, or down or always-down, ++ systemd-networkd will set the link up or down, respectively, ++ when the interface is (re)configured. When always-up or ++ always-down, systemd-networkd will set the link up ++ or down, respectively, any time systemd-networkd detects a change in ++ the administrative state. When BindCarrier= is also set, this is ++ automatically set to bound and any other value is ignored. ++ ++ The administrative state is not the same as the carrier state, so using ++ always-up does not mean the link will never lose carrier. The link ++ carrier depends on both the administrative state as well as the network device's physical ++ connection. However, to avoid reconfiguration failures, when using always-up, ++ IgnoreCarrierLoss= is forced to true. ++ ++ + + + +@@ -561,8 +591,9 @@ + + A link name or a list of link names. When set, controls the behavior of the current + link. When all links in the list are in an operational down state, the current link is brought +- down. When at least one link has carrier, the current interface is brought up. +- ++ down. When at least one link has carrier, the current interface is brought up. ++ ++ This forces ActivationPolicy= to be set to bound. + + + +@@ -929,6 +960,10 @@ + of the interface even if its carrier is lost. When unset, the value specified with + is used. + ++ ++ When ActivationPolicy= is set to always-up, this ++ is forced to true. ++ + + + +--- a/src/network/networkd-link.c ++++ b/src/network/networkd-link.c +@@ -2332,17 +2332,38 @@ + assert(link); + assert(link->network); + +- if (!hashmap_isempty(link->bound_to_links)) { ++ switch (link->network->activation_policy) { ++ case ACTIVATION_POLICY_BOUND: + r = link_handle_bound_to_list(link); + if (r < 0) + return r; +- } else if (!(link->flags & IFF_UP)) { ++ break; ++ case ACTIVATION_POLICY_UP: ++ if (link->activated) ++ break; ++ _fallthrough_; ++ case ACTIVATION_POLICY_ALWAYS_UP: + r = link_up(link); + if (r < 0) { + link_enter_failed(link); + return r; + } ++ break; ++ case ACTIVATION_POLICY_DOWN: ++ if (link->activated) ++ break; ++ _fallthrough_; ++ case ACTIVATION_POLICY_ALWAYS_DOWN: ++ r = link_down(link, NULL); ++ if (r < 0) { ++ link_enter_failed(link); ++ return r; ++ } ++ break; ++ default: ++ break; + } ++ link->activated = true; + + if (link->network->bridge) { + r = link_set_bridge(link); +@@ -3417,6 +3438,7 @@ + return r; + + link_set_state(link, LINK_STATE_PENDING); ++ link->activated = false; + link_dirty(link); + + /* link_configure_duid() returns 0 if it requests product UUID. In that case, +@@ -3992,6 +4014,16 @@ + static int link_admin_state_up(Link *link) { + int r; + ++ assert(link); ++ ++ if (!link->network) ++ return 0; ++ ++ if (link->network->activation_policy == ACTIVATION_POLICY_ALWAYS_DOWN) { ++ log_link_info(link, "ActivationPolicy is \"always-off\", forcing link down"); ++ return link_down(link, NULL); ++ } ++ + /* We set the ipv6 mtu after the device mtu, but the kernel resets + * ipv6 mtu on NETDEV_UP, so we need to reset it. The check for + * ipv6_mtu_set prevents this from trying to set it too early before +@@ -4006,6 +4038,21 @@ + return 0; + } + ++static int link_admin_state_down(Link *link) { ++ ++ assert(link); ++ ++ if (!link->network) ++ return 0; ++ ++ if (link->network->activation_policy == ACTIVATION_POLICY_ALWAYS_UP) { ++ log_link_info(link, "ActivationPolicy is \"always-on\", forcing link up"); ++ return link_up(link); ++ } ++ ++ return 0; ++} ++ + int link_update(Link *link, sd_netlink_message *m) { + _cleanup_strv_free_ char **s = NULL; + struct ether_addr mac; +@@ -4194,9 +4241,14 @@ + r = link_admin_state_up(link); + if (r < 0) + return r; +- } else if (link_was_admin_up && !(link->flags & IFF_UP)) ++ } else if (link_was_admin_up && !(link->flags & IFF_UP)) { + log_link_info(link, "Link DOWN"); + ++ r = link_admin_state_down(link); ++ if (r < 0) ++ return r; ++ } ++ + r = link_update_lldp(link); + if (r < 0) + return r; +--- a/src/network/networkd-link.h ++++ b/src/network/networkd-link.h +@@ -123,6 +123,7 @@ + bool setting_mtu:1; + bool setting_genmode:1; + bool ipv6_mtu_set:1; ++ bool activated:1; + + LIST_HEAD(Address, pool_addresses); + +--- a/src/network/networkd-network-gperf.gperf ++++ b/src/network/networkd-network-gperf.gperf +@@ -53,6 +53,7 @@ + Link.Multicast, config_parse_tristate, 0, offsetof(Network, multicast) + Link.AllMulticast, config_parse_tristate, 0, offsetof(Network, allmulticast) + Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged) ++Link.ActivationPolicy, config_parse_activation_policy, 0, offsetof(Network, activation_policy) + Link.RequiredForOnline, config_parse_required_for_online, 0, 0 + SR-IOV.VirtualFunction, config_parse_sr_iov_uint32, 0, 0 + SR-IOV.VLANId, config_parse_sr_iov_uint32, 0, 0 +--- a/src/network/networkd-network.c ++++ b/src/network/networkd-network.c +@@ -274,9 +274,6 @@ + if (network->dhcp_use_gateway < 0) + network->dhcp_use_gateway = network->dhcp_use_routes; + +- if (network->ignore_carrier_loss < 0) +- network->ignore_carrier_loss = network->configure_without_carrier; +- + if (network->dhcp_critical >= 0) { + if (network->keep_configuration >= 0) + log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. " +@@ -288,6 +285,30 @@ + network->keep_configuration = KEEP_CONFIGURATION_NO; + } + ++ if (!strv_isempty(network->bind_carrier)) { ++ if (!IN_SET(network->activation_policy, _ACTIVATION_POLICY_INVALID, ACTIVATION_POLICY_BOUND)) ++ log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. " ++ "Setting ActivationPolicy=bound.", network->filename); ++ network->activation_policy = ACTIVATION_POLICY_BOUND; ++ } else if (network->activation_policy == ACTIVATION_POLICY_BOUND) { ++ log_warning("%s: ActivationPolicy=bound requires BindCarrier=. " ++ "Ignoring ActivationPolicy=bound.", network->filename); ++ network->activation_policy = ACTIVATION_POLICY_UP; ++ } ++ ++ if (network->activation_policy == _ACTIVATION_POLICY_INVALID) ++ network->activation_policy = ACTIVATION_POLICY_UP; ++ ++ if (network->activation_policy == ACTIVATION_POLICY_ALWAYS_UP) { ++ if (network->ignore_carrier_loss == false) ++ log_warning("%s: IgnoreCarrierLoss=false conflicts with ActivationPolicy=always-up. " ++ "Setting IgnoreCarrierLoss=true.", network->filename); ++ network->ignore_carrier_loss = true; ++ } ++ ++ if (network->ignore_carrier_loss < 0) ++ network->ignore_carrier_loss = network->configure_without_carrier; ++ + if (network->keep_configuration < 0) + network->keep_configuration = KEEP_CONFIGURATION_NO; + +@@ -392,6 +413,7 @@ + + .required_for_online = true, + .required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT, ++ .activation_policy = _ACTIVATION_POLICY_INVALID, + .dhcp = ADDRESS_FAMILY_NO, + .dhcp_critical = -1, + .dhcp_use_ntp = true, +@@ -1418,3 +1440,15 @@ + + DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode, IPv6LinkLocalAddressGenMode); + DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_link_local_address_gen_mode, ipv6_link_local_address_gen_mode, IPv6LinkLocalAddressGenMode, "Failed to parse IPv6 link local address generation mode"); ++ ++static const char* const activation_policy_table[_ACTIVATION_POLICY_MAX] = { ++ [ACTIVATION_POLICY_UP] = "up", ++ [ACTIVATION_POLICY_ALWAYS_UP] = "always-up", ++ [ACTIVATION_POLICY_MANUAL] = "manual", ++ [ACTIVATION_POLICY_ALWAYS_DOWN] = "always-down", ++ [ACTIVATION_POLICY_DOWN] = "down", ++ [ACTIVATION_POLICY_BOUND] = "bound", ++}; ++ ++DEFINE_STRING_TABLE_LOOKUP(activation_policy, ActivationPolicy); ++DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy, activation_policy, ActivationPolicy, "Failed to parse activation policy"); +--- a/src/network/networkd-network.h ++++ b/src/network/networkd-network.h +@@ -63,6 +63,17 @@ + _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID = -1 + } IPv6LinkLocalAddressGenMode; + ++typedef enum ActivationPolicy { ++ ACTIVATION_POLICY_UP, ++ ACTIVATION_POLICY_ALWAYS_UP, ++ ACTIVATION_POLICY_MANUAL, ++ ACTIVATION_POLICY_ALWAYS_DOWN, ++ ACTIVATION_POLICY_DOWN, ++ ACTIVATION_POLICY_BOUND, ++ _ACTIVATION_POLICY_MAX, ++ _ACTIVATION_POLICY_INVALID = -1 ++} ActivationPolicy; ++ + typedef struct Manager Manager; + + typedef struct NetworkDHCPServerEmitAddress { +@@ -278,6 +289,7 @@ + + bool required_for_online; /* Is this network required to be considered online? */ + LinkOperationalStateRange required_operstate_for_online; ++ ActivationPolicy activation_policy; + + /* LLDP support */ + LLDPMode lldp_mode; /* LLDP reception */ +@@ -367,6 +379,7 @@ + CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online); + CONFIG_PARSER_PROTOTYPE(config_parse_keep_configuration); + CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_link_local_address_gen_mode); ++CONFIG_PARSER_PROTOTYPE(config_parse_activation_policy); + + const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, GPERF_LEN_TYPE length); + +@@ -378,3 +391,6 @@ + + const char* ipv6_link_local_address_gen_mode_to_string(IPv6LinkLocalAddressGenMode s) _const_; + IPv6LinkLocalAddressGenMode ipv6_link_local_address_gen_mode_from_string(const char *s) _pure_; ++ ++const char* activation_policy_to_string(ActivationPolicy i) _const_; ++ActivationPolicy activation_policy_from_string(const char *s) _pure_; +--- a/test/fuzz/fuzz-network-parser/directives.network ++++ b/test/fuzz/fuzz-network-parser/directives.network +@@ -30,6 +30,7 @@ + MACAddress= + PermanentMACAddress= + [Link] ++ActivationPolicy= + RequiredForOnline= + ARP= + AllMulticast= diff -Nru systemd-246.6/debian/patches/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch systemd-246.6/debian/patches/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch --- systemd-246.6/debian/patches/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-246.6/debian/patches/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch 2021-05-27 15:12:21.000000000 +0000 @@ -0,0 +1,121 @@ +From 2236d75df955118ad5d84c5ab787484c0921dfda Mon Sep 17 00:00:00 2001 +From: Dan Streetman +Date: Thu, 18 Jun 2020 18:31:18 -0400 +Subject: [PATCH 2/3] test: add ActivationPolicy= unit tests +Origin: upstream, https://github.com/systemd/systemd/pull/16228 +Bug-Ubuntu: https://bugs.launchpad.net/netplan/+bug/1664844 + +--- + .../conf/25-activation-policy.network | 6 +++ + .../always-down.conf | 2 + + .../always-up.conf | 2 + + .../25-activation-policy.network.d/down.conf | 2 + + .../manual.conf | 2 + + .../25-activation-policy.network.d/up.conf | 2 + + test/test-network/systemd-networkd-tests.py | 48 +++++++++++++++++++ + 7 files changed, 64 insertions(+) + create mode 100644 test/test-network/conf/25-activation-policy.network + create mode 100644 test/test-network/conf/25-activation-policy.network.d/always-down.conf + create mode 100644 test/test-network/conf/25-activation-policy.network.d/always-up.conf + create mode 100644 test/test-network/conf/25-activation-policy.network.d/down.conf + create mode 100644 test/test-network/conf/25-activation-policy.network.d/manual.conf + create mode 100644 test/test-network/conf/25-activation-policy.network.d/up.conf + +--- /dev/null ++++ b/test/test-network/conf/25-activation-policy.network +@@ -0,0 +1,6 @@ ++[Match] ++Name=test1 ++ ++[Network] ++Address=192.168.10.30/24 ++Gateway=192.168.10.1 +--- /dev/null ++++ b/test/test-network/conf/25-activation-policy.network.d/always-down.conf +@@ -0,0 +1,2 @@ ++[Link] ++ActivationPolicy=always-down +--- /dev/null ++++ b/test/test-network/conf/25-activation-policy.network.d/always-up.conf +@@ -0,0 +1,2 @@ ++[Link] ++ActivationPolicy=always-up +--- /dev/null ++++ b/test/test-network/conf/25-activation-policy.network.d/down.conf +@@ -0,0 +1,2 @@ ++[Link] ++ActivationPolicy=down +--- /dev/null ++++ b/test/test-network/conf/25-activation-policy.network.d/manual.conf +@@ -0,0 +1,2 @@ ++[Link] ++ActivationPolicy=manual +--- /dev/null ++++ b/test/test-network/conf/25-activation-policy.network.d/up.conf +@@ -0,0 +1,2 @@ ++[Link] ++ActivationPolicy=up +--- a/test/test-network/systemd-networkd-tests.py ++++ b/test/test-network/systemd-networkd-tests.py +@@ -1693,6 +1693,7 @@ + '25-address-link-section.network', + '25-address-preferred-lifetime-zero.network', + '25-address-static.network', ++ '25-activation-policy.network', + '25-bind-carrier.network', + '25-bond-active-backup-slave.netdev', + '25-fibrule-invert.network', +@@ -2429,6 +2430,53 @@ + self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1') + self.wait_operstate('test1', 'routable') + ++ def _test_activation_policy(self, test): ++ self.setUp() ++ conffile = '25-activation-policy.network' ++ if test: ++ conffile = f'{conffile}.d/{test}.conf' ++ copy_unit_to_networkd_unit_path('11-dummy.netdev', conffile, dropins=False) ++ start_networkd() ++ ++ always = test.startswith('always') ++ if test == 'manual': ++ initial_up = 'UP' in check_output('ip link show test1') ++ else: ++ initial_up = not test.endswith('down') # note: default is up ++ expect_up = initial_up ++ next_up = not expect_up ++ ++ # if initial expected state is down, must wait for setup_state to reach configuring ++ # so systemd-networkd considers it 'activated' ++ setup_state = None if initial_up else 'configuring' ++ ++ for iteration in range(4): ++ with self.subTest(iteration=iteration, expect_up=expect_up): ++ operstate = 'routable' if expect_up else 'off' ++ self.wait_operstate('test1', operstate, setup_state=setup_state, setup_timeout=20) ++ setup_state = None ++ ++ if expect_up: ++ self.assertIn('UP', check_output('ip link show test1')) ++ self.assertIn('192.168.10.30/24', check_output('ip address show test1')) ++ self.assertIn('default via 192.168.10.1', check_output('ip route show')) ++ else: ++ self.assertIn('DOWN', check_output('ip link show test1')) ++ ++ if next_up: ++ check_output('ip link set dev test1 up') ++ else: ++ check_output('ip link set dev test1 down') ++ expect_up = initial_up if always else next_up ++ next_up = not next_up ++ ++ self.tearDown() ++ ++ def test_activation_policy(self): ++ for test in ['up', 'always-up', 'manual', 'always-down', 'down', '']: ++ with self.subTest(test=test): ++ self._test_activation_policy(test) ++ + def test_domain(self): + copy_unit_to_networkd_unit_path('12-dummy.netdev', '24-search-domain.network') + start_networkd() diff -Nru systemd-246.6/debian/patches/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch systemd-246.6/debian/patches/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch --- systemd-246.6/debian/patches/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-246.6/debian/patches/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch 2021-05-27 15:12:21.000000000 +0000 @@ -0,0 +1,110 @@ +From a853652ae983699460b160bc2bf72f6fae0bfcd6 Mon Sep 17 00:00:00 2001 +From: Dan Streetman +Date: Thu, 13 Aug 2020 11:52:53 -0400 +Subject: [PATCH 3/3] save link activation policy to state file and display in + networkctl +Origin: upstream, https://github.com/systemd/systemd/pull/16228 +Bug-Ubuntu: https://bugs.launchpad.net/netplan/+bug/1664844 + +--- + src/libsystemd/sd-network/sd-network.c | 21 +++++++++++++++++++++ + src/network/networkctl.c | 12 +++++++++++- + src/network/networkd-link.c | 3 +++ + src/systemd/sd-network.h | 5 +++++ + test/test-network/systemd-networkd-tests.py | 1 + + 5 files changed, 41 insertions(+), 1 deletion(-) + +--- a/src/libsystemd/sd-network/sd-network.c ++++ b/src/libsystemd/sd-network/sd-network.c +@@ -212,6 +212,27 @@ + return 0; + } + ++_public_ int sd_network_link_get_activation_policy(int ifindex, char **policy) { ++ _cleanup_free_ char *s = NULL; ++ int r; ++ ++ assert_return(policy, -EINVAL); ++ ++ r = network_link_get_string(ifindex, "ACTIVATION_POLICY", &s); ++ if (r < 0) { ++ if (r != -ENODATA) ++ return r; ++ ++ /* For compatibility, assuming up. */ ++ s = strdup("up"); ++ if (!s) ++ return -ENOMEM; ++ } ++ ++ *policy = TAKE_PTR(s); ++ return 0; ++} ++ + _public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) { + return network_link_get_string(ifindex, "LLMNR", llmnr); + } +--- a/src/network/networkctl.c ++++ b/src/network/networkctl.c +@@ -1389,7 +1389,7 @@ + + _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL, **route_domains = NULL; + _cleanup_free_ char *t = NULL, *network = NULL, *iaid = NULL, *duid = NULL, +- *setup_state = NULL, *operational_state = NULL, *lease_file = NULL; ++ *setup_state = NULL, *operational_state = NULL, *lease_file = NULL, *activation_policy = NULL; + const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL, + *on_color_operational, *off_color_operational, *on_color_setup, *off_color_setup; + _cleanup_free_ int *carrier_bound_to = NULL, *carrier_bound_by = NULL; +@@ -2065,6 +2065,16 @@ + if (r < 0) + return r; + ++ r = sd_network_link_get_activation_policy(info->ifindex, &activation_policy); ++ if (r >= 0) { ++ r = table_add_many(table, ++ TABLE_EMPTY, ++ TABLE_STRING, "Activation Policy:", ++ TABLE_STRING, activation_policy); ++ if (r < 0) ++ return table_log_add_error(r); ++ } ++ + if (lease) { + const void *client_id; + size_t client_id_len; +--- a/src/network/networkd-link.c ++++ b/src/network/networkd-link.c +@@ -4425,6 +4425,9 @@ + st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? ":" : "", + st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? strempty(link_operstate_to_string(st.max)) : ""); + ++ fprintf(f, "ACTIVATION_POLICY=%s\n", ++ activation_policy_to_string(link->network->activation_policy)); ++ + fprintf(f, "NETWORK_FILE=%s\n", link->network->filename); + + /************************************************************/ +--- a/src/systemd/sd-network.h ++++ b/src/systemd/sd-network.h +@@ -103,6 +103,11 @@ + */ + int sd_network_link_get_required_for_online(int ifindex); + ++/* Get activation policy for ifindex. ++ * Possible values are as specified for ActivationPolicy= ++ */ ++int sd_network_link_get_activation_policy(int ifindex, char **policy); ++ + /* Get path to .network file applied to link */ + int sd_network_link_get_network_file(int ifindex, char **filename); + +--- a/test/test-network/systemd-networkd-tests.py ++++ b/test/test-network/systemd-networkd-tests.py +@@ -2738,6 +2738,7 @@ + self.assertRegex(data, r'OPER_STATE=routable') + self.assertRegex(data, r'REQUIRED_FOR_ONLINE=yes') + self.assertRegex(data, r'REQUIRED_OPER_STATE_FOR_ONLINE=routable') ++ self.assertRegex(data, r'ACTIVATION_POLICY=up') + self.assertRegex(data, r'NETWORK_FILE=/run/systemd/network/state-file-tests.network') + self.assertRegex(data, r'DNS=10.10.10.10#aaa.com 10.10.10.11:1111#bbb.com \[1111:2222::3333\]:1234#ccc.com') + self.assertRegex(data, r'NTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org') diff -Nru systemd-246.6/debian/patches/lp1785383-resolved-address-DVE-2018-0001.patch systemd-246.6/debian/patches/lp1785383-resolved-address-DVE-2018-0001.patch --- systemd-246.6/debian/patches/lp1785383-resolved-address-DVE-2018-0001.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-246.6/debian/patches/lp1785383-resolved-address-DVE-2018-0001.patch 2021-05-27 15:12:21.000000000 +0000 @@ -0,0 +1,161 @@ +From 1ed4e584f3a03f47d2313314b6b5a78c9dc6f135 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 12 Nov 2020 17:05:36 +0100 +Subject: [PATCH] resolved: address DVE-2018-0001 +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/bionic/+source/systemd/+bug/1785383 +Origin: upstream, https://github.com/systemd/systemd/commit/1ed4e584f3a03f47d2313314b6b5a78c9dc6f135 + +This is an updated version of #8608 with more restrictive logic. To +quite the original bug: + + Some captive portals, lie and do not respond with the captive portal + IP address, if the query is with EDNS0 enabled and D0 bit set to + zero. Thus retry "secure" domain name look ups with less secure + methods, upon NXDOMAIN. + +https://github.com/dns-violations/dns-violations/blob/master/2018/DVE-2018-0001.md + +Yes, this fix sucks hard, but I guess this is what we need to do to make +sure resolved works IRL. + +Heavily based on the original patch from Dimitri John Ledkov, and I +copied the commentary verbatim. + +Replaces: #8608 +--- + src/resolve/resolved-dns-transaction.c | 69 +++++++++++++++++++++----- + src/resolve/resolved-dns-transaction.h | 7 ++- + 2 files changed, 62 insertions(+), 14 deletions(-) + +--- a/src/resolve/resolved-dns-transaction.c ++++ b/src/resolve/resolved-dns-transaction.c +@@ -204,7 +204,8 @@ int dns_transaction_new(DnsTransaction * + t->answer_nsec_ttl = (uint32_t) -1; + t->key = dns_resource_key_ref(key); + t->current_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID; +- t->clamp_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID; ++ t->clamp_feature_level_servfail = _DNS_SERVER_FEATURE_LEVEL_INVALID; ++ t->clamp_feature_level_nxdomain = _DNS_SERVER_FEATURE_LEVEL_INVALID; + + t->id = pick_new_id(s->manager); + +@@ -386,15 +387,20 @@ static int dns_transaction_pick_server(D + + /* If we changed the server invalidate the feature level clamping, as the new server might have completely + * different properties. */ +- if (server != t->server) +- t->clamp_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID; ++ if (server != t->server) { ++ t->clamp_feature_level_servfail = _DNS_SERVER_FEATURE_LEVEL_INVALID; ++ t->clamp_feature_level_nxdomain = _DNS_SERVER_FEATURE_LEVEL_INVALID; ++ } + + t->current_feature_level = dns_server_possible_feature_level(server); + + /* Clamp the feature level if that is requested. */ +- if (t->clamp_feature_level != _DNS_SERVER_FEATURE_LEVEL_INVALID && +- t->current_feature_level > t->clamp_feature_level) +- t->current_feature_level = t->clamp_feature_level; ++ if (t->clamp_feature_level_servfail != _DNS_SERVER_FEATURE_LEVEL_INVALID && ++ t->current_feature_level > t->clamp_feature_level_servfail) ++ t->current_feature_level = t->clamp_feature_level_servfail; ++ if (t->clamp_feature_level_nxdomain != _DNS_SERVER_FEATURE_LEVEL_INVALID && ++ t->current_feature_level > t->clamp_feature_level_nxdomain) ++ t->current_feature_level = t->clamp_feature_level_nxdomain; + + log_debug("Using feature level %s for transaction %u.", dns_server_feature_level_to_string(t->current_feature_level), t->id); + +@@ -1010,19 +1016,19 @@ void dns_transaction_process_reply(DnsTr + /* Reduce this feature level by one and try again. */ + switch (t->current_feature_level) { + case DNS_SERVER_FEATURE_LEVEL_TLS_DO: +- t->clamp_feature_level = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN; ++ t->clamp_feature_level_servfail = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN; + break; + case DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN + 1: + /* Skip plain TLS when TLS is not supported */ +- t->clamp_feature_level = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN - 1; ++ t->clamp_feature_level_servfail = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN - 1; + break; + default: +- t->clamp_feature_level = t->current_feature_level - 1; ++ t->clamp_feature_level_servfail = t->current_feature_level - 1; + } + + log_debug("Server returned error %s, retrying transaction with reduced feature level %s.", + dns_rcode_to_string(DNS_PACKET_RCODE(p)), +- dns_server_feature_level_to_string(t->clamp_feature_level)); ++ dns_server_feature_level_to_string(t->clamp_feature_level_servfail)); + + dns_transaction_retry(t, false /* use the same server */); + return; +@@ -1091,13 +1097,51 @@ void dns_transaction_process_reply(DnsTr + return; + } + ++ if (t->scope->protocol == DNS_PROTOCOL_DNS && ++ DNS_PACKET_RCODE(p) == DNS_RCODE_NXDOMAIN && ++ p->opt && !DNS_PACKET_DO(p) && ++ t->current_feature_level >= DNS_SERVER_FEATURE_LEVEL_EDNS0 && ++ IN_SET(t->current_feature_level, DNS_SERVER_FEATURE_LEVEL_UDP, DNS_SERVER_FEATURE_LEVEL_EDNS0, DNS_SERVER_FEATURE_LEVEL_DO, DNS_SERVER_FEATURE_LEVEL_LARGE) && ++ t->scope->dnssec_mode != DNSSEC_YES) { ++ ++ /* Some captive portals are special in that the Aruba/Datavalet hardware will miss ++ * replacing the packets with the local server IP to point to the authenticated side ++ * of the network if EDNS0 is enabled. Instead they return NXDOMAIN, with DO bit set ++ * to zero... nothing to see here, yet respond with the captive portal IP, when using ++ * the more simple UDP level. ++ * ++ * Common portal names that fail like so are: ++ * secure.datavalet.io ++ * securelogin.arubanetworks.com ++ * securelogin.networks.mycompany.com ++ * ++ * Thus retry NXDOMAIN RCODES with a lower feature level. ++ * ++ * Do not lower the server's tracked feature level, as the captive portal should not ++ * be lying for the wider internet (e.g. _other_ queries were observed fine with ++ * EDNS0 on these networks, post auth), i.e. let's just lower the level transaction's ++ * feature level. ++ * ++ * This is reported as https://github.com/dns-violations/dns-violations/blob/master/2018/DVE-2018-0001.md ++ */ ++ ++ t->clamp_feature_level_nxdomain = DNS_SERVER_FEATURE_LEVEL_UDP; ++ ++ log_debug("Server returned error %s in EDNS0 mode, retrying transaction with reduced feature level %s (DVE-2018-0001 mitigation)", ++ dns_rcode_to_string(DNS_PACKET_RCODE(p)), ++ dns_server_feature_level_to_string(t->clamp_feature_level_nxdomain)); ++ ++ dns_transaction_retry(t, false /* use the same server */); ++ return; ++ } ++ + if (t->server) { + /* Report that we successfully received a valid packet with a good rcode after we initially got a bad + * rcode and subsequently downgraded the protocol */ + + if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN) && +- t->clamp_feature_level != _DNS_SERVER_FEATURE_LEVEL_INVALID) +- dns_server_packet_rcode_downgrade(t->server, t->clamp_feature_level); ++ t->clamp_feature_level_servfail != _DNS_SERVER_FEATURE_LEVEL_INVALID) ++ dns_server_packet_rcode_downgrade(t->server, t->clamp_feature_level_servfail); + + /* Report that the OPT RR was missing */ + if (!p->opt) +--- a/src/resolve/resolved-dns-transaction.h ++++ b/src/resolve/resolved-dns-transaction.h +@@ -106,8 +106,11 @@ struct DnsTransaction { + /* The features of the DNS server at time of transaction start */ + DnsServerFeatureLevel current_feature_level; + +- /* If we got SERVFAIL back, we retry the lookup, using a lower feature level than we used before. */ +- DnsServerFeatureLevel clamp_feature_level; ++ /* If we got SERVFAIL back, we retry the lookup, using a lower feature level than we used ++ * before. Similar, if we get NXDOMAIN in pure EDNS0 mode, we check in EDNS0-less mode before giving ++ * up (as mitigation for DVE-2018-0001). */ ++ DnsServerFeatureLevel clamp_feature_level_servfail; ++ DnsServerFeatureLevel clamp_feature_level_nxdomain; + + /* Query candidates this transaction is referenced by and that + * shall be notified about this specific transaction diff -Nru systemd-246.6/debian/patches/lp1880258-log-nxdomain-as-debug.patch systemd-246.6/debian/patches/lp1880258-log-nxdomain-as-debug.patch --- systemd-246.6/debian/patches/lp1880258-log-nxdomain-as-debug.patch 2021-03-10 21:03:13.000000000 +0000 +++ systemd-246.6/debian/patches/lp1880258-log-nxdomain-as-debug.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -Bug-Ubuntu: https://bugs.launchpad.net/bugs/1880258 -Forwarded: not-needed -Reviewed-By: Dan Streetman - ---- systemd-246.6.orig/src/resolve/resolved-dns-transaction.c -+++ systemd-246.6/src/resolve/resolved-dns-transaction.c -@@ -1049,9 +1049,9 @@ void dns_transaction_process_reply(DnsTr - char key_str[DNS_RESOURCE_KEY_STRING_MAX]; - dns_resource_key_to_string(t->key, key_str, sizeof key_str); - t->current_feature_level = DNS_SERVER_FEATURE_LEVEL_UDP; -- log_warning("Server returned error %s, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level %s.", -- dns_rcode_to_string(DNS_PACKET_RCODE(p)), -- dns_server_feature_level_to_string(t->current_feature_level)); -+ log_debug("Server returned error %s, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level %s.", -+ dns_rcode_to_string(DNS_PACKET_RCODE(p)), -+ dns_server_feature_level_to_string(t->current_feature_level)); - dns_transaction_retry(t, false /* use the same server */); - return; - } diff -Nru systemd-246.6/debian/patches/lp1902891-core-mount-mount-command-may-fail-after-adding-the-c.patch systemd-246.6/debian/patches/lp1902891-core-mount-mount-command-may-fail-after-adding-the-c.patch --- systemd-246.6/debian/patches/lp1902891-core-mount-mount-command-may-fail-after-adding-the-c.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-246.6/debian/patches/lp1902891-core-mount-mount-command-may-fail-after-adding-the-c.patch 2021-05-27 15:12:21.000000000 +0000 @@ -0,0 +1,32 @@ +From 2fa0bd7d57863dffda89190a70a83c51bd7d114a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 17 Nov 2020 09:13:59 +0900 +Subject: [PATCH] core/mount: mount command may fail after adding the + corresponding proc mountinfo entry +Origin: upstream, https://github.com/systemd/systemd/commit/2fa0bd7d57863dffda89190a70a83c51bd7d114a +Bug: https://github.com/systemd/systemd/issues/17617 +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1902891 + +Hopefully fixes #17617. +--- + src/core/mount.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1952,6 +1952,15 @@ static int mount_process_proc_self_mount + mount_enter_dead(mount, MOUNT_SUCCESS); + break; + ++ case MOUNT_MOUNTING_DONE: ++ /* The mount command may add the corresponding proc mountinfo entry and ++ * then remove it because of an internal error. E.g., fuse.sshfs seems ++ * to do that when the connection fails. See #17617. To handle such the ++ * case, let's once set the state back to mounting. Then, the unit can ++ * correctly enter the failed state later in mount_sigchld(). */ ++ mount_set_state(mount, MOUNT_MOUNTING); ++ break; ++ + default: + break; + } diff -Nru systemd-246.6/debian/patches/lp1921696/0001-rfkill-improve-error-logging.patch systemd-246.6/debian/patches/lp1921696/0001-rfkill-improve-error-logging.patch --- systemd-246.6/debian/patches/lp1921696/0001-rfkill-improve-error-logging.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-246.6/debian/patches/lp1921696/0001-rfkill-improve-error-logging.patch 2021-05-27 15:12:21.000000000 +0000 @@ -0,0 +1,121 @@ +From 6c7afdeab010025c80508effd2b0039bc5181b82 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 18 Feb 2021 10:40:16 +0100 +Subject: [PATCH 1/2] rfkill: improve error logging +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/groovy/+source/systemd/+bug/1921696 +Origin: upstream, https://github.com/systemd/systemd/pull/18679 + +If we get something of unexpected size, log the sizes. Also, don't log twice. +--- + src/rfkill/rfkill.c | 66 +++++++++++++++++++++------------------------ + 1 file changed, 30 insertions(+), 36 deletions(-) + +diff --git a/src/rfkill/rfkill.c b/src/rfkill/rfkill.c +index 91dc72f425..238d2cb579 100644 +--- a/src/rfkill/rfkill.c ++++ b/src/rfkill/rfkill.c +@@ -135,8 +135,6 @@ static int determine_state_file( + + static int load_state(Context *c, const struct rfkill_event *event) { + _cleanup_free_ char *state_file = NULL, *value = NULL; +- struct rfkill_event we; +- ssize_t l; + int b, r; + + assert(c); +@@ -168,18 +166,19 @@ static int load_state(Context *c, const struct rfkill_event *event) { + if (b < 0) + return log_error_errno(b, "Failed to parse state file %s: %m", state_file); + +- we = (struct rfkill_event) { +- .op = RFKILL_OP_CHANGE, ++ struct rfkill_event we = { + .idx = event->idx, ++ .op = RFKILL_OP_CHANGE, + .soft = b, + }; + +- l = write(c->rfkill_fd, &we, sizeof(we)); ++ ssize_t l = write(c->rfkill_fd, &we, sizeof we); + if (l < 0) + return log_error_errno(errno, "Failed to restore rfkill state for %i: %m", event->idx); +- if (l != sizeof(we)) ++ if (l != sizeof we) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Couldn't write rfkill event structure, too short."); ++ "Couldn't write rfkill event structure, too short (wrote %zd of %zu bytes).", ++ l, sizeof we); + + log_debug("Loaded state '%s' from %s.", one_zero(b), state_file); + return 0; +@@ -306,43 +305,38 @@ static int run(int argc, char *argv[]) { + + for (;;) { + struct rfkill_event event; +- const char *type; +- ssize_t l; + +- l = read(c.rfkill_fd, &event, sizeof(event)); ++ ssize_t l = read(c.rfkill_fd, &event, sizeof event); + if (l < 0) { +- if (errno == EAGAIN) { +- +- if (!ready) { +- /* Notify manager that we are +- * now finished with +- * processing whatever was +- * queued */ +- (void) sd_notify(false, "READY=1"); +- ready = true; +- } +- +- /* Hang around for a bit, maybe there's more coming */ +- +- r = fd_wait_for_event(c.rfkill_fd, POLLIN, EXIT_USEC); +- if (r == -EINTR) +- continue; +- if (r < 0) +- return log_error_errno(r, "Failed to poll() on device: %m"); +- if (r > 0) +- continue; +- +- log_debug("All events read and idle, exiting."); +- break; ++ if (errno != EAGAIN) ++ return log_error_errno(errno, "Failed to read from /dev/rfkill: %m"); ++ ++ if (!ready) { ++ /* Notify manager that we are now finished with processing whatever was ++ * queued */ ++ (void) sd_notify(false, "READY=1"); ++ ready = true; + } + +- log_error_errno(errno, "Failed to read from /dev/rfkill: %m"); ++ /* Hang around for a bit, maybe there's more coming */ ++ ++ r = fd_wait_for_event(c.rfkill_fd, POLLIN, EXIT_USEC); ++ if (r == -EINTR) ++ continue; ++ if (r < 0) ++ return log_error_errno(r, "Failed to poll() on device: %m"); ++ if (r > 0) ++ continue; ++ ++ log_debug("All events read and idle, exiting."); ++ break; + } + + if (l != RFKILL_EVENT_SIZE_V1) +- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Read event structure of invalid size."); ++ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Read event structure of unexpected size (%zd, not %d)", ++ l, RFKILL_EVENT_SIZE_V1); + +- type = rfkill_type_to_string(event.type); ++ const char *type = rfkill_type_to_string(event.type); + if (!type) { + log_debug("An rfkill device of unknown type %i discovered, ignoring.", event.type); + continue; +-- +2.25.1 + diff -Nru systemd-246.6/debian/patches/lp1921696/0002-rfkill-use-short-writes-and-accept-long-reads.patch systemd-246.6/debian/patches/lp1921696/0002-rfkill-use-short-writes-and-accept-long-reads.patch --- systemd-246.6/debian/patches/lp1921696/0002-rfkill-use-short-writes-and-accept-long-reads.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-246.6/debian/patches/lp1921696/0002-rfkill-use-short-writes-and-accept-long-reads.patch 2021-05-27 15:12:21.000000000 +0000 @@ -0,0 +1,123 @@ +From a71c09685021cbcecb7566a00342421f635cc002 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 18 Feb 2021 10:48:08 +0100 +Subject: [PATCH 2/2] rfkill: use short writes and accept long reads +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/groovy/+source/systemd/+bug/1921696 +Origin: upstream, https://github.com/systemd/systemd/pull/18679 + +I'm seeing the following with kernel-core-5.10.16-200.fc33.x86_64: + +$ sudo SYSTEMD_LOG_LEVEL=debug build/systemd-rfkill +Reading struct rfkill_event: got 8 bytes. +A new rfkill device has been added with index 0 and type bluetooth. +Found cgroup2 on /sys/fs/cgroup/, full unified hierarchy +Found container virtualization none. +rfkill0: Operating on rfkill device 'tpacpi_bluetooth_sw'. +Writing struct rfkill_event successful (8 of 9 bytes). +Loaded state '0' from /var/lib/systemd/rfkill/platform-thinkpad_acpi:bluetooth. +Reading struct rfkill_event: got 8 bytes. +A new rfkill device has been added with index 1 and type wwan. +rfkill1: Operating on rfkill device 'tpacpi_wwan_sw'. +Writing struct rfkill_event successful (8 of 9 bytes). +Loaded state '0' from /var/lib/systemd/rfkill/platform-thinkpad_acpi:wwan. +Reading struct rfkill_event: got 8 bytes. +A new rfkill device has been added with index 2 and type bluetooth. +rfkill2: Operating on rfkill device 'hci0'. +Writing struct rfkill_event successful (8 of 9 bytes). +Loaded state '0' from /var/lib/systemd/rfkill/pci-0000:00:14.0-usb-0:7:1.0:bluetooth. +Reading struct rfkill_event: got 8 bytes. +A new rfkill device has been added with index 3 and type wlan. +rfkill3: Operating on rfkill device 'phy0'. +Writing struct rfkill_event successful (8 of 9 bytes). +Loaded state '0' from /var/lib/systemd/rfkill/pci-0000:04:00.0:wlan. +All events read and idle, exiting. + +We were expecting a read of exactly RFKILL_EVENT_SIZE_V1==8 bytes. But the +structure has 9 after [1]. + +[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=14486c82612a177cb910980c70ba900827ca0894 + +For some reason the kernel does not accept the full structure size, but cuts +the write short after 8 bytes: + +static ssize_t rfkill_fop_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + struct rfkill_event ev; + + /* we don't need the 'hard' variable but accept it */ + if (count < RFKILL_EVENT_SIZE_V1 - 1) + return -EINVAL; + + /* + * Copy as much data as we can accept into our 'ev' buffer, + * but tell userspace how much we've copied so it can determine + * our API version even in a write() call, if it cares. + */ + count = min(count, sizeof(ev)); + if (copy_from_user(&ev, buf, count)) + return -EFAULT; + +... so it should accept the full size. I'm not sure what is going on here. + +But we don't care about the extra fields, so let's accept a write as long as +it's at least RFKILL_EVENT_SIZE_V1. + +Fixes #18677. +--- + src/rfkill/rfkill.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/src/rfkill/rfkill.c b/src/rfkill/rfkill.c +index 238d2cb579..e2d1a1be5f 100644 +--- a/src/rfkill/rfkill.c ++++ b/src/rfkill/rfkill.c +@@ -171,14 +171,17 @@ static int load_state(Context *c, const struct rfkill_event *event) { + .op = RFKILL_OP_CHANGE, + .soft = b, + }; ++ assert_cc(offsetof(struct rfkill_event, op) < RFKILL_EVENT_SIZE_V1); ++ assert_cc(offsetof(struct rfkill_event, soft) < RFKILL_EVENT_SIZE_V1); + + ssize_t l = write(c->rfkill_fd, &we, sizeof we); + if (l < 0) + return log_error_errno(errno, "Failed to restore rfkill state for %i: %m", event->idx); +- if (l != sizeof we) ++ if (l < RFKILL_EVENT_SIZE_V1) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Couldn't write rfkill event structure, too short (wrote %zd of %zu bytes).", + l, sizeof we); ++ log_debug("Writing struct rfkill_event successful (%zd of %zu bytes).", l, sizeof we); + + log_debug("Loaded state '%s' from %s.", one_zero(b), state_file); + return 0; +@@ -304,7 +307,7 @@ static int run(int argc, char *argv[]) { + } + + for (;;) { +- struct rfkill_event event; ++ struct rfkill_event event = {}; + + ssize_t l = read(c.rfkill_fd, &event, sizeof event); + if (l < 0) { +@@ -332,9 +335,15 @@ static int run(int argc, char *argv[]) { + break; + } + +- if (l != RFKILL_EVENT_SIZE_V1) +- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Read event structure of unexpected size (%zd, not %d)", ++ if (l < RFKILL_EVENT_SIZE_V1) ++ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short read of struct rfkill_event: (%zd < %d)", + l, RFKILL_EVENT_SIZE_V1); ++ log_debug("Reading struct rfkill_event: got %zd bytes.", l); ++ ++ /* The event structure has more fields. We only care about the first few, so it's OK if we ++ * don't read the full structure. */ ++ assert_cc(offsetof(struct rfkill_event, op) < RFKILL_EVENT_SIZE_V1); ++ assert_cc(offsetof(struct rfkill_event, type) < RFKILL_EVENT_SIZE_V1); + + const char *type = rfkill_type_to_string(event.type); + if (!type) { +-- +2.25.1 + diff -Nru systemd-246.6/debian/patches/lp1926547-hwdb-60-keyboard-Update-Dell-Privacy-Micmute-Hotkey-.patch systemd-246.6/debian/patches/lp1926547-hwdb-60-keyboard-Update-Dell-Privacy-Micmute-Hotkey-.patch --- systemd-246.6/debian/patches/lp1926547-hwdb-60-keyboard-Update-Dell-Privacy-Micmute-Hotkey-.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-246.6/debian/patches/lp1926547-hwdb-60-keyboard-Update-Dell-Privacy-Micmute-Hotkey-.patch 2021-05-27 15:12:21.000000000 +0000 @@ -0,0 +1,35 @@ +From 9e04eb0d5fc07617d5e37df991eac11d5812c92e Mon Sep 17 00:00:00 2001 +From: Perry Yuan +Date: Sun, 7 Mar 2021 21:50:49 -0500 +Subject: [PATCH] hwdb: 60-keyboard:: Update Dell Privacy Micmute Hotkey Map +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1926547 +Origin: upstream, https://github.com/systemd/systemd/commit/9e04eb0d5fc +Origin: upstream, https://github.com/systemd/systemd/commit/5ed0ea29287 + +Dell new Privacy feature provide new hardware level privacy +protect for users +This patch remaps scancode 0x120001 to key code F20 micmute +The old matching string cannot cover some other Dell products +which have the privacy feature,expand the string to all the system +that can load the privacy driver,privacy driver already detect the +system if it can support this feature. So here we can safely just +map the micmute key to scancode 0x120001 + +Signed-off-by: Perry Yuan +--- + hwdb.d/60-keyboard.hwdb | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/hwdb.d/60-keyboard.hwdb ++++ b/hwdb.d/60-keyboard.hwdb +@@ -378,6 +378,10 @@ evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr + evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision* + KEYBOARD_KEY_100150=f20 # Mic mute toggle, should be micmute + ++# Dell Latitude privacy microphone mute ++evdev:name:Dell Privacy Driver:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*:* ++ KEYBOARD_KEY_120001=f20 # Mic mute toggle, should be micmute ++ + ########################################################### + # Everex + ########################################################### diff -Nru systemd-246.6/debian/patches/lp1929560-network-move-set-MAC-and-set-nomaster-operations-out.patch systemd-246.6/debian/patches/lp1929560-network-move-set-MAC-and-set-nomaster-operations-out.patch --- systemd-246.6/debian/patches/lp1929560-network-move-set-MAC-and-set-nomaster-operations-out.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-246.6/debian/patches/lp1929560-network-move-set-MAC-and-set-nomaster-operations-out.patch 2021-05-27 15:12:21.000000000 +0000 @@ -0,0 +1,169 @@ +From e16e4b3bedc57919b3ecb4096e941709a5d39b8a Mon Sep 17 00:00:00 2001 +From: Dan Streetman +Date: Wed, 17 Jun 2020 16:28:39 -0400 +Subject: [PATCH] network: move set-MAC and set-nomaster operations out of + link_up() +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1929560 +Origin: upstream, https://github.com/systemd/systemd/commit/e16e4b3bedc57919b3ecb4096e941709a5d39b8a + +These should not be bundled into the link_up() operation, as that is +not (currently) called during interface configuration if the interface +already is IFF_UP, which is unrelated to the need to change the mac +to a user-defined value, or set 'nomaster' on the interface. + +Additionally, there is no need to re-set the mac or re-assert nomaster +every time the interface is brought up; those should be only part of +normal initial interface configuration. + +Fixes: #17391 +--- + src/network/networkd-link.c | 120 ++++++++++++++++++++++++++++++++---- + 1 file changed, 107 insertions(+), 13 deletions(-) + +--- a/src/network/networkd-link.c ++++ b/src/network/networkd-link.c +@@ -1487,6 +1487,105 @@ static int link_set_proxy_arp(Link *link + + static int link_configure_continue(Link *link); + ++static int link_mac_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { ++ int r; ++ ++ assert(link); ++ ++ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) ++ return 1; ++ ++ r = sd_netlink_message_get_errno(m); ++ if (r < 0) ++ log_link_message_warning_errno(link, m, r, "Could not set MAC address, ignoring"); ++ else ++ log_link_debug(link, "Setting MAC address done."); ++ ++ return 1; ++} ++ ++static int link_set_mac(Link *link) { ++ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; ++ int r; ++ ++ assert(link); ++ assert(link->network); ++ assert(link->manager); ++ assert(link->manager->rtnl); ++ ++ if (!link->network->mac) ++ return 0; ++ ++ log_link_debug(link, "Setting MAC address"); ++ ++ r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex); ++ if (r < 0) ++ return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); ++ ++ r = sd_netlink_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac); ++ if (r < 0) ++ return log_link_error_errno(link, r, "Could not set MAC address: %m"); ++ ++ r = netlink_call_async(link->manager->rtnl, NULL, req, link_mac_handler, ++ link_netlink_destroy_callback, link); ++ if (r < 0) ++ return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); ++ ++ link_ref(link); ++ ++ return 0; ++} ++ ++static int link_nomaster_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { ++ int r; ++ ++ assert(link); ++ ++ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) ++ return 1; ++ ++ r = sd_netlink_message_get_errno(m); ++ if (r < 0) ++ log_link_message_warning_errno(link, m, r, "Could not set nomaster, ignoring"); ++ else ++ log_link_debug(link, "Setting nomaster done."); ++ ++ return 1; ++} ++ ++static int link_set_nomaster(Link *link) { ++ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; ++ int r; ++ ++ assert(link); ++ assert(link->network); ++ assert(link->manager); ++ assert(link->manager->rtnl); ++ ++ /* set it free if not enslaved with networkd */ ++ if (link->network->bridge || link->network->bond || link->network->vrf) ++ return 0; ++ ++ log_link_debug(link, "Setting nomaster"); ++ ++ r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex); ++ if (r < 0) ++ return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); ++ ++ r = sd_netlink_message_append_u32(req, IFLA_MASTER, 0); ++ if (r < 0) ++ return log_link_error_errno(link, r, "Could not append IFLA_MASTER attribute: %m"); ++ ++ r = netlink_call_async(link->manager->rtnl, NULL, req, link_nomaster_handler, ++ link_netlink_destroy_callback, link); ++ if (r < 0) ++ return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); ++ ++ link_ref(link); ++ ++ return 0; ++} ++ + static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + int r; + +@@ -1910,23 +2009,10 @@ static int link_up(Link *link) { + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); + +- /* set it free if not enslaved with networkd */ +- if (!link->network->bridge && !link->network->bond && !link->network->vrf) { +- r = sd_netlink_message_append_u32(req, IFLA_MASTER, 0); +- if (r < 0) +- return log_link_error_errno(link, r, "Could not append IFLA_MASTER attribute: %m"); +- } +- + r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP); + if (r < 0) + return log_link_error_errno(link, r, "Could not set link flags: %m"); + +- if (link->network->mac) { +- r = sd_netlink_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac); +- if (r < 0) +- return log_link_error_errno(link, r, "Could not set MAC address: %m"); +- } +- + r = netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler, + link_netlink_destroy_callback, link); + if (r < 0) +@@ -3116,6 +3202,14 @@ static int link_configure(Link *link) { + if (r < 0) + return r; + ++ r = link_set_mac(link); ++ if (r < 0) ++ return r; ++ ++ r = link_set_nomaster(link); ++ if (r < 0) ++ return r; ++ + r = link_set_flags(link); + if (r < 0) + return r; diff -Nru systemd-246.6/debian/patches/series systemd-246.6/debian/patches/series --- systemd-246.6/debian/patches/series 2021-03-10 21:03:13.000000000 +0000 +++ systemd-246.6/debian/patches/series 2021-05-27 15:12:21.000000000 +0000 @@ -32,7 +32,6 @@ debian/UBUNTU-test-sleep-skip-test_fiemap-upon-inapproriate-ioctl-.patch debian/UBUNTU-Support-system-image-read-only-etc.patch debian/UBUNTU-units-disable-journald-watchdog.patch -debian/UBUNTU-resolved-Mitigate-DVE-2018-0001-by-retrying-NXDOMAIN-with.patch debian/UBUNTU-Revert-namespace-be-more-careful-when-handling-namespacin.patch Skip-falling-back-to-device-name-when-net_get_name-device.patch debian/UBUNTU-Revert-cgroup-Continue-unit-reset-if-cgroup-is-busy.patch @@ -57,8 +56,16 @@ lp1907306/0008-sd-dhcp-client-fix-renew-rebind-timeout-calculation-.patch lp1902960-udev-re-assign-ID_NET_DRIVER-ID_NET_LINK_FILE-ID_NET.patch lp1911187-systemctl-do-not-shutdown-immediately-on-scheduled-shutdo.patch -lp1880258-log-nxdomain-as-debug.patch lp1913763-udev-rules-add-rule-to-create-dev-ptp_hyperv.patch lp1918696-shared-seccomp-util-address-family-filtering-is-brok.patch lp1915887-Downgrade-a-couple-of-warnings-to-debug.patch lp1887744-basic-unit-file-when-loading-linked-unit-files-use-l.patch +lp1921696/0001-rfkill-improve-error-logging.patch +lp1921696/0002-rfkill-use-short-writes-and-accept-long-reads.patch +lp1926547-hwdb-60-keyboard-Update-Dell-Privacy-Micmute-Hotkey-.patch +lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch +lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch +lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch +lp1929560-network-move-set-MAC-and-set-nomaster-operations-out.patch +lp1902891-core-mount-mount-command-may-fail-after-adding-the-c.patch +lp1785383-resolved-address-DVE-2018-0001.patch