aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJaganath Kanakkassery <jaganath.k@samsung.com>2014-12-11 01:13:12 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-12-11 08:08:47 -0500
commit3ad675827f4a3623b7fc51ffe8fdb0347b3cbc53 (patch)
treef8952e7de7fc3ea48ae2f633059a441bc2dc55df /net
parent134d3b3550f050b9bec37111824452064d1ed928 (diff)
Bluetooth: Fix missing hci_dev_lock/unlock in mgmt req_complete()
mgmt_pending_remove() should be called with hci_dev_lock protection and currently the rule to take dev lock is that all mgmt req_complete functions should take dev lock. So this patch fixes the same in the missing functions Without this patch there is a chance of invalid memory access while accessing the mgmt_pending list like below bluetoothd: 392] [0] Backtrace: bluetoothd: 392] [0] [<c04ec770>] (pending_eir_or_class+0x0/0x68) from [<c04f1830>] (add_uuid+0x34/0x1c4) bluetoothd: 392] [0] [<c04f17fc>] (add_uuid+0x0/0x1c4) from [<c04f3cc4>] (mgmt_control+0x204/0x274) bluetoothd: 392] [0] [<c04f3ac0>] (mgmt_control+0x0/0x274) from [<c04f609c>] (hci_sock_sendmsg+0x80/0x308) bluetoothd: 392] [0] [<c04f601c>] (hci_sock_sendmsg+0x0/0x308) from [<c03d4d68>] (sock_aio_write+0x144/0x174) bluetoothd: 392] [0] r8:00000000 r7 7c1be90 r6 7c1be18 r5:00000017 r4 a90ea80 bluetoothd: 392] [0] [<c03d4c24>] (sock_aio_write+0x0/0x174) from [<c00e2d4c>] (do_sync_write+0xb0/0xe0) bluetoothd: 392] [0] [<c00e2c9c>] (do_sync_write+0x0/0xe0) from [<c00e371c>] (vfs_write+0x134/0x13c) bluetoothd: 392] [0] r8:00000000 r7 7c1bf70 r6:beeca5c8 r5:00000017 r4 7c05900 bluetoothd: 392] [0] [<c00e35e8>] (vfs_write+0x0/0x13c) from [<c00e3910>] (sys_write+0x44/0x70) bluetoothd: 392] [0] r8:00000000 r7:00000004 r6:00000017 r5:beeca5c8 r4 7c05900 bluetoothd: 392] [0] [<c00e38cc>] (sys_write+0x0/0x70) from [<c000e3c0>] (ret_fast_syscall+0x0/0x30) bluetoothd: 392] [0] r9 7c1a000 r8:c000e568 r6:400b5f10 r5:403896d8 r4:beeca604 bluetoothd: 392] [0] Code: e28cc00c e152000c 0a00000f e3a00001 (e1d210b8) bluetoothd: 392] [0] ---[ end trace 67b6ac67435864c4 ]--- bluetoothd: 392] [0] Kernel panic - not syncing: Fatal exception Signed-off-by: Jaganath Kanakkassery <jaganath.k@samsung.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_core.c2
-rw-r--r--net/bluetooth/mgmt.c18
2 files changed, 14 insertions, 6 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 96e7321c57a4..ecd7c01317bc 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3083,7 +3083,9 @@ static void hci_power_on(struct work_struct *work)
3083 3083
3084 err = hci_dev_do_open(hdev); 3084 err = hci_dev_do_open(hdev);
3085 if (err < 0) { 3085 if (err < 0) {
3086 hci_dev_lock(hdev);
3086 mgmt_set_powered_failed(hdev, err); 3087 mgmt_set_powered_failed(hdev, err);
3088 hci_dev_unlock(hdev);
3087 return; 3089 return;
3088 } 3090 }
3089 3091
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 44b20deb6038..16ac03730f4d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2199,12 +2199,14 @@ static void le_enable_complete(struct hci_dev *hdev, u8 status)
2199{ 2199{
2200 struct cmd_lookup match = { NULL, hdev }; 2200 struct cmd_lookup match = { NULL, hdev };
2201 2201
2202 hci_dev_lock(hdev);
2203
2202 if (status) { 2204 if (status) {
2203 u8 mgmt_err = mgmt_status(status); 2205 u8 mgmt_err = mgmt_status(status);
2204 2206
2205 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp, 2207 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp,
2206 &mgmt_err); 2208 &mgmt_err);
2207 return; 2209 goto unlock;
2208 } 2210 }
2209 2211
2210 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match); 2212 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match);
@@ -2222,17 +2224,16 @@ static void le_enable_complete(struct hci_dev *hdev, u8 status)
2222 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 2224 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
2223 struct hci_request req; 2225 struct hci_request req;
2224 2226
2225 hci_dev_lock(hdev);
2226
2227 hci_req_init(&req, hdev); 2227 hci_req_init(&req, hdev);
2228 update_adv_data(&req); 2228 update_adv_data(&req);
2229 update_scan_rsp_data(&req); 2229 update_scan_rsp_data(&req);
2230 hci_req_run(&req, NULL); 2230 hci_req_run(&req, NULL);
2231 2231
2232 hci_update_background_scan(hdev); 2232 hci_update_background_scan(hdev);
2233
2234 hci_dev_unlock(hdev);
2235 } 2233 }
2234
2235unlock:
2236 hci_dev_unlock(hdev);
2236} 2237}
2237 2238
2238static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) 2239static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
@@ -4279,12 +4280,14 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status)
4279{ 4280{
4280 struct cmd_lookup match = { NULL, hdev }; 4281 struct cmd_lookup match = { NULL, hdev };
4281 4282
4283 hci_dev_lock(hdev);
4284
4282 if (status) { 4285 if (status) {
4283 u8 mgmt_err = mgmt_status(status); 4286 u8 mgmt_err = mgmt_status(status);
4284 4287
4285 mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, 4288 mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev,
4286 cmd_status_rsp, &mgmt_err); 4289 cmd_status_rsp, &mgmt_err);
4287 return; 4290 goto unlock;
4288 } 4291 }
4289 4292
4290 if (test_bit(HCI_LE_ADV, &hdev->dev_flags)) 4293 if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
@@ -4299,6 +4302,9 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status)
4299 4302
4300 if (match.sk) 4303 if (match.sk)
4301 sock_put(match.sk); 4304 sock_put(match.sk);
4305
4306unlock:
4307 hci_dev_unlock(hdev);
4302} 4308}
4303 4309
4304static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, 4310static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,