Loading...
libkern/c++/OSSerialize.cpp xnu-12377.101.15 xnu-7195.60.75
--- xnu/xnu-12377.101.15/libkern/c++/OSSerialize.cpp
+++ xnu/xnu-7195.60.75/libkern/c++/OSSerialize.cpp
@@ -30,8 +30,10 @@
 #define IOKIT_ENABLE_SHARED_PTR
 
 #include <sys/cdefs.h>
-#include <vm/vm_kern_xnu.h>
-#include <os/hash.h>
+
+__BEGIN_DECLS
+#include <vm/vm_kern.h>
+__END_DECLS
 
 #include <libkern/c++/OSContainers.h>
 #include <libkern/c++/OSLib.h>
@@ -53,16 +55,6 @@
 OSMetaClassDefineReservedUnused(OSSerialize, 6);
 OSMetaClassDefineReservedUnused(OSSerialize, 7);
 
-static inline kmem_guard_t
-OSSerialize_guard()
-{
-	kmem_guard_t guard = {
-		.kmg_tag     = IOMemoryTag(kernel_map),
-	};
-
-	return guard;
-}
-
 
 char *
 OSSerialize::text() const
@@ -200,8 +192,6 @@
 bool
 OSSerialize::initWithCapacity(unsigned int inCapacity)
 {
-	kmem_return_t kmr;
-
 	if (!super::init()) {
 		return false;
 	}
@@ -216,28 +206,26 @@
 	if (!inCapacity) {
 		inCapacity = 1;
 	}
-	if (round_page_overflow(inCapacity, &inCapacity)) {
+	if (round_page_overflow(inCapacity, &capacity)) {
 		tags.reset();
 		return false;
 	}
 
-	capacityIncrement = inCapacity;
+	capacityIncrement = capacity;
 
 	// allocate from the kernel map so that we can safely map this data
 	// into user space (the primary use of the OSSerialize object)
 
-	kmr = kmem_alloc_guard(kernel_map, inCapacity, /* mask */ 0,
-	    (kma_flags_t)(KMA_ZERO | KMA_DATA_SHARED), OSSerialize_guard());
-
-	if (kmr.kmr_return == KERN_SUCCESS) {
-		data = (char *)kmr.kmr_ptr;
-		capacity = inCapacity;
-		OSCONTAINER_ACCUMSIZE(capacity);
-		return true;
-	}
-
-	capacity = 0;
-	return false;
+	kern_return_t rc = kmem_alloc(kernel_map, (vm_offset_t *)&data, capacity, IOMemoryTag(kernel_map));
+	if (rc) {
+		return false;
+	}
+	bzero((void *)data, capacity);
+
+
+	OSCONTAINER_ACCUMSIZE(capacity);
+
+	return true;
 }
 
 OSSharedPtr<OSSerialize>
@@ -277,7 +265,7 @@
 unsigned int
 OSSerialize::ensureCapacity(unsigned int newCapacity)
 {
-	kmem_return_t kmr;
+	char *newData;
 
 	if (newCapacity <= capacity) {
 		return capacity;
@@ -287,18 +275,25 @@
 		return capacity;
 	}
 
-	kmr = kmem_realloc_guard(kernel_map, (vm_offset_t)data, capacity,
-	    newCapacity, (kmr_flags_t)(KMR_ZERO | KMR_DATA | KMR_FREEOLD),
-	    OSSerialize_guard());
-
-	if (kmr.kmr_return == KERN_SUCCESS) {
-		size_t delta = 0;
-
-		data     = (char *)kmr.kmr_ptr;
-		delta   -= capacity;
+	kern_return_t rc = kmem_realloc(kernel_map,
+	    (vm_offset_t)data,
+	    capacity,
+	    (vm_offset_t *)&newData,
+	    newCapacity,
+	    VM_KERN_MEMORY_IOKIT);
+	if (!rc) {
+		OSCONTAINER_ACCUMSIZE(newCapacity);
+
+		// kmem realloc does not free the old address range
+		kmem_free(kernel_map, (vm_offset_t)data, capacity);
+		OSCONTAINER_ACCUMSIZE(-((size_t)capacity));
+
+		// kmem realloc does not zero out the new memory
+		// and this could end up going to user land
+		bzero(&newData[capacity], newCapacity - capacity);
+
+		data = newData;
 		capacity = newCapacity;
-		delta   += capacity;
-		OSCONTAINER_ACCUMSIZE(delta);
 	}
 
 	return capacity;
@@ -307,12 +302,9 @@
 void
 OSSerialize::free()
 {
-	if (capacity) {
-		kmem_free_guard(kernel_map, (vm_offset_t)data, capacity,
-		    KMF_NONE, OSSerialize_guard());
+	if (data) {
+		kmem_free(kernel_map, (vm_offset_t)data, capacity);
 		OSCONTAINER_ACCUMSIZE( -((size_t)capacity));
-		data = nullptr;
-		capacity = 0;
 	}
 	super::free();
 }