Bluetooth: Fix issue with RFCOMM getsockopt operation

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Fri Nov 22 17:59:06 EST 2013


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=60c7a3c9c77239d5a7430c42a2c796881716cca1
Commit:     60c7a3c9c77239d5a7430c42a2c796881716cca1
Parent:     8ce9beac4661f576ea0d518b9f086bb52a171a37
Author:     Marcel Holtmann <marcel at holtmann.org>
AuthorDate: Sat Nov 2 02:36:31 2013 -0700
Committer:  Gustavo Padovan <gustavo.padovan at collabora.co.uk>
CommitDate: Wed Nov 13 11:36:52 2013 -0200

    Bluetooth: Fix issue with RFCOMM getsockopt operation
    
    The commit 94a86df01082557e2de45865e538d7fb6c46231c seem to have
    uncovered a long standing bug that did not trigger so far.
    
    BUG: unable to handle kernel paging request at 00000009dd503502
    IP: [<ffffffff815b1868>] rfcomm_sock_getsockopt+0x128/0x200
    PGD 0
    Oops: 0000 [#1] SMP
    Modules linked in: ath5k ath mac80211 cfg80211
    CPU: 2 PID: 1459 Comm: bluetoothd Not tainted 3.11.0-133163-gcebd830 #2
    Hardware name: System manufacturer System Product Name/P6T DELUXE V2, BIOS
    1202    12/22/2010
    task: ffff8803304106a0 ti: ffff88033046a000 task.ti: ffff88033046a000
    RIP: 0010:[<ffffffff815b1868>]  [<ffffffff815b1868>]
    rfcomm_sock_getsockopt+0x128/0x200
    RSP: 0018:ffff88033046bed8  EFLAGS: 00010246
    RAX: 00000009dd503502 RBX: 0000000000000003 RCX: 00007fffa2ed5548
    RDX: 0000000000000003 RSI: 0000000000000012 RDI: ffff88032fd37480
    RBP: ffff88033046bf28 R08: 00007fffa2ed554c R09: ffff88032f5707d8
    R10: 00007fffa2ed5548 R11: 0000000000000202 R12: ffff880330bbd000
    R13: 00007fffa2ed5548 R14: 0000000000000003 R15: 00007fffa2ed554c
    FS:  00007fc44cfac700(0000) GS:ffff88033fc80000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00000009dd503502 CR3: 00000003304c2000 CR4: 00000000000007e0
    Stack:
    ffff88033046bf28 ffffffff815b0f2f ffff88033046bf18 0002ffff81105ef6
    0000000600000000 ffff88032fd37480 0000000000000012 00007fffa2ed5548
    0000000000000003 00007fffa2ed554c ffff88033046bf78 ffffffff814c0380
    Call Trace:
    [<ffffffff815b0f2f>] ? rfcomm_sock_setsockopt+0x5f/0x190
    [<ffffffff814c0380>] SyS_getsockopt+0x60/0xb0
    [<ffffffff815e0852>] system_call_fastpath+0x16/0x1b
    Code: 02 00 00 00 0f 47 d0 4c 89 ef e8 74 13 cd ff 83 f8 01 19 c9 f7 d1 83 e1
    f2 e9 4b ff ff ff 0f 1f 44 00 00 49 8b 84 24 70 02 00 00 <4c> 8b 30 4c 89 c0 e8
    2d 19 cd ff 85 c0 49 89 d7 b9 f2 ff ff ff
    RIP  [<ffffffff815b1868>] rfcomm_sock_getsockopt+0x128/0x200
    RSP <ffff88033046bed8>
    CR2: 00000009dd503502
    
    It triggers in the following segment of the code:
    
    0x1313 is in rfcomm_sock_getsockopt (net/bluetooth/rfcomm/sock.c:743).
    738
    739	static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
    740	{
    741		struct sock *sk = sock->sk;
    742		struct rfcomm_conninfo cinfo;
    743		struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
    744		int len, err = 0;
    745		u32 opt;
    746
    747		BT_DBG("sk %p", sk);
    
    The l2cap_pi(sk) is wrong here since it should have been rfcomm_pi(sk),
    but that socket of course does not contain the low-level connection
    details requested here.
    
    Tracking down the actual offending commit, it seems that this has been
    introduced when doing some L2CAP refactoring:
    
    commit 8c1d787be4b62d2d1b6f04953eca4bcf7c839d44
    Author: Gustavo F. Padovan <padovan at profusion.mobi>
    Date:   Wed Apr 13 20:23:55 2011 -0300
    
    @@ -743,6 +743,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
            struct sock *sk = sock->sk;
            struct sock *l2cap_sk;
            struct rfcomm_conninfo cinfo;
    +       struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
            int len, err = 0;
            u32 opt;
    
    @@ -787,8 +788,8 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
    
                    l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
    
    -               cinfo.hci_handle = l2cap_pi(l2cap_sk)->conn->hcon->handle;
    -               memcpy(cinfo.dev_class, l2cap_pi(l2cap_sk)->conn->hcon->dev_class, 3);
    +               cinfo.hci_handle = conn->hcon->handle;
    +               memcpy(cinfo.dev_class, conn->hcon->dev_class, 3);
    
    The l2cap_sk got accidentally mixed into the sk (which is RFCOMM) and
    now causing a problem within getsocketopt() system call. To fix this,
    just re-introduce l2cap_sk and make sure the right socket is used for
    the low-level connection details.
    
    Reported-by: Fabio Rossi <rossi.f at inwind.it>
    Reported-by: Janusz Dziedzic <janusz.dziedzic at gmail.com>
    Tested-by: Janusz Dziedzic <janusz.dziedzic at gmail.com>
    Signed-off-by: Marcel Holtmann <marcel at holtmann.org>
    Signed-off-by: Johan Hedberg <johan.hedberg at intel.com>
---
 net/bluetooth/rfcomm/sock.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 30b3721..7096cfe 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -732,8 +732,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
 static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
 {
 	struct sock *sk = sock->sk;
+	struct sock *l2cap_sk;
+	struct l2cap_conn *conn;
 	struct rfcomm_conninfo cinfo;
-	struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
 	int len, err = 0;
 	u32 opt;
 
@@ -776,6 +777,9 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
 			break;
 		}
 
+		l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
+		conn = l2cap_pi(l2cap_sk)->chan->conn;
+
 		memset(&cinfo, 0, sizeof(cinfo));
 		cinfo.hci_handle = conn->hcon->handle;
 		memcpy(cinfo.dev_class, conn->hcon->dev_class, 3);



More information about the linux-mtd-cvs mailing list