Skip to content

Commit 46d8c74

Browse files
ian-abbottgregkh
authored andcommitted
comedi: Fix initialization of data for instructions that write to subdevice
Some Comedi subdevice instruction handlers are known to access instruction data elements beyond the first `insn->n` elements in some cases. The `do_insn_ioctl()` and `do_insnlist_ioctl()` functions allocate at least `MIN_SAMPLES` (16) data elements to deal with this, but they do not initialize all of that. For Comedi instruction codes that write to the subdevice, the first `insn->n` data elements are copied from user-space, but the remaining elements are left uninitialized. That could be a problem if the subdevice instruction handler reads the uninitialized data. Ensure that the first `MIN_SAMPLES` elements are initialized before calling these instruction handlers, filling the uncopied elements with 0. For `do_insnlist_ioctl()`, the same data buffer elements are used for handling a list of instructions, so ensure the first `MIN_SAMPLES` elements are initialized for each instruction that writes to the subdevice. Fixes: ed9eccb ("Staging: add comedi core") Cc: [email protected] # 5.13+ Signed-off-by: Ian Abbott <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e9cb262 commit 46d8c74

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

drivers/comedi/comedi_fops.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,21 +1556,27 @@ static int do_insnlist_ioctl(struct comedi_device *dev,
15561556
}
15571557

15581558
for (i = 0; i < n_insns; ++i) {
1559+
unsigned int n = insns[i].n;
1560+
15591561
if (insns[i].insn & INSN_MASK_WRITE) {
15601562
if (copy_from_user(data, insns[i].data,
1561-
insns[i].n * sizeof(unsigned int))) {
1563+
n * sizeof(unsigned int))) {
15621564
dev_dbg(dev->class_dev,
15631565
"copy_from_user failed\n");
15641566
ret = -EFAULT;
15651567
goto error;
15661568
}
1569+
if (n < MIN_SAMPLES) {
1570+
memset(&data[n], 0, (MIN_SAMPLES - n) *
1571+
sizeof(unsigned int));
1572+
}
15671573
}
15681574
ret = parse_insn(dev, insns + i, data, file);
15691575
if (ret < 0)
15701576
goto error;
15711577
if (insns[i].insn & INSN_MASK_READ) {
15721578
if (copy_to_user(insns[i].data, data,
1573-
insns[i].n * sizeof(unsigned int))) {
1579+
n * sizeof(unsigned int))) {
15741580
dev_dbg(dev->class_dev,
15751581
"copy_to_user failed\n");
15761582
ret = -EFAULT;
@@ -1643,6 +1649,10 @@ static int do_insn_ioctl(struct comedi_device *dev,
16431649
ret = -EFAULT;
16441650
goto error;
16451651
}
1652+
if (insn->n < MIN_SAMPLES) {
1653+
memset(&data[insn->n], 0,
1654+
(MIN_SAMPLES - insn->n) * sizeof(unsigned int));
1655+
}
16461656
}
16471657
ret = parse_insn(dev, insn, data, file);
16481658
if (ret < 0)

0 commit comments

Comments
 (0)