summaryrefslogtreecommitdiffstats
path: root/src/core/malloc.c
diff options
context:
space:
mode:
authorMichael Brown2010-11-05 23:37:00 +0100
committerMichael Brown2010-11-08 04:35:35 +0100
commit13e4b9ec498e4374cf7208b18723e87796aa1735 (patch)
treedfd970a19e0b6913da4201769b6c3f5e70db1566 /src/core/malloc.c
parent[refcnt] Check reference validity on each use of ref_get() and ref_put() (diff)
downloadipxe-13e4b9ec498e4374cf7208b18723e87796aa1735.tar.gz
ipxe-13e4b9ec498e4374cf7208b18723e87796aa1735.tar.xz
ipxe-13e4b9ec498e4374cf7208b18723e87796aa1735.zip
[malloc] Avoid immediately clobbering reference count when freeing memory
Rearrange the fields in struct memory_block (without altering MIN_MEMBLOCK_SIZE) so that the "count" field of a reference-counted object is left intact when the memory containing the object is freed. This allows for the possibility of detecting reference-counting errors such as double-freeing. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core/malloc.c')
-rw-r--r--src/core/malloc.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/core/malloc.c b/src/core/malloc.c
index d317ce17..6e3a4216 100644
--- a/src/core/malloc.c
+++ b/src/core/malloc.c
@@ -25,6 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/io.h>
#include <ipxe/list.h>
#include <ipxe/init.h>
+#include <ipxe/refcnt.h>
#include <ipxe/malloc.h>
/** @file
@@ -35,10 +36,21 @@ FILE_LICENCE ( GPL2_OR_LATER );
/** A free block of memory */
struct memory_block {
- /** List of free blocks */
- struct list_head list;
/** Size of this block */
size_t size;
+ /** Padding
+ *
+ * This padding exists to cover the "count" field of a
+ * reference counter, in the common case where a reference
+ * counter is the first element of a dynamically-allocated
+ * object. It avoids clobbering the "count" field as soon as
+ * the memory is freed, and so allows for the possibility of
+ * detecting reference counting errors.
+ */
+ char pad[ offsetof ( struct refcnt, count ) +
+ sizeof ( ( ( struct refcnt * ) NULL )->count ) ];
+ /** List of free blocks */
+ struct list_head list;
};
#define MIN_MEMBLOCK_SIZE \