Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
From: Bob Pearson <rpearsonhpe@gmail.com>
To: Leon Romanovsky <leon@kernel.org>
Cc: Zhu Yanjun <zyjzyj2000@gmail.com>,
	Jason Gunthorpe <jgg@nvidia.com>,
	RDMA mailing list <linux-rdma@vger.kernel.org>,
	Bob Pearson <rpearson@hpe.com>
Subject: Re: [PATCH for-next] RDMA/rxe: Fix coding error in rxe_rcv_mcast_pkt
Date: Thu, 28 Jan 2021 11:32:22 -0600	[thread overview]
Message-ID: <201d9976-674d-3022-46d2-104a6a8e2535@gmail.com> (raw)
In-Reply-To: <20210128125724.GD5097@unreal>

On 1/28/21 6:57 AM, Leon Romanovsky wrote:
> On Wed, Jan 27, 2021 at 10:23:53PM -0600, Bob Pearson wrote:
>> On 1/27/21 9:53 PM, Bob Pearson wrote:
>>> On 1/27/21 9:50 PM, Zhu Yanjun wrote:
>>>> On Thu, Jan 28, 2021 at 9:12 AM Bob Pearson <rpearsonhpe@gmail.com> wrote:
>>>>>
>>>>> rxe_rcv_mcast_pkt() in rxe_recv.c can leak SKBs in error path
>>>>> code. The loop over the QPs attached to a multicast group
>>>>> creates new cloned SKBs for all but the last QP in the list
>>>>> and passes the SKB and its clones to rxe_rcv_pkt() for further
>>>>> processing. Any QPs that do not pass some checks are skipped.
>>>>> If the last QP in the list fails the tests the SKB is leaked.
>>>>> This patch checks if the SKB for the last QP was used and if
>>>>> not frees it. Also removes a redundant loop invariant assignment.
>>>>>
>>>>> Fixes: 8700e3e7c4857 ("Soft RoCE driver")
>>>>> Fixes: 71abf20b28ff8 ("RDMA/rxe: Handle skb_clone() failure in rxe_recv.c")
>>>>> Signed-off-by: Bob Pearson <rpearson@hpe.com>
>>>>> ---
>>>>>  drivers/infiniband/sw/rxe/rxe_recv.c | 18 +++++++++++-------
>>>>>  1 file changed, 11 insertions(+), 7 deletions(-)
>>>>>
>>>>> diff --git a/drivers/infiniband/sw/rxe/rxe_recv.c b/drivers/infiniband/sw/rxe/rxe_recv.c
>>>>> index c9984a28eecc..57cc25e3b4ad 100644
>>>>> --- a/drivers/infiniband/sw/rxe/rxe_recv.c
>>>>> +++ b/drivers/infiniband/sw/rxe/rxe_recv.c
>>>>> @@ -252,7 +252,6 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb)
>>>>>
>>>>>         list_for_each_entry(mce, &mcg->qp_list, qp_list) {
>>>>>                 qp = mce->qp;
>>>>> -               pkt = SKB_TO_PKT(skb);
>>>>>
>>>>>                 /* validate qp for incoming packet */
>>>>>                 err = check_type_state(rxe, pkt, qp);
>>>>> @@ -264,12 +263,18 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb)
>>>>>                         continue;
>>>>>
>>>>>                 /* for all but the last qp create a new clone of the
>>>>> -                * skb and pass to the qp.
>>>>> +                * skb and pass to the qp. If an error occurs in the
>>>>> +                * checks for the last qp in the list we need to
>>>>> +                * free the skb since it hasn't been passed on to
>>>>> +                * rxe_rcv_pkt() which would free it later.
>>>>>                  */
>>>>> -               if (mce->qp_list.next != &mcg->qp_list)
>>>>> +               if (mce->qp_list.next != &mcg->qp_list) {
>>>>>                         per_qp_skb = skb_clone(skb, GFP_ATOMIC);
>>>>> -               else
>>>>> +               } else {
>>>>>                         per_qp_skb = skb;
>>>>> +                       /* show we have consumed the skb */
>>>>> +                       skb = NULL;
>>>>> +               }
>>>>>
>>>>>                 if (unlikely(!per_qp_skb))
>>>>>                         continue;
>>>>> @@ -284,10 +289,9 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb)
>>>>>
>>>>>         rxe_drop_ref(mcg);      /* drop ref from rxe_pool_get_key. */
>>>>>
>>>>> -       return;
>>>>> -
>>>>>  err1:
>>>>> -       kfree_skb(skb);
>>>>> +       if (skb)
>>>>> +               kfree_skb(skb);
>>>>
>>>> "if (skb)" is not needed here.
>>>>
>>>> The implemetation of kfree_skb:
>>>>
>>>> void kfree_skb(struct sk_buff *skb)
>>>> {
>>>> if (unlikely(!skb))
>>>> return;
>>>> if (likely(atomic_read(&skb->users) == 1))
>>>> smp_rmb();
>>>> else if (likely(!atomic_dec_and_test(&skb->users)))
>>>> return;
>>>> trace_kfree_skb(skb, __builtin_return_address(0));
>>>> __kfree_skb(skb);
>>>> }
>>>>
>>>> Zhu Yanjun
>>>>>  }
>>>>>
>>>>>  /**
>>>>> --
>>>>> 2.27.0
>>>>>
>>> Agreed but the reason I wrote that was to make it obvious why I set skb to NULL above. But as long as it is clear without it I can remove the test.
>>>
>> Actually I should have written
>>
>> if (unlikely(skb))
>> 	kfree_skb(skb);
> 
> Please don't put "if (a) kfree(a);" constructions unless you want to
> deal with daily flux of patches with attempt to remove "if".
> 
> Thanks
> 
>>
>>
Yes I get it. Thanks. -- bob

      reply	other threads:[~2021-01-28 17:33 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-28  1:12 [PATCH for-next] RDMA/rxe: Fix coding error in rxe_rcv_mcast_pkt Bob Pearson
2021-01-28  3:50 ` Zhu Yanjun
2021-01-28  3:53   ` Bob Pearson
2021-01-28  4:23     ` Bob Pearson
2021-01-28  5:00       ` Zhu Yanjun
2021-01-28 12:57       ` Leon Romanovsky
2021-01-28 17:32         ` Bob Pearson [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201d9976-674d-3022-46d2-104a6a8e2535@gmail.com \
    --to=rpearsonhpe@gmail.com \
    --cc=jgg@nvidia.com \
    --cc=leon@kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=rpearson@hpe.com \
    --cc=zyjzyj2000@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox