svn commit: r212058 - in head/sys: kern vm
Matthew D Fleming
mdf at FreeBSD.org
Tue Aug 31 16:57:59 UTC 2010
Author: mdf
Date: Tue Aug 31 16:57:58 2010
New Revision: 212058
URL: http://svn.freebsd.org/changeset/base/212058
Log:
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
Modified:
head/sys/kern/kern_malloc.c
head/sys/vm/memguard.c
head/sys/vm/memguard.h
Modified: head/sys/kern/kern_malloc.c
==============================================================================
--- head/sys/kern/kern_malloc.c Tue Aug 31 15:58:15 2010 (r212057)
+++ head/sys/kern/kern_malloc.c Tue Aug 31 16:57:58 2010 (r212058)
@@ -566,11 +566,8 @@ realloc(void *addr, unsigned long size,
*/
#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,
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);
Modified: head/sys/vm/memguard.c
==============================================================================
--- head/sys/vm/memguard.c Tue Aug 31 15:58:15 2010 (r212057)
+++ head/sys/vm/memguard.c Tue Aug 31 16:57:58 2010 (r212058)
@@ -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)
{
Modified: head/sys/vm/memguard.h
==============================================================================
--- head/sys/vm/memguard.h Tue Aug 31 15:58:15 2010 (r212057)
+++ head/sys/vm/memguard.h Tue Aug 31 16:57:58 2010 (r212058)
@@ -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
More information about the svn-src-head
mailing list