Package: release.debian.org Severity: normal Tags: buster User: release.debian....@packages.debian.org Usertags: pu
Hi folks, I'd like to upload a stable update for efivar, with two (sets of) fixes backported from upstream. * Firstly, there's a simple initialisation fix to fix some possible crashes. * Secondly, there's support for newer systems that need extra NVME support doing device lookups. (#975417). This is an important update for supporting installation and boot on those new systems. The reporter of the bug has tested with test packages and all looks good. Debdiff attached. -- System Information: Debian Release: 10.6 APT prefers stable-debug APT policy: (500, 'stable-debug'), (500, 'stable'), (500, 'oldstable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 4.19.0-12-amd64 (SMP w/4 CPU cores) Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8), LANGUAGE=en_GB:en (charmap=UTF-8) Shell: /bin/sh linked to /usr/bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled
diff -Nru efivar-37/debian/changelog efivar-37/debian/changelog --- efivar-37/debian/changelog 2019-03-01 17:55:07.000000000 +0000 +++ efivar-37/debian/changelog 2020-11-22 00:03:59.000000000 +0000 @@ -1,3 +1,13 @@ +efivar (37-2+deb10u1) buster; urgency=medium + + * Backport important fixes from unstable: + + fix uninitialized variable in parse_acpi_root, saving possible + segfault. + + Add support for nvme-fabrics and nvme-subsystem devices. Closes: + #975417 + + -- Steve McIntyre <93...@debian.org> Sun, 22 Nov 2020 00:03:59 +0000 + efivar (37-2) unstable; urgency=medium * Cherry-pick fix from upstream: diff -Nru efivar-37/debian/patches/0001-Fix-the-error-path-in-set_disk_and_part_name.patch efivar-37/debian/patches/0001-Fix-the-error-path-in-set_disk_and_part_name.patch --- efivar-37/debian/patches/0001-Fix-the-error-path-in-set_disk_and_part_name.patch 1970-01-01 01:00:00.000000000 +0100 +++ efivar-37/debian/patches/0001-Fix-the-error-path-in-set_disk_and_part_name.patch 2020-11-21 23:57:27.000000000 +0000 @@ -0,0 +1,74 @@ +From 22bc0866e941cbfe57de6522db51e9cf2c6b3ff1 Mon Sep 17 00:00:00 2001 +From: Peter Jones <pjo...@redhat.com> +Date: Wed, 2 Oct 2019 17:01:00 -0400 +Subject: [PATCH] Fix the error path in set_disk_and_part_name() + +Signed-off-by: Peter Jones <pjo...@redhat.com> + +[ dannf: Context adjustments due to upstream whitespace cleanup; + Included to simplify the application of + 0003-Try-even-harder-to-find-disk-device-symlinks-in-sysf.patch ] + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1891718 +Bug: https://github.com/rhboot/efivar/issues/157 +Origin: upstream, https://github.com/rhboot/efivar/commit/22bc0866e941cbfe57de6522db51e9cf2c6b3ff1 +Last-Updated: 2020-09-30 + +Index: efivar-37/src/linux.c +=================================================================== +--- efivar-37.orig/src/linux.c ++++ efivar-37/src/linux.c +@@ -1,6 +1,6 @@ + /* + * libefiboot - library for the manipulation of EFI boot variables +- * Copyright 2012-2015 Red Hat, Inc. ++ * Copyright 2012-2019 Red Hat, Inc. + * Copyright (C) 2001 Dell Computer Corporation <matt_dom...@dell.com> + * + * This library is free software; you can redistribute it and/or +@@ -169,6 +169,8 @@ set_disk_name(struct device *dev, const + int HIDDEN + set_disk_and_part_name(struct device *dev) + { ++ int rc = -1; ++ + /* + * results are like such: + * maj:min -> ../../devices/pci$PCI_STUFF/$BLOCKDEV_STUFF/block/$DISK/$PART +@@ -200,6 +202,7 @@ set_disk_and_part_name(struct device *de + set_disk_name(dev, "%s", penultimate); + set_part_name(dev, "%s", ultimate); + debug("disk:%s part:%s", penultimate, ultimate); ++ rc = 0; + } else if (ultimate && approximate && !strcmp(approximate, "nvme")) { + /* + * 259:0 -> ../../devices/pci0000:00/0000:00:1d.0/0000:05:00.0/nvme/nvme0/nvme0n1 +@@ -207,6 +210,7 @@ set_disk_and_part_name(struct device *de + set_disk_name(dev, "%s", ultimate); + set_part_name(dev, "%sp%d", ultimate, dev->part); + debug("disk:%s part:%sp%d", ultimate, ultimate, dev->part); ++ rc = 0; + } else if (ultimate && penultimate && !strcmp(penultimate, "block")) { + /* + * 253:0 -> ../../devices/virtual/block/dm-0 (... I guess) +@@ -220,15 +224,19 @@ set_disk_and_part_name(struct device *de + set_disk_name(dev, "%s", ultimate); + set_part_name(dev, "%s%d", ultimate, dev->part); + debug("disk:%s part:%s%d", ultimate, ultimate, dev->part); ++ rc = 0; + } else if (ultimate && approximate && !strcmp(approximate, "mtd")) { + /* + * 31:0 -> ../../devices/platform/1e000000.palmbus/1e000b00.spi/spi_master/spi32766/spi32766.0/mtd/mtd0/mtdblock0 + */ + set_disk_name(dev, "%s", ultimate); + debug("disk:%s", ultimate); ++ rc = 0; + } + +- return 0; ++ if (rc < 0) ++ efi_error("Could not parse disk name:\"%s\"", dev->link); ++ return rc; + } + + static struct dev_probe *dev_probes[] = { diff -Nru efivar-37/debian/patches/0002-sysfs-parsers-make-all-the-sys-block-link-parsers-wo.patch efivar-37/debian/patches/0002-sysfs-parsers-make-all-the-sys-block-link-parsers-wo.patch --- efivar-37/debian/patches/0002-sysfs-parsers-make-all-the-sys-block-link-parsers-wo.patch 1970-01-01 01:00:00.000000000 +0100 +++ efivar-37/debian/patches/0002-sysfs-parsers-make-all-the-sys-block-link-parsers-wo.patch 2020-11-21 23:57:27.000000000 +0000 @@ -0,0 +1,92 @@ +From 4718694094647b981b74453445d000b0296b6544 Mon Sep 17 00:00:00 2001 +From: Peter Jones <pjo...@redhat.com> +Date: Tue, 15 Oct 2019 16:53:27 -0400 +Subject: [PATCH] sysfs parsers: make all the /sys/block link parsers work the + same way + +Apparently I wrote some of these one way and some the other, and the one +special case where everything was "current+sz" instead of some form of +"current += pos; sz += pos; ...; return sz;" or the subtraction version. + +Make them all the same, where possible. + +Signed-off-by: Peter Jones <pjo...@redhat.com> + +[ dannf: Restrict to just linux-nvme.c; + Context adjustments due to upstream whitespace cleanup; + drop call to dbgmk() call - it didn't exist in v37; + included to simplify application of later patches in series ] + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1891718 +Bug: https://github.com/rhboot/efivar/issues/157 +Origin: upstream, https://github.com/rhboot/efivar/commit/4718694094647b981b74453445d000b0296b6544 +Last-Updated: 2020-09-30 + +Index: efivar-37/src/linux-nvme.c +=================================================================== +--- efivar-37.orig/src/linux-nvme.c ++++ efivar-37/src/linux-nvme.c +@@ -24,6 +24,7 @@ + #include <fcntl.h> + #include <inttypes.h> + #include <stdint.h> ++#include <sys/param.h> + #include <unistd.h> + + #include "efiboot.h" +@@ -48,25 +49,28 @@ + */ + + static ssize_t +-parse_nvme(struct device *dev, const char *current, const char *root UNUSED) ++parse_nvme(struct device *dev, const char *path, const char *root UNUSED) + { ++ const char *current = path; + int rc; + int32_t tosser0, tosser1, tosser2, ctrl_id, ns_id, partition; + uint8_t *filebuf = NULL; +- int pos0 = 0, pos1 = 0; ++ int pos0 = -1, pos1 = -1, pos2 = -1; + + debug("entry"); + + debug("searching for nvme/nvme0/nvme0n1 or nvme/nvme0/nvme0n1/nvme0n1p1"); +- rc = sscanf(current, "nvme/nvme%d/nvme%dn%d%n/nvme%dn%dp%d%n", +- &tosser0, &ctrl_id, &ns_id, &pos0, +- &tosser1, &tosser2, &partition, &pos1); +- debug("current:\"%s\" rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1); ++ rc = sscanf(current, "%nnvme/nvme%d/nvme%dn%d%n/nvme%dn%dp%d%n", ++ &pos0, &tosser0, &ctrl_id, &ns_id, ++ &pos1, &tosser1, &tosser2, &partition, &pos2); ++ debug("current:\"%s\" rc:%d pos0:%d pos1:%d pos2:%d\n", current, rc, pos0, pos1, pos2); + /* + * If it isn't of that form, it's not one of our nvme devices. + */ + if (rc != 3 && rc != 6) + return 0; ++ if (rc == 3) ++ pos2 = pos1; + + dev->nvme_info.ctrl_id = ctrl_id; + dev->nvme_info.ns_id = ns_id; +@@ -77,8 +81,9 @@ parse_nvme(struct device *dev, const cha + if (dev->part == -1) + dev->part = partition; + +- pos0 = pos1; ++ pos1 = pos2; + } ++ current += pos1; + + /* + * now fish the eui out of sysfs is there is one... +@@ -110,7 +115,8 @@ parse_nvme(struct device *dev, const cha + memcpy(dev->nvme_info.eui, eui, sizeof(eui)); + } + +- return pos0; ++ debug("current:'%s' sz:%zd", current, current - path); ++ return current - path; + } + + static ssize_t diff -Nru efivar-37/debian/patches/0003-Try-even-harder-to-find-disk-device-symlinks-in-sysf.patch efivar-37/debian/patches/0003-Try-even-harder-to-find-disk-device-symlinks-in-sysf.patch --- efivar-37/debian/patches/0003-Try-even-harder-to-find-disk-device-symlinks-in-sysf.patch 1970-01-01 01:00:00.000000000 +0100 +++ efivar-37/debian/patches/0003-Try-even-harder-to-find-disk-device-symlinks-in-sysf.patch 2020-11-21 23:57:27.000000000 +0000 @@ -0,0 +1,209 @@ +From c9c1424d0e09bf33b747d37c43177c63367b1290 Mon Sep 17 00:00:00 2001 +From: Peter Jones <pjo...@redhat.com> +Date: Fri, 11 Oct 2019 14:20:54 -0400 +Subject: [PATCH] Try even harder to find disk device symlinks in sysfs. + +Today's realization is that the thing encoded into the structure of +sysfs is, in the best case, the dependency graph of the makefile targets +to build a device driver. + +In the case of nvme-fabric, or really wherever the kernel has +class_create() and device_create() in the same function, there's an +extra level of indirection. + +Anyway, in this patch we stop pretending sysfs isn't completely absurd, +and just try adding "/device" in the middle of the driver symlink path, +until we actually either get ENOENT on the device symlink or find a +device symlink that actually has a driver symlink under it. + +Signed-off-by: Peter Jones <pjo...@redhat.com> + +[ dannf: Context adjustments due to upstream whitespace cleanup; + Adjust to omit efi_error_pop() call that didn't exist in v37; + included to simplify application of later patches in series ] + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1891718 +Bug: https://github.com/rhboot/efivar/issues/157 +Origin: upstream, https://github.com/rhboot/efivar/commit/c9c1424d0e09bf33b747d37c43177c63367b1290 +Last-Updated: 2020-09-30 + +Index: efivar-37/src/linux-nvme.c +=================================================================== +--- efivar-37.orig/src/linux-nvme.c ++++ efivar-37/src/linux-nvme.c +@@ -88,13 +88,12 @@ parse_nvme(struct device *dev, const cha + /* + * now fish the eui out of sysfs is there is one... + */ +- rc = read_sysfs_file(&filebuf, +- "class/block/nvme%dn%d/eui", +- ctrl_id, ns_id); +- if ((rc < 0 && errno == ENOENT) || filebuf == NULL) { +- rc = read_sysfs_file(&filebuf, +- "class/block/nvme%dn%d/device/eui", +- ctrl_id, ns_id); ++ char *euipath = NULL; ++ rc = read_sysfs_file(&filebuf, "class/block/nvme%dn%d/eui", ctrl_id, ns_id); ++ if (rc < 0 && (errno == ENOENT || errno == ENOTDIR)) { ++ rc = find_device_file(&euipath, "eui", "class/block/nvme%dn%d", ctrl_id, ns_id); ++ if (rc >= 0 && euipath != NULL) ++ rc = read_sysfs_file(&filebuf, "%s", euipath); + } + if (rc >= 0 && filebuf != NULL) { + uint8_t eui[8]; +Index: efivar-37/src/linux.c +=================================================================== +--- efivar-37.orig/src/linux.c ++++ efivar-37/src/linux.c +@@ -410,24 +410,32 @@ struct device HIDDEN + goto err; + } + +- if (dev->device[0] != 0) { +- rc = sysfs_readlink(&tmpbuf, "block/%s/device/driver", dev->disk_name); ++ /* ++ * So, on a normal disk, you get something like: ++ * /sys/block/sda/device -> ../../0:0:0:0 ++ * /sys/block/sda/device/driver -> ../../../../../../../bus/scsi/drivers/sd ++ * ++ * On a directly attached nvme device you get: ++ * /sys/block/nvme0n1/device -> ../../nvme0 ++ * /sys/block/nvme0n1/device/device -> ../../../0000:6e:00.0 ++ * /sys/block/nvme0n1/device/device/driver -> ../../../../bus/pci/drivers/nvme ++ * ++ * On a fabric-attached nvme device, you get something like: ++ * /sys/block/nvme0n1/device -> ../../nvme0 ++ * /sys/block/nvme0n1/device/device -> ../../ctl ++ * /sys/block/nvme0n1/device/device/device -> ../../../../../0000:6e:00.0 ++ * /sys/block/nvme0n1/device/device/device/driver -> ../../../../../../bus/pci/drivers/nvme-fabrics ++ * ++ * ... I think? I don't have one in front of me. ++ */ ++ ++ char *filepath = NULL; ++ rc = find_device_file(&filepath, "driver", "block/%s", dev->disk_name); ++ if (rc >= 0) { ++ rc = sysfs_readlink(&tmpbuf, "%s", filepath); + if (rc < 0 || !tmpbuf) { +- if (errno == ENOENT) { +- /* +- * nvme, for example, will have nvme0n1/device point +- * at nvme0, and we need to look for device/driver +- * there. +- */ +- rc = sysfs_readlink(&tmpbuf, +- "block/%s/device/device/driver", +- dev->disk_name); +- } +- if (rc < 0 || !tmpbuf) { +- efi_error("readlink of /sys/block/%s/device/driver failed", +- dev->disk_name); +- goto err; +- } ++ efi_error("readlink of /sys/%s failed", filepath); ++ goto err; + } + + linkbuf = pathseg(tmpbuf, -1); +@@ -438,7 +446,7 @@ struct device HIDDEN + + dev->driver = strdup(linkbuf); + } else { +- dev->driver = strdup(""); ++ dev->driver = strdup(""); + } + + if (!dev->driver) { +Index: efivar-37/src/linux.h +=================================================================== +--- efivar-37.orig/src/linux.h ++++ efivar-37/src/linux.h +@@ -1,6 +1,6 @@ + /* + * libefiboot - library for the manipulation of EFI boot variables +- * Copyright 2012-2015 Red Hat, Inc. ++ * Copyright 2012-2019 Red Hat, Inc. + * Copyright (C) 2001 Dell Computer Corporation <matt_dom...@dell.com> + * + * This library is free software; you can redistribute it and/or +@@ -196,6 +196,22 @@ extern ssize_t HIDDEN make_mac_path(uint + bufsize_; \ + }) + ++#define sysfs_access(mode, fmt, args...) \ ++ ({ \ ++ int rc_; \ ++ char *pn_; \ ++ \ ++ rc_ = asprintfa(&pn_, "/sys/" fmt, ## args); \ ++ if (rc_ >= 0) { \ ++ rc_ = access(pn_, mode); \ ++ if (rc_ < 0) \ ++ efi_error("could not access %s", pn_); \ ++ } else { \ ++ efi_error("could not allocate memory"); \ ++ } \ ++ rc_; \ ++ }) ++ + #define sysfs_readlink(linkbuf, fmt, args...) \ + ({ \ + char *_lb = alloca(PATH_MAX+1); \ +@@ -251,6 +267,57 @@ extern ssize_t HIDDEN make_mac_path(uint + dir_; \ + }) + ++/* ++ * Iterate a /sys/block directory looking for device/foo, device/device/foo, ++ * etc. I'm not proud of this method. ++ */ ++#define find_device_file(result, name, fmt, args...) \ ++ ({ \ ++ int rc_ = 0; \ ++ debug("searching for %s from in %s", name, dev->disk_name); \ ++ for (unsigned int try_ = 0; true; try_++) { \ ++ char slashdev_[sizeof("device") \ ++ + try_ * strlen("/device")]; \ ++ \ ++ char *nul_ = stpcpy(slashdev_, "device"); \ ++ for (unsigned int i_ = 0; i_ < try_; i_++) \ ++ nul_ = stpcpy(nul_, "/device"); \ ++ \ ++ debug("trying /sys/" fmt "/%s/%s", \ ++ ## args, slashdev_, name); \ ++ \ ++ rc_ = sysfs_access(F_OK, fmt "/%s", ## args, slashdev_);\ ++ if (rc_ < 0) { \ ++ if (errno == ENOENT) { \ ++ break; \ ++ } \ ++ efi_error("cannot access /sys/"fmt"/%s: %m", \ ++ ## args, slashdev_); \ ++ goto find_device_link_err_; \ ++ } \ ++ \ ++ rc_ = sysfs_access(F_OK, fmt "/%s/%s", \ ++ ## args, slashdev_, name); \ ++ if (rc_ < 0) { \ ++ if (errno == ENOENT) { \ ++ break; \ ++ } \ ++ efi_error("cannot access /sys/"fmt"/%s/%s: %m", \ ++ ## args, slashdev_, name); \ ++ goto find_device_link_err_; \ ++ } \ ++ \ ++ rc_ = asprintfa(result, fmt "/%s/%s", \ ++ ## args, slashdev_, name); \ ++ if (rc_ < 0) { \ ++ efi_error("cannot allocate memory: %m"); \ ++ goto find_device_link_err_; \ ++ } \ ++ } \ ++find_device_link_err_: \ ++ rc_; \ ++ }) ++ + #define DEV_PROVIDES_ROOT 1 + #define DEV_PROVIDES_HD 2 + #define DEV_ABBREV_ONLY 4 diff -Nru efivar-37/debian/patches/0004-Handle-sys-devices-virtual-nvme-fabrics-nvme-subsyst.patch efivar-37/debian/patches/0004-Handle-sys-devices-virtual-nvme-fabrics-nvme-subsyst.patch --- efivar-37/debian/patches/0004-Handle-sys-devices-virtual-nvme-fabrics-nvme-subsyst.patch 1970-01-01 01:00:00.000000000 +0100 +++ efivar-37/debian/patches/0004-Handle-sys-devices-virtual-nvme-fabrics-nvme-subsyst.patch 2020-11-21 23:57:27.000000000 +0000 @@ -0,0 +1,309 @@ +From c41da0bdce04ab0f99b992d51ff6fd0ab55d040a Mon Sep 17 00:00:00 2001 +From: Peter Jones <pjo...@redhat.com> +Date: Wed, 2 Oct 2019 17:04:12 -0400 +Subject: [PATCH] Handle /sys/devices/virtual/{nvme-fabrics,nvme-subsystem} + devices + +Signed-off-by: Peter Jones <pjo...@redhat.com> + +[ dannf: Context adjustments due to upstream whitespace cleanup and + dbgmk() calls; + drop new calls to dbgmk() - it didn't exist in v37 ] + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1891718 +Bug: https://github.com/rhboot/efivar/issues/157 +Origin: upstream, https://github.com/rhboot/efivar/commit/c41da0bdce04ab0f99b992d51ff6fd0ab55d040a +Last-Updated: 2020-09-30 + +Index: efivar-37/src/linux-nvme.c +=================================================================== +--- efivar-37.orig/src/linux-nvme.c ++++ efivar-37/src/linux-nvme.c +@@ -15,7 +15,6 @@ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. +- * + */ + + #include "fix_coverity.h" +@@ -35,6 +34,12 @@ + * /sys/dev/block/$major:$minor looks like: + * 259:0 -> ../../devices/pci0000:00/0000:00:1d.0/0000:05:00.0/nvme/nvme0/nvme0n1 + * 259:1 -> ../../devices/pci0000:00/0000:00:1d.0/0000:05:00.0/nvme/nvme0/nvme0n1/nvme0n1p1 ++ * or: ++ * 259:0 ->../../devices/virtual/nvme-fabrics/ctl/nvme0/nvme0n1 ++ * 259:1 ->../../devices/virtual/nvme-fabrics/ctl/nvme0/nvme0n1/nvme0n1p1 ++ * or: ++ * 259:5 -> ../../devices/virtual/nvme-subsystem/nvme-subsys0/nvme0n1 ++ * 259:6 -> ../../devices/virtual/nvme-subsystem/nvme-subsys0/nvme0n1/nvme0n1p1 + * + * /sys/dev/block/259:0/device looks like: + * device -> ../../nvme0 +@@ -56,14 +61,41 @@ parse_nvme(struct device *dev, const cha + int32_t tosser0, tosser1, tosser2, ctrl_id, ns_id, partition; + uint8_t *filebuf = NULL; + int pos0 = -1, pos1 = -1, pos2 = -1; ++ ssize_t sz = 0; ++ struct subdir { ++ const char * const name; ++ const char * const fmt; ++ int *pos0, *pos1; ++ } subdirs[] = { ++ {"nvme-subsysN/", "%nnvme-subsys%d/%n", &pos0, &pos2}, ++ {"ctl/", "%nctl/%n%n", &pos0, &pos1}, ++ {"nvme/", "%nnvme/%n%n", &pos0, &pos1}, ++ {NULL, } ++ }; + + debug("entry"); + +- debug("searching for nvme/nvme0/nvme0n1 or nvme/nvme0/nvme0n1/nvme0n1p1"); +- rc = sscanf(current, "%nnvme/nvme%d/nvme%dn%d%n/nvme%dn%dp%d%n", +- &pos0, &tosser0, &ctrl_id, &ns_id, +- &pos1, &tosser1, &tosser2, &partition, &pos2); +- debug("current:\"%s\" rc:%d pos0:%d pos1:%d pos2:%d\n", current, rc, pos0, pos1, pos2); ++ /* ++ * in this case, *any* of these is okay. ++ */ ++ for (int i = 0; subdirs[i].name; i++) { ++ debug("searching for %s", subdirs[i].name); ++ pos0 = tosser0 = pos1 = -1; ++ rc = sscanf(current, subdirs[i].fmt, &pos0, &pos1, &pos2); ++ debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, ++ *subdirs[i].pos0, *subdirs[i].pos1); ++ if (*subdirs[i].pos0 >= 0 && *subdirs[i].pos1 >= *subdirs[i].pos0) { ++ sz += *subdirs[i].pos1; ++ current += *subdirs[i].pos1; ++ break; ++ } ++ } ++ ++ debug("searching for nvme0/nvme0n1 or nvme0/nvme0n1/nvme0n1p1"); ++ rc = sscanf(current, "%nnvme%d/nvme%dn%d%n/nvme%dn%dp%d%n", ++ &pos0, &tosser0, &ctrl_id, &ns_id, &pos1, ++ &tosser1, &tosser2, &partition, &pos2); ++ debug("current:'%s' rc:%d pos0:%d pos1:%d pos2:%d\n", current, rc, pos0, pos1, pos2); + /* + * If it isn't of that form, it's not one of our nvme devices. + */ +@@ -81,13 +113,15 @@ parse_nvme(struct device *dev, const cha + if (dev->part == -1) + dev->part = partition; + +- pos1 = pos2; ++ pos1 = pos2; + } ++ + current += pos1; + + /* + * now fish the eui out of sysfs is there is one... + */ ++ debug("looking for the eui"); + char *euipath = NULL; + rc = read_sysfs_file(&filebuf, "class/block/nvme%dn%d/eui", ctrl_id, ns_id); + if (rc < 0 && (errno == ENOENT || errno == ENOTDIR)) { +@@ -110,6 +144,9 @@ parse_nvme(struct device *dev, const cha + errno = EINVAL; + return -1; + } ++ debug("eui is %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", ++ eui[0], eui[1], eui[2], eui[3], ++ eui[4], eui[5], eui[6], eui[7]); + dev->nvme_info.has_eui = 1; + memcpy(dev->nvme_info.eui, eui, sizeof(eui)); + } +Index: efivar-37/src/linux-virtual-root.c +=================================================================== +--- /dev/null ++++ efivar-37/src/linux-virtual-root.c +@@ -0,0 +1,87 @@ ++/* ++ * libefiboot - library for the manipulation of EFI boot variables ++ * Copyright 2012-2019 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of the ++ * License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see ++ * <http://www.gnu.org/licenses/>. ++ */ ++ ++#include "fix_coverity.h" ++ ++#include <errno.h> ++#include <fcntl.h> ++#include <inttypes.h> ++#include <stdint.h> ++#include <unistd.h> ++ ++#include "efiboot.h" ++ ++/* ++ * Support virtually rooted devices (fibre+nvme, etc.) ++ * ++ * /sys/dev/block/$major:$minor looks like: ++ * 259:0 ->../../devices/virtual/nvme-fabrics/ctl/nvme0/nvme0n1 ++ * 259:1 ->../../devices/virtual/nvme-fabrics/ctl/nvme0/nvme0n1/nvme0n1p1 ++ * or: ++ * 259:5 -> ../../devices/virtual/nvme-subsystem/nvme-subsys0/nvme0n1 ++ * 259:6 -> ../../devices/virtual/nvme-subsystem/nvme-subsys0/nvme0n1/nvme0n1p1 ++ */ ++ ++static ssize_t ++parse_virtual_root(struct device *dev UNUSED, const char *current, const char *root UNUSED) ++{ ++ int rc; ++ ssize_t sz; ++ int pos0 = 0, pos1 = 0; ++ struct subdir { ++ const char * const name; ++ const char * const fmt; ++ } subdirs[] = { ++ {"../../devices/virtual", "%n../../devices/virtual/%n"}, ++ {"nvme-subsystem/", "%nnvme-subsystem/%n"}, ++ {"nvme-fabrics/ctl/", "%nnvme-fabrics/ctl/%n"}, ++ {NULL, NULL} ++ }; ++ ++ debug("entry"); ++ ++ for (int i = 0; subdirs[i].name; i++) { ++ debug("searching for %s", subdirs[i].name); ++ pos0 = pos1 = -1; ++ rc = sscanf(current, subdirs[i].fmt, &pos0, &pos1); ++ debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1); ++ if (rc == 1) { ++ sz += pos1; ++ current += pos1; ++ if (i > 0) ++ goto found; ++ } ++ } ++ ++ sz = 0; ++found: ++ debug("current:'%s' sz:%zd\n", current, sz); ++ return sz; ++} ++ ++static enum interface_type virtual_root_iftypes[] = { virtual_root, unknown }; ++ ++struct dev_probe HIDDEN virtual_root_parser = { ++ .name = "virtual_root", ++ .iftypes = virtual_root_iftypes, ++ .flags = DEV_ABBREV_ONLY|DEV_PROVIDES_ROOT, ++ .parse = parse_virtual_root, ++}; ++ ++// vim:fenc=utf-8:tw=75:noet +Index: efivar-37/src/linux.h +=================================================================== +--- efivar-37.orig/src/linux.h ++++ efivar-37/src/linux.h +@@ -99,7 +99,8 @@ struct emmc_info { + + enum interface_type { + unknown, +- isa, acpi_root, pci_root, soc_root, pci, network, ++ isa, acpi_root, pci_root, soc_root, virtual_root, ++ pci, network, + ata, atapi, scsi, sata, sas, + usb, i1394, fibre, i2o, + md, virtblk, +@@ -344,6 +345,7 @@ extern struct dev_probe pmem_parser; + extern struct dev_probe pci_root_parser; + extern struct dev_probe acpi_root_parser; + extern struct dev_probe soc_root_parser; ++extern struct dev_probe virtual_root_parser; + extern struct dev_probe pci_parser; + extern struct dev_probe sas_parser; + extern struct dev_probe sata_parser; +Index: efivar-37/src/linux.c +=================================================================== +--- efivar-37.orig/src/linux.c ++++ efivar-37/src/linux.c +@@ -170,16 +170,17 @@ int HIDDEN + set_disk_and_part_name(struct device *dev) + { + int rc = -1; +- +- /* +- * results are like such: +- * maj:min -> ../../devices/pci$PCI_STUFF/$BLOCKDEV_STUFF/block/$DISK/$PART +- */ +- + char *ultimate = pathseg(dev->link, -1); + char *penultimate = pathseg(dev->link, -2); + char *approximate = pathseg(dev->link, -3); + char *proximate = pathseg(dev->link, -4); ++ char *psl5 = pathseg(dev->link, -5); ++ ++ ++ /* ++ * devlinks look something like: ++ * maj:min -> ../../devices/pci$PCI_STUFF/$BLOCKDEV_STUFF/block/$DISK/$PART ++ */ + + errno = 0; + debug("dev->disk_name:%p dev->part_name:%p", dev->disk_name, dev->part_name); +@@ -188,6 +189,7 @@ set_disk_and_part_name(struct device *de + debug("penultimate:\"%s\"", penultimate ? : ""); + debug("approximate:\"%s\"", approximate ? : ""); + debug("proximate:\"%s\"", proximate ? : ""); ++ debug("psl5:'%s'", psl5 ? : ""); + + if (ultimate && penultimate && + ((proximate && !strcmp(proximate, "nvme")) || +@@ -232,6 +234,34 @@ set_disk_and_part_name(struct device *de + set_disk_name(dev, "%s", ultimate); + debug("disk:%s", ultimate); + rc = 0; ++ } else if ((proximate && ultimate && !strcmp(proximate, "nvme-fabrics")) || ++ (approximate && ultimate && !strcmp(approximate, "nvme-subsystem"))) { ++ /* ++ * 259:0 ->../../devices/virtual/nvme-fabrics/ctl/nvme0/nvme0n1 ++ * ^ proximate ^ ultimate ++ * or ++ * 259:5 -> ../../devices/virtual/nvme-subsystem/nvme-subsys0/nvme0n1 ++ * ^ approximate ^ penultimate ++ * ultimate ^ ++ */ ++ set_disk_name(dev, "%s", ultimate); ++ debug("disk:%s", ultimate); ++ rc = 0; ++ } else if ((psl5 && penultimate && ultimate && !strcmp(psl5, "nvme-fabrics")) || ++ (proximate && penultimate && ultimate && !strcmp(proximate, "nvme-subsystem"))) { ++ /* ++ * 259:1 -> ../../devices/virtual/nvme-fabrics/ctl/nvme0/nvme0n1/nvme0n1p1 ++ * ^psl5 ^ penultimate ++ * ultimate ^ ++ * or ++ * 259:6 -> ../../devices/virtual/nvme-subsystem/nvme-subsys0/nvme0n1/nvme0n1p1 ++ * ^ proximate ^ penultimate ++ * ultimate ^ ++ */ ++ set_disk_name(dev, "%s", penultimate); ++ set_part_name(dev, "%s", ultimate); ++ debug("disk:%s part:%s", penultimate, ultimate); ++ rc = 0; + } + + if (rc < 0) +@@ -248,6 +278,7 @@ static struct dev_probe *dev_probes[] = + &acpi_root_parser, + &pci_root_parser, + &soc_root_parser, ++ &virtual_root_parser, + &pci_parser, + &virtblk_parser, + &sas_parser, diff -Nru efivar-37/debian/patches/0005-Fix-variable-sz-uninitialized-error.patch efivar-37/debian/patches/0005-Fix-variable-sz-uninitialized-error.patch --- efivar-37/debian/patches/0005-Fix-variable-sz-uninitialized-error.patch 1970-01-01 01:00:00.000000000 +0100 +++ efivar-37/debian/patches/0005-Fix-variable-sz-uninitialized-error.patch 2020-11-21 23:57:27.000000000 +0000 @@ -0,0 +1,38 @@ +From 9dc04c2fd88b6e0e0fe411885041925d52f71af3 Mon Sep 17 00:00:00 2001 +From: Chih-Wei Huang <cwhu...@linux.org.tw> +Date: Wed, 22 Jan 2020 12:16:12 +0800 +Subject: [PATCH 2/2] Fix variable 'sz' uninitialized error + +To fix the error: + +external/efivar/src/linux-virtual-root.c:66:4: error: variable 'sz' is uninitialized when used here [-Werror,-Wuninitialized] + sz += pos1; + ^~ +external/efivar/src/linux-virtual-root.c:45:12: note: initialize the variable 'sz' to silence this warning + ssize_t sz; + ^ + = 0 +1 error generated. + +Fixes: c41da0bd ("Handle /sys/devices/virtual/{nvme-fabrics,nvme-subsystem} devices") + +Signed-off-by: Chih-Wei Huang <cwhu...@linux.org.tw> + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1891718 +Bug: https://github.com/rhboot/efivar/issues/157 +Origin: upstream, https://github.com/rhboot/efivar/commit/9dc04c2fd88b6e0e0fe411885041925d52f71af3 +Last-Updated: 2020-09-30 + +Index: efivar-37/src/linux-virtual-root.c +=================================================================== +--- efivar-37.orig/src/linux-virtual-root.c ++++ efivar-37/src/linux-virtual-root.c +@@ -42,7 +42,7 @@ static ssize_t + parse_virtual_root(struct device *dev UNUSED, const char *current, const char *root UNUSED) + { + int rc; +- ssize_t sz; ++ ssize_t sz = 0; + int pos0 = 0, pos1 = 0; + struct subdir { + const char * const name; diff -Nru efivar-37/debian/patches/0006-Fix-parsing-for-nvme-subsystem-devices.patch efivar-37/debian/patches/0006-Fix-parsing-for-nvme-subsystem-devices.patch --- efivar-37/debian/patches/0006-Fix-parsing-for-nvme-subsystem-devices.patch 1970-01-01 01:00:00.000000000 +0100 +++ efivar-37/debian/patches/0006-Fix-parsing-for-nvme-subsystem-devices.patch 2020-11-21 23:57:27.000000000 +0000 @@ -0,0 +1,91 @@ +From 4e12f997f8b6af76ef65e7045c232b7d642a1af4 Mon Sep 17 00:00:00 2001 +From: dann frazier <dann.fraz...@canonical.com> +Date: Mon, 17 Aug 2020 13:11:15 -0600 +Subject: [PATCH] Fix parsing for nvme-subsystem devices + +nvme-subsystem devices have a link that looks like: + ../../devices/virtual/nvme-subsystem/nvme-subsys0/nvme0n1 + +However, the current code expects an additional /nvme0/ component, i.e.: + ../../devices/virtual/nvme-subsystem/nvme-subsys0/nvme0/nvme0n1 + +Fix this by adding a separate branch for parsing nvme-subsystem devices. + +Resolves github issue #157. + +Signed-off-by: dann frazier <dann.fraz...@canonical.com> + +[ dannf: Context adjustments due to upstream whitespace cleanup and + dbgmk() calls ] + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1891718 +Bug: https://github.com/rhboot/efivar/issues/157 +Origin: upstream, https://github.com/rhboot/efivar/commit/4e12f997f8b6af76ef65e7045c232b7d642a1af4 +Last-Updated: 2020-10-08 + +Index: efivar/src/linux-nvme.c +=================================================================== +--- efivar.orig/src/linux-nvme.c ++++ efivar/src/linux-nvme.c +@@ -57,7 +57,7 @@ static ssize_t + parse_nvme(struct device *dev, const char *path, const char *root UNUSED) + { + const char *current = path; +- int rc; ++ int i, rc; + int32_t tosser0, tosser1, tosser2, ctrl_id, ns_id, partition; + uint8_t *filebuf = NULL; + int pos0 = -1, pos1 = -1, pos2 = -1; +@@ -78,7 +78,7 @@ parse_nvme(struct device *dev, const cha + /* + * in this case, *any* of these is okay. + */ +- for (int i = 0; subdirs[i].name; i++) { ++ for (i = 0; subdirs[i].name; i++) { + debug("searching for %s", subdirs[i].name); + pos0 = tosser0 = pos1 = -1; + rc = sscanf(current, subdirs[i].fmt, &pos0, &pos1, &pos2); +@@ -91,18 +91,31 @@ parse_nvme(struct device *dev, const cha + } + } + +- debug("searching for nvme0/nvme0n1 or nvme0/nvme0n1/nvme0n1p1"); +- rc = sscanf(current, "%nnvme%d/nvme%dn%d%n/nvme%dn%dp%d%n", +- &pos0, &tosser0, &ctrl_id, &ns_id, &pos1, +- &tosser1, &tosser2, &partition, &pos2); +- debug("current:'%s' rc:%d pos0:%d pos1:%d pos2:%d\n", current, rc, pos0, pos1, pos2); +- /* +- * If it isn't of that form, it's not one of our nvme devices. +- */ +- if (rc != 3 && rc != 6) +- return 0; +- if (rc == 3) +- pos2 = pos1; ++ if (!subdirs[i].name) ++ return 0; ++ ++ debug("searching for nvme-subsysN/"); ++ if (!strncmp("nvme-subsysN/", subdirs[i].name, 13)) { ++ debug("searching for nvme0n1"); ++ rc = sscanf(current, "%nnvme%dn%d%n", ++ &pos0, &ctrl_id, &ns_id, &pos1); ++ debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1); ++ if (rc != 2) ++ return 0; ++ } else { ++ debug("searching for nvme0/nvme0n1 or nvme0/nvme0n1/nvme0n1p1"); ++ rc = sscanf(current, "%nnvme%d/nvme%dn%d%n/nvme%dn%dp%d%n", ++ &pos0, &tosser0, &ctrl_id, &ns_id, &pos1, ++ &tosser1, &tosser2, &partition, &pos2); ++ debug("current:'%s' rc:%d pos0:%d pos1:%d pos2:%d\n", current, rc, pos0, pos1, pos2); ++ /* ++ * If it isn't of that form, it's not one of our nvme devices. ++ */ ++ if (rc != 3 && rc != 6) ++ return 0; ++ if (rc == 3) ++ pos2 = pos1; ++ } + + dev->nvme_info.ctrl_id = ctrl_id; + dev->nvme_info.ns_id = ns_id; diff -Nru efivar-37/debian/patches/Always-initialize-any-variable-we-use-with-sscanf-s-.patch efivar-37/debian/patches/Always-initialize-any-variable-we-use-with-sscanf-s-.patch --- efivar-37/debian/patches/Always-initialize-any-variable-we-use-with-sscanf-s-.patch 1970-01-01 01:00:00.000000000 +0100 +++ efivar-37/debian/patches/Always-initialize-any-variable-we-use-with-sscanf-s-.patch 2020-11-21 23:53:27.000000000 +0000 @@ -0,0 +1,76 @@ +From 5dc12cc56c79d293cf68d12a0b84373a785745e7 Mon Sep 17 00:00:00 2001 +From: Peter Jones <pjo...@redhat.com> +Date: Tue, 28 May 2019 16:27:31 -0400 +Subject: [PATCH] Always initialize any variable we use with sscanf's %n + +Signed-off-by: Peter Jones <pjo...@redhat.com> + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1892792 +Origin: upstream,https://github.com/rhboot/efivar/commit/5dc12cc56c79d293cf68d12a0b84373a785745e7 +Last-Updated: 2020-08-24 + +Index: efivar/src/linux-acpi-root.c +=================================================================== +--- efivar.orig/src/linux-acpi-root.c ++++ efivar/src/linux-acpi-root.c +@@ -44,7 +44,7 @@ static ssize_t + parse_acpi_root(struct device *dev, const char *current, const char *root UNUSED) + { + int rc; +- int pos; ++ int pos = 0; + uint16_t pad0; + uint8_t pad1; + char *acpi_header = NULL; +Index: efivar/src/linux-pci-root.c +=================================================================== +--- efivar.orig/src/linux-pci-root.c ++++ efivar/src/linux-pci-root.c +@@ -44,7 +44,7 @@ static ssize_t + parse_pci_root(struct device *dev, const char *current, const char *root UNUSED) + { + int rc; +- int pos; ++ int pos = 0; + uint16_t root_domain; + uint8_t root_bus; + const char *devpart = current; +Index: efivar/src/linux-pci.c +=================================================================== +--- efivar.orig/src/linux-pci.c ++++ efivar/src/linux-pci.c +@@ -46,7 +46,7 @@ static ssize_t + parse_pci(struct device *dev, const char *current, const char *root) + { + int rc; +- int pos; ++ int pos = 0; + const char *devpart = current; + + debug("entry"); +Index: efivar/src/linux-soc-root.c +=================================================================== +--- efivar.orig/src/linux-soc-root.c ++++ efivar/src/linux-soc-root.c +@@ -41,7 +41,7 @@ static ssize_t + parse_soc_root(struct device *dev UNUSED, const char *current, const char *root UNUSED) + { + int rc; +- int pos; ++ int pos = 0; + const char *devpart = current; + + debug("entry"); +Index: efivar/src/linux-virtblk.c +=================================================================== +--- efivar.orig/src/linux-virtblk.c ++++ efivar/src/linux-virtblk.c +@@ -48,7 +48,7 @@ static ssize_t + parse_virtblk(struct device *dev, const char *current, const char *root UNUSED) + { + uint32_t tosser; +- int pos; ++ int pos = 0; + int rc; + + debug("entry"); diff -Nru efivar-37/debian/patches/series efivar-37/debian/patches/series --- efivar-37/debian/patches/series 2019-03-01 17:55:07.000000000 +0000 +++ efivar-37/debian/patches/series 2020-11-21 23:57:27.000000000 +0000 @@ -1 +1,8 @@ remove-arrows.patch +Always-initialize-any-variable-we-use-with-sscanf-s-.patch +0001-Fix-the-error-path-in-set_disk_and_part_name.patch +0002-sysfs-parsers-make-all-the-sys-block-link-parsers-wo.patch +0003-Try-even-harder-to-find-disk-device-symlinks-in-sysf.patch +0004-Handle-sys-devices-virtual-nvme-fabrics-nvme-subsyst.patch +0005-Fix-variable-sz-uninitialized-error.patch +0006-Fix-parsing-for-nvme-subsystem-devices.patch