Re: [PATCH v4 05/45] drm/connector: Check drm_connector_init pointers arguments

From: Jani Nikula
Date: Wed Nov 29 2023 - 04:38:56 EST


On Wed, 29 Nov 2023, Maxime Ripard <mripard@xxxxxxxxxx> wrote:
> Hi Ville,
>
> On Tue, Nov 28, 2023 at 03:49:08PM +0200, Ville Syrjälä wrote:
>> On Tue, Nov 28, 2023 at 02:29:40PM +0100, Maxime Ripard wrote:
>> > On Tue, Nov 28, 2023 at 02:54:02PM +0200, Jani Nikula wrote:
>> > > On Tue, 28 Nov 2023, Maxime Ripard <mripard@xxxxxxxxxx> wrote:
>> > > > All the drm_connector_init variants take at least a pointer to the
>> > > > device, connector and hooks implementation.
>> > > >
>> > > > However, none of them check their value before dereferencing those
>> > > > pointers which can lead to a NULL-pointer dereference if the author
>> > > > isn't careful.
>> > >
>> > > Arguably oopsing on the spot is preferrable when this can't be caused by
>> > > user input. It's always a mistake that should be caught early during
>> > > development.
>> > >
>> > > Not everyone checks the return value of drm_connector_init and friends,
>> > > so those cases will lead to more mysterious bugs later. And probably
>> > > oopses as well.
>> >
>> > So maybe we can do both then, with something like
>> >
>> > if (WARN_ON(!dev))
>> > return -EINVAL
>> >
>> > if (drm_WARN_ON(dev, !connector || !funcs))
>> > return -EINVAL;
>> >
>> > I'd still like to check for this, so we can have proper testing, and we
>> > already check for those pointers in some places (like funcs in
>> > drm_connector_init), so if we don't cover everything we're inconsistent.
>>
>> People will invariably cargo-cult this kind of stuff absolutely
>> everywhere and then all your functions will have tons of dead
>> code to check their arguments.
>
> And that's a bad thing because... ?
>
> Also, are you really saying that checking that your arguments make sense
> is cargo-cult?

It's a powerful thing to be able to assume a NULL argument is always a
fatal programming error on the caller's side, and should oops and get
caught immediately. It's an assertion.

We're not talking about user input or anything like that here.

If you start checking for things that can't happen, and return errors
for them, you start gracefully handling things that don't have anything
graceful about them.

Having such checks in place trains people to think they *may* happen.

While it should fail fast and loud at the developer's first smoke test,
and get fixed then and there.


BR,
Jani.


>
> We're already doing it in some parts of KMS, so we have to be
> consistent, and the answer to "most drivers don't check the error"
> cannot be "let's just give on error checking then".
>
>> I'd prefer not to go there usually.
>>
>> Should we perhaps start to use the (arguably hideous)
>> - void f(struct foo *bar)
>> + void f(struct foo bar[static 1])
>> syntax to tell the compiler we don't accept NULL pointers?
>>
>> Hmm. Apparently that has the same problem as using any
>> other kind of array syntax in the prototype. That is,
>> the compiler demands to know the definition of 'struct foo'
>> even though we're passing in effectively a pointer. Sigh.
>
> Honestly, I don't care as long as it's something we can unit-test to
> make sure we make it consistent. We can't unit test a complete kernel
> crash.

--
Jani Nikula, Intel