c2a6082b13
ssia
65 lines
2.0 KiB
Diff
65 lines
2.0 KiB
Diff
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
|
|
|