All of lore.kernel.org
 help / color / mirror / Atom feed
From: Solar Designer <solar@openwall.com>
To: kernel-hardening@lists.openwall.com
Subject: Re: [kernel-hardening] kmalloc() nofail allocations
Date: Sat, 20 Aug 2011 20:31:20 +0400	[thread overview]
Message-ID: <20110820163120.GA7256@openwall.com> (raw)
In-Reply-To: <20110820142723.GA5708@albatros>

Vasiliy,

Overall, I like this.  My biggest concern is that it implies that the
kernel will always have a can't fail memory allocation interface.  So if
kernel developers at some point want to change this, they'll have a hard
time making such changes.  On the other hand, the current situation with
some code assuming that failures are impossible and some other code
checking for them anyway is inconsistent and not very helpful for
possible memory allocation semantics changes anyway.

So let's give this a try.

On Sat, Aug 20, 2011 at 06:27:23PM +0400, Vasiliy Kulikov wrote:
> Here is a patch to do it.  I've implemented k(m|z)alloc() and
> kmem_cache_{z,}alloc() nofail variants.  As a result, setuid() cannot
> fail with any reason, but EACCES.
> 
> kernel/cred.c is partly moved to _nofail() too, just to show how much
> error handling code it removes.

This mostly looks good to me.  Some comments are below:

> +#define kmalloc_nofail(size, flags) \
> +({ \
> +	void *p; \
> +	(void)BUILD_BUG_ON_ZERO(size > (PAGE_SIZE << (PAGE_ALLOC_COSTLY_ORDER-1))); \
> +	if (flags & __GFP_NORETRY) \
> +		panic("Attempt to call kmalloc_nofail() with __GFP_NORETRY"); \
> +	p = kmalloc(size, flags); \
> +	if (p == NULL) \
> +		panic("kmalloc_nofail() returned NULL\n"); \
> +	p; \
> +})

You need to enclose size and flags in braces in this macro.

Also, I think portions of this macro should be moved into a non-inline
function defined in some .c file - to reduce total code size.  Then the
macro (and thus duplicated code) could be shortened to:

#define kmalloc_nofail(size, flags) \
({ \
	(void)BUILD_BUG_ON_ZERO((size) > (PAGE_SIZE << (PAGE_ALLOC_COSTLY_ORDER-1))); \
	_kmalloc_nofail((size), (flags)); \
})

or to optimize it for speed at the cost of slight size increase:

#define kmalloc_nofail(size, flags) \
({ \
	void *p; \
	(void)BUILD_BUG_ON_ZERO((size) > (PAGE_SIZE << (PAGE_ALLOC_COSTLY_ORDER-1))); \
	p = kmalloc((size), (flags)); \
	if (((flags) & __GFP_NORETRY) || p == NULL) \
		kmalloc_nofail_panic((flags), p); \
	p; \
})

so you have only one instance of a function call on error instead of
two calls to panic() and you don't rely on the compiler and linker
combining the many instances of constant strings.

You can leave these changes for after your initial RFC postings to LKML
if you like, though.

> +#define kzalloc_nofail(size, flags) \
> +	kmalloc_nofail(size, (flags | __GFP_ZERO))

Need braces around flags.

> +#define kmem_cache_zalloc_nofail(cache, flags) \
> +	kmem_cache_alloc_nofail(cache, (flags | __GFP_ZERO))

Need braces around cache and flags.

> +/* This is a slightly weaker check than kmalloc_nofail() as kmem check is runtime check :\ */
> +#define kmem_cache_alloc_nofail(cache, flags) \
> +({ \
> +	void *p; \
> +	if ((cache)->objsize > (PAGE_SIZE << (PAGE_ALLOC_COSTLY_ORDER-1))) \
> +		panic("Too big size (%lu) for kmem_cache_alloc_nofail()!", \
> +			(long)(cache)->objsize); \
> +	if (flags & __GFP_NORETRY); \
> +		panic("Attempt to call kmem_cache_alloc_nofail() with __GFP_NORETRY"); \
> +	p = kmem_cache_alloc(cache, flags); \
> +	if (p == NULL) \
> +		panic("kmem_cache_alloc() returned NULL\n"); \
> +	p; \
> +})

Similar comments apply here.  Since the size check is runtime anyway,
perhaps it should be moved into a non-inline function.

Please fix at least the braces, and bring this to LKML for discussion.

Thanks,

Alexander

  reply	other threads:[~2011-08-20 16:31 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-17 19:15 [kernel-hardening] kmalloc() nofail allocations Vasiliy Kulikov
2011-08-20 14:27 ` [kernel-hardening] " Vasiliy Kulikov
2011-08-20 16:31   ` Solar Designer [this message]
2011-08-22  9:24     ` [kernel-hardening] " Vasiliy Kulikov
2011-08-22  9:38       ` Solar Designer
2011-08-22  9:45         ` Vasiliy Kulikov
2011-08-22  9:53           ` Solar Designer
2011-08-22 10:05             ` Vasiliy Kulikov

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=20110820163120.GA7256@openwall.com \
    --to=solar@openwall.com \
    --cc=kernel-hardening@lists.openwall.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.