lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20151222022226.GY20997@ZenIV.linux.org.uk>
Date:	Tue, 22 Dec 2015 02:22:26 +0000
From:	Al Viro <viro@...IV.linux.org.uk>
To:	Linus Torvalds <torvalds@...ux-foundation.org>
Cc:	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: Re: [RFC] free_pages stuff

On Mon, Dec 21, 2015 at 05:16:44PM -0800, Linus Torvalds wrote:
> On Dec 21, 2015 17:04, "Al Viro" <viro@...iv.linux.org.uk> wrote:
> >
> > > And quite frankly, even the "new name" is likely a bad idea. If you
> > > want to allocate a page, and get a pointer, just use "kmalloc()".
> > > Boom, done!
> >
> > Erm...  You've just described the absolute majority of callers.  Really.
> 
> That wasn't my point.
> 
> I totally believe that most of the legacy users actually wanted a pointer.
> 
> But that doesn't mean that we should just convert a legacy interface. We
> should either just create a new interface and leave old users alone, or if
> we care about that code and really want to remove the cast, maybe it should
> just use kmalloc() instead.
> 
> Long ago, allocating a page using kmalloc() was a bad idea, because there
> was overhead for it in the allocation and the code.
> 
> These days, kmalloc() not only doesn't have the allocation overhead, but
> may actually scale better too, thanks to percpu caches etc.
> 
> So my point here is that not only is it wrong to change the calling
> convention for a legacy function (and it really probably doesn't get much
> more legacy than get_free_page - I think it's been around forever), but

Yes - present in v0.01, with similar situation re callers even back then ;-)

> even the "let's make up a new name" conversion may be wrong, because it's
> entirely possible that the code in question should just be using kmalloc().
> 
> So I don't think an automatic conversion is a good idea. I suspect that old
> code that somebody isn't actively working on should just be left alone, and
> code that *is* actively worked on should maybe consider kmalloc().

Agreed.  Again, what I really wanted was to get the clear picture of what
uses _are_ there.  In more details than just "grepping seems to indicate
that...".  It's really pretty much all of them.

> And if the code really explicitly wants a page (or set of aligned pages)
> for some vm reason, I suspect having the cast there isn't a bad thing. It's
> clearly not just a random pointer allocation if the bit pattern of the
> pointer matters.

BTW, I'm not sure we don't have code that would assume that
kmalloc(PAGE_SIZE,...) always returns something PAGE_SIZE-aligned.

FWIW, pointer-returning get_free_page() would not be a flagday change at
all - we only have __get_free_page()/__get_free_pages() right now.  And I'm
not sure that it wouldn't make sense to add void *-returning variants without
underscores - not for bulk conversion of existing callers, but for new
places that want a page.  Because most of the new ones (and new ones keep
appearing; it's not just ancient code) still want a pointer.  And yes, quite
a few of those should be using something else.

Example (went into the tree just three months ago):
static inline void *scif_zalloc(size_t size)
{
        void *ret = NULL;
        size_t align = ALIGN(size, PAGE_SIZE);

        if (align && get_order(align) < MAX_ORDER)
                ret = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
                                               get_order(align));
        return ret ? ret : vzalloc(align);
}

This clearly should be using kzalloc() instead of __get_free_pages() (and
I'm not sure whether the cutoff is right - similar "kmalloc if not too
large, vmalloc otherwise" tends to have cutoff lower than MAX_ORDER;
PAGE_ALLOC_COSTLY_ORDER is more common).  The callers do not look like
they would care about page alignment - at least quite a few of them do
not.

Incidentally, those caller include the following example of lousy naming:
        (*pages)->phys_addr = scif_zalloc(nr_pages * sizeof(dma_addr_t));
First of all, the address is clearly virtual - it's an array!  What's more,
I really wonder whether it's DMA or physical addresses that are stored there.
It's declared as an array of dma_addr_t, but...
                (*pages)->phys_addr[i] =
                        __scif_off_to_dma_addr(window, offset +
                                               (i * PAGE_SIZE));
                (*pages)->phys_addr[i] = scif_get_phys((*pages)->phys_addr[i],
                                                        ep);
and
static phys_addr_t scif_get_phys(phys_addr_t phys, struct scif_endpt *ep)
seems to indicate something fishy going on.

Typechecking for different kinds of addresses is really too weak, and the
amount of casts we have around them doesn't help either ;-/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ