summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authorrstone <rstone@FreeBSD.org>2015-04-01 12:42:26 +0000
committerrstone <rstone@FreeBSD.org>2015-04-01 12:42:26 +0000
commit57feb6fb43533ca4e0343a17ff4b78f93c27e3dd (patch)
treea5f9ea26e9cde6035646a47810b3727348fe048b /sys/vm
parent67c45e2f58234d2572b6698f17fcda098763a240 (diff)
downloadFreeBSD-src-57feb6fb43533ca4e0343a17ff4b78f93c27e3dd.zip
FreeBSD-src-57feb6fb43533ca4e0343a17ff4b78f93c27e3dd.tar.gz
Fix integer truncation bug in malloc(9)
A couple of internal functions used by malloc(9) and uma truncated a size_t down to an int. This could cause any number of issues (e.g. indefinite sleeps, memory corruption) if any kernel subsystem tried to allocate 2GB or more through malloc. zfs would attempt such an allocation when run on a system with 2TB or more of RAM. Note to self: When this is MFCed, sparc64 needs the same fix. Differential revision: https://reviews.freebsd.org/D2106 Reviewed by: kib Reported by: Michael Fuckner <michael@fuckner.net> Tested by: Michael Fuckner <michael@fuckner.net> MFC after: 2 weeks
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/uma.h5
-rw-r--r--sys/vm/uma_core.c18
-rw-r--r--sys/vm/uma_int.h7
3 files changed, 16 insertions, 14 deletions
diff --git a/sys/vm/uma.h b/sys/vm/uma.h
index 5012d98..df6cc5c 100644
--- a/sys/vm/uma.h
+++ b/sys/vm/uma.h
@@ -382,7 +382,8 @@ uma_zfree(uma_zone_t zone, void *item)
* A pointer to the allocated memory or NULL on failure.
*/
-typedef void *(*uma_alloc)(uma_zone_t zone, int size, uint8_t *pflag, int wait);
+typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, uint8_t *pflag,
+ int wait);
/*
* Backend page free routines
@@ -395,7 +396,7 @@ typedef void *(*uma_alloc)(uma_zone_t zone, int size, uint8_t *pflag, int wait);
* Returns:
* None
*/
-typedef void (*uma_free)(void *item, int size, uint8_t pflag);
+typedef void (*uma_free)(void *item, vm_size_t size, uint8_t pflag);
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index 2bb6260..7556803 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -230,10 +230,10 @@ enum zfreeskip { SKIP_NONE = 0, SKIP_DTOR, SKIP_FINI };
/* Prototypes.. */
-static void *noobj_alloc(uma_zone_t, int, uint8_t *, int);
-static void *page_alloc(uma_zone_t, int, uint8_t *, int);
-static void *startup_alloc(uma_zone_t, int, uint8_t *, int);
-static void page_free(void *, int, uint8_t);
+static void *noobj_alloc(uma_zone_t, vm_size_t, uint8_t *, int);
+static void *page_alloc(uma_zone_t, vm_size_t, uint8_t *, int);
+static void *startup_alloc(uma_zone_t, vm_size_t, uint8_t *, int);
+static void page_free(void *, vm_size_t, uint8_t);
static uma_slab_t keg_alloc_slab(uma_keg_t, uma_zone_t, int);
static void cache_drain(uma_zone_t);
static void bucket_drain(uma_zone_t, uma_bucket_t);
@@ -1038,7 +1038,7 @@ out:
* the VM is ready.
*/
static void *
-startup_alloc(uma_zone_t zone, int bytes, uint8_t *pflag, int wait)
+startup_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait)
{
uma_keg_t keg;
uma_slab_t tmps;
@@ -1098,7 +1098,7 @@ startup_alloc(uma_zone_t zone, int bytes, uint8_t *pflag, int wait)
* NULL if M_NOWAIT is set.
*/
static void *
-page_alloc(uma_zone_t zone, int bytes, uint8_t *pflag, int wait)
+page_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait)
{
void *p; /* Returned page */
@@ -1120,7 +1120,7 @@ page_alloc(uma_zone_t zone, int bytes, uint8_t *pflag, int wait)
* NULL if M_NOWAIT is set.
*/
static void *
-noobj_alloc(uma_zone_t zone, int bytes, uint8_t *flags, int wait)
+noobj_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *flags, int wait)
{
TAILQ_HEAD(, vm_page) alloctail;
u_long npages;
@@ -1183,7 +1183,7 @@ noobj_alloc(uma_zone_t zone, int bytes, uint8_t *flags, int wait)
* Nothing
*/
static void
-page_free(void *mem, int size, uint8_t flags)
+page_free(void *mem, vm_size_t size, uint8_t flags)
{
struct vmem *vmem;
@@ -3266,7 +3266,7 @@ uma_zone_exhausted_nolock(uma_zone_t zone)
}
void *
-uma_large_malloc(int size, int wait)
+uma_large_malloc(vm_size_t size, int wait)
{
void *mem;
uma_slab_t slab;
diff --git a/sys/vm/uma_int.h b/sys/vm/uma_int.h
index 1ffc7d5..ad2a405 100644
--- a/sys/vm/uma_int.h
+++ b/sys/vm/uma_int.h
@@ -341,7 +341,7 @@ zone_first_keg(uma_zone_t zone)
#ifdef _KERNEL
/* Internal prototypes */
static __inline uma_slab_t hash_sfind(struct uma_hash *hash, uint8_t *data);
-void *uma_large_malloc(int size, int wait);
+void *uma_large_malloc(vm_size_t size, int wait);
void uma_large_free(uma_slab_t slab);
/* Lock Macros */
@@ -424,8 +424,9 @@ vsetslab(vm_offset_t va, uma_slab_t slab)
* if they can provide more effecient allocation functions. This is useful
* for using direct mapped addresses.
*/
-void *uma_small_alloc(uma_zone_t zone, int bytes, uint8_t *pflag, int wait);
-void uma_small_free(void *mem, int size, uint8_t flags);
+void *uma_small_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag,
+ int wait);
+void uma_small_free(void *mem, vm_size_t size, uint8_t flags);
#endif /* _KERNEL */
#endif /* VM_UMA_INT_H */
OpenPOWER on IntegriCloud