From: Greg Kroah-Hartman Date: Sun, 24 Aug 2025 07:57:47 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v5.4.297~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=854af7a585eea04764d1cf3128e4648f22417325;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: comedi-fail-comedi_insnlist-ioctl-if-n_insns-is-too-large.patch comedi-fix-initialization-of-data-for-instructions-that-write-to-subdevice.patch --- diff --git a/queue-5.4/comedi-fail-comedi_insnlist-ioctl-if-n_insns-is-too-large.patch b/queue-5.4/comedi-fail-comedi_insnlist-ioctl-if-n_insns-is-too-large.patch new file mode 100644 index 0000000000..c04c99367f --- /dev/null +++ b/queue-5.4/comedi-fail-comedi_insnlist-ioctl-if-n_insns-is-too-large.patch @@ -0,0 +1,87 @@ +From abbotti@mev.co.uk Mon Jul 28 14:18:49 2025 +From: Ian Abbott +Date: Mon, 28 Jul 2025 13:18:20 +0100 +Subject: comedi: Fail COMEDI_INSNLIST ioctl if n_insns is too large +To: stable@vger.kernel.org +Cc: Ian Abbott , syzbot+d6995b62e5ac7d79557a@syzkaller.appspotmail.com, Greg Kroah-Hartman , Sasha Levin +Message-ID: <20250728121821.276086-1-abbotti@mev.co.uk> + +From: Ian Abbott + +[ Upstream commit 08ae4b20f5e82101d77326ecab9089e110f224cc ] + +The handling of the `COMEDI_INSNLIST` ioctl allocates a kernel buffer to +hold the array of `struct comedi_insn`, getting the length from the +`n_insns` member of the `struct comedi_insnlist` supplied by the user. +The allocation will fail with a WARNING and a stack dump if it is too +large. + +Avoid that by failing with an `-EINVAL` error if the supplied `n_insns` +value is unreasonable. + +Define the limit on the `n_insns` value in the `MAX_INSNS` macro. Set +this to the same value as `MAX_SAMPLES` (65536), which is the maximum +allowed sum of the values of the member `n` in the array of `struct +comedi_insn`, and sensible comedi instructions will have an `n` of at +least 1. + +Reported-by: syzbot+d6995b62e5ac7d79557a@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=d6995b62e5ac7d79557a +Fixes: ed9eccbe8970 ("Staging: add comedi core") +Tested-by: Ian Abbott +Cc: stable@vger.kernel.org # 5.13+ +Signed-off-by: Ian Abbott +Link: https://lore.kernel.org/r/20250704120405.83028-1-abbotti@mev.co.uk +Signed-off-by: Greg Kroah-Hartman +[ Reworked for before commit bac42fb21259 ("comedi: get rid of compat_alloc_user_space() mess in COMEDI_CMD{,TEST} compat") ] +Signed-off-by: Ian Abbott +Signed-off-by: Greg Kroah-Hartman +--- +v2: Fixed a build error due to applying a fixup to the wrong commit. +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/comedi/comedi_compat32.c | 3 +++ + drivers/staging/comedi/comedi_fops.c | 13 +++++++++++++ + 2 files changed, 16 insertions(+) + +--- a/drivers/staging/comedi/comedi_compat32.c ++++ b/drivers/staging/comedi/comedi_compat32.c +@@ -360,6 +360,9 @@ static int compat_insnlist(struct file * + if (err) + return -EFAULT; + ++ if (n_insns > 65536) /* See MAX_INSNS in comedi_fops.c */ ++ return -EINVAL; ++ + /* Allocate user memory to copy insnlist and insns into. */ + s = compat_alloc_user_space(offsetof(struct combined_insnlist, + insn[n_insns])); +--- a/drivers/staging/comedi/comedi_fops.c ++++ b/drivers/staging/comedi/comedi_fops.c +@@ -1519,6 +1519,16 @@ out: + return ret; + } + ++#define MAX_INSNS 65536 ++static int check_insnlist_len(struct comedi_device *dev, unsigned int n_insns) ++{ ++ if (n_insns > MAX_INSNS) { ++ dev_dbg(dev->class_dev, "insnlist length too large\n"); ++ return -EINVAL; ++ } ++ return 0; ++} ++ + /* + * COMEDI_INSNLIST ioctl + * synchronous instruction list +@@ -1551,6 +1561,9 @@ static int do_insnlist_ioctl(struct come + if (copy_from_user(&insnlist, arg, sizeof(insnlist))) + return -EFAULT; + ++ ret = check_insnlist_len(dev, insnlist.n_insns); ++ if (ret) ++ return ret; + insns = kcalloc(insnlist.n_insns, sizeof(*insns), GFP_KERNEL); + if (!insns) { + ret = -ENOMEM; diff --git a/queue-5.4/comedi-fix-initialization-of-data-for-instructions-that-write-to-subdevice.patch b/queue-5.4/comedi-fix-initialization-of-data-for-instructions-that-write-to-subdevice.patch new file mode 100644 index 0000000000..b2aaad3bd0 --- /dev/null +++ b/queue-5.4/comedi-fix-initialization-of-data-for-instructions-that-write-to-subdevice.patch @@ -0,0 +1,86 @@ +From abbotti@mev.co.uk Mon Jul 28 14:22:12 2025 +From: Ian Abbott +Date: Mon, 28 Jul 2025 13:21:56 +0100 +Subject: comedi: Fix initialization of data for instructions that write to subdevice +To: stable@vger.kernel.org +Cc: Ian Abbott , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20250728122156.276222-1-abbotti@mev.co.uk> + +From: Ian Abbott + +[ Upstream commit 46d8c744136ce2454aa4c35c138cc06817f92b8e ] + +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: ed9eccbe8970 ("Staging: add comedi core") +Cc: stable@vger.kernel.org # 5.13+ +Signed-off-by: Ian Abbott +Link: https://lore.kernel.org/r/20250707161439.88385-1-abbotti@mev.co.uk +Signed-off-by: Greg Kroah-Hartman +[ Reworked for before commit bac42fb21259 ("comedi: get rid of compat_alloc_user_space() mess in COMEDI_CMD{,TEST} compat") ] +Signed-off-by: Ian Abbott +Signed-off-by: Greg Kroah-Hartman +--- +v2: Fixed a patch application error due to fixing up the wrong commit. +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/comedi/comedi_fops.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/staging/comedi/comedi_fops.c ++++ b/drivers/staging/comedi/comedi_fops.c +@@ -1584,21 +1584,27 @@ static int do_insnlist_ioctl(struct come + } + + for (i = 0; i < insnlist.n_insns; ++i) { ++ unsigned int n = insns[i].n; ++ + if (insns[i].insn & INSN_MASK_WRITE) { + if (copy_from_user(data, insns[i].data, +- insns[i].n * sizeof(unsigned int))) { ++ n * sizeof(unsigned int))) { + dev_dbg(dev->class_dev, + "copy_from_user failed\n"); + ret = -EFAULT; + goto error; + } ++ if (n < MIN_SAMPLES) { ++ memset(&data[n], 0, (MIN_SAMPLES - n) * ++ sizeof(unsigned int)); ++ } + } + ret = parse_insn(dev, insns + i, data, file); + if (ret < 0) + goto error; + if (insns[i].insn & INSN_MASK_READ) { + if (copy_to_user(insns[i].data, data, +- insns[i].n * sizeof(unsigned int))) { ++ n * sizeof(unsigned int))) { + dev_dbg(dev->class_dev, + "copy_to_user failed\n"); + ret = -EFAULT; +@@ -1665,6 +1671,10 @@ static int do_insn_ioctl(struct comedi_d + ret = -EFAULT; + goto error; + } ++ if (insn.n < MIN_SAMPLES) { ++ memset(&data[insn.n], 0, ++ (MIN_SAMPLES - insn.n) * sizeof(unsigned int)); ++ } + } + ret = parse_insn(dev, &insn, data, file); + if (ret < 0) diff --git a/queue-5.4/series b/queue-5.4/series index ef9ad4505b..dda78e405f 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -326,3 +326,5 @@ mips-include-kbuild_cppflags-in-checkflags-invocation.patch kbuild-add-clang_flags-to-as-instr.patch kbuild-add-clang_flags-to-kbuild_cppflags.patch kbuild-add-kbuild_cppflags-to-as-option-invocation.patch +comedi-fix-initialization-of-data-for-instructions-that-write-to-subdevice.patch +comedi-fail-comedi_insnlist-ioctl-if-n_insns-is-too-large.patch