Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Feb 2016 12:43:55 -0700
From:      Warner Losh <imp@bsdimp.com>
To:        John Baldwin <jhb@freebsd.org>
Cc:        "freebsd-arch@freebsd.org" <freebsd-arch@freebsd.org>, Brooks Davis <brooks@freebsd.org>,  Mike Belopuhov <mike@belopuhov.com>, Ryan Stone <rysto32@gmail.com>,  "freebsd-arch@freebsd.org" <arch@freebsd.org>
Subject:   Re: OpenBSD mallocarray
Message-ID:  <CANCZdfqeR4nHEWPSv-EdW3OA1UcJTXtLhXijHX7p01-FTpo6Sg@mail.gmail.com>
In-Reply-To: <1955470.jNCaThvui8@ralph.baldwin.cx>
References:  <CAB815ZafpqJoqr1oH8mDJM=0RxLptQJpoJLexw6P6zOi7oSXTQ@mail.gmail.com> <20160201224854.GB1747@spindle.one-eyed-alien.net> <CANCZdfqDDE5jigsDUSpLPjoqGNPCqn4kipX-eqYBBYakuTiBWA@mail.gmail.com> <1955470.jNCaThvui8@ralph.baldwin.cx>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Feb 3, 2016 at 12:39 PM, John Baldwin <jhb@freebsd.org> wrote:

> On Monday, February 01, 2016 04:01:14 PM Warner Losh wrote:
> > On Mon, Feb 1, 2016 at 3:48 PM, Brooks Davis <brooks@freebsd.org> wrote:
> >
> > > On Mon, Feb 01, 2016 at 02:12:20PM -0700, Warner Losh wrote:
> > > >
> > > > > On Feb 1, 2016, at 2:02 PM, Mike Belopuhov <mike@belopuhov.com>
> wrote:
> > > > >
> > > > > On Mon, Feb 01, 2016 at 15:56 -0500, Ryan Stone wrote:
> > > > >> On Mon, Feb 1, 2016 at 3:16 PM, Conrad Meyer <cem@freebsd.org>
> wrote:
> > > > >>
> > > > >>>
> > > > >>> Sure.  +1 from me.  I don't think we want the M_CANFAIL hack,
> though.
> > > > >>>
> > > > >>> Best,
> > > > >>> Conrad
> > > > >>>
> > > > >>>
> > > > >> That may be the OpenBSD equivalent of M_NOWAIT.
> > > > >
> > > > > Not quite.  From the man page:
> > > > >
> > > > >   M_CANFAIL
> > > > >
> > > > >   In the M_WAITOK case, if not enough memory is available,
> > > > >   return NULL instead of calling panic(9).  If mallocarray()
> > > > >   detects an overflow or malloc() detects an excessive
> > > > >   allocation, return NULL instead of calling panic(9).
> > > >
> > > > Yea, we don???t want it calling panic. Ever. That turns an overflow
> > > > into a DoS. Arguments should be properly checked so we can
> > > > properly return EINVAL for bat-**** crazy ones. FreeBSD???s malloc
> > > > doesn???t cave an excessive detector in it.
> > > >
> > > > My concern with this is that we have a number of different allocation
> > > > routines in FreeBSD. This only goes after the malloc() vector, and
> > > > even then it requires code changes.
> > > >
> > > > At best, CANFAIL is a kludge to fail with a panic instead of an
> > > > overflow. That???s got to be at most a transient thing until all the
> > > > code that it is kludged into with out proper thought is fixed. I???m
> not
> > > > sure that???s something that we want to encourage. I???m all for
> > > > safety, but this flag seems both unsafe and unwise.
> > >
> > > Given that current code could be doing literally anything in the
> > > overflow case (and thanks to modern undefined behavior optimizations is
> > > likely doing something extraordinarily bizarre), I think turning
> overflows
> > > into panics is a good thing.  Yes, you can argue that means you've
> added
> > > a DoS vector, but best case you had an under allocation and bizarre
> > > memory corruption before.  If the default or even only behavior is
> going
> > > to be that overflow fails then we need a static checker that ensure we
> > > check the return value even in the M_WAITOK.  Otherwise there will be
> > > blind conversions of malloc to mallocarray that go unchecked.
> > >
> >
> > Returning NULL should be sufficient. Blind conversion of malloc to
> > mallocarray in the kernel is also stupid. Intelligent conversion is
> > needed to ensure that the error conditions are handled correctly.
> > There's no need for a flag to say 'I am going to do the right thing
> > if you give me NULL back'. The conversion should do the right
> > thing when you get NULL back. A quick survey of the current kernel
> > shows that there's not very many that could be using user defined
> > values, but does show a large number of places where we could
> > use this API.
> >
> > I guess this comes down to 'why is it an unreasonable burden to
> > test the return value in code that's converted?' We're already changing
> > the code.
> >
> > If you absolutely must have a flag, I'd prefer M_CANPANIC or something
> > that is also easy to add for the 'mindless' case that we can easily
> > grep for so we know when we're removed all the stupid 'mindless'
> > cases from the tree.
>
> Having M_WAITOK-anything return NULL will be a POLA violation.  It doesn't
> return NULL for anything else.  I think having a separate M_CANFAIL flag
> is also rather pointless.  If we want to have this, I think it should
> work similar to malloc().  M_WAITOK panics if you do stupid things
> (malloc(9) does this for sufficiently large overflow when it exhausts kmem
> contrary to Warner's earlier claim), M_NOWAIT returns NULL.
>

Exausting kmem isn't influenced by simple args. But I do stand corrected.


> In general I think I most prefer Bruce's approach of having a separate
> macro
> to check for overflow explicitly so it can be handled as a separate error.
> In particular, if mallocarry(..., M_NOWAIT) fails, is it because of memory
> shortage (in which case retrying in the future might be sensible) or is it
> due to overflow (in which case it will fail no matter how many times you
> retry)?  You'd then have to have the macro anyway to differentiate and
> handle
> this case.
>
> Warner also seems to be assuming that we should do check for overflow
> explicitly for any user-supplied values before calling malloc() or
> malloc()-like things.  This means N hand-rolled (and possibly buggy)
> checks,
> or a shared macro to do the check.  I think this is another argument in
> favor
> of Bruce's approach. :)
>

I like Bruce's approach. And it works for more than just malloc.


> If you go that route, then mallocarray() is really just an assertion
> checker.  It should only fail because a programmer ommitted an explicit
> overflow check for a user-supplied value or screwed up an in-kernel
> value.  In that case I think panic'ing sooner when the overflow is obvious
> is more useful for debugging the error than a NULL pointer deference
> some time later (or requests that get retried forever and go possibly
> unnoticed).
>

That would be fine. On its own, mallocarray() has all the issues we've
talked about.

Warner



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CANCZdfqeR4nHEWPSv-EdW3OA1UcJTXtLhXijHX7p01-FTpo6Sg>