]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 22 Apr 2018 09:15:57 +0000 (11:15 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 22 Apr 2018 09:15:57 +0000 (11:15 +0200)
added patches:
alsa-rawmidi-fix-missing-input-substream-checks-in-compat-ioctls.patch
hid-hidraw-fix-crash-on-hidiocgfeature-with-a-destroyed-device.patch
mips-memset.s-eva-fault-support-for-small_memset.patch
mips-memset.s-fix-clobber-of-v1-in-last_fixup.patch
mips-memset.s-fix-return-of-__clear_user-from-lpartial_fixup.patch
powerpc-lib-fix-off-by-one-in-alternate-feature-patching.patch

queue-3.18/alsa-rawmidi-fix-missing-input-substream-checks-in-compat-ioctls.patch [new file with mode: 0644]
queue-3.18/hid-hidraw-fix-crash-on-hidiocgfeature-with-a-destroyed-device.patch [new file with mode: 0644]
queue-3.18/mips-memset.s-eva-fault-support-for-small_memset.patch [new file with mode: 0644]
queue-3.18/mips-memset.s-fix-clobber-of-v1-in-last_fixup.patch [new file with mode: 0644]
queue-3.18/mips-memset.s-fix-return-of-__clear_user-from-lpartial_fixup.patch [new file with mode: 0644]
queue-3.18/powerpc-lib-fix-off-by-one-in-alternate-feature-patching.patch [new file with mode: 0644]
queue-3.18/series

diff --git a/queue-3.18/alsa-rawmidi-fix-missing-input-substream-checks-in-compat-ioctls.patch b/queue-3.18/alsa-rawmidi-fix-missing-input-substream-checks-in-compat-ioctls.patch
new file mode 100644 (file)
index 0000000..00a75c2
--- /dev/null
@@ -0,0 +1,93 @@
+From 8a56ef4f3ffba9ebf4967b61ef600b0a7ba10f11 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 19 Apr 2018 18:16:15 +0200
+Subject: ALSA: rawmidi: Fix missing input substream checks in compat ioctls
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 8a56ef4f3ffba9ebf4967b61ef600b0a7ba10f11 upstream.
+
+Some rawmidi compat ioctls lack of the input substream checks
+(although they do check only for rfile->output).  This many eventually
+lead to an Oops as NULL substream is passed to the rawmidi core
+functions.
+
+Fix it by adding the proper checks before each function call.
+
+The bug was spotted by syzkaller.
+
+Reported-by: syzbot+f7a0348affc3b67bc617@syzkaller.appspotmail.com
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/rawmidi_compat.c |   18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+--- a/sound/core/rawmidi_compat.c
++++ b/sound/core/rawmidi_compat.c
+@@ -36,8 +36,6 @@ static int snd_rawmidi_ioctl_params_comp
+       struct snd_rawmidi_params params;
+       unsigned int val;
+-      if (rfile->output == NULL)
+-              return -EINVAL;
+       if (get_user(params.stream, &src->stream) ||
+           get_user(params.buffer_size, &src->buffer_size) ||
+           get_user(params.avail_min, &src->avail_min) ||
+@@ -46,8 +44,12 @@ static int snd_rawmidi_ioctl_params_comp
+       params.no_active_sensing = val;
+       switch (params.stream) {
+       case SNDRV_RAWMIDI_STREAM_OUTPUT:
++              if (!rfile->output)
++                      return -EINVAL;
+               return snd_rawmidi_output_params(rfile->output, &params);
+       case SNDRV_RAWMIDI_STREAM_INPUT:
++              if (!rfile->input)
++                      return -EINVAL;
+               return snd_rawmidi_input_params(rfile->input, &params);
+       }
+       return -EINVAL;
+@@ -67,16 +69,18 @@ static int snd_rawmidi_ioctl_status_comp
+       int err;
+       struct snd_rawmidi_status status;
+-      if (rfile->output == NULL)
+-              return -EINVAL;
+       if (get_user(status.stream, &src->stream))
+               return -EFAULT;
+       switch (status.stream) {
+       case SNDRV_RAWMIDI_STREAM_OUTPUT:
++              if (!rfile->output)
++                      return -EINVAL;
+               err = snd_rawmidi_output_status(rfile->output, &status);
+               break;
+       case SNDRV_RAWMIDI_STREAM_INPUT:
++              if (!rfile->input)
++                      return -EINVAL;
+               err = snd_rawmidi_input_status(rfile->input, &status);
+               break;
+       default:
+@@ -113,16 +117,18 @@ static int snd_rawmidi_ioctl_status_x32(
+       int err;
+       struct snd_rawmidi_status status;
+-      if (rfile->output == NULL)
+-              return -EINVAL;
+       if (get_user(status.stream, &src->stream))
+               return -EFAULT;
+       switch (status.stream) {
+       case SNDRV_RAWMIDI_STREAM_OUTPUT:
++              if (!rfile->output)
++                      return -EINVAL;
+               err = snd_rawmidi_output_status(rfile->output, &status);
+               break;
+       case SNDRV_RAWMIDI_STREAM_INPUT:
++              if (!rfile->input)
++                      return -EINVAL;
+               err = snd_rawmidi_input_status(rfile->input, &status);
+               break;
+       default:
diff --git a/queue-3.18/hid-hidraw-fix-crash-on-hidiocgfeature-with-a-destroyed-device.patch b/queue-3.18/hid-hidraw-fix-crash-on-hidiocgfeature-with-a-destroyed-device.patch
new file mode 100644 (file)
index 0000000..f9fc47f
--- /dev/null
@@ -0,0 +1,40 @@
+From a955358d54695e4ad9f7d6489a7ac4d69a8fc711 Mon Sep 17 00:00:00 2001
+From: Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+Date: Fri, 6 Apr 2018 01:09:36 +0200
+Subject: HID: hidraw: Fix crash on HIDIOCGFEATURE with a destroyed device
+
+From: Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+commit a955358d54695e4ad9f7d6489a7ac4d69a8fc711 upstream.
+
+Doing `ioctl(HIDIOCGFEATURE)` in a tight loop on a hidraw device
+and then disconnecting the device, or unloading the driver, can
+cause a NULL pointer dereference.
+
+When a hidraw device is destroyed it sets 0 to `dev->exist`.
+Most functions check 'dev->exist' before doing its work, but
+`hidraw_get_report()` was missing that check.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hidraw.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/hid/hidraw.c
++++ b/drivers/hid/hidraw.c
+@@ -197,6 +197,11 @@ static ssize_t hidraw_get_report(struct
+       int ret = 0, len;
+       unsigned char report_number;
++      if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
++              ret = -ENODEV;
++              goto out;
++      }
++
+       dev = hidraw_table[minor]->hid;
+       if (!dev->ll_driver->raw_request) {
diff --git a/queue-3.18/mips-memset.s-eva-fault-support-for-small_memset.patch b/queue-3.18/mips-memset.s-eva-fault-support-for-small_memset.patch
new file mode 100644 (file)
index 0000000..af94b90
--- /dev/null
@@ -0,0 +1,65 @@
+From 8a8158c85e1e774a44fbe81106fa41138580dfd1 Mon Sep 17 00:00:00 2001
+From: Matt Redfearn <matt.redfearn@mips.com>
+Date: Thu, 29 Mar 2018 10:28:23 +0100
+Subject: MIPS: memset.S: EVA & fault support for small_memset
+
+From: Matt Redfearn <matt.redfearn@mips.com>
+
+commit 8a8158c85e1e774a44fbe81106fa41138580dfd1 upstream.
+
+The MIPS kernel memset / bzero implementation includes a small_memset
+branch which is used when the region to be set is smaller than a long (4
+bytes on 32bit, 8 bytes on 64bit). The current small_memset
+implementation uses a simple store byte loop to write the destination.
+There are 2 issues with this implementation:
+
+1. When EVA mode is active, user and kernel address spaces may overlap.
+Currently the use of the sb instruction means kernel mode addressing is
+always used and an intended write to userspace may actually overwrite
+some critical kernel data.
+
+2. If the write triggers a page fault, for example by calling
+__clear_user(NULL, 2), instead of gracefully handling the fault, an OOPS
+is triggered.
+
+Fix these issues by replacing the sb instruction with the EX() macro,
+which will emit EVA compatible instuctions as required. Additionally
+implement a fault fixup for small_memset which sets a2 to the number of
+bytes that could not be cleared (as defined by __clear_user).
+
+Reported-by: Chuanhua Lei <chuanhua.lei@intel.com>
+Signed-off-by: Matt Redfearn <matt.redfearn@mips.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: linux-mips@linux-mips.org
+Cc: stable@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/18975/
+Signed-off-by: James Hogan <jhogan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/lib/memset.S |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/lib/memset.S
++++ b/arch/mips/lib/memset.S
+@@ -178,7 +178,7 @@
+ 1:    PTR_ADDIU       a0, 1                   /* fill bytewise */
+       R10KCBARRIER(0(ra))
+       bne             t1, a0, 1b
+-      sb              a1, -1(a0)
++       EX(sb, a1, -1(a0), .Lsmall_fixup\@)
+ 2:    jr              ra                      /* done */
+       move            a2, zero
+@@ -212,6 +212,11 @@
+       jr              ra
+       andi            v1, a2, STORMASK
++.Lsmall_fixup\@:
++      PTR_SUBU        a2, t1, a0
++      jr              ra
++       PTR_ADDIU      a2, 1
++
+       .endm
+ /*
diff --git a/queue-3.18/mips-memset.s-fix-clobber-of-v1-in-last_fixup.patch b/queue-3.18/mips-memset.s-fix-clobber-of-v1-in-last_fixup.patch
new file mode 100644 (file)
index 0000000..c0d719a
--- /dev/null
@@ -0,0 +1,77 @@
+From c96eebf07692e53bf4dd5987510d8b550e793598 Mon Sep 17 00:00:00 2001
+From: Matt Redfearn <matt.redfearn@mips.com>
+Date: Tue, 17 Apr 2018 16:40:00 +0100
+Subject: MIPS: memset.S: Fix clobber of v1 in last_fixup
+
+From: Matt Redfearn <matt.redfearn@mips.com>
+
+commit c96eebf07692e53bf4dd5987510d8b550e793598 upstream.
+
+The label .Llast_fixup\@ is jumped to on page fault within the final
+byte set loop of memset (on < MIPSR6 architectures). For some reason, in
+this fault handler, the v1 register is randomly set to a2 & STORMASK.
+This clobbers v1 for the calling function. This can be observed with the
+following test code:
+
+static int __init __attribute__((optimize("O0"))) test_clear_user(void)
+{
+  register int t asm("v1");
+  char *test;
+  int j, k;
+
+  pr_info("\n\n\nTesting clear_user\n");
+  test = vmalloc(PAGE_SIZE);
+
+  for (j = 256; j < 512; j++) {
+    t = 0xa5a5a5a5;
+    if ((k = clear_user(test + PAGE_SIZE - 256, j)) != j - 256) {
+        pr_err("clear_user (%px %d) returned %d\n", test + PAGE_SIZE - 256, j, k);
+    }
+    if (t != 0xa5a5a5a5) {
+       pr_err("v1 was clobbered to 0x%x!\n", t);
+    }
+  }
+
+  return 0;
+}
+late_initcall(test_clear_user);
+
+Which demonstrates that v1 is indeed clobbered (MIPS64):
+
+Testing clear_user
+v1 was clobbered to 0x1!
+v1 was clobbered to 0x2!
+v1 was clobbered to 0x3!
+v1 was clobbered to 0x4!
+v1 was clobbered to 0x5!
+v1 was clobbered to 0x6!
+v1 was clobbered to 0x7!
+
+Since the number of bytes that could not be set is already contained in
+a2, the andi placing a value in v1 is not necessary and actively
+harmful in clobbering v1.
+
+Reported-by: James Hogan <jhogan@kernel.org>
+Signed-off-by: Matt Redfearn <matt.redfearn@mips.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: linux-mips@linux-mips.org
+Cc: stable@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/19109/
+Signed-off-by: James Hogan <jhogan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/lib/memset.S |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/lib/memset.S
++++ b/arch/mips/lib/memset.S
+@@ -210,7 +210,7 @@
+ .Llast_fixup\@:
+       jr              ra
+-      andi            v1, a2, STORMASK
++       nop
+ .Lsmall_fixup\@:
+       PTR_SUBU        a2, t1, a0
diff --git a/queue-3.18/mips-memset.s-fix-return-of-__clear_user-from-lpartial_fixup.patch b/queue-3.18/mips-memset.s-fix-return-of-__clear_user-from-lpartial_fixup.patch
new file mode 100644 (file)
index 0000000..6ec0e85
--- /dev/null
@@ -0,0 +1,57 @@
+From daf70d89f80c6e1772233da9e020114b1254e7e0 Mon Sep 17 00:00:00 2001
+From: Matt Redfearn <matt.redfearn@mips.com>
+Date: Tue, 17 Apr 2018 15:52:21 +0100
+Subject: MIPS: memset.S: Fix return of __clear_user from Lpartial_fixup
+
+From: Matt Redfearn <matt.redfearn@mips.com>
+
+commit daf70d89f80c6e1772233da9e020114b1254e7e0 upstream.
+
+The __clear_user function is defined to return the number of bytes that
+could not be cleared. From the underlying memset / bzero implementation
+this means setting register a2 to that number on return. Currently if a
+page fault is triggered within the memset_partial block, the value
+loaded into a2 on return is meaningless.
+
+The label .Lpartial_fixup\@ is jumped to on page fault. In order to work
+out how many bytes failed to copy, the exception handler should find how
+many bytes left in the partial block (andi a2, STORMASK), add that to
+the partial block end address (a2), and subtract the faulting address to
+get the remainder. Currently it incorrectly subtracts the partial block
+start address (t1), which has additionally been clobbered to generate a
+jump target in memset_partial. Fix this by adding the block end address
+instead.
+
+This issue was found with the following test code:
+      int j, k;
+      for (j = 0; j < 512; j++) {
+        if ((k = clear_user(NULL, j)) != j) {
+           pr_err("clear_user (NULL %d) returned %d\n", j, k);
+        }
+      }
+Which now passes on Creator Ci40 (MIPS32) and Cavium Octeon II (MIPS64).
+
+Suggested-by: James Hogan <jhogan@kernel.org>
+Signed-off-by: Matt Redfearn <matt.redfearn@mips.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: linux-mips@linux-mips.org
+Cc: stable@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/19108/
+Signed-off-by: James Hogan <jhogan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/lib/memset.S |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/lib/memset.S
++++ b/arch/mips/lib/memset.S
+@@ -204,7 +204,7 @@
+       PTR_L           t0, TI_TASK($28)
+       andi            a2, STORMASK
+       LONG_L          t0, THREAD_BUADDR(t0)
+-      LONG_ADDU       a2, t1
++      LONG_ADDU       a2, a0
+       jr              ra
+       LONG_SUBU       a2, t0
diff --git a/queue-3.18/powerpc-lib-fix-off-by-one-in-alternate-feature-patching.patch b/queue-3.18/powerpc-lib-fix-off-by-one-in-alternate-feature-patching.patch
new file mode 100644 (file)
index 0000000..b26045a
--- /dev/null
@@ -0,0 +1,53 @@
+From b8858581febb050688e276b956796bc4a78299ed Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Mon, 16 Apr 2018 23:25:19 +1000
+Subject: powerpc/lib: Fix off-by-one in alternate feature patching
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit b8858581febb050688e276b956796bc4a78299ed upstream.
+
+When we patch an alternate feature section, we have to adjust any
+relative branches that branch out of the alternate section.
+
+But currently we have a bug if we have a branch that points to past
+the last instruction of the alternate section, eg:
+
+  FTR_SECTION_ELSE
+  1:     b       2f
+         or      6,6,6
+  2:
+  ALT_FTR_SECTION_END(...)
+         nop
+
+This will result in a relative branch at 1 with a target that equals
+the end of the alternate section.
+
+That branch does not need adjusting when it's moved to the non-else
+location. Currently we do adjust it, resulting in a branch that goes
+off into the link-time location of the else section, which is junk.
+
+The fix is to not patch branches that have a target == end of the
+alternate section.
+
+Fixes: d20fe50a7b3c ("KVM: PPC: Book3S HV: Branch inside feature section")
+Fixes: 9b1a735de64c ("powerpc: Add logic to patch alternative feature sections")
+Cc: stable@vger.kernel.org # v2.6.27+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/lib/feature-fixups.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/lib/feature-fixups.c
++++ b/arch/powerpc/lib/feature-fixups.c
+@@ -52,7 +52,7 @@ static int patch_alt_instruction(unsigne
+               unsigned int *target = (unsigned int *)branch_target(src);
+               /* Branch within the section doesn't need translating */
+-              if (target < alt_start || target >= alt_end) {
++              if (target < alt_start || target > alt_end) {
+                       instr = translate_branch(dest, src);
+                       if (!instr)
+                               return 1;
index 46942da0d48074164387a154493ac3285fb1eeba..18a7cce207e7c87bdfa75de778eb1ecb6feb0db3 100644 (file)
@@ -38,3 +38,9 @@ ext4-add-validity-checks-for-bitmap-block-numbers.patch
 ext4-fail-ext4_iget-for-root-directory-if-unallocated.patch
 ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the-superblock.patch
 drm-radeon-fix-pcie-lane-width-calculation.patch
+alsa-rawmidi-fix-missing-input-substream-checks-in-compat-ioctls.patch
+hid-hidraw-fix-crash-on-hidiocgfeature-with-a-destroyed-device.patch
+mips-memset.s-eva-fault-support-for-small_memset.patch
+mips-memset.s-fix-return-of-__clear_user-from-lpartial_fixup.patch
+mips-memset.s-fix-clobber-of-v1-in-last_fixup.patch
+powerpc-lib-fix-off-by-one-in-alternate-feature-patching.patch