lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 14 Jul 2022 17:37:48 +0900
From:   Jeongik Cha <jeongik@...gle.com>
To:     Johannes Berg <johannes@...solutions.net>,
        Kalle Valo <kvalo@...nel.org>,
        "David S. Miller" <davem@...emloft.net>,
        Eric Dumazet <edumazet@...gle.com>,
        Jakub Kicinski <kuba@...nel.org>,
        Paolo Abeni <pabeni@...hat.com>
Cc:     adelva@...gle.com, kernel-team@...roid.com, jaeman@...gle.com,
        linux-wireless@...r.kernel.org, netdev@...r.kernel.org,
        linux-kernel@...r.kernel.org
Subject: Re: [PATCH v1] wifi: mac80211_hwsim: fix race condition in pending packet

On Mon, Jul 4, 2022 at 5:44 PM Jeongik Cha <jeongik@...gle.com> wrote:
>
> A pending packet uses a cookie as an unique key, but it can be duplicated
> because it didn't use atomic operators.
>
> And also, a pending packet can be null in hwsim_tx_info_frame_received_nl
> due to race condition with mac80211_hwsim_stop.
>
> For this,
>  * Use an atomic type and operator for a cookie
>  * Add a lock around the loop for pending packets
>
> Signed-off-by: Jeongik Cha <jeongik@...gle.com>
> ---
>  drivers/net/wireless/mac80211_hwsim.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
> index c5bb97b381cf..ea006248ffcd 100644
> --- a/drivers/net/wireless/mac80211_hwsim.c
> +++ b/drivers/net/wireless/mac80211_hwsim.c
> @@ -687,7 +687,7 @@ struct mac80211_hwsim_data {
>         bool ps_poll_pending;
>         struct dentry *debugfs;
>
> -       uintptr_t pending_cookie;
> +       atomic64_t pending_cookie;
>         struct sk_buff_head pending;    /* packets pending */
>         /*
>          * Only radios in the same group can communicate together (the
> @@ -1358,7 +1358,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
>         int i;
>         struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES];
>         struct hwsim_tx_rate_flag tx_attempts_flags[IEEE80211_TX_MAX_RATES];
> -       uintptr_t cookie;
> +       u64 cookie;
>
>         if (data->ps != PS_DISABLED)
>                 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
> @@ -1427,8 +1427,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
>                 goto nla_put_failure;
>
>         /* We create a cookie to identify this skb */
> -       data->pending_cookie++;
> -       cookie = data->pending_cookie;
> +       cookie = (u64)atomic64_inc_return(&data->pending_cookie);
>         info->rate_driver_data[0] = (void *)cookie;
>         if (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD))
>                 goto nla_put_failure;
> @@ -4178,6 +4177,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
>         const u8 *src;
>         unsigned int hwsim_flags;
>         int i;
> +       unsigned long flags;
>         bool found = false;
>
>         if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
> @@ -4205,18 +4205,20 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
>         }
>
>         /* look for the skb matching the cookie passed back from user */
> +       spin_lock_irqsave(&data2->pending.lock, flags);
>         skb_queue_walk_safe(&data2->pending, skb, tmp) {
>                 u64 skb_cookie;
>
>                 txi = IEEE80211_SKB_CB(skb);
> -               skb_cookie = (u64)(uintptr_t)txi->rate_driver_data[0];
> +               skb_cookie = (u64)txi->rate_driver_data[0];
>
>                 if (skb_cookie == ret_skb_cookie) {
> -                       skb_unlink(skb, &data2->pending);
> +                       __skb_unlink(skb, &data2->pending);
>                         found = true;
>                         break;
>                 }
>         }
> +       spin_unlock_irqrestore(&data2->pending.lock, flags);
>
>         /* not found */
>         if (!found)
> --
> 2.37.0.rc0.161.g10f37bed90-goog
>

Hello Johannes!

It fixes kernel panics during a long test which uses mac80211_hwsim
driver. So I think it would be beneficial if we could merge this into
LTS branches. Could you share your opinion?

Thanks
Jeongik

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ