]>
Commit | Line | Data |
---|---|---|
b0c1a8bd GKH |
1 | From 45292be0b3db0b7f8286683b376e2d9f949d11f9 Mon Sep 17 00:00:00 2001 |
2 | From: Ian Abbott <abbotti@mev.co.uk> | |
3 | Date: Fri, 17 Feb 2017 11:09:08 +0000 | |
4 | Subject: staging: comedi: jr3_pci: fix possible null pointer dereference | |
5 | ||
6 | From: Ian Abbott <abbotti@mev.co.uk> | |
7 | ||
8 | commit 45292be0b3db0b7f8286683b376e2d9f949d11f9 upstream. | |
9 | ||
10 | For some reason, the driver does not consider allocation of the | |
11 | subdevice private data to be a fatal error when attaching the COMEDI | |
12 | device. It tests the subdevice private data pointer for validity at | |
13 | certain points, but omits some crucial tests. In particular, | |
14 | `jr3_pci_auto_attach()` calls `jr3_pci_alloc_spriv()` to allocate and | |
15 | initialize the subdevice private data, but the same function | |
16 | subsequently dereferences the pointer to access the `next_time_min` and | |
17 | `next_time_max` members without checking it first. The other missing | |
18 | test is in the timer expiry routine `jr3_pci_poll_dev()`, but it will | |
19 | crash before it gets that far. | |
20 | ||
21 | Fix the bug by returning `-ENOMEM` from `jr3_pci_auto_attach()` as soon | |
22 | as one of the calls to `jr3_pci_alloc_spriv()` returns `NULL`. The | |
23 | COMEDI core will subsequently call `jr3_pci_detach()` to clean up. | |
24 | ||
25 | Signed-off-by: Ian Abbott <abbotti@mev.co.uk> | |
26 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
27 | ||
28 | --- | |
29 | drivers/staging/comedi/drivers/jr3_pci.c | 11 ++++++----- | |
30 | 1 file changed, 6 insertions(+), 5 deletions(-) | |
31 | ||
32 | --- a/drivers/staging/comedi/drivers/jr3_pci.c | |
33 | +++ b/drivers/staging/comedi/drivers/jr3_pci.c | |
34 | @@ -727,11 +727,12 @@ static int jr3_pci_auto_attach(struct co | |
35 | s->insn_read = jr3_pci_ai_insn_read; | |
36 | ||
37 | spriv = jr3_pci_alloc_spriv(dev, s); | |
38 | - if (spriv) { | |
39 | - /* Channel specific range and maxdata */ | |
40 | - s->range_table_list = spriv->range_table_list; | |
41 | - s->maxdata_list = spriv->maxdata_list; | |
42 | - } | |
43 | + if (!spriv) | |
44 | + return -ENOMEM; | |
45 | + | |
46 | + /* Channel specific range and maxdata */ | |
47 | + s->range_table_list = spriv->range_table_list; | |
48 | + s->maxdata_list = spriv->maxdata_list; | |
49 | } | |
50 | ||
51 | /* Reset DSP card */ |