Skip to content

Commit 09b6c08

Browse files
mkarhumaagregkh
authored andcommitted
Bluetooth: Fix debugfs NULL pointer dereference
[ Upstream commit 30d65e0 ] Fix crash caused by NULL pointer dereference when debugfs functions le_max_key_read, le_max_key_size_write, le_min_key_size_read or le_min_key_size_write and Bluetooth adapter was powered off. Fix is to move max_key_size and min_key_size from smp_dev to hci_dev. At the same time they were renamed to le_max_key_size and le_min_key_size. BUG: unable to handle kernel NULL pointer dereference at 00000000000002e8 PGD 0 P4D 0 Oops: 0000 [#24] SMP PTI CPU: 2 PID: 6255 Comm: cat Tainted: G D OE 4.18.9-200.fc28.x86_64 #1 Hardware name: LENOVO 4286CTO/4286CTO, BIOS 8DET76WW (1.46 ) 06/21/2018 RIP: 0010:le_max_key_size_read+0x45/0xb0 [bluetooth] Code: 00 00 00 48 83 ec 10 65 48 8b 04 25 28 00 00 00 48 89 44 24 08 31 c0 48 8b 87 c8 00 00 00 48 8d 7c 24 04 48 8b 80 48 0a 00 00 <48> 8b 80 e8 02 00 00 0f b6 48 52 e8 fb b6 b3 ed be 04 00 00 00 48 RSP: 0018:ffffab23c3ff3df0 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 00007f0b4ca2e000 RCX: ffffab23c3ff3f08 RDX: ffffffffc0ddb033 RSI: 0000000000000004 RDI: ffffab23c3ff3df4 RBP: 0000000000020000 R08: 0000000000000000 R09: 0000000000000000 R10: ffffab23c3ff3ed8 R11: 0000000000000000 R12: ffffab23c3ff3f08 R13: 00007f0b4ca2e000 R14: 0000000000020000 R15: ffffab23c3ff3f08 FS: 00007f0b4ca0f540(0000) GS:ffff91bd5e280000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000000002e8 CR3: 00000000629fa006 CR4: 00000000000606e0 Call Trace: full_proxy_read+0x53/0x80 __vfs_read+0x36/0x180 vfs_read+0x8a/0x140 ksys_read+0x4f/0xb0 do_syscall_64+0x5b/0x160 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Signed-off-by: Matias Karhumaa <matias.karhumaa@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 6496b96 commit 09b6c08

File tree

3 files changed

+13
-14
lines changed

3 files changed

+13
-14
lines changed

include/net/bluetooth/hci_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ struct hci_dev {
259259
__u16 le_max_tx_time;
260260
__u16 le_max_rx_len;
261261
__u16 le_max_rx_time;
262+
__u8 le_max_key_size;
263+
__u8 le_min_key_size;
262264
__u16 discov_interleaved_timeout;
263265
__u16 conn_info_min_age;
264266
__u16 conn_info_max_age;

net/bluetooth/hci_core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3084,6 +3084,8 @@ struct hci_dev *hci_alloc_dev(void)
30843084
hdev->le_max_tx_time = 0x0148;
30853085
hdev->le_max_rx_len = 0x001b;
30863086
hdev->le_max_rx_time = 0x0148;
3087+
hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
3088+
hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
30873089
hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
30883090
hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
30893091

net/bluetooth/smp.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,6 @@ struct smp_dev {
8888
u8 local_rand[16];
8989
bool debug_key;
9090

91-
u8 min_key_size;
92-
u8 max_key_size;
93-
9491
struct crypto_cipher *tfm_aes;
9592
struct crypto_shash *tfm_cmac;
9693
struct crypto_kpp *tfm_ecdh;
@@ -720,7 +717,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
720717
if (rsp == NULL) {
721718
req->io_capability = conn->hcon->io_capability;
722719
req->oob_flag = oob_flag;
723-
req->max_key_size = SMP_DEV(hdev)->max_key_size;
720+
req->max_key_size = hdev->le_max_key_size;
724721
req->init_key_dist = local_dist;
725722
req->resp_key_dist = remote_dist;
726723
req->auth_req = (authreq & AUTH_REQ_MASK(hdev));
@@ -731,7 +728,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
731728

732729
rsp->io_capability = conn->hcon->io_capability;
733730
rsp->oob_flag = oob_flag;
734-
rsp->max_key_size = SMP_DEV(hdev)->max_key_size;
731+
rsp->max_key_size = hdev->le_max_key_size;
735732
rsp->init_key_dist = req->init_key_dist & remote_dist;
736733
rsp->resp_key_dist = req->resp_key_dist & local_dist;
737734
rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev));
@@ -745,7 +742,7 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
745742
struct hci_dev *hdev = conn->hcon->hdev;
746743
struct smp_chan *smp = chan->data;
747744

748-
if (max_key_size > SMP_DEV(hdev)->max_key_size ||
745+
if (max_key_size > hdev->le_max_key_size ||
749746
max_key_size < SMP_MIN_ENC_KEY_SIZE)
750747
return SMP_ENC_KEY_SIZE;
751748

@@ -3264,8 +3261,6 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
32643261
smp->tfm_aes = tfm_aes;
32653262
smp->tfm_cmac = tfm_cmac;
32663263
smp->tfm_ecdh = tfm_ecdh;
3267-
smp->min_key_size = SMP_MIN_ENC_KEY_SIZE;
3268-
smp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
32693264

32703265
create_chan:
32713266
chan = l2cap_chan_create();
@@ -3391,7 +3386,7 @@ static ssize_t le_min_key_size_read(struct file *file,
33913386
struct hci_dev *hdev = file->private_data;
33923387
char buf[4];
33933388

3394-
snprintf(buf, sizeof(buf), "%2u\n", SMP_DEV(hdev)->min_key_size);
3389+
snprintf(buf, sizeof(buf), "%2u\n", hdev->le_min_key_size);
33953390

33963391
return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
33973392
}
@@ -3412,11 +3407,11 @@ static ssize_t le_min_key_size_write(struct file *file,
34123407

34133408
sscanf(buf, "%hhu", &key_size);
34143409

3415-
if (key_size > SMP_DEV(hdev)->max_key_size ||
3410+
if (key_size > hdev->le_max_key_size ||
34163411
key_size < SMP_MIN_ENC_KEY_SIZE)
34173412
return -EINVAL;
34183413

3419-
SMP_DEV(hdev)->min_key_size = key_size;
3414+
hdev->le_min_key_size = key_size;
34203415

34213416
return count;
34223417
}
@@ -3435,7 +3430,7 @@ static ssize_t le_max_key_size_read(struct file *file,
34353430
struct hci_dev *hdev = file->private_data;
34363431
char buf[4];
34373432

3438-
snprintf(buf, sizeof(buf), "%2u\n", SMP_DEV(hdev)->max_key_size);
3433+
snprintf(buf, sizeof(buf), "%2u\n", hdev->le_max_key_size);
34393434

34403435
return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
34413436
}
@@ -3457,10 +3452,10 @@ static ssize_t le_max_key_size_write(struct file *file,
34573452
sscanf(buf, "%hhu", &key_size);
34583453

34593454
if (key_size > SMP_MAX_ENC_KEY_SIZE ||
3460-
key_size < SMP_DEV(hdev)->min_key_size)
3455+
key_size < hdev->le_min_key_size)
34613456
return -EINVAL;
34623457

3463-
SMP_DEV(hdev)->max_key_size = key_size;
3458+
hdev->le_max_key_size = key_size;
34643459

34653460
return count;
34663461
}

0 commit comments

Comments
 (0)