Re: [PATCH] work around for l2cap NULL dereference in l2cap_conn_start

From: Andrei Emeltchenko
Date: Thu Mar 24 2011 - 11:37:46 EST


Hi Gustavo,

On Mon, Feb 28, 2011 at 7:03 AM, David Fries <david@xxxxxxxxx> wrote:
> On Sun, Feb 27, 2011 at 04:15:45PM -0300, Gustavo F. Padovan wrote:
>> I pushed the following patch to bluetooth-2.6 tree. It should fix the problem
>> by avoiding connections to be accepted before a L2CAP info response comes:
>
> Is
> git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git
> the bluetooth-2.6 tree you mentioned?  I don't see your patch there.
> As a side note, the inline patch in your e-mail has the tabs replaced by
> spaces, once I changed them, it applied cleanly.
>
> I first reverted to the base N900 kernel-power-2.6.28 46 (none of my
> changes or debugging), it crashed as expected.  I then applied your
> patch 743400e0, and it still crashed.

the same for me. Your patch with adding BT_CONNECT2 check seems
have no effect since sk_state == BT_CONNECT2 for my case.

I've posted series of patches which fixes the issue but I believe it is better
to keep check for parent.

Search my patches by "[RFCv1 0/3] Set of patches fixing kernel crash"

Regards,
Andrei

> I added back the
> l2cap_conn_start parent check and some debugging in af_bluetooth.c
> dmesg debug output and patches follow.
>
> I haven't at all looked into the bluetooth protocol, but what connect
> sequence difference does it make if I power on the bluetooth headset
> and press play on the headset before it automatically pairs with the
> N900, vs power on bluetooth headset, wait for it to pair then press
> play?  I ask this partly because I'm curiouse, but mostly how I
> trigger the bug.  This is with pulse audio running, but no
> applications playing audio or responding to a play event from the
> headset.
>
> [  443.424560] bt_accept_dequeue, parent cd54ba00 newsock c81f0180, defer_setup && BT_CONNECT2
> [  443.427368] avoided crash in l2cap_conn_start sk c6d3f600 result 1 status 2
> [  443.518463] bt_accept_dequeue, parent cdee9c00 newsock c81f0000, BT_CONNECTED
> [  443.729736] bt_accept_dequeue, parent cd54be00 newsock c81f0000, BT_CONNECTED
> [  443.813537] bt_accept_dequeue, parent cd54b600 newsock c81f0180, defer_setup && BT_CONNECT2
>
> From 5bc80fafac43b6698e271f1246cb24e596bf2ef1 Mon Sep 17 00:00:00 2001
> From: David Fries <david@xxxxxxxxx>
> Date: Sun, 6 Feb 2011 14:34:49 -0600
> Subject: [PATCH 1/2] work around for l2cap NULL dereference in l2cap_conn_start print sk
>
> ---
>  net/bluetooth/l2cap.c |   11 ++++++++++-
>  1 files changed, 10 insertions(+), 1 deletions(-)
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index fda7741..ff05f51 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -400,7 +400,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
>                                        struct sock *parent = bt_sk(sk)->parent;
>                                        rsp.result = cpu_to_le16(L2CAP_CR_PEND);
>                                        rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
> -                                       parent->sk_data_ready(parent, 0);
> +                                       if(!parent) {
> +                                               printk(KERN_DEBUG "avoided "
> +                                                       "crash in %s sk %p "
> +                                                       "result %d status %d\n",
> +                                                       __func__, sk,
> +                                                       rsp.result, rsp.status);
> +                                       } else {
> +                                               parent->sk_data_ready(parent,
> +                                                       0);
> +                                       }
>
>                                } else {
>                                        sk->sk_state = BT_CONFIG;
> --
> 1.7.2.3
>
>
> From 42b9a6ef68a1cd0ef025b826afcfb0ef23342fe5 Mon Sep 17 00:00:00 2001
> From: David Fries <david@xxxxxxxxx>
> Date: Sun, 27 Feb 2011 21:50:14 -0600
> Subject: [PATCH 2/2] af_bluetooth.c debug
>
> ---
>  net/bluetooth/af_bluetooth.c |   12 ++++++++++++
>  1 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
> index 8e910f1..57cd360 100644
> --- a/net/bluetooth/af_bluetooth.c
> +++ b/net/bluetooth/af_bluetooth.c
> @@ -211,6 +211,18 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
>                        continue;
>                }
>
> +               if (bt_sk(parent)->defer_setup && sk->sk_state == BT_CONNECT2)
> +                       printk("%s, parent %p newsock %p, "
> +                               "defer_setup && BT_CONNECT2\n", __func__,
> +                               parent, newsock);
> +               if (sk->sk_state == BT_CONNECTED)
> +                       printk("%s, parent %p newsock %p, "
> +                               "BT_CONNECTED\n", __func__,
> +                               parent, newsock);
> +               if (!newsock)
> +                       printk("%s, parent %p newsock %p, "
> +                               "!newsock\n", __func__,
> +                               parent, newsock);
>                if ((bt_sk(parent)->defer_setup && sk->sk_state == BT_CONNECT2)
>                                || sk->sk_state == BT_CONNECTED || !newsock) {
>                        bt_accept_unlink(sk);
> --
> 1.7.2.3
>
>
>> commit 743400e01a33779f93b79c84a1b0d1a2d27338c8
>> Author: Gustavo F. Padovan <padovan@xxxxxxxxxxxxxx>
>> Date:   Sun Feb 27 16:05:07 2011 -0300
>>
>>     Bluetooth: Don't accept l2cap connection before info_rsp
>>
>>     When using defer_setup accepting a connection before receive the L2CAP
>>     Info Response for the connection lead us to a crash in l2cap_conn_start(.
>>
>>     Reported-by: David Fries <david@xxxxxxxxx>
>>     Reported-by: Liang Bao <tim.bao@xxxxxxxxx>
>>     Signed-off-by: Gustavo F. Padovan <padovan@xxxxxxxxxxxxxx>
>>
>> diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
>> index c4cf3f5..a8ca42b 100644
>> --- a/net/bluetooth/af_bluetooth.c
>> +++ b/net/bluetooth/af_bluetooth.c
>> @@ -211,8 +211,8 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
>>                         continue;
>>                 }
>>
>> -               if (sk->sk_state == BT_CONNECTED || !newsock ||
>> -                                               bt_sk(parent)->defer_setup) {
>> +               if ((bt_sk(parent)->defer_setup && sk->sk_state == BT_CONNECT2)
>> +                               || sk->sk_state == BT_CONNECTED || !newsock) {
>>                         bt_accept_unlink(sk);
>>                         if (newsock)
>>                                 sock_graft(sk, newsock);
>>
>>
>> --
>> Gustavo F. Padovan
>> http://profusion.mobi
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
> --
> David Fries <david@xxxxxxxxx>
> http://fries.net/~david/ (PGP encryption key available)
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/