[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#975425: buster-pu: package efivar/32-2+deb10u1



Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@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 <93sam@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 <pjones@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 <pjones@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_Domsch@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 <pjones@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 <pjones@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 <pjones@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 <pjones@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_Domsch@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 <pjones@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 <pjones@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 <cwhuang@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 <cwhuang@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.frazier@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.frazier@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 <pjones@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 <pjones@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

Reply to: