kcalloc/kmalloc_array could BUILD_BUG_ON for too-big constant arguments (was Re: [PATCH] [RESEND] aic7xxx: replace kmalloc/memset by kzalloc)
The following is a sketch of how a macro kcalloc could BUILD_BUG_ON for overflows of two compile-time operands, or call "kcalloc_variable" for nonconstant arguments. Tested on gcc 4.7.2 only, since it's what I had to hand. I didn't do any testing beyond checking that fn2 didn't build, and that fn1/3 had plausible-looking code on x86_64. typedef unsigned long size_t; #define SIZE_MAX (~(size_t)0) typedef int gfp_t; extern void *kzalloc(size_t n, gfp_t flags); extern void *kcalloc_variable(size_t n, size_t size, gfp_t flags); #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) #define kcalloc(n, size, flags) \ __builtin_choose_expr(__builtin_constant_p((n) | (size)), \ ( \ BUILD_BUG_ON((n) > SIZE_MAX / (size)), \ kzalloc((n) * (size), (flags)) \ ), kcalloc_variable((n), (size), (flags))) void fn1() { kcalloc(3, 3, 0); } //void fn2() { kcalloc(2, ~(size_t)0, 0); }// compile-time BUILD_BUG_ON void fn3(int i) { kcalloc(2, i, 0); } Jeff -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [RESEND] aic7xxx: replace kmalloc/memset by kzalloc
On 03/24/2015 04:16 PM, Elliott, Robert (Server Storage) wrote: > > It was a reply to the original post on 2014-10-16, not the resend > this month. > > From http://permalink.gmane.org/gmane.linux.kernel/1808168: > > kcalloc is helpful when one of the values is a variable that > might cause the multiply to overflow during runtime. Here, > two constants are being multiplied together, which can > be done and checked by the compiler at compile time. > > Since kcalloc and kmalloc_array are both static inline > functions: > static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) > { > if (size != 0 && n > SIZE_MAX / size) > return NULL; > return __kmalloc(n * size, flags); > } > static inline void *kcalloc(size_t n, size_t size, gfp_t flags) > { > return kmalloc_array(n, size, flags | __GFP_ZERO); > } > > a compiler that detects an overflow will probably just reduce > that to an inlined "return NULL." > > BUILD_BUG_ON could be used to trigger a compile-time error, > instead of building a kernel that returns a run-time error. Ok, I hope we agree to get back to kzalloc() for which the compiler won't miss size_t overflows. Thanks for the reviews! Michael. -- Michael Opdenacker, CEO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com +33 484 258 098 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH] [RESEND] aic7xxx: replace kmalloc/memset by kzalloc
> -Original Message- > From: Joe Perches [mailto:j...@perches.com] > Sent: Tuesday, March 24, 2015 3:57 PM > To: Michael Opdenacker > Cc: Hannes Reinecke; jbottom...@parallels.com; Elliott, Robert (Server > Storage); linux-s...@vger.kernel.org; linux-kernel@vger.kernel.org > Subject: Re: [PATCH] [RESEND] aic7xxx: replace kmalloc/memset by kzalloc > > On Tue, 2015-03-24 at 13:46 -0700, Michael Opdenacker wrote: ... > > On 03/22/2015 11:59 PM, Hannes Reinecke wrote: > > > On 03/22/2015 05:31 PM, Michael Opdenacker wrote: > > >> This replaces kmalloc + memset by a call to kzalloc > > >> (or kcalloc when appropriate, which zeroes memory too) > > >> ... > > I'm sending a version that reverts the use of kcalloc() instead of > > kzalloc(). For reasons I don't understand, I didn't see the end of > > Robert Elliott's comment that the use of kcalloc() could prevent the > > compiler from detecting an overflow. > > I'm confused. I don't see that comment either, but > the entire point of kcalloc is to prevent overflows > by returning NULL when an overflow might occur. It was a reply to the original post on 2014-10-16, not the resend this month. >From http://permalink.gmane.org/gmane.linux.kernel/1808168: kcalloc is helpful when one of the values is a variable that might cause the multiply to overflow during runtime. Here, two constants are being multiplied together, which can be done and checked by the compiler at compile time. Since kcalloc and kmalloc_array are both static inline functions: static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) { if (size != 0 && n > SIZE_MAX / size) return NULL; return __kmalloc(n * size, flags); } static inline void *kcalloc(size_t n, size_t size, gfp_t flags) { return kmalloc_array(n, size, flags | __GFP_ZERO); } a compiler that detects an overflow will probably just reduce that to an inlined "return NULL." BUILD_BUG_ON could be used to trigger a compile-time error, instead of building a kernel that returns a run-time error. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [RESEND] aic7xxx: replace kmalloc/memset by kzalloc
On Tue, 2015-03-24 at 13:46 -0700, Michael Opdenacker wrote: > Hi, > > On 03/22/2015 11:59 PM, Hannes Reinecke wrote: > > On 03/22/2015 05:31 PM, Michael Opdenacker wrote: > >> This replaces kmalloc + memset by a call to kzalloc > >> (or kcalloc when appropriate, which zeroes memory too) > >> > >> This also fixes one checkpatch.pl issue in the process. > >> > >> This improvement was suggested by "make coccicheck" > >> > >> Signed-off-by: Michael Opdenacker > > Reviewed-by: Hannes Reinecke > > I'm sending a version that reverts the use of kcalloc() instead of > kzalloc(). For reasons I don't understand, I didn't see the end of > Robert Elliott's comment that the use of kcalloc() could prevent the > compiler from detecting an overflow. I'm confused. I don't see that comment either, but the entire point of kcalloc is to prevent overflows by returning NULL when an overflow might occur. from include/linux/slab.h: /** * kmalloc_array - allocate memory for an array. * @n: number of elements. * @size: element size. * @flags: the type of memory to allocate (see kmalloc). */ static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) { if (size != 0 && n > SIZE_MAX / size) return NULL; return __kmalloc(n * size, flags); } /** * kcalloc - allocate memory for an array. The memory is set to zero. * @n: number of elements. * @size: element size. * @flags: the type of memory to allocate (see kmalloc). */ static inline void *kcalloc(size_t n, size_t size, gfp_t flags) { return kmalloc_array(n, size, flags | __GFP_ZERO); } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [RESEND] aic7xxx: replace kmalloc/memset by kzalloc
Hi, On 03/22/2015 11:59 PM, Hannes Reinecke wrote: > On 03/22/2015 05:31 PM, Michael Opdenacker wrote: >> This replaces kmalloc + memset by a call to kzalloc >> (or kcalloc when appropriate, which zeroes memory too) >> >> This also fixes one checkpatch.pl issue in the process. >> >> This improvement was suggested by "make coccicheck" >> >> Signed-off-by: Michael Opdenacker > Reviewed-by: Hannes Reinecke I'm sending a version that reverts the use of kcalloc() instead of kzalloc(). For reasons I don't understand, I didn't see the end of Robert Elliott's comment that the use of kcalloc() could prevent the compiler from detecting an overflow. Michael. -- Michael Opdenacker, CEO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com +33 484 258 098 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [RESEND] aic7xxx: replace kmalloc/memset by kzalloc
On 03/22/2015 05:31 PM, Michael Opdenacker wrote: > This replaces kmalloc + memset by a call to kzalloc > (or kcalloc when appropriate, which zeroes memory too) > > This also fixes one checkpatch.pl issue in the process. > > This improvement was suggested by "make coccicheck" > > Signed-off-by: Michael Opdenacker Reviewed-by: Hannes Reinecke Cheers, Hannes -- Dr. Hannes ReineckezSeries & Storage h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/