Re: [PATCH] checks: fix simple-bus compatible matching

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



On Wed, Sep 19, 2018 at 09:19:14AM -0700, Rob Herring wrote:
> On Tue, Sep 18, 2018 at 9:38 PM David Gibson
> <david@xxxxxxxxxxxxxxxxxxxxx> wrote:
> >
> > On Tue, Sep 18, 2018 at 04:46:38PM -0700, Rob Herring wrote:
> > > Since commit 7975f6422260 ("Fix widespread incorrect use of strneq(),
> > > replace with new strprefixeq()") simple-bus checks have been silently
> > > skipped. The problem was 'end - str' is one more than the string length
> > > and the strnlen in strprefixeq fails. This can't be fixed simply by
> > > subtracting one as it is possible to have multiple '\0' at the end of
> > > the property. So first check the property is null terminated and then
> > > use streq() for comparisons.
> > >
> > > Add some tests so the problem doesn't happen again.
> > >
> > > Fixes: 7975f6422260 ("Fix widespread incorrect use of strneq(), replace with new strprefixeq()")
> > > Reported-by: Kumar Gala <kumar.gala@xxxxxxxxxx>
> > > Signed-off-by: Rob Herring <robh@xxxxxxxxxx>
> >
> > So, the existing version was definitely wrong.  The second parameter
> > to strprefixeq needs to be the exact length of the prefix to compare,
> > and it's clearly not here.  But your proposed version isn't quite
> > right either.
> >
> > > ---
> > >  checks.c                                    |  8 ++++++--
> > >  tests/run_tests.sh                          |  4 ++++
> > >  tests/unit-addr-simple-bus-compatible.dts   | 18 ++++++++++++++++++
> > >  tests/unit-addr-simple-bus-reg-mismatch.dts | 18 ++++++++++++++++++
> > >  4 files changed, 46 insertions(+), 2 deletions(-)
> > >  create mode 100644 tests/unit-addr-simple-bus-compatible.dts
> > >  create mode 100644 tests/unit-addr-simple-bus-reg-mismatch.dts
> > >
> > > diff --git a/checks.c b/checks.c
> > > index 9c9b0c328af6..1ccbfa60c839 100644
> > > --- a/checks.c
> > > +++ b/checks.c
> > > @@ -908,9 +908,13 @@ static bool node_is_compatible(struct node *node, const char *compat)
> > >       if (!prop)
> > >               return false;
> > >
> > > -     for (str = prop->val.val, end = str + prop->val.len; str < end;
> > > +     str = prop->val.val;
> > > +     if (strnlen(str, prop->val.len) == prop->val.len)
> > > +             return false;
> >
> > This will catch the case where the property has no \0s at all, but not
> > a case like say...
> >         compatible = "foo", /bits/ 8 <'s' 'i' 'm'>;
> 
> That's just crap.

Well, yes, that's kind of the point.

> We do also validate already that compatible is a
> string list. Not sure offhand if that's a dependency for this.

Ah.. good point.  If we add a dependency for that, your original
should be fine - and you can even drop that initial check.

> Maybe I should just check that the last byte is null.

Adding a dependency on the stringlist check seems better to me (and
amounts to almost the same thing).

> > > +
> > > +     for (end = str + prop->val.len; str < end;
> > >            str += strnlen(str, end - str) + 1) {
> > > -             if (strprefixeq(str, end - str, compat))
> > > +             if (streq(str, compat))
> >
> > ...which will lead to this streq() running over the end of the property.
> >
> > I think you instead will need something like this:
> >         len = strlen(compat);
> >         /* ... */
> >         if ((end - str) > len && (memcmp(str, compat, len) == 0))
> >                 /* ... */
> 
> That would match if say we have "simple-bus-foo" and compat is
> "simple-bus". The memcmp would need to be len + 1, but then that is
> just back to strcmp aka streq.

Yeah, I meant len + 1.  When the length is known in advance, I
generally prefer memcmp to strcmp().

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux