From dafd65b150d31a0d3027f9d8798cb6b401394829 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 19 Jun 2023 18:44:54 +0200 Subject: [PATCH 1/4] rules: split out DMI related rules from udev-default.rules The DMI rules where so far guarded by an ACTION=="add" rule, but that doesn't really make sense for setting properties (only for setting access modes/ownership of nodes). Hence let's move this into its own file, that guards properly on ACTION!="remove". Before this change the hardware vendor/model info would be dropped whenever the device was retriggered. --- rules.d/50-udev-default.rules.in | 10 ---------- rules.d/60-dmi-id.rules | 14 ++++++++++++++ rules.d/meson.build | 1 + 3 files changed, 15 insertions(+), 10 deletions(-) create mode 100644 rules.d/60-dmi-id.rules diff --git a/rules.d/50-udev-default.rules.in b/rules.d/50-udev-default.rules.in index 50ac005016..35dfc76e61 100644 --- a/rules.d/50-udev-default.rules.in +++ b/rules.d/50-udev-default.rules.in @@ -110,14 +110,4 @@ SUBSYSTEM=="ptp", ATTR{clock_name}=="KVM virtual PTP", SYMLINK += "ptp_kvm" SUBSYSTEM=="ptp", ATTR{clock_name}=="hyperv", SYMLINK += "ptp_hyperv" -SUBSYSTEM!="dmi", GOTO="dmi_end" -ENV{ID_SYS_VENDOR_IS_RUBBISH}!="1", ENV{ID_VENDOR}="$attr{sys_vendor}" -ENV{ID_SYSFS_ATTRIBUTE_MODEL}=="", ENV{ID_PRODUCT_NAME_IS_RUBBISH}!="1", ENV{ID_MODEL}="$attr{product_name}" -ENV{ID_SYSFS_ATTRIBUTE_MODEL}=="product_name", ENV{ID_MODEL}="$attr{product_name}" -ENV{ID_SYSFS_ATTRIBUTE_MODEL}=="product_version", ENV{ID_MODEL}="$attr{product_version}" -# fallback to board information -ENV{ID_VENDOR}=="", ENV{ID_VENDOR}="$attr{board_vendor}" -ENV{ID_MODEL}=="", ENV{ID_MODEL}="$attr{board_name}" -LABEL="dmi_end" - LABEL="default_end" diff --git a/rules.d/60-dmi-id.rules b/rules.d/60-dmi-id.rules new file mode 100644 index 0000000000..6c61ea24ab --- /dev/null +++ b/rules.d/60-dmi-id.rules @@ -0,0 +1,14 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="dmi_end" +SUBSYSTEM!="dmi", GOTO="dmi_end" + +ENV{ID_SYS_VENDOR_IS_RUBBISH}!="1", ENV{ID_VENDOR}="$attr{sys_vendor}" +ENV{ID_SYSFS_ATTRIBUTE_MODEL}=="", ENV{ID_PRODUCT_NAME_IS_RUBBISH}!="1", ENV{ID_MODEL}="$attr{product_name}" +ENV{ID_SYSFS_ATTRIBUTE_MODEL}=="product_name", ENV{ID_MODEL}="$attr{product_name}" +ENV{ID_SYSFS_ATTRIBUTE_MODEL}=="product_version", ENV{ID_MODEL}="$attr{product_version}" +# fallback to board information +ENV{ID_VENDOR}=="", ENV{ID_VENDOR}="$attr{board_vendor}" +ENV{ID_MODEL}=="", ENV{ID_MODEL}="$attr{board_name}" + +LABEL="dmi_end" diff --git a/rules.d/meson.build b/rules.d/meson.build index 7280f5b995..20fca222da 100644 --- a/rules.d/meson.build +++ b/rules.d/meson.build @@ -8,6 +8,7 @@ rules = [ [files('60-autosuspend.rules', '60-block.rules', '60-cdrom_id.rules', + '60-dmi-id.rules', '60-drm.rules', '60-evdev.rules', '60-fido-id.rules', From e7932afe1bb91412c8ff26dba46513605199196e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 19 Jun 2023 18:46:36 +0200 Subject: [PATCH 2/4] hostnamed: don't read DMI data within a container If we run in a container we should show info about the container, not the host. --- src/hostname/hostnamed.c | 25 +++++++++++++++++++++++++ test/units/testsuite-71.sh | 1 + 2 files changed, 26 insertions(+) diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 97b1c61748..2f63ac4dcf 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -179,12 +179,34 @@ static void context_read_os_release(Context *c) { c->etc_os_release_stat = current_stat; } +static bool use_dmi_data(void) { + int r; + + r = getenv_bool("SYSTEMD_HOSTNAME_FORCE_DMI"); + if (r >= 0) { + log_debug("Honouring $SYSTEMD_HOSTNAME_FORCE_DMI override: %s", yes_no(r)); + return r; + } + if (r != -ENXIO) + log_debug_errno(r, "Failed to parse $SYSTEMD_HOSTNAME_FORCE_DMI, ignoring: %m"); + + if (detect_container() > 0) { + log_debug("Running in a container, not using DMI hardware data."); + return false; + } + + return true; +} + static int get_dmi_data(const char *database_key, const char *regular_key, char **ret) { _cleanup_(sd_device_unrefp) sd_device *device = NULL; _cleanup_free_ char *b = NULL; const char *s = NULL; int r; + if (!use_dmi_data()) + return -ENOENT; + r = sd_device_new_from_syspath(&device, "/sys/class/dmi/id"); if (r < 0) return log_debug_errno(r, "Failed to open /sys/class/dmi/id device, ignoring: %m"); @@ -223,6 +245,9 @@ static int get_hardware_firmware_data(const char *sysattr, char **ret) { assert(sysattr); + if (!use_dmi_data()) + return -ENOENT; + r = sd_device_new_from_syspath(&device, "/sys/class/dmi/id"); if (r < 0) return log_debug_errno(r, "Failed to open /sys/class/dmi/id device, ignoring: %m"); diff --git a/test/units/testsuite-71.sh b/test/units/testsuite-71.sh index 1c884324cb..6f99ecadd8 100755 --- a/test/units/testsuite-71.sh +++ b/test/units/testsuite-71.sh @@ -112,6 +112,7 @@ testcase_firmware_date() { cat >/run/systemd/system/systemd-hostnamed.service.d/override.conf < Date: Mon, 19 Jun 2023 18:49:05 +0200 Subject: [PATCH 3/4] rules: drop weird spaces --- rules.d/50-udev-default.rules.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rules.d/50-udev-default.rules.in b/rules.d/50-udev-default.rules.in index 35dfc76e61..b37e8bd3d5 100644 --- a/rules.d/50-udev-default.rules.in +++ b/rules.d/50-udev-default.rules.in @@ -106,8 +106,7 @@ KERNEL=="vhost-net", GROUP="kvm", MODE="{{DEV_KVM_MODE}}", OPTIONS+="static_node KERNEL=="udmabuf", GROUP="kvm" -SUBSYSTEM=="ptp", ATTR{clock_name}=="KVM virtual PTP", SYMLINK += "ptp_kvm" - -SUBSYSTEM=="ptp", ATTR{clock_name}=="hyperv", SYMLINK += "ptp_hyperv" +SUBSYSTEM=="ptp", ATTR{clock_name}=="KVM virtual PTP", SYMLINK+="ptp_kvm" +SUBSYSTEM=="ptp", ATTR{clock_name}=="hyperv", SYMLINK+="ptp_hyperv" LABEL="default_end" From 7dad6de158cbc280988efa9e52e6d2b9c840ea9f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 20 Jun 2023 15:00:07 +0200 Subject: [PATCH 4/4] hostnamed: when parsing day/month of firmware date, force decimal parsing safe_atou() by default determines the base from the prefix 0x, 0b, 0o and for compat with just 0 for octal. This is not what we want here, since the date components are padded with zeroes yet still decimal. Hence force decimal parsing (and while we are at it, prohibit a couple of unexpected decorations). WIthout this we'd fail to parse any the 8th and 9th day of each months, as well aus aug and september of every year, because these look like octal numbers but cannot actually parsed as such. Let's change the testcase to check for a date that exposes this bheaviour. --- src/hostname/hostnamed.c | 6 +++--- test/units/testsuite-71.sh | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 2f63ac4dcf..9ef45f8e75 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -307,20 +307,20 @@ static int get_firmware_date(usec_t *ret) { return -EINVAL; unsigned m, d, y; - r = safe_atou(month, &m); + r = safe_atou_full(month, 10 | SAFE_ATO_REFUSE_PLUS_MINUS | SAFE_ATO_REFUSE_LEADING_WHITESPACE, &m); if (r < 0) return r; if (m < 1 || m > 12) return -EINVAL; m -= 1; - r = safe_atou(day, &d); + r = safe_atou_full(day, 10 | SAFE_ATO_REFUSE_PLUS_MINUS | SAFE_ATO_REFUSE_LEADING_WHITESPACE, &d); if (r < 0) return r; if (d < 1 || d > 31) return -EINVAL; - r = safe_atou(year, &y); + r = safe_atou_full(year, 10 | SAFE_ATO_REFUSE_PLUS_MINUS | SAFE_ATO_REFUSE_LEADING_WHITESPACE, &y); if (r < 0) return r; if (y < 1970 || y > (unsigned) INT_MAX) diff --git a/test/units/testsuite-71.sh b/test/units/testsuite-71.sh index 6f99ecadd8..9d84dd89ed 100755 --- a/test/units/testsuite-71.sh +++ b/test/units/testsuite-71.sh @@ -119,9 +119,9 @@ EOF mount -t tmpfs none /sys/class/dmi/id echo '1' >/sys/class/dmi/id/uevent - echo '01/01/2000' >/sys/class/dmi/id/bios_date + echo '09/08/2000' >/sys/class/dmi/id/bios_date systemctl stop systemd-hostnamed - assert_in '2000-01-01' "$(hostnamectl)" + assert_in '2000-09-08' "$(hostnamectl)" echo '2022' >/sys/class/dmi/id/bios_date systemctl stop systemd-hostnamed