kernel-hardening.lists.openwall.com archive mirror
 help / color / mirror / Atom feed
From: "Gote, Nitin R" <nitin.r.gote@intel.com>
To: Kees Cook <keescook@chromium.org>,
	Vegard Nossum <vegard.nossum@gmail.com>
Cc: "kernel-hardening@lists.openwall.com"
	<kernel-hardening@lists.openwall.com>
Subject: RE: Regarding have kfree() (and related) set the pointer to NULL too
Date: Wed, 17 Jul 2019 10:01:21 +0000	[thread overview]
Message-ID: <12356C813DFF6F479B608F81178A561587A39C@BGSMSX101.gar.corp.intel.com> (raw)
In-Reply-To: <12356C813DFF6F479B608F81178A5615875DA9@BGSMSX101.gar.corp.intel.com>

> > -----Original Message-----
> > From: Kees Cook [mailto:keescook@chromium.org]
> > Sent: Thursday, June 27, 2019 9:52 PM
> > To: Vegard Nossum <vegard.nossum@gmail.com>
> > Cc: Gote, Nitin R <nitin.r.gote@intel.com>; kernel-
> > hardening@lists.openwall.com
> > Subject: Re: Regarding have kfree() (and related) set the pointer to
> > NULL too
> >
> > On Thu, Jun 27, 2019 at 01:45:06PM +0200, Vegard Nossum wrote:
> > > On Thu, 27 Jun 2019 at 12:23, Gote, Nitin R <nitin.r.gote@intel.com>
> wrote:
> > > > Hi,
> > > >
> > > > I’m looking  into “have kfree() (and related) set the pointer to NULL too”
> > task.
> > > >
> > > > As per my understanding, I did below changes :
> > > >
> > > > Could you please provide some points on below ways ?
> > > > @@ -3754,6 +3754,7 @@ void kfree(const void *objp)
> > > >         debug_check_no_obj_freed(objp, c->object_size);
> > > >         __cache_free(c, (void *)objp, _RET_IP_);
> > > >         local_irq_restore(flags);
> > > > +       objp = NULL;
> > > >
> > > > }
> > >
> > > This will not do anything, since the assignment happens to the local
> > > variable inside kfree() rather than to the original expression that
> > > was passed to it as an argument.
> > >
> > > Consider that the code in the caller looks like this:
> > >
> > > void *x = kmalloc(...);
> > > kfree(x);
> > > pr_info("x = %p\n", x);
> > >
> > > this will still print "x = (some non-NULL address)" because the
> > > variable 'x' in the caller still retains its original value.
> > >
> > > You could try wrapping kfree() in a C macro, something like
> > >
> > > #define kfree(x) real_kfree(x); (x) = NULL;
> >
> > Right, though we want to avoid silent double-evaluation, so we have to
> > do some macro tricks. I suspect the starting point is something like:
> >
> > #define kfree(x)			\
> > 	do {				\
> > 		typeof(x) *ptr = &(x);	\
> > 		real_kfree(*ptr);	\
> > 		*ptr = NULL;		\
> > 	} while (0)
> >
> > However, there are a non-zero number of places in the kernel where
> > kfree() is used on things that are not simple memory references, like
> > function return values, or copies of the actual reference:
> >
> > 	kfree(get_my_allocation(foo));
> >

We have not found any clue or compiler extension on this case to know x 
is value or variable.

There are around 300 such cases in kernel where kfree() is used on function return values. 

One proposal is we can refactor the kfree() call by assigning it to local variable so that
we can overcome the compilation issue (error: lvalue required as unary & operand).

Please let us know that we should proceed with this proposal or you (or anyone)
have other proposals.

> > or
> >
> > 	previous = something->allocation;
> > 	...
> > 	kfree(previous)
> >

As of now, we don't have any idea to overcome this case. 
So, we are keeping this for later stage. 

In case anyone has idea on this then let me know, 
we are ready to work on this. 

> > So the larger work is figuring out how to gracefully deal with those
> > using a reasonable API, or through refactoring.
> >
> > However, before getting too far, it's worth going though past
> > use-after-free vulnerabilities to figure out how many would have been
> > rendered harmless (NULL deref instead of UaF) with this change. Has
> > this been studied before, etc. With this information it's easier to
> > decide if the benefit of this refactoring is worth the work to do it.
> >

Thanks,
Nitin


  reply	other threads:[~2019-07-17 10:01 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-27 10:19 Regarding have kfree() (and related) set the pointer to NULL too Gote, Nitin R
2019-06-27 11:45 ` Vegard Nossum
2019-06-27 16:21   ` Kees Cook
2019-07-06 20:52     ` Gote, Nitin R
2019-07-17 10:01       ` Gote, Nitin R [this message]
2019-07-22 17:10         ` 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=12356C813DFF6F479B608F81178A561587A39C@BGSMSX101.gar.corp.intel.com \
    --to=nitin.r.gote@intel.com \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=vegard.nossum@gmail.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 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).