|
@@ -2241,7 +2241,7 @@ void *__kmalloc(size_t size, gfp_t flags)
|
|
|
|
|
|
if (s)
|
|
|
return slab_alloc(s, flags, -1, __builtin_return_address(0));
|
|
|
- return NULL;
|
|
|
+ return ZERO_SIZE_PTR;
|
|
|
}
|
|
|
EXPORT_SYMBOL(__kmalloc);
|
|
|
|
|
@@ -2252,16 +2252,20 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node)
|
|
|
|
|
|
if (s)
|
|
|
return slab_alloc(s, flags, node, __builtin_return_address(0));
|
|
|
- return NULL;
|
|
|
+ return ZERO_SIZE_PTR;
|
|
|
}
|
|
|
EXPORT_SYMBOL(__kmalloc_node);
|
|
|
#endif
|
|
|
|
|
|
size_t ksize(const void *object)
|
|
|
{
|
|
|
- struct page *page = get_object_page(object);
|
|
|
+ struct page *page;
|
|
|
struct kmem_cache *s;
|
|
|
|
|
|
+ if (object == ZERO_SIZE_PTR)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ page = get_object_page(object);
|
|
|
BUG_ON(!page);
|
|
|
s = page->slab;
|
|
|
BUG_ON(!s);
|
|
@@ -2293,7 +2297,13 @@ void kfree(const void *x)
|
|
|
struct kmem_cache *s;
|
|
|
struct page *page;
|
|
|
|
|
|
- if (!x)
|
|
|
+ /*
|
|
|
+ * This has to be an unsigned comparison. According to Linus
|
|
|
+ * some gcc version treat a pointer as a signed entity. Then
|
|
|
+ * this comparison would be true for all "negative" pointers
|
|
|
+ * (which would cover the whole upper half of the address space).
|
|
|
+ */
|
|
|
+ if ((unsigned long)x <= (unsigned long)ZERO_SIZE_PTR)
|
|
|
return;
|
|
|
|
|
|
page = virt_to_head_page(x);
|
|
@@ -2398,12 +2408,12 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags)
|
|
|
void *ret;
|
|
|
size_t ks;
|
|
|
|
|
|
- if (unlikely(!p))
|
|
|
+ if (unlikely(!p || p == ZERO_SIZE_PTR))
|
|
|
return kmalloc(new_size, flags);
|
|
|
|
|
|
if (unlikely(!new_size)) {
|
|
|
kfree(p);
|
|
|
- return NULL;
|
|
|
+ return ZERO_SIZE_PTR;
|
|
|
}
|
|
|
|
|
|
ks = ksize(p);
|
|
@@ -2652,7 +2662,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller)
|
|
|
struct kmem_cache *s = get_slab(size, gfpflags);
|
|
|
|
|
|
if (!s)
|
|
|
- return NULL;
|
|
|
+ return ZERO_SIZE_PTR;
|
|
|
|
|
|
return slab_alloc(s, gfpflags, -1, caller);
|
|
|
}
|
|
@@ -2663,7 +2673,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
|
|
|
struct kmem_cache *s = get_slab(size, gfpflags);
|
|
|
|
|
|
if (!s)
|
|
|
- return NULL;
|
|
|
+ return ZERO_SIZE_PTR;
|
|
|
|
|
|
return slab_alloc(s, gfpflags, node, caller);
|
|
|
}
|