2021-07-25 17:53:19

by Harshvardhan Jha

[permalink] [raw]
Subject: [PATCH] 9p/xen: Fix end of loop tests for list_for_each_entry

The list_for_each_entry() iterator, "priv" in this code, can never be
NULL so the warning would never be printed.

Signed-off-by: Harshvardhan Jha <[email protected]>
---
From static analysis. Not tested.
---
net/9p/trans_xen.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
index f4fea28e05da..3ec1a51a6944 100644
--- a/net/9p/trans_xen.c
+++ b/net/9p/trans_xen.c
@@ -138,7 +138,7 @@ static bool p9_xen_write_todo(struct xen_9pfs_dataring *ring, RING_IDX size)

static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
{
- struct xen_9pfs_front_priv *priv = NULL;
+ struct xen_9pfs_front_priv *priv;
RING_IDX cons, prod, masked_cons, masked_prod;
unsigned long flags;
u32 size = p9_req->tc.size;
@@ -151,7 +151,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
break;
}
read_unlock(&xen_9pfs_lock);
- if (!priv || priv->client != client)
+ if (list_entry_is_head(priv, &xen_9pfs_devs, list))
return -EINVAL;

num = p9_req->tc.tag % priv->num_rings;
--
2.32.0


2021-07-25 20:50:05

by Dominique Martinet

[permalink] [raw]
Subject: Re: [PATCH] 9p/xen: Fix end of loop tests for list_for_each_entry

Harshvardhan Jha wrote on Sun, Jul 25, 2021 at 11:21:03PM +0530:
> The list_for_each_entry() iterator, "priv" in this code, can never be
> NULL so the warning would never be printed.

hm? priv won't be NULL but priv->client won't be client, so it will
return -EINVAL alright in practice?

This does fix an invalid read after the list head, so there's a real
bug, but the commit message needs fixing.

>
> Signed-off-by: Harshvardhan Jha <[email protected]>
> ---
> From static analysis. Not tested.

+Stefano in To - I also can't test xen right now :/
This looks functional to me but if you have a bit of time to spare just
a mount test can't hurt.

> ---
> net/9p/trans_xen.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
> index f4fea28e05da..3ec1a51a6944 100644
> --- a/net/9p/trans_xen.c
> +++ b/net/9p/trans_xen.c
> @@ -138,7 +138,7 @@ static bool p9_xen_write_todo(struct xen_9pfs_dataring *ring, RING_IDX size)
>
> static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
> {
> - struct xen_9pfs_front_priv *priv = NULL;
> + struct xen_9pfs_front_priv *priv;
> RING_IDX cons, prod, masked_cons, masked_prod;
> unsigned long flags;
> u32 size = p9_req->tc.size;
> @@ -151,7 +151,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
> break;
> }
> read_unlock(&xen_9pfs_lock);
> - if (!priv || priv->client != client)
> + if (list_entry_is_head(priv, &xen_9pfs_devs, list))
> return -EINVAL;
>
> num = p9_req->tc.tag % priv->num_rings;
--
Dominique

2021-07-26 21:31:42

by Stefano Stabellini

[permalink] [raw]
Subject: Re: [PATCH] 9p/xen: Fix end of loop tests for list_for_each_entry

On Mon, 26 Jul 2021, [email protected] wrote:
> Harshvardhan Jha wrote on Sun, Jul 25, 2021 at 11:21:03PM +0530:
> > The list_for_each_entry() iterator, "priv" in this code, can never be
> > NULL so the warning would never be printed.
>
> hm? priv won't be NULL but priv->client won't be client, so it will
> return -EINVAL alright in practice?
>
> This does fix an invalid read after the list head, so there's a real
> bug, but the commit message needs fixing.

Agreed


> > Signed-off-by: Harshvardhan Jha <[email protected]>
> > ---
> > From static analysis. Not tested.
>
> +Stefano in To - I also can't test xen right now :/
> This looks functional to me but if you have a bit of time to spare just
> a mount test can't hurt.

Yes, I did test it successfully. Aside from the commit messaged to be
reworded:

Reviewed-by: Stefano Stabellini <[email protected]>
Tested-by: Stefano Stabellini <[email protected]>


> > ---
> > net/9p/trans_xen.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
> > index f4fea28e05da..3ec1a51a6944 100644
> > --- a/net/9p/trans_xen.c
> > +++ b/net/9p/trans_xen.c
> > @@ -138,7 +138,7 @@ static bool p9_xen_write_todo(struct xen_9pfs_dataring *ring, RING_IDX size)
> >
> > static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
> > {
> > - struct xen_9pfs_front_priv *priv = NULL;
> > + struct xen_9pfs_front_priv *priv;
> > RING_IDX cons, prod, masked_cons, masked_prod;
> > unsigned long flags;
> > u32 size = p9_req->tc.size;
> > @@ -151,7 +151,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
> > break;
> > }
> > read_unlock(&xen_9pfs_lock);
> > - if (!priv || priv->client != client)
> > + if (list_entry_is_head(priv, &xen_9pfs_devs, list))
> > return -EINVAL;
> >
> > num = p9_req->tc.tag % priv->num_rings;

2021-07-26 22:26:37

by Harshvardhan Jha

[permalink] [raw]
Subject: Re: [External] : Re: [PATCH] 9p/xen: Fix end of loop tests for list_for_each_entry



On 27/07/21 3:00 am, Stefano Stabellini wrote:
> On Mon, 26 Jul 2021, [email protected] wrote:
>> Harshvardhan Jha wrote on Sun, Jul 25, 2021 at 11:21:03PM +0530:
>>> The list_for_each_entry() iterator, "priv" in this code, can never be
>>> NULL so the warning would never be printed.
>>
>> hm? priv won't be NULL but priv->client won't be client, so it will
>> return -EINVAL alright in practice?
>>
>> This does fix an invalid read after the list head, so there's a real
>> bug, but the commit message needs fixing.
>
> Agreed
>
>
>>> Signed-off-by: Harshvardhan Jha <[email protected]>
>>> ---
>>> From static analysis. Not tested.
>>
>> +Stefano in To - I also can't test xen right now :/
>> This looks functional to me but if you have a bit of time to spare just
>> a mount test can't hurt.
>
> Yes, I did test it successfully. Aside from the commit messaged to be
> reworded:
How's this?
===========================BEGIN========================================
9p/xen: Fix end of loop tests for list_for_each_entry

This patch addresses the following problems:
- priv can never be NULL, so this part of the check is useless
- if the loop ran through the whole list, priv->client is invalid and
it is more appropriate and sufficient to check for the end of
list_for_each_entry loop condition.

Signed-off-by: Harshvardhan Jha <[email protected]>
---
From static analysis. Not tested.
===========================END==========================================
>
> Reviewed-by: Stefano Stabellini <[email protected]>
> Tested-by: Stefano Stabellini <[email protected]>
>
>
>>> ---
>>> net/9p/trans_xen.c | 4 ++--
>>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
>>> index f4fea28e05da..3ec1a51a6944 100644
>>> --- a/net/9p/trans_xen.c
>>> +++ b/net/9p/trans_xen.c
>>> @@ -138,7 +138,7 @@ static bool p9_xen_write_todo(struct xen_9pfs_dataring *ring, RING_IDX size)
>>>
>>> static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
>>> {
>>> - struct xen_9pfs_front_priv *priv = NULL;
>>> + struct xen_9pfs_front_priv *priv;
>>> RING_IDX cons, prod, masked_cons, masked_prod;
>>> unsigned long flags;
>>> u32 size = p9_req->tc.size;
>>> @@ -151,7 +151,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
>>> break;
>>> }
>>> read_unlock(&xen_9pfs_lock);
>>> - if (!priv || priv->client != client)
>>> + if (list_entry_is_head(priv, &xen_9pfs_devs, list))
>>> return -EINVAL;
>>>
>>> num = p9_req->tc.tag % priv->num_rings;

2021-07-26 23:56:14

by Stefano Stabellini

[permalink] [raw]
Subject: Re: [External] : Re: [PATCH] 9p/xen: Fix end of loop tests for list_for_each_entry

On Tue, 27 Jul 2021, Harshvardhan Jha wrote:
> On 27/07/21 3:00 am, Stefano Stabellini wrote:
> > On Mon, 26 Jul 2021, [email protected] wrote:
> > > Harshvardhan Jha wrote on Sun, Jul 25, 2021 at 11:21:03PM +0530:
> > > > The list_for_each_entry() iterator, "priv" in this code, can never be
> > > > NULL so the warning would never be printed.
> > >
> > > hm? priv won't be NULL but priv->client won't be client, so it will
> > > return -EINVAL alright in practice?
> > >
> > > This does fix an invalid read after the list head, so there's a real
> > > bug, but the commit message needs fixing.
> >
> > Agreed
> >
> >
> > > > Signed-off-by: Harshvardhan Jha <[email protected]>
> > > > ---
> > > > From static analysis. Not tested.
> > >
> > > +Stefano in To - I also can't test xen right now :/
> > > This looks functional to me but if you have a bit of time to spare just
> > > a mount test can't hurt.
> >
> > Yes, I did test it successfully. Aside from the commit messaged to be
> > reworded:
> How's this?
> ===========================BEGIN========================================
> 9p/xen: Fix end of loop tests for list_for_each_entry
>
> This patch addresses the following problems:
> - priv can never be NULL, so this part of the check is useless
> - if the loop ran through the whole list, priv->client is invalid and
> it is more appropriate and sufficient to check for the end of
> list_for_each_entry loop condition.
>
> Signed-off-by: Harshvardhan Jha <[email protected]>

That's fine


> ---
> From static analysis. Not tested.
> ===========================END==========================================
> >
> > Reviewed-by: Stefano Stabellini <[email protected]>
> > Tested-by: Stefano Stabellini <[email protected]>
> >
> >
> > > > ---
> > > > net/9p/trans_xen.c | 4 ++--
> > > > 1 file changed, 2 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
> > > > index f4fea28e05da..3ec1a51a6944 100644
> > > > --- a/net/9p/trans_xen.c
> > > > +++ b/net/9p/trans_xen.c
> > > > @@ -138,7 +138,7 @@ static bool p9_xen_write_todo(struct
> > > > xen_9pfs_dataring *ring, RING_IDX size)
> > > > static int p9_xen_request(struct p9_client *client, struct p9_req_t
> > > > *p9_req)
> > > > {
> > > > - struct xen_9pfs_front_priv *priv = NULL;
> > > > + struct xen_9pfs_front_priv *priv;
> > > > RING_IDX cons, prod, masked_cons, masked_prod;
> > > > unsigned long flags;
> > > > u32 size = p9_req->tc.size;
> > > > @@ -151,7 +151,7 @@ static int p9_xen_request(struct p9_client *client,
> > > > struct p9_req_t *p9_req)
> > > > break;
> > > > }
> > > > read_unlock(&xen_9pfs_lock);
> > > > - if (!priv || priv->client != client)
> > > > + if (list_entry_is_head(priv, &xen_9pfs_devs, list))
> > > > return -EINVAL;
> > > > num = p9_req->tc.tag % priv->num_rings;
>

2021-07-27 00:02:08

by Dominique Martinet

[permalink] [raw]
Subject: Re: [External] : Re: [PATCH] 9p/xen: Fix end of loop tests for list_for_each_entry

Stefano Stabellini wrote on Mon, Jul 26, 2021 at 04:54:29PM -0700:
> > > Yes, I did test it successfully. Aside from the commit messaged to be
> > > reworded:
> > How's this?
> > ===========================BEGIN========================================
> > 9p/xen: Fix end of loop tests for list_for_each_entry
> >
> > This patch addresses the following problems:
> > - priv can never be NULL, so this part of the check is useless
> > - if the loop ran through the whole list, priv->client is invalid and
> > it is more appropriate and sufficient to check for the end of
> > list_for_each_entry loop condition.
> >
> > Signed-off-by: Harshvardhan Jha <[email protected]>

Will take the patch with this text as commit message later tonight


> > > Reviewed-by: Stefano Stabellini <[email protected]>
> > > Tested-by: Stefano Stabellini <[email protected]>

Thanks for the test!

--
Dominique

2021-07-27 00:03:48

by Harshvardhan Jha

[permalink] [raw]
Subject: Re: [External] : Re: [PATCH] 9p/xen: Fix end of loop tests for list_for_each_entry



On 27/07/21 5:29 am, [email protected] wrote:
> Stefano Stabellini wrote on Mon, Jul 26, 2021 at 04:54:29PM -0700:
>>>> Yes, I did test it successfully. Aside from the commit messaged to be
>>>> reworded:
>>> How's this?
>>> ===========================BEGIN========================================
>>> 9p/xen: Fix end of loop tests for list_for_each_entry
>>>
>>> This patch addresses the following problems:
>>> - priv can never be NULL, so this part of the check is useless
>>> - if the loop ran through the whole list, priv->client is invalid and
>>> it is more appropriate and sufficient to check for the end of
>>> list_for_each_entry loop condition.
>>>
>>> Signed-off-by: Harshvardhan Jha <[email protected]>
>
> Will take the patch with this text as commit message later tonight
If you want I can resend the patch with this commit message
>
>
>>>> Reviewed-by: Stefano Stabellini <[email protected]>
>>>> Tested-by: Stefano Stabellini <[email protected]>
>
> Thanks for the test!
>

2021-07-27 00:10:28

by Harshvardhan Jha

[permalink] [raw]
Subject: [PATCH] 9p/xen: Fix end of loop tests for list_for_each_entry

This patch addresses the following problems:
- priv can never be NULL, so this part of the check is useless
- if the loop ran through the whole list, priv->client is invalid and
it is more appropriate and sufficient to check for the end of
list_for_each_entry loop condition.

Signed-off-by: Harshvardhan Jha <[email protected]>
---
net/9p/trans_xen.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
index f4fea28e05da..3ec1a51a6944 100644
--- a/net/9p/trans_xen.c
+++ b/net/9p/trans_xen.c
@@ -138,7 +138,7 @@ static bool p9_xen_write_todo(struct xen_9pfs_dataring *ring, RING_IDX size)

static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
{
- struct xen_9pfs_front_priv *priv = NULL;
+ struct xen_9pfs_front_priv *priv;
RING_IDX cons, prod, masked_cons, masked_prod;
unsigned long flags;
u32 size = p9_req->tc.size;
@@ -151,7 +151,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
break;
}
read_unlock(&xen_9pfs_lock);
- if (!priv || priv->client != client)
+ if (list_entry_is_head(priv, &xen_9pfs_devs, list))
return -EINVAL;

num = p9_req->tc.tag % priv->num_rings;
--
2.32.0

2021-07-27 14:11:29

by Dominique Martinet

[permalink] [raw]
Subject: Re: [PATCH] 9p/xen: Fix end of loop tests for list_for_each_entry

Harshvardhan Jha wrote on Tue, Jul 27, 2021 at 05:37:10AM +0530:
> This patch addresses the following problems:
> - priv can never be NULL, so this part of the check is useless
> - if the loop ran through the whole list, priv->client is invalid and
> it is more appropriate and sufficient to check for the end of
> list_for_each_entry loop condition.
>
> Signed-off-by: Harshvardhan Jha <[email protected]>

Alright, taken and pushed to linux-next.
I'll send it to Linus next week-ish

FWIW, this isn't a merge so messing with the commit message is fine and
you didn't really need to resend (either is fine), but if you do for
next time please tag in the subject it's a v2 (e.g. [PATCH v2]),
optionally with a changelog below the three dashes that won't be
included in the final commit message (not really useful here as we discussed
the change just before, but for bigger subsystems it can help)

--
Dominique