dmidecode/0021-dmidecode-Don-t-allocate-more-memory-than-needed.patch

65 lines
2.0 KiB
Diff
Raw Normal View History

From bd78a5dfd47043db08982464bcae4759c0980975 Mon Sep 17 00:00:00 2001
From: Jean Delvare <jdelvare@suse.de>
Date: Wed, 1 Aug 2018 09:54:55 +0200
Subject: [PATCH 21/21] dmidecode: Don't allocate more memory than needed
If the actual DMI table size is less than the announced maximum
(which is allowed for 64-bit SMBIOS 3 entry points), we may allocate
significantly more memory than is actually needed. If reading from
/dev/mem, there's nothing we can do about that. However, is reading
from sysfs or from a dump file, we can easily check the file size
and compute the actual table size from it. That way we only allocate
the required amount of memory.
Credits to Lionel Debroux for seeding the idea when performing fuzz
testing on dmidecode.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
---
util.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/util.c b/util.c
index 0aafcb1..7049817 100644
--- a/util.c
+++ b/util.c
@@ -90,16 +90,16 @@ int checksum(const u8 *buf, size_t len)
/*
* Reads all of file from given offset, up to max_len bytes.
- * A buffer of max_len bytes is allocated by this function, and
+ * A buffer of at most max_len bytes is allocated by this function, and
* needs to be freed by the caller.
* This provides a similar usage model to mem_chunk()
*
- * Returns pointer to buffer of max_len bytes, or NULL on error, and
+ * Returns a pointer to the allocated buffer, or NULL on error, and
* sets max_len to the length actually read.
- *
*/
void *read_file(off_t base, size_t *max_len, const char *filename)
{
+ struct stat statbuf;
int fd;
size_t r2 = 0;
ssize_t r;
@@ -124,6 +124,15 @@ void *read_file(off_t base, size_t *max_len, const char *filename)
goto out;
}
+ /*
+ * Check file size, don't allocate more than can be read.
+ */
+ if (fstat(fd, &statbuf) == 0)
+ {
+ if (base + (off_t)*max_len > statbuf.st_size)
+ *max_len = statbuf.st_size - base;
+ }
+
if ((p = malloc(*max_len)) == NULL)
{
perror("malloc");
--
2.17.1