summaryrefslogtreecommitdiff
path: root/poky/meta/recipes-devtools/dmidecode/dmidecode/CVE-2023-30630_4.patch
blob: 5fa72b4f9be91bbfb980cc63686f1c7f5966f48f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
From 2b83c4b898f8325313162f588765411e8e3e5561 Mon Sep 17 00:00:00 2001
From: Jean Delvare <jdelvare@suse.de>
Date: Tue, 27 Jun 2023 10:58:11 +0000
Subject: [PATCH] Don't read beyond sysfs entry point buffer

Functions smbios_decode() and smbios3_decode() include a check
against buffer overrun. This check assumes that the buffer length is
always 32 bytes. This is true when reading from /dev/mem or from a
dump file, however when reading from sysfs, the buffer length is the
size of the actual sysfs attribute file, typically 31 bytes for an
SMBIOS 2.x entry point and 24 bytes for an SMBIOS 3.x entry point.

In the unlikely event of a malformed entry point, with encoded length
larger than expected but smaller than or equal to 32, we would hit a
buffer overrun. So properly pass the actual buffer length as an
argument and perform the check against it.

In practice, this will never happen, because on the Linux kernel
side, the size of the sysfs attribute file is decided from the entry
point length field. So it is technically impossible for them not to
match. But user-space code should not make such assumptions.

Signed-off-by: Jean Delvare <jdelvare@suse.de>

CVE: CVE-2023-30630

Upstream-Status: Backport
[https://git.savannah.nongnu.org/cgit/dmidecode.git/commit/?id=2b83c4b898f8325313162f588765411e8e3e5561]

Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
 dmidecode.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/dmidecode.c b/dmidecode.c
index b4dbc9d..870d94e 100644
--- a/dmidecode.c
+++ b/dmidecode.c
@@ -5736,14 +5736,14 @@ static void overwrite_smbios3_address(u8 *buf)
	buf[0x17] = 0;
 }

-static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
+static int smbios3_decode(u8 *buf, size_t buf_len, const char *devmem, u32 flags)
 {
	u32 ver, len;
	u64 offset;
	u8 *table;

	/* Don't let checksum run beyond the buffer */
-	if (buf[0x06] > 0x20)
+        if (buf[0x06] > buf_len)
	{
		fprintf(stderr,
			"Entry point length too large (%u bytes, expected %u).\n",
@@ -5782,14 +5782,14 @@ static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
	return 1;
 }

-static int smbios_decode(u8 *buf, const char *devmem, u32 flags)
+static int smbios_decode(u8 *buf, size_t buf_len, const char *devmem, u32 flags)
 {
	u16 ver;
	u32 len;
         u8 *table;

	/* Don't let checksum run beyond the buffer */
-	if (buf[0x05] > 0x20)
+        if (buf[0x05] > buf_len)
	{
		fprintf(stderr,
			"Entry point length too large (%u bytes, expected %u).\n",
@@ -6018,12 +6018,12 @@ int main(int argc, char * const argv[])

		if (memcmp(buf, "_SM3_", 5) == 0)
		{
-			if (smbios3_decode(buf, opt.dumpfile, 0))
+                        if (smbios3_decode(buf, size, opt.dumpfile, 0))
				found++;
		}
		else if (memcmp(buf, "_SM_", 4) == 0)
		{
-			if (smbios_decode(buf, opt.dumpfile, 0))
+                        if (smbios_decode(buf, size, opt.dumpfile, 0))
				found++;
		}
		else if (memcmp(buf, "_DMI_", 5) == 0)
@@ -6046,12 +6046,12 @@ int main(int argc, char * const argv[])
			pr_info("Getting SMBIOS data from sysfs.");
		if (size >= 24 && memcmp(buf, "_SM3_", 5) == 0)
		{
-			if (smbios3_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET))
+                        if (smbios3_decode(buf, size, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET))
				found++;
		}
		else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0)
		{
-			if (smbios_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET))
+                        if (smbios_decode(buf, size, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET))
				found++;
		}
		else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0)
@@ -6088,12 +6088,12 @@ int main(int argc, char * const argv[])

	if (memcmp(buf, "_SM3_", 5) == 0)
	{
-		if (smbios3_decode(buf, opt.devmem, 0))
+                if (smbios3_decode(buf, 0x20, opt.devmem, 0))
			found++;
	}
	else if (memcmp(buf, "_SM_", 4) == 0)
	{
-		if (smbios_decode(buf, opt.devmem, 0))
+                if (smbios_decode(buf, 0x20, opt.devmem, 0))
			found++;
	}
	goto done;
@@ -6114,7 +6114,7 @@ memory_scan:
	{
		if (memcmp(buf + fp, "_SM3_", 5) == 0)
		{
-			if (smbios3_decode(buf + fp, opt.devmem, 0))
+                        if (smbios3_decode(buf + fp, 0x20, opt.devmem, 0))
			{
				found++;
				goto done;
@@ -6127,7 +6127,7 @@ memory_scan:
	{
		if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
		{
-			if (smbios_decode(buf + fp, opt.devmem, 0))
+                        if (smbios_decode(buf + fp, 0x20, opt.devmem, 0))
			{
				found++;
				goto done;
--
2.35.5