|
|
Message-ID: <12356C813DFF6F479B608F81178A5615875DA9@BGSMSX101.gar.corp.intel.com>
Date: Sat, 6 Jul 2019 20:52:44 +0000
From: "Gote, Nitin R" <nitin.r.gote@...el.com>
To: Kees Cook <keescook@...omium.org>, Vegard Nossum <vegard.nossum@...il.com>
CC: "kernel-hardening@...ts.openwall.com"
<kernel-hardening@...ts.openwall.com>
Subject: RE: Regarding have kfree() (and related) set the pointer to NULL too
> -----Original Message-----
> From: Kees Cook [mailto:keescook@...omium.org]
> Sent: Thursday, June 27, 2019 9:52 PM
> To: Vegard Nossum <vegard.nossum@...il.com>
> Cc: Gote, Nitin R <nitin.r.gote@...el.com>; kernel-
> hardening@...ts.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@...el.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));
>
> or
>
> previous = something->allocation;
> ...
> kfree(prevous)
>
> 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.
>
As per my understanding from above comment is that,
First need to check below changes are harmless or not using tool like KASAN (KASAN report).
> #define kfree(x) \
> do { \
> typeof(x) *ptr = &(x); \
> real_kfree(*ptr); \
> *ptr = NULL; \
> } while (0)
If I misunderstood this, Could you please elaborate this? As I'm not able to conclude on this completely.
--
Nitin Gote.
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.