kernel: use kcalloc instead kmalloc/memset
Subsystems (5)
PATCH 1/1 kernel: use kcalloc instead kmalloc/memset
This patch converts kernel/ to use kcalloc instead of kmalloc/memset.
---
intermodule.c | 3 +-- params.c | 4 ++-- power/pm.c | 3 +-- resource.c | 3 +-- workqueue.c | 3 +-- 5 files changed, 6 insertions(+), 10 deletions(-)
kernel/resource.c +1 -2
@@ -430,10 +430,9 @@ EXPORT_SYMBOL(adjust_resource);*/ struct resource *__request_region (struct resource *parent,unsigned long start,unsigned long n,const char *name) { -struct resource *res =kmalloc (sizeof (*res),GFP_KERNEL ); +struct resource *res =kcalloc (1 ,sizeof (*res),GFP_KERNEL );if (res) { -memset (res,0 ,sizeof (*res)); res->name = name; res->start = start; res->end = start + n -1 ;
kernel/intermodule.c +1 -2
@@ -39,7 +39,7 @@ void inter_module_register(const char *istruct list_head *tmp;struct inter_module_entry *ime, *ime_new; -if (!(ime_new =kmalloc (sizeof (*ime),GFP_KERNEL ))) { +if (!(ime_new =kcalloc (1 ,sizeof (*ime),GFP_KERNEL ))) {/* Overloaded kernel, not fatal */ printk(KERN_ERR "Aiee, inter_module_register: cannot kmalloc entry for '%s'\n",
@@ -47,7 +47,6 @@ void inter_module_register(const char *i kmalloc_failed =1 ;return ; } -memset (ime_new,0 ,sizeof (*ime_new)); ime_new->im_name = im_name; ime_new->owner = owner; ime_new->userdata = userdata;
kernel/params.c +2 -2
@@ -542,8 +542,8 @@ static void __init kernel_param_sysfs_se {struct module_kobject *mk; - mk =kmalloc (sizeof (struct module_kobject ),GFP_KERNEL ); -memset (mk,0 ,sizeof (struct module_kobject )); + mk =kcalloc (1 ,sizeof (struct module_kobject ),GFP_KERNEL ); +BUG_ON (!mk); mk->mod =THIS_MODULE ;kobj_set_kset_s (mk, module_subsys);
kernel/power/pm.c +1 -2
@@ -60,9 +60,8 @@ struct pm_dev *pm_register(pm_dev_t type unsigned long id, pm_callback callback) { -struct pm_dev *dev =kmalloc (sizeof (struct pm_dev ),GFP_KERNEL ); +struct pm_dev *dev =kcalloc (1 ,sizeof (struct pm_dev ),GFP_KERNEL );if (dev) { -memset (dev,0 ,sizeof (*dev)); dev->type = type; dev->id = id; dev->callback = callback;
kernel/workqueue.c +1 -2
@@ -310,10 +310,9 @@ struct workqueue_struct *__create_workquBUG_ON (strlen (name) >10 ); - wq =kmalloc (sizeof (*wq),GFP_KERNEL ); + wq =kcalloc (1 ,sizeof (*wq),GFP_KERNEL );if (!wq)return NULL ; -memset (wq,0 ,sizeof (*wq)); wq->name = name;/* We don't need the distraction of CPUs appearing and vanishing. */
Quoted 3 lines · Pekka Enberg
This patch converts
kernel/to use kcalloc instead of kmalloc/memset.
grr.
Quoted 2 lines
- struct resource *res =
kmalloc(sizeof(*res), GFP_KERNEL);
+ struct resource *res =kcalloc(1, sizeof(*res), GFP_KERNEL);
Notice how every conversion you did passes in `1' in the first argument?
And that's going to happen again and again and again. Each callsite needlessly passing that silly third argument, adding more kernel text.
If we're going to do this, we should add a two-arg helper function first, and use that, no?
Hi Andrew,
Quoted 1 line · Pekka Enberg
Quoted 1 line
This patch converts
kernel/to use kcalloc instead of kmalloc/memset.
Quoted 1 line · Andrew Morton
grr.
I am learning grep. Please don't eat me!
Quoted 10 lines
Quoted 2 lines
- struct resource *res =
kmalloc(sizeof(*res), GFP_KERNEL);
+ struct resource *res =kcalloc(1, sizeof(*res), GFP_KERNEL);Notice how every conversion you did passes in `1' in the first argument?
And that's going to happen again and again and again. Each callsite needlessly passing that silly third argument, adding more kernel text.
If we're going to do this, we should add a two-arg helper function first, and use that, no?
This was discussed some time ago [1] and here's a patch for you to do that.
Pekka
1. http://marc.theaimsgroup.com/?l=linux-kernel&m=111279001428661&w=2
[PATCH] use kzalloc instead of kmalloc/memset
This patch introduces a kzalloc wrapper and converts kernel/ to use it.
---
include/linux/slab.h | 5 +++++ kernel/intermodule.c | 3 +-- kernel/params.c | 4 ++-- kernel/power/pm.c | 3 +-- kernel/resource.c | 3 +-- kernel/workqueue.c | 3 +-- 6 files changed, 11 insertions(+), 10 deletions(-)
kernel/resource.c +1 -2
@@ -430,10 +430,9 @@ EXPORT_SYMBOL(adjust_resource);*/ struct resource *__request_region (struct resource *parent,unsigned long start,unsigned long n,const char *name) { -struct resource *res =kmalloc (sizeof (*res),GFP_KERNEL ); +struct resource *res =kzalloc (sizeof (*res),GFP_KERNEL );if (res) { -memset (res,0 ,sizeof (*res)); res->name = name; res->start = start; res->end = start + n -1 ;
kernel/intermodule.c +1 -2
@@ -39,7 +39,7 @@ void inter_module_register(const char *istruct list_head *tmp;struct inter_module_entry *ime, *ime_new; -if (!(ime_new =kmalloc (sizeof (*ime),GFP_KERNEL ))) { +if (!(ime_new =kzalloc (sizeof (*ime),GFP_KERNEL ))) {/* Overloaded kernel, not fatal */ printk(KERN_ERR "Aiee, inter_module_register: cannot kmalloc entry for '%s'\n",
@@ -47,7 +47,6 @@ void inter_module_register(const char *i kmalloc_failed =1 ;return ; } -memset (ime_new,0 ,sizeof (*ime_new)); ime_new->im_name = im_name; ime_new->owner = owner; ime_new->userdata = userdata;
kernel/params.c +2 -2
@@ -542,8 +542,8 @@ static void __init kernel_param_sysfs_se {struct module_kobject *mk; - mk =kmalloc (sizeof (struct module_kobject ),GFP_KERNEL ); -memset (mk,0 ,sizeof (struct module_kobject )); + mk =kzalloc (sizeof (struct module_kobject ),GFP_KERNEL ); +BUG_ON (!mk); mk->mod =THIS_MODULE ;kobj_set_kset_s (mk, module_subsys);
kernel/power/pm.c +1 -2
@@ -60,9 +60,8 @@ struct pm_dev *pm_register(pm_dev_t type unsigned long id, pm_callback callback) { -struct pm_dev *dev =kmalloc (sizeof (struct pm_dev ),GFP_KERNEL ); +struct pm_dev *dev =kzalloc (sizeof (struct pm_dev ),GFP_KERNEL );if (dev) { -memset (dev,0 ,sizeof (*dev)); dev->type = type; dev->id = id; dev->callback = callback;
kernel/workqueue.c +1 -2
@@ -310,10 +310,9 @@ struct workqueue_struct *__create_workquBUG_ON (strlen (name) >10 ); - wq =kmalloc (sizeof (*wq),GFP_KERNEL ); + wq =kzalloc (sizeof (*wq),GFP_KERNEL );if (!wq)return NULL ; -memset (wq,0 ,sizeof (*wq)); wq->name = name;/* We don't need the distraction of CPUs appearing and vanishing. */
include/linux/slab.h +5 -0
@@ -103,6 +103,11 @@ extern void *kcalloc(size_t, size_t, unsextern void kfree (const void *);extern unsigned int ksize (const void *); +static inline void *kzalloc (size_t size,unsigned int __nocast flags) +{ +return kcalloc (1 , size, flags); +} +#ifdef CONFIG_NUMA extern void *kmem_cache_alloc_node (kmem_cache_t *,int flags,int node);extern void *kmalloc_node (size_t size,unsigned int __nocast flags,int node);
Quoted 3 lines · Pekka J Enberg
[PATCH] use kzalloc instead of kmalloc/memset
dammit, I was hoping for akpmalloc()
include/linux/slab.h extern void *kcalloc(size_t, size_t, uns · line 110
Quoted 6 lines
include/linux/slab.h +5
-0+static inline void *kzalloc (size_t size,unsigned int __nocast flags) +{ +return kcalloc (1 , size, flags); +} +
That'll generate just as much code as simply using kcalloc(1, ...). This function should be out-of-line and EXPORT_SYMBOL()ed. And kcalloc() can call it too..
Quoted 3 lines · Andrew Morton
That'll generate just as much code as simply using
kcalloc(1, ...). This function should be out-of-line and EXPORT_SYMBOL()ed. Andkcalloc()can call it too..
Yes, much better now. Thanks Andrew.
Pekka
[PATCH] introduce kzalloc
This patch introduces a kzalloc wrapper and converts kernel/ to use it.
---
include/linux/slab.h | 1 + kernel/intermodule.c | 3 +-- kernel/params.c | 4 ++-- kernel/power/pm.c | 3 +-- kernel/resource.c | 3 +-- kernel/workqueue.c | 3 +-- mm/slab.c | 19 +++++++++++++++---- 7 files changed, 22 insertions(+), 14 deletions(-)
kernel/resource.c +1 -2
@@ -430,10 +430,9 @@ EXPORT_SYMBOL(adjust_resource);*/ struct resource *__request_region (struct resource *parent,unsigned long start,unsigned long n,const char *name) { -struct resource *res =kmalloc (sizeof (*res),GFP_KERNEL ); +struct resource *res =kzalloc (sizeof (*res),GFP_KERNEL );if (res) { -memset (res,0 ,sizeof (*res)); res->name = name; res->start = start; res->end = start + n -1 ;
kernel/intermodule.c +1 -2
@@ -39,7 +39,7 @@ void inter_module_register(const char *istruct list_head *tmp;struct inter_module_entry *ime, *ime_new; -if (!(ime_new =kmalloc (sizeof (*ime),GFP_KERNEL ))) { +if (!(ime_new =kzalloc (sizeof (*ime),GFP_KERNEL ))) {/* Overloaded kernel, not fatal */ printk(KERN_ERR "Aiee, inter_module_register: cannot kmalloc entry for '%s'\n",
@@ -47,7 +47,6 @@ void inter_module_register(const char *i kmalloc_failed =1 ;return ; } -memset (ime_new,0 ,sizeof (*ime_new)); ime_new->im_name = im_name; ime_new->owner = owner; ime_new->userdata = userdata;
kernel/params.c +2 -2
@@ -542,8 +542,8 @@ static void __init kernel_param_sysfs_se {struct module_kobject *mk; - mk =kmalloc (sizeof (struct module_kobject ),GFP_KERNEL ); -memset (mk,0 ,sizeof (struct module_kobject )); + mk =kzalloc (sizeof (struct module_kobject ),GFP_KERNEL ); +BUG_ON (!mk); mk->mod =THIS_MODULE ;kobj_set_kset_s (mk, module_subsys);
kernel/power/pm.c +1 -2
@@ -60,9 +60,8 @@ struct pm_dev *pm_register(pm_dev_t type unsigned long id, pm_callback callback) { -struct pm_dev *dev =kmalloc (sizeof (struct pm_dev ),GFP_KERNEL ); +struct pm_dev *dev =kzalloc (sizeof (struct pm_dev ),GFP_KERNEL );if (dev) { -memset (dev,0 ,sizeof (*dev)); dev->type = type; dev->id = id; dev->callback = callback;
kernel/workqueue.c +1 -2
@@ -310,10 +310,9 @@ struct workqueue_struct *__create_workquBUG_ON (strlen (name) >10 ); - wq =kmalloc (sizeof (*wq),GFP_KERNEL ); + wq =kzalloc (sizeof (*wq),GFP_KERNEL );if (!wq)return NULL ; -memset (wq,0 ,sizeof (*wq)); wq->name = name;/* We don't need the distraction of CPUs appearing and vanishing. */
include/linux/slab.h +1 -0
@@ -100,6 +100,7 @@ found: }extern void *kcalloc (size_t ,size_t ,unsigned int __nocast ); +extern void *kzalloc (size_t ,unsigned int __nocast );extern void kfree (const void *);extern unsigned int ksize (const void *);
mm/slab.c +15 -4
@@ -2555,6 +2555,20 @@ void kmem_cache_free(kmem_cache_t *cacheEXPORT_SYMBOL (kmem_cache_free);/** +* kzalloc - allocate memory. The memory is set to zero. +* @size: how many bytes of memory are required. +* @flags: the type of memory to allocate. +*/ +void *kzalloc (size_t size,unsigned int __nocast flags) +{ +void *ret =kmalloc (size, flags); +if (ret) +memset (ret,0 , size); +return ret; +} +EXPORT_SYMBOL (kzalloc); + +/** * kcalloc - allocate memory for an array. The memory is set to zero. * @n: number of elements. * @size: element size.
@@ -2567,10 +2581,7 @@ void *kcalloc(size_t n, size_t size, unsif (n !=0 && size >INT_MAX / n)return ret; - ret =kmalloc (n * size, flags); -if (ret) -memset (ret,0 , n * size); -return ret; +return kzalloc (n * size, flags); }EXPORT_SYMBOL (kcalloc);
Hi,
Quoted 9 lines · Andrew Morton
include/linux/slab.h extern void *kcalloc(size_t, size_t, uns · line 110
Quoted 5 lines
include/linux/slab.h +5
-0+static inline void *kzalloc (size_t size,unsigned int __nocast flags) +{ +return kcalloc (1 , size, flags); +} +That'll generate just as much code as simply using
kcalloc(1, ...). This function should be out-of-line and EXPORT_SYMBOL()ed. Andkcalloc()can call it too..
BTW we already have 420 "kcalloc(1, ...)" user and 41 without the 1 argument, most of them are in sound, which introduced it in first place. Can we please deprecate that function before it spreads any further?
bye, Roman
Quoted 14 lines · Roman Zippel
Hi,
Quoted 9 lines · Andrew Morton
include/linux/slab.h extern void *kcalloc(size_t, size_t, uns · line 110
Quoted 5 lines
include/linux/slab.h +5
-0+static inline void *kzalloc (size_t size,unsigned int __nocast flags) +{ +return kcalloc (1 , size, flags); +} +That'll generate just as much code as simply using
kcalloc(1, ...). This function should be out-of-line and EXPORT_SYMBOL()ed. Andkcalloc()can call it too..
Quoted 3 lines
BTW we already have 420 "
kcalloc(1, ...)" user and 41 without the 1 argument, most of them are in sound, which introduced it in first place. Can we please deprecate that function before it spreads any further?
kcalloc does have value, in that it's a nice api to avoid multiplication overflows. Just for "1" it's indeed not the most useful API.
Quoted 2 lines · Roman Zippel
Quoted 2 lines
BTW we already have 420 "
kcalloc(1, ...)" user and 41 without the 1 argument, most of them are in sound, which introduced it in first place. Can we please deprecate that function before it spreads any further?
Quoted 2 lines · Arjan van de Ven
kcalloc does have value, in that it's a nice api to avoid multiplication overflows. Just for "1" it's indeed not the most useful API.
Indeed, kcalloc should not be deprecated as it is meant for array allocation. I can send patches that replace kcalloc(1,...) with kzalloc if there are no other janitors interested...
Pekka
Hi,
Quoted 2 lines · Arjan van de Ven
kcalloc does have value, in that it's a nice api to avoid multiplication overflows. Just for "1" it's indeed not the most useful API.
This would imply a similiar kmalloc() would be useful as well. Second, how relevant is it for the kernel? Is that really the best place to check for rogue user parameters?
bye, Roman
Quoted 9 lines · Roman Zippel
Hi,
Quoted 2 lines · Arjan van de Ven
kcalloc does have value, in that it's a nice api to avoid multiplication overflows. Just for "1" it's indeed not the most useful API.
This would imply a similiar
kmalloc()would be useful as well. Second, how relevant is it for the kernel?
we've had a non-negliable amount of security holes because of this
Quoted 2 lines
Is that really the best place
to check for rogue user parameters?
it makes it easy and safe. Of course you can and should check it in all users. Just that using a safer API is generally better than forcing everyone to do it themselves.
Quoted 2 lines · Arjan van de Ven
Quoted 2 lines
kcalloc does have value, in that it's a nice api to avoid multiplication overflows. Just for "1" it's indeed not the most useful API.
Quoted 2 lines · Roman Zippel
This would imply a similiar
kmalloc()would be useful as well.
Second, how relevant is it for the kernel? Is that really the best place to check for rogue user parameters?
Please note that the first version of kcalloc() carried over from ALSA took only one size parameter but we decided to make it similar to standard calloc(). It is useful as an array allocator which is why I think we should keep both and simply get rid of the kcalloc(1,...) form.
Pekka
Hi,
Quoted 4 lines · Arjan van de Ven
Quoted 2 lines
This would imply a similiar
kmalloc()would be useful as well. Second, how relevant is it for the kernel?we've had a non-negliable amount of security holes because of this
So why don't we have a similiar kmalloc()?
Quoted 6 lines
Quoted 2 lines
Is that really the best place
to check for rogue user parameters?it makes it easy and safe. Of course you can and should check it in all users. Just that using a safer API is generally better than forcing everyone to do it themselves.
How exactly does this make it a "safe API"? Even if it checks for this one case, it still makes the user suspectible for allocating big amounts of unswappable memory.
bye, Roman
Quoted 10 lines · Roman Zippel
Hi,
Quoted 4 lines · Arjan van de Ven
Quoted 2 lines
This would imply a similiar
kmalloc()would be useful as well. Second, how relevant is it for the kernel?we've had a non-negliable amount of security holes because of this
So why don't we have a similiar
kmalloc()?
nope kmalloc is not an array allocator
Quoted 11 lines
Quoted 7 lines
Quoted 3 lines
Is that really the best place
to check for rogue user parameters?it makes it easy and safe. Of course you can and should check it in all users. Just that using a safer API is generally better than forcing everyone to do it themselves.
How exactly does this make it a "safe API"? Even if it checks for this one case, it still makes the user suspectible for allocating big amounts of unswappable memory.
128Kb max.
Hi,
Quoted 10 lines · Arjan van de Ven
Quoted 3 lines
Quoted 1 line
we've had a non-negliable amount of security holes because of this
So why don't we have a similiar
kmalloc()?nope kmalloc is not an array allocator
Quoted 4 lines
Quoted 3 lines
it makes it easy and safe. Of course you can and should check it in all users. Just that using a safer API is generally better than forcing everyone to do it themselves.
Quoted 5 lines
Quoted 3 lines
How exactly does this make it a "safe API"? Even if it checks for this one case, it still makes the user suspectible for allocating big amounts of unswappable memory.
128Kb max.
You completely missed the point and didn't answer my questions at all... :-(
bye, Roman
Quoted 14 lines · Roman Zippel
Hi,
Quoted 10 lines · Arjan van de Ven
Quoted 3 lines
Quoted 1 line
we've had a non-negliable amount of security holes because of this
So why don't we have a similiar
kmalloc()?nope kmalloc is not an array allocator
Quoted 4 lines
Quoted 3 lines
it makes it easy and safe. Of course you can and should check it in all users. Just that using a safer API is generally better than forcing everyone to do it themselves.
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
How exactly does this make it a "safe API"? Even if it checks for this one case, it still makes the user suspectible for allocating big amounts of unswappable memory.
128Kb max.
You completely missed the point and didn't answer my questions at all... :-(
I found it hard to understand your question.
Maybe it helps if I give the basic bug scenario first (pseudo C)
void some_ioctl_func(...)
{
int count, i;
struct foo *ptr;
copy_from_user(&count,...); ptr = kmalloc(sizeof(struct foo) * count);
if (!ptr)
return -ENOMEM;
for (i=0; i<count; i++) {
initialize(ptr+i); }
}
if the user picks count such that the multiplication overflows, the kmalloc will actually *succeed* in getting a chunk between 0 and 128Kb. The subsequent "fill the array up" will overwrite a LOT of kernel memory though.
Fixing the hole of course involves checking "count" for too high a value. Using kcalloc() will check for this same overflow inside kcalloc and prevent it (eg return NULL) if one of these slips through.
Quoted 7 lines · Roman Zippel
Quoted 4 lines · Arjan van de Ven
Quoted 2 lines
This would imply a similiar
kmalloc()would be useful as well. Second, how relevant is it for the kernel?we've had a non-negliable amount of security holes because of this
So why don't we have a similiar
kmalloc()?
You mean something like:
static void __bad_kmalloc_safe_nonconstant_size(void); static void __bad_kmalloc_safe_zero_size(void); static void __bad_kmalloc_safe_too_large_size(void); static void __bad_kmalloc_safe_too_large(void);
static inline void *kmalloc_safe(size_t nmemb, size_t size,int flags) {
if (!__builtin_constant_p(size))
__bad_kmalloc_safe_nonconstant_size();
if ( !size )
__bad_kmalloc_safe_zero_size();
if ( size > 0x10000)
__bad_kmalloc_safe_too_large_size();
if (__builtin_constant_p(nmemb) && nmemb > 0x20000/size)
__bad_kmalloc_safe_too_large();
if (nmemb <= 0x20000/size)
return kmalloc(nmemb*size,flags);
else return 0; }Signature · 4 lines
http://dmoz.org/profiles/pollei.html http://sourceforge.net/users/stephen_pollei/ http://www.orkut.com/Profile.aspx?uid=2455954990164098214 http://stephen_pollei.home.comcast.net/
Quoted 7 lines · Stephen Pollei
Quoted 5 lines · Arjan van de Ven
Quoted 3 lines
Quoted 2 lines
This would imply a similiar
kmalloc()would be useful as well. Second, how relevant is it for the kernel?we've had a non-negliable amount of security holes because of this
So why don't we have a similiar
kmalloc()?You mean something like:
static void__bad_kmalloc_safe_nonconstant_size(void);
Hmm. If we had kcmalloc then we may be able to add a zero bit to the slab allocator. If we would obtain zeroed pages for the slab then we may skip zeroing of individual entries. However, the cache warming effect of the current zeroing is then not occurring. Not sure if this would make sense but this is a possible optimization if we had kcmalloc.
Quoted 5 lines · Christoph Lameter
Hmm. If we had kcmalloc then we may be able to add a zero bit to the slab allocator. If we would obtain zeroed pages for the slab then we may skip zeroing of individual entries. However, the cache warming effect of the current zeroing is then not occurring. Not sure if this would make sense but this is a possible optimization if we had kcmalloc.
Well there is kzalloc and kcalloc. I just thought a safe non-zeroing version would be nice.
You could warm the cache with prefetch, but you'd need to profile the diferent cases to see what is worth doing and what isn't.
Signature · 4 lines
http://dmoz.org/profiles/pollei.html http://sourceforge.net/users/stephen_pollei/ http://www.orkut.com/Profile.aspx?uid=2455954990164098214 http://stephen_pollei.home.comcast.net/
Hi,
Quoted 20 lines · Arjan van de Ven
Maybe it helps if I give the basic bug scenario first (pseudo C)
void
some_ioctl_func(...)
{
int count, i;
struct foo *ptr;copy_from_user(&count,...); ptr = kmalloc(sizeof(struct foo) * count);if (!ptr)
return -ENOMEM;for (i=0; i<count; i++) { initialize(ptr+i);}
}
Quoted 8 lines
if the user picks count such that the multiplication overflows, the kmalloc will actually *succeed* in getting a chunk between 0 and 128Kb. The subsequent "fill the array up" will overwrite a LOT of kernel memory though.
Fixing the hole of course involves checking "count" for too high a value. Using
kcalloc()will check for this same overflow inside kcalloc and prevent it (eg return NULL) if one of these slips through.
What prevents a rogue user to call this function a number of times to waste resources?kcalloc() covers only small part of what is needed to make an interface secure, once one checked everything else, the safety provided by kcalloc() is pretty much redundant.
Relying on the current allocation limits would be rather foolish as these can change anytime and hardcoding such assumptions is a really bad idea. Kernel coding requires a careful use of the memory resource, so it's the job of the driver to define reasonable limits, e.g. such arrays don't make much sense if they require too much space and the driver should define a limit like (PAGESIZE/sizeof(struct foo)). If the driver writer doesn't think about memory usage, then kcalloc() will do pretty much nothing too improve the driver, it may avoid a few problem cases, but there will be certainly more than enough problems left.
I actually looked at the current kcalloc users and besides a few unchecked module parameters, the arguments were either constant or had to be checked anyway. I didn't find a single example which required the "safety" of kcalloc().
bye, Roman
Quoted 4 lines · Roman Zippel
I actually looked at the current kcalloc users and besides a few unchecked module parameters, the arguments were either constant or had to be checked anyway. I didn't find a single example which required the "safety" of
kcalloc().
Every caller of kcalloc() should do proper bounds checking. It's just that when they forget to do it, we hopefully avoid a buffer overflow which can be exploited.
Pekka
Quoted 25 lines · Pekka J Enberg
...
mm/slab.c +14
-0@@ -2555,6 +2555,20 @@ void kmem_cache_free(kmem_cache_t *cacheEXPORT_SYMBOL (kmem_cache_free);/** +* kzalloc - allocate memory. The memory is set to zero. +* @size: how many bytes of memory are required. +* @flags: the type of memory to allocate. +*/ +void *kzalloc (size_t size,unsigned int __nocast flags) +{ +void *ret =kmalloc (size, flags); +if (ret) +memset (ret,0 , size); +return ret; +} +EXPORT_SYMBOL (kzalloc); + +/** * kcalloc - allocate memory for an array. The memory is set to zero. * @n: number of elements. * @size: element size.
mm/slab.c void *kcalloc(size_t n, size_t size, uns · line 2586
Quoted 10 lines
mm/slab.c +1
-4@@ -2567,10 +2581,7 @@ void *kcalloc(size_t n, size_t size, unsif (n !=0 && size >INT_MAX / n)return ret; - ret =kmalloc (n * size, flags); -if (ret) -memset (ret,0 , n * size); -return ret; +return kzalloc (n * size, flags); }EXPORT_SYMBOL (kcalloc);
Looking at how few is left from kcalloc, can't we make it a "static inline" function in slab.h?
This would optimize nicely for all of the users where the first or even the first two parameters are constant at compile-time and shouldn't do much harm for the other users.
As a side effect, the difference between kcalloc(1, ...) and kzalloc() would become a coding style question without any effect on the generated code.
cu
Adrian
Signature · 4 lines
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon SeedQuoted 3 lines
What prevents a rogue user to call this function a number of times to waste resources?
Sorry to jump in, but wasting resources is a different matter than overwriting kernel memory.
Jan Engelhardt
At Sat, 6 Aug 2005 17:09:40 +0200,
Quoted 42 lines · Adrian Bunk
Quoted 25 lines · Pekka J Enberg
...
mm/slab.c +14
-0@@ -2555,6 +2555,20 @@ void kmem_cache_free(kmem_cache_t *cacheEXPORT_SYMBOL (kmem_cache_free);/** +* kzalloc - allocate memory. The memory is set to zero. +* @size: how many bytes of memory are required. +* @flags: the type of memory to allocate. +*/ +void *kzalloc (size_t size,unsigned int __nocast flags) +{ +void *ret =kmalloc (size, flags); +if (ret) +memset (ret,0 , size); +return ret; +} +EXPORT_SYMBOL (kzalloc); + +/** * kcalloc - allocate memory for an array. The memory is set to zero. * @n: number of elements. * @size: element size. mm/slab.c void *kcalloc(size_t n, size_t size, uns · line 2586
Quoted 10 lines
mm/slab.c +1
-4@@ -2567,10 +2581,7 @@ void *kcalloc(size_t n, size_t size, unsif (n !=0 && size >INT_MAX / n)return ret; - ret =kmalloc (n * size, flags); -if (ret) -memset (ret,0 , n * size); -return ret; +return kzalloc (n * size, flags); }EXPORT_SYMBOL (kcalloc);Looking at how few is left from kcalloc, can't we make it a "static inline" function in
slab.h?
Quoted 7 lines
This would optimize nicely for all of the users where the first or even the first two parameters are constant at compile-time and shouldn't do much harm for the other users.
As a side effect, the difference between
kcalloc(1, ...)andkzalloc()would become a coding style question without any effect on the generated code.
How about to use __builtin_constant_p() like kmalloc? The code readability would be worsen, though...
Takashi
Quoted 11 lines · Takashi Iwai
At Sat, 6 Aug 2005 17:09:40 +0200,
Quoted 9 lines · Adrian Bunk
Looking at how few is left from kcalloc, can't we make it a "static inline" function in
slab.h?This would optimize nicely for all of the users where the first or even the first two parameters are constant at compile-time and shouldn't do much harm for the other users.
Quoted 6 lines
Quoted 3 lines
As a side effect, the difference between
kcalloc(1, ...)andkzalloc()would become a coding style question without any effect on the generated code.How about to use
__builtin_constant_p()like kmalloc? The code readability would be worsen, though...
Where should this make any difference?
If the function is "static inline", gcc can e.g. always determine at compile-time that 1 >= 0 can never be false and therefore optimize it away.
Quoted 1 line
Takashi
cu
Adrian
Signature · 4 lines
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon SeedAt Mon, 8 Aug 2005 23:05:24 +0200,
Quoted 17 lines · Adrian Bunk
Quoted 15 lines · Takashi Iwai
At Sat, 6 Aug 2005 17:09:40 +0200,
Quoted 12 lines · Adrian Bunk
Looking at how few is left from kcalloc, can't we make it a "static inline" function in
slab.h?This would optimize nicely for all of the users where the first or even the first two parameters are constant at compile-time and shouldn't do much harm for the other users.
As a side effect, the difference between
kcalloc(1, ...)andkzalloc()would become a coding style question without any effect on the generated code.
Quoted 8 lines
Quoted 2 lines
How about to use
__builtin_constant_p()like kmalloc? The code readability would be worsen, though...Where should this make any difference?
If the function is "static inline", gcc can e.g. always determine at compile-time that 1 >= 0 can never be false and therefore optimize it away.
Argh, forget my post. It was just lack of caffeine :)
Takashi