kernel-hardening.lists.openwall.com archive mirror
 help / color / mirror / Atom feed
From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
To: Matthew Wilcox <willy@infradead.org>, Kees Cook <keescook@chromium.org>
Cc: Matthew Wilcox <mawilcox@microsoft.com>,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	kernel-hardening@lists.openwall.com
Subject: Re: [PATCH 04/13] mm: Use array_size() helpers for kmalloc()
Date: Wed, 9 May 2018 20:00:28 +0200	[thread overview]
Message-ID: <fea0a346-6f36-ff8c-f036-13f22dfb9bfe@rasmusvillemoes.dk> (raw)
In-Reply-To: <20180509113446.GA18549@bombadil.infradead.org>

On 2018-05-09 13:34, Matthew Wilcox wrote:
> On Tue, May 08, 2018 at 05:42:20PM -0700, Kees Cook wrote:
>> @@ -499,6 +500,8 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
>>   */
>>  static __always_inline void *kmalloc(size_t size, gfp_t flags)
>>  {
>> +	if (size == SIZE_MAX)
>> +		return NULL;
>>  	if (__builtin_constant_p(size)) {
>>  		if (size > KMALLOC_MAX_CACHE_SIZE)
>>  			return kmalloc_large(size, flags);
> 
> I don't like the add-checking-to-every-call-site part of this patch.
> Fine, the compiler will optimise it away if it can calculate it at compile
> time, but there are a lot of situations where it can't.  You aren't
> adding any safety by doing this; trying to allocate SIZE_MAX bytes is
> guaranteed to fail, and it doesn't need to fail quickly.

Yeah, agree that we don't want to add a size check to all callers,
including those where the size doesn't even come from one of the new
*_size helpers; that just adds bloat. It's true that the overflow case
does not have to fail quickly, but I was worried that the saturating
helpers would end up making gcc emit a cmov instruction, thus stalling
the regular path. But it seems that it actually ends up doing a forward
jump, sets %rdi to SIZE_MAX, then jumps back to the call of __kmalloc,
so it should be ok.

With __builtin_constant_p(size) && size == SIZE_MAX, gcc could be smart
enough to elide those two instructions and have the jo go directly to
the caller's error handling, but at least gcc 5.4 doesn't seem to be
that smart. So let's just omit that part for now.

But in case of the kmalloc_array functions, with a direct call of
__builtin_mul_overflow(), gcc does combine the "return NULL" with the
callers error handling, thus avoiding the six byte "%rdi = -1; jmp
back;" thunk. That, along with the churn factor, might be an argument
for leaving the current callers of *_array alone. But if we are going to
keep those longer-term, we might as well convert kmalloc(a, b) into
kmalloc_array(a, b) instead of kmalloc(array_size(a, b)). In any case, I
do see the usefulness of the struct_size helper, and agree that we
definitely should not introduce a new *_struct variant that needs to be
implemented in all families.

>> @@ -624,11 +629,13 @@ int memcg_update_all_caches(int num_memcgs);
>>   */
>>  static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
>>  {
>> -	if (size != 0 && n > SIZE_MAX / size)
>> +	size_t bytes = array_size(n, size);
>> +
>> +	if (bytes == SIZE_MAX)
>>  		return NULL;
>>  	if (__builtin_constant_p(n) && __builtin_constant_p(size))
>> -		return kmalloc(n * size, flags);
>> -	return __kmalloc(n * size, flags);
>> +		return kmalloc(bytes, flags);
>> +	return __kmalloc(bytes, flags);
>>  }
>>  
>>  /**
>> @@ -639,7 +646,9 @@ static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
>>   */
>>  static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
>>  {
>> -	return kmalloc_array(n, size, flags | __GFP_ZERO);
>> +	size_t bytes = array_size(n, size);
>> +
>> +	return kmalloc(bytes, flags | __GFP_ZERO);
>>  }
> 
> Hmm.  I wonder why we have the kmalloc/__kmalloc "optimisation"
> in kmalloc_array, but not kcalloc.  Bet we don't really need it in
> kmalloc_array.  I'll do some testing.
> 

Huh? Because kcalloc is implemented in terms of kmalloc_array? And can't
we just keep it that way?

Rasmus

  parent reply	other threads:[~2018-05-09 18:00 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-09  0:42 [RFC][PATCH 00/13] Provide saturating helpers for allocation Kees Cook
2018-05-09  0:42 ` [PATCH 01/13] compiler.h: enable builtin overflow checkers and add fallback code Kees Cook
2018-05-09  0:42 ` [PATCH 02/13] lib: add runtime test of check_*_overflow functions Kees Cook
2018-05-09  0:42 ` [PATCH 03/13] overflow.h: Add allocation size calculation helpers Kees Cook
2018-05-09 18:27   ` Rasmus Villemoes
2018-05-09 18:49     ` Kees Cook
2018-05-09  0:42 ` [PATCH 04/13] mm: Use array_size() helpers for kmalloc() Kees Cook
2018-05-09 11:34   ` Matthew Wilcox
2018-05-09 17:58     ` Kees Cook
2018-05-09 18:00     ` Rasmus Villemoes [this message]
2018-05-09 18:07       ` Kees Cook
2018-05-09 18:39         ` Rasmus Villemoes
2018-05-09  0:42 ` [PATCH 05/13] mm: Use array_size() helpers for kvmalloc() Kees Cook
2018-05-09  0:42 ` [PATCH 06/13] treewide: Use struct_size() for kmalloc()-family Kees Cook
2018-05-09  0:42 ` [PATCH 07/13] treewide: Use struct_size() for vmalloc()-family Kees Cook
2018-05-09  0:42 ` [PATCH 08/13] treewide: Use struct_size() for devm_kmalloc() and friends Kees Cook
2018-05-09  0:42 ` [PATCH 09/13] treewide: Use array_size() for kmalloc()-family Kees Cook
2018-05-09  0:42 ` [PATCH 10/13] treewide: Use array_size() for kmalloc()-family, leftovers Kees Cook
2018-05-09  0:42 ` [PATCH 11/13] treewide: Use array_size() for vmalloc() Kees Cook
2018-05-09  0:42 ` [PATCH 12/13] treewide: Use array_size() for devm_*alloc()-like Kees Cook
2018-05-09  0:42 ` [PATCH 13/13] treewide: Use array_size() for devm_*alloc()-like, leftovers Kees Cook
2018-05-09 16:08 ` [RFC][PATCH 00/13] Provide saturating helpers for allocation Laura Abbott
2018-05-09 17:01   ` Kees Cook

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fea0a346-6f36-ff8c-f036-13f22dfb9bfe@rasmusvillemoes.dk \
    --to=linux@rasmusvillemoes.dk \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mawilcox@microsoft.com \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).