Re: [PATCH] selinux: reduce the use of hard-coded hash sizes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Feb 18, 2020 at 5:44 PM Stephen Smalley <sds@xxxxxxxxxxxxx> wrote:
> On 2/18/20 11:18 AM, Stephen Smalley wrote:
> > On 2/18/20 10:21 AM, Ondrej Mosnacek wrote:
> >> On Tue, Feb 18, 2020 at 3:59 PM Stephen Smalley <sds@xxxxxxxxxxxxx>
> >> wrote:
> >>> On 2/17/20 6:49 AM, Ondrej Mosnacek wrote:
> >>>> Instead allocate hash tables with just the right size based on the
> >>>> actual number of elements (which is almost always known beforehand, we
> >>>> just need to defer the hashtab allocation to the right time). The only
> >>>> case when we don't know the size (with the current policy format) is
> >>>> the
> >>>> new filename transitions hashtable. Here I just left the existing
> >>>> value.
> >>>>
> >>>> After this patch, the time to load Fedora policy on x86_64 decreases
> >>>> from 950 ms to 220 ms. If the unconfined module is removed, it
> >>>> decreases
> >>>> from 870 ms to 170 ms. It is also likely that other operations are
> >>>> going
> >>>> to be faster, mainly string_to_context_struct() or mls_compute_sid(),
> >>>> but I didn't try to quantify that.
> >>>>
> >>>> The memory usage increases a bit after this patch, but only by ~1-2 MB
> >>>> (it is hard to measure precisely). I believe it is a small price to pay
> >>>> for the increased performance.
> >>>>
> >>>> Signed-off-by: Ondrej Mosnacek <omosnace@xxxxxxxxxx>
> >>>> ---
> >>>>    security/selinux/ss/hashtab.c  | 21 ++++++++++++--
> >>>>    security/selinux/ss/hashtab.h  |  2 +-
> >>>>    security/selinux/ss/policydb.c | 53
> >>>> +++++++++++++---------------------
> >>>>    security/selinux/ss/policydb.h |  2 --
> >>>>    4 files changed, 40 insertions(+), 38 deletions(-)
> >>>>
> >>>> diff --git a/security/selinux/ss/hashtab.c
> >>>> b/security/selinux/ss/hashtab.c
> >>>> index ebfdaa31ee32..554a91ef3f06 100644
> >>>> --- a/security/selinux/ss/hashtab.c
> >>>> +++ b/security/selinux/ss/hashtab.c
> >>>> @@ -27,6 +41,9 @@ struct hashtab *hashtab_create(u32
> >>>> (*hash_value)(struct hashtab *h, const void *
> >>>>        p->nel = 0;
> >>>>        p->hash_value = hash_value;
> >>>>        p->keycmp = keycmp;
> >>>> +     if (!size)
> >>>> +             return p;
> >>>> +
> >>>>        p->htable = kmalloc_array(size, sizeof(*p->htable), GFP_KERNEL);
> >>>>        if (!p->htable) {
> >>>>                kfree(p);
> >>>
> >>> Thanks, this looks promising.  However, I was wondering: if we end up
> >>> with size == 0 (e.g. policy happens to have an empty table), does the
> >>> rest of the hashtab_* code always correctly handle the fact that
> >>> ->htable could be NULL?  Doesn't look obviously safe to me on a quick
> >>> look.
> >>
> >> Hm... it seems I didn't think this through when I was trying to handle
> >> this case. I was rebasing this patch all over the place as I was
> >> working on other changes in parallel, so maybe I just lost the safety
> >> somewhere along the way... I think I will just clamp the minimum size
> >> to 1, as that seems both safer and simpler. The extra 8-byte
> >> allocation shouldn't cost much (there are only O(number of classes +
> >> commons) hash tables and these make no sense to have 0 entries).
> >
> > Hmm...on booting this kernel, I am seeing a number of calls to
> > hashtab_create() with nel_hint==0 leading to size == 0 and nothing is
> > obviously breaking, so maybe this is safe?
>
> I guess this happens for any class that doesn't define any of its own
> permissions (beyond the inherited common ones).  Probably could just add
> some simple checks to hashtab_* where absent to ensure we don't ever
> dereference ->htable if NULL.

Yeah, OK. I only needed to add a check to hashtab_insert() and
hashtab_search(), the rest will already do the sane thing as-is.

-- 
Ondrej Mosnacek <omosnace at redhat dot com>
Software Engineer, Security Technologies
Red Hat, Inc.




[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux