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