File biosdevname-Read-DMI-entries-from-sys-firmware-dmi-tables-DMI.patch of Package biosdevname

From 345ea79e5f020e9776ba8de64b2dccad9df56584 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Thu, 13 Aug 2020 13:24:35 +0200
Subject: [PATCH 2/3] Read DMI entries from /sys/firmware/dmi/tables/DMI

A kernel with Secure Boot lockdown may prohibit reading the contents
of /dev/mem, hence biosdevname fails.  The recent kernel provides the
DMI byte contents in /sys/firmware/dmi/tables/*, and we can use this
instead of poking /dev/mem.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/dmidecode/dmidecode.c | 54 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 41 insertions(+), 13 deletions(-)

diff --git a/src/dmidecode/dmidecode.c b/src/dmidecode/dmidecode.c
index a01a6ce074f1..f4c12694ef13 100644
--- a/src/dmidecode/dmidecode.c
+++ b/src/dmidecode/dmidecode.c
@@ -229,7 +229,7 @@ static int isvalidsmbios(int mjr, int mnr)
 	return 0;
 }
 
-static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, const struct libbiosdevname_state *state)
+static int dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, const struct libbiosdevname_state *state, int sysfs)
 {
 	u8 *buf;
 	u8 *data;
@@ -237,14 +237,19 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, c
 
 	/* Verify SMBIOS version */
 	if (!isvalidsmbios(ver >> 8, ver & 0xFF)) {
-		return;
+		return 0;
 	}
-	if((buf=mem_chunk(base, len, devmem))==NULL)
+
+	if (sysfs)
+		buf = __mem_chunk(0, len, devmem, 0);
+	else
+		buf = mem_chunk(base, len, devmem);
+	if(buf == NULL)
 	{
 #ifndef USE_MMAP
 		printf("Table is unreachable, sorry. Try compiling dmidecode with -DUSE_MMAP.\n");
 #endif
-		return;
+		return 0;
 	}
 
 	data=buf;
@@ -280,18 +285,18 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, c
 		i++;
 	}
 	free(buf);
+	return 1;
 }
 
-
-static int smbios_decode(u8 *buf, const char *devmem, const struct libbiosdevname_state *state)
+static int smbios_decode(u8 *buf, const char *devmem, const struct libbiosdevname_state *state, int sysfs)
 {
 	if(checksum(buf, buf[0x05])
 	   && memcmp(buf+0x10, "_DMI_", 5)==0
 	   && checksum(buf+0x10, 0x0F))
 	{
-		dmi_table(DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C),
-			  (buf[0x06]<<8)+buf[0x07], devmem, state);
-		return 1;
+		return dmi_table(DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C),
+				 (buf[0x06]<<8)+buf[0x07], devmem, state,
+				 sysfs);
 	}
 
 	return 0;
@@ -302,13 +307,32 @@ static int legacy_decode(u8 *buf, const char *devmem, const struct libbiosdevnam
 	if(checksum(buf, 0x0F))
 	{
 		dmi_table(DWORD(buf+0x08), WORD(buf+0x06), WORD(buf+0x0C),
-			  ((buf[0x0E]&0xF0)<<4)+(buf[0x0E]&0x0F), devmem, state);
+			  ((buf[0x0E]&0xF0)<<4)+(buf[0x0E]&0x0F), devmem, state, 0);
 		return 1;
 	}
 
 	return 0;
 }
 
+#define SYSFS_TABLE_SMBIOS	"/sys/firmware/dmi/tables/smbios_entry_point"
+#define SYSFS_TABLE_DMI		"/sys/firmware/dmi/tables/DMI"
+
+static int smibios_decode_from_sysfs(const struct libbiosdevname_state *state)
+{
+	FILE *fp;
+	u8 buf[0x1f];
+	int len;
+
+	fp = fopen(SYSFS_TABLE_SMBIOS, "r");
+	if (!fp)
+		return 0;
+	len = fread(buf, 1, sizeof(buf), fp);
+	fclose(fp);
+	if (len == 0x1f && memcmp(buf, "_SM_", 4) == 0)
+		return smbios_decode(buf, SYSFS_TABLE_DMI, state, 1);
+	return 0;
+}
+
 /*
  * Probe for EFI interface
  */
@@ -417,7 +441,11 @@ int dmidecode_main(const struct libbiosdevname_state *state)
 	if (dmidecode_read_file(state))
 		return 0;
 
-	/* First try EFI (ia64, Intel-based Mac) */
+	/* First try sysfs entries */
+	if (smibios_decode_from_sysfs(state))
+		return 0;
+
+	/* Next try EFI (ia64, Intel-based Mac) */
 	efi=address_from_efi(&fp);
 	switch(efi)
 	{
@@ -434,7 +462,7 @@ int dmidecode_main(const struct libbiosdevname_state *state)
 		goto exit_free;
 	}
 
-	if(smbios_decode(buf, devmem, state))
+	if(smbios_decode(buf, devmem, state, 0))
 		found++;
 	goto done;
 
@@ -450,7 +478,7 @@ memory_scan:
 	{
 		if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0)
 		{
-			if(smbios_decode(buf+fp, devmem, state))
+			if(smbios_decode(buf+fp, devmem, state, 0))
 			{
 				found++;
 				fp+=16;
-- 
2.16.4
openSUSE Build Service is sponsored by