summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormdf <mdf@FreeBSD.org>2010-08-31 16:57:58 +0000
committermdf <mdf@FreeBSD.org>2010-08-31 16:57:58 +0000
commit42170bf6d6b1aa24e8b524672f3bbaf280e7e7c9 (patch)
tree52db48d2d45957d087b493ecb0f31698ab2834fd /sys
parent655a96888d55c63b6496de2c02332278739d62f6 (diff)
downloadFreeBSD-src-42170bf6d6b1aa24e8b524672f3bbaf280e7e7c9.zip
FreeBSD-src-42170bf6d6b1aa24e8b524672f3bbaf280e7e7c9.tar.gz
The realloc case for memguard(9) will copy too many bytes when
reallocating to a smaller-sized allocation. Fix this issue. Noticed by: alc Reviewed by: alc Approved by: zml (mentor) MFC after: 3 weeks
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_malloc.c11
-rw-r--r--sys/vm/memguard.c25
-rw-r--r--sys/vm/memguard.h2
3 files changed, 29 insertions, 9 deletions
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index 00df9dd..1e97b55 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -566,11 +566,8 @@ realloc(void *addr, unsigned long size, struct malloc_type *mtp, int flags)
*/
#ifdef DEBUG_MEMGUARD
- if (is_memguard_addr(addr)) {
- slab = NULL;
- alloc = size;
- goto remalloc;
- }
+ if (is_memguard_addr(addr))
+ return (memguard_realloc(addr, size, mtp, flags));
#endif
#ifdef DEBUG_REDZONE
@@ -595,10 +592,6 @@ realloc(void *addr, unsigned long size, struct malloc_type *mtp, int flags)
return (addr);
#endif /* !DEBUG_REDZONE */
-#ifdef DEBUG_MEMGUARD
-remalloc:
-#endif
-
/* Allocate a new, bigger (or smaller) block */
if ((newaddr = malloc(size, mtp, flags)) == NULL)
return (NULL);
diff --git a/sys/vm/memguard.c b/sys/vm/memguard.c
index c3d93e0..85893ab 100644
--- a/sys/vm/memguard.c
+++ b/sys/vm/memguard.c
@@ -399,6 +399,31 @@ memguard_free(void *ptr)
vm_map_unlock(memguard_map);
}
+/*
+ * Re-allocate an allocation that was originally guarded.
+ */
+void *
+memguard_realloc(void *addr, unsigned long size, struct malloc_type *mtp,
+ int flags)
+{
+ void *newaddr;
+ u_long old_size;
+
+ /*
+ * Allocate the new block. Force the allocation to be guarded
+ * as the original may have been guarded through random
+ * chance, and that should be preserved.
+ */
+ if ((newaddr = memguard_alloc(size, flags)) == NULL)
+ return (NULL);
+
+ /* Copy over original contents. */
+ old_size = *v2sizep(trunc_page((uintptr_t)addr));
+ bcopy(addr, newaddr, min(size, old_size));
+ memguard_free(addr);
+ return (newaddr);
+}
+
int
memguard_cmp(struct malloc_type *mtp, unsigned long size)
{
diff --git a/sys/vm/memguard.h b/sys/vm/memguard.h
index ba7c2f1..25238b4 100644
--- a/sys/vm/memguard.h
+++ b/sys/vm/memguard.h
@@ -38,6 +38,7 @@ struct vm_map;
unsigned long memguard_fudge(unsigned long, unsigned long);
void memguard_init(struct vm_map *);
void *memguard_alloc(unsigned long, int);
+void *memguard_realloc(void *, unsigned long, struct malloc_type *, int);
void memguard_free(void *);
int memguard_cmp(struct malloc_type *, unsigned long);
int is_memguard_addr(void *);
@@ -45,6 +46,7 @@ int is_memguard_addr(void *);
#define memguard_fudge(size, xxx) (size)
#define memguard_init(map) do { } while (0)
#define memguard_alloc(size, flags) NULL
+#define memguard_realloc(a, s, mtp, f) NULL
#define memguard_free(addr) do { } while (0)
#define memguard_cmp(mtp, size) 0
#define is_memguard_addr(addr) 0
OpenPOWER on IntegriCloud