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

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