Re: [GIT PULL] Driver core fix for 4.5-rc4

From: Linus Torvalds
Date: Sun Feb 14 2016 - 15:58:17 EST


On Sun, Feb 14, 2016 at 11:02 AM, Greg KH <gregkh@xxxxxxxxxxxxxxxxxxx> wrote:
>
> Here is one driver core, well klist, fix for 4.5-rc4. It fixes a
> problem found in the scsi device list traversal that probably also could
> be triggered by other subsystems.

So I pulled this, but quite frankly, the fix smells bad to me.

If the n_ref kref can go down to zero at any time, how is that "struct
klist_node *n" safe to ever even touch in the caller?

IOW, what is it that protects that klist_node from not having entirely
been released, and any access to the kref might be a use-after-free
(and the use of "kref_get_unless_zero()" just hides the problem).

So it smells to me like if the kref can go down to zero, the caller is
basically passing in a random pointer.

Please make me feel better about my pull. I need a virtual hug.

(Also, rather than assigning i_dur twice like this:

+ i->i_cur = NULL;
+ if (n && kref_get_unless_zero(&n->n_ref))
+ i->i_cur = n;

I think it would have been cleaner to [in]validate "n" first (perhaps
with a comment about _why_ that is needed yet safe):

+ if (n && !kref_get_unless_zero(&n->n_ref))
+ n = NULL;

and then just do a simple:

+ i->i_cur = n;

afterwards).

But I care less about that small syntactic issue than I care about
understanding why it's safe to pass around a klist_node that might not
exist any more.

Linus