From: Greg Kroah-Hartman Date: Mon, 26 Jun 2017 06:15:43 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v3.18.59~32 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=61f6b9306302eff88258a5849ea15d8489d7d0d8;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: autofs-sanity-check-status-reported-with-autofs_dev_ioctl_fail.patch cifs-improve-readdir-verbosity.patch fs-exec.c-account-for-argv-envp-pointers.patch hid-add-quirk-for-dell-pixart-oem-mouse.patch kvm-ppc-book3s-hv-preserve-userspace-htm-state-properly.patch lib-cmdline.c-fix-get_options-overflow-while-parsing-ranges.patch signal-only-reschedule-timers-on-signals-timers-have-sent.patch --- diff --git a/queue-4.4/autofs-sanity-check-status-reported-with-autofs_dev_ioctl_fail.patch b/queue-4.4/autofs-sanity-check-status-reported-with-autofs_dev_ioctl_fail.patch new file mode 100644 index 00000000000..2d5f930b4f6 --- /dev/null +++ b/queue-4.4/autofs-sanity-check-status-reported-with-autofs_dev_ioctl_fail.patch @@ -0,0 +1,43 @@ +From 9fa4eb8e490a28de40964b1b0e583d8db4c7e57c Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 23 Jun 2017 15:08:43 -0700 +Subject: autofs: sanity check status reported with AUTOFS_DEV_IOCTL_FAIL + +From: NeilBrown + +commit 9fa4eb8e490a28de40964b1b0e583d8db4c7e57c upstream. + +If a positive status is passed with the AUTOFS_DEV_IOCTL_FAIL ioctl, +autofs4_d_automount() will return + + ERR_PTR(status) + +with that status to follow_automount(), which will then dereference an +invalid pointer. + +So treat a positive status the same as zero, and map to ENOENT. + +See comment in systemd src/core/automount.c::automount_send_ready(). + +Link: http://lkml.kernel.org/r/871sqwczx5.fsf@notabene.neil.brown.name +Signed-off-by: NeilBrown +Cc: Ian Kent +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/autofs4/dev-ioctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/autofs4/dev-ioctl.c ++++ b/fs/autofs4/dev-ioctl.c +@@ -331,7 +331,7 @@ static int autofs_dev_ioctl_fail(struct + int status; + + token = (autofs_wqt_t) param->fail.token; +- status = param->fail.status ? param->fail.status : -ENOENT; ++ status = param->fail.status < 0 ? param->fail.status : -ENOENT; + return autofs4_wait_release(sbi, token, status); + } + diff --git a/queue-4.4/cifs-improve-readdir-verbosity.patch b/queue-4.4/cifs-improve-readdir-verbosity.patch new file mode 100644 index 00000000000..68f7cf1a25a --- /dev/null +++ b/queue-4.4/cifs-improve-readdir-verbosity.patch @@ -0,0 +1,60 @@ +From dcd87838c06f05ab7650b249ebf0d5b57ae63e1e Mon Sep 17 00:00:00 2001 +From: Pavel Shilovsky +Date: Tue, 6 Jun 2017 16:58:58 -0700 +Subject: CIFS: Improve readdir verbosity + +From: Pavel Shilovsky + +commit dcd87838c06f05ab7650b249ebf0d5b57ae63e1e upstream. + +Downgrade the loglevel for SMB2 to prevent filling the log +with messages if e.g. readdir was interrupted. Also make SMB2 +and SMB1 codepaths do the same logging during readdir. + +Signed-off-by: Pavel Shilovsky +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb1ops.c | 9 +++++++-- + fs/cifs/smb2ops.c | 4 ++-- + 2 files changed, 9 insertions(+), 4 deletions(-) + +--- a/fs/cifs/smb1ops.c ++++ b/fs/cifs/smb1ops.c +@@ -849,8 +849,13 @@ cifs_query_dir_first(const unsigned int + struct cifs_fid *fid, __u16 search_flags, + struct cifs_search_info *srch_inf) + { +- return CIFSFindFirst(xid, tcon, path, cifs_sb, +- &fid->netfid, search_flags, srch_inf, true); ++ int rc; ++ ++ rc = CIFSFindFirst(xid, tcon, path, cifs_sb, ++ &fid->netfid, search_flags, srch_inf, true); ++ if (rc) ++ cifs_dbg(FYI, "find first failed=%d\n", rc); ++ return rc; + } + + static int +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -909,7 +909,7 @@ smb2_query_dir_first(const unsigned int + rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL); + kfree(utf16_path); + if (rc) { +- cifs_dbg(VFS, "open dir failed\n"); ++ cifs_dbg(FYI, "open dir failed rc=%d\n", rc); + return rc; + } + +@@ -919,7 +919,7 @@ smb2_query_dir_first(const unsigned int + rc = SMB2_query_directory(xid, tcon, fid->persistent_fid, + fid->volatile_fid, 0, srch_inf); + if (rc) { +- cifs_dbg(VFS, "query directory failed\n"); ++ cifs_dbg(FYI, "query directory failed rc=%d\n", rc); + SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid); + } + return rc; diff --git a/queue-4.4/fs-exec.c-account-for-argv-envp-pointers.patch b/queue-4.4/fs-exec.c-account-for-argv-envp-pointers.patch new file mode 100644 index 00000000000..81e92d63295 --- /dev/null +++ b/queue-4.4/fs-exec.c-account-for-argv-envp-pointers.patch @@ -0,0 +1,89 @@ +From 98da7d08850fb8bdeb395d6368ed15753304aa0c Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Fri, 23 Jun 2017 15:08:57 -0700 +Subject: fs/exec.c: account for argv/envp pointers + +From: Kees Cook + +commit 98da7d08850fb8bdeb395d6368ed15753304aa0c upstream. + +When limiting the argv/envp strings during exec to 1/4 of the stack limit, +the storage of the pointers to the strings was not included. This means +that an exec with huge numbers of tiny strings could eat 1/4 of the stack +limit in strings and then additional space would be later used by the +pointers to the strings. + +For example, on 32-bit with a 8MB stack rlimit, an exec with 1677721 +single-byte strings would consume less than 2MB of stack, the max (8MB / +4) amount allowed, but the pointers to the strings would consume the +remaining additional stack space (1677721 * 4 == 6710884). + +The result (1677721 + 6710884 == 8388605) would exhaust stack space +entirely. Controlling this stack exhaustion could result in +pathological behavior in setuid binaries (CVE-2017-1000365). + +[akpm@linux-foundation.org: additional commenting from Kees] +Fixes: b6a2fea39318 ("mm: variable length argument support") +Link: http://lkml.kernel.org/r/20170622001720.GA32173@beast +Signed-off-by: Kees Cook +Acked-by: Rik van Riel +Acked-by: Michal Hocko +Cc: Alexander Viro +Cc: Qualys Security Advisory +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/exec.c | 28 ++++++++++++++++++++++++---- + 1 file changed, 24 insertions(+), 4 deletions(-) + +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -206,8 +206,26 @@ static struct page *get_arg_page(struct + + if (write) { + unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; ++ unsigned long ptr_size; + struct rlimit *rlim; + ++ /* ++ * Since the stack will hold pointers to the strings, we ++ * must account for them as well. ++ * ++ * The size calculation is the entire vma while each arg page is ++ * built, so each time we get here it's calculating how far it ++ * is currently (rather than each call being just the newly ++ * added size from the arg page). As a result, we need to ++ * always add the entire size of the pointers, so that on the ++ * last call to get_arg_page() we'll actually have the entire ++ * correct size. ++ */ ++ ptr_size = (bprm->argc + bprm->envc) * sizeof(void *); ++ if (ptr_size > ULONG_MAX - size) ++ goto fail; ++ size += ptr_size; ++ + acct_arg_size(bprm, size / PAGE_SIZE); + + /* +@@ -225,13 +243,15 @@ static struct page *get_arg_page(struct + * to work from. + */ + rlim = current->signal->rlim; +- if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) { +- put_page(page); +- return NULL; +- } ++ if (size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) ++ goto fail; + } + + return page; ++ ++fail: ++ put_page(page); ++ return NULL; + } + + static void put_arg_page(struct page *page) diff --git a/queue-4.4/hid-add-quirk-for-dell-pixart-oem-mouse.patch b/queue-4.4/hid-add-quirk-for-dell-pixart-oem-mouse.patch new file mode 100644 index 00000000000..bbb301a8cde --- /dev/null +++ b/queue-4.4/hid-add-quirk-for-dell-pixart-oem-mouse.patch @@ -0,0 +1,43 @@ +From 3db28271f0feae129262d30e41384a7c4c767987 Mon Sep 17 00:00:00 2001 +From: Sebastian Parschauer +Date: Tue, 6 Jun 2017 13:53:13 +0200 +Subject: HID: Add quirk for Dell PIXART OEM mouse + +From: Sebastian Parschauer + +commit 3db28271f0feae129262d30e41384a7c4c767987 upstream. + +This mouse is also known under other IDs. It needs the quirk +ALWAYS_POLL or will disconnect in runlevel 1 or 3. + +Signed-off-by: Sebastian Parschauer +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-ids.h | 3 +++ + drivers/hid/usbhid/hid-quirks.c | 1 + + 2 files changed, 4 insertions(+) + +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -285,6 +285,9 @@ + #define USB_VENDOR_ID_DEALEXTREAME 0x10c5 + #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a + ++#define USB_VENDOR_ID_DELL 0x413c ++#define USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE 0x301a ++ + #define USB_VENDOR_ID_DELORME 0x1163 + #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 + #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -72,6 +72,7 @@ static const struct hid_blacklist { + { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET }, ++ { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL }, diff --git a/queue-4.4/kvm-ppc-book3s-hv-preserve-userspace-htm-state-properly.patch b/queue-4.4/kvm-ppc-book3s-hv-preserve-userspace-htm-state-properly.patch new file mode 100644 index 00000000000..77d7d2e6be9 --- /dev/null +++ b/queue-4.4/kvm-ppc-book3s-hv-preserve-userspace-htm-state-properly.patch @@ -0,0 +1,63 @@ +From 46a704f8409f79fd66567ad3f8a7304830a84293 Mon Sep 17 00:00:00 2001 +From: Paul Mackerras +Date: Thu, 15 Jun 2017 16:10:27 +1000 +Subject: KVM: PPC: Book3S HV: Preserve userspace HTM state properly + +From: Paul Mackerras + +commit 46a704f8409f79fd66567ad3f8a7304830a84293 upstream. + +If userspace attempts to call the KVM_RUN ioctl when it has hardware +transactional memory (HTM) enabled, the values that it has put in the +HTM-related SPRs TFHAR, TFIAR and TEXASR will get overwritten by +guest values. To fix this, we detect this condition and save those +SPR values in the thread struct, and disable HTM for the task. If +userspace goes to access those SPRs or the HTM facility in future, +a TM-unavailable interrupt will occur and the handler will reload +those SPRs and re-enable HTM. + +If userspace has started a transaction and suspended it, we would +currently lose the transactional state in the guest entry path and +would almost certainly get a "TM Bad Thing" interrupt, which would +cause the host to crash. To avoid this, we detect this case and +return from the KVM_RUN ioctl with an EINVAL error, with the KVM +exit reason set to KVM_EXIT_FAIL_ENTRY. + +Fixes: b005255e12a3 ("KVM: PPC: Book3S HV: Context-switch new POWER8 SPRs", 2014-01-08) +Signed-off-by: Paul Mackerras +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kvm/book3s_hv.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +--- a/arch/powerpc/kvm/book3s_hv.c ++++ b/arch/powerpc/kvm/book3s_hv.c +@@ -2693,6 +2693,27 @@ static int kvmppc_vcpu_run_hv(struct kvm + return -EINVAL; + } + ++ /* ++ * Don't allow entry with a suspended transaction, because ++ * the guest entry/exit code will lose it. ++ * If the guest has TM enabled, save away their TM-related SPRs ++ * (they will get restored by the TM unavailable interrupt). ++ */ ++#ifdef CONFIG_PPC_TRANSACTIONAL_MEM ++ if (cpu_has_feature(CPU_FTR_TM) && current->thread.regs && ++ (current->thread.regs->msr & MSR_TM)) { ++ if (MSR_TM_ACTIVE(current->thread.regs->msr)) { ++ run->exit_reason = KVM_EXIT_FAIL_ENTRY; ++ run->fail_entry.hardware_entry_failure_reason = 0; ++ return -EINVAL; ++ } ++ current->thread.tm_tfhar = mfspr(SPRN_TFHAR); ++ current->thread.tm_tfiar = mfspr(SPRN_TFIAR); ++ current->thread.tm_texasr = mfspr(SPRN_TEXASR); ++ current->thread.regs->msr &= ~MSR_TM; ++ } ++#endif ++ + kvmppc_core_prepare_to_enter(vcpu); + + /* No need to go into the guest when all we'll do is come back out */ diff --git a/queue-4.4/lib-cmdline.c-fix-get_options-overflow-while-parsing-ranges.patch b/queue-4.4/lib-cmdline.c-fix-get_options-overflow-while-parsing-ranges.patch new file mode 100644 index 00000000000..c6c8678ca24 --- /dev/null +++ b/queue-4.4/lib-cmdline.c-fix-get_options-overflow-while-parsing-ranges.patch @@ -0,0 +1,53 @@ +From a91e0f680bcd9e10c253ae8b62462a38bd48f09f Mon Sep 17 00:00:00 2001 +From: Ilya Matveychikov +Date: Fri, 23 Jun 2017 15:08:49 -0700 +Subject: lib/cmdline.c: fix get_options() overflow while parsing ranges + +From: Ilya Matveychikov + +commit a91e0f680bcd9e10c253ae8b62462a38bd48f09f upstream. + +When using get_options() it's possible to specify a range of numbers, +like 1-100500. The problem is that it doesn't track array size while +calling internally to get_range() which iterates over the range and +fills the memory with numbers. + +Link: http://lkml.kernel.org/r/2613C75C-B04D-4BFF-82A6-12F97BA0F620@gmail.com +Signed-off-by: Ilya V. Matveychikov +Cc: Jonathan Corbet +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + lib/cmdline.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/lib/cmdline.c ++++ b/lib/cmdline.c +@@ -22,14 +22,14 @@ + * the values[M, M+1, ..., N] into the ints array in get_options. + */ + +-static int get_range(char **str, int *pint) ++static int get_range(char **str, int *pint, int n) + { + int x, inc_counter, upper_range; + + (*str)++; + upper_range = simple_strtol((*str), NULL, 0); + inc_counter = upper_range - *pint; +- for (x = *pint; x < upper_range; x++) ++ for (x = *pint; n && x < upper_range; x++, n--) + *pint++ = x; + return inc_counter; + } +@@ -96,7 +96,7 @@ char *get_options(const char *str, int n + break; + if (res == 3) { + int range_nums; +- range_nums = get_range((char **)&str, ints + i); ++ range_nums = get_range((char **)&str, ints + i, nints - i); + if (range_nums < 0) + break; + /* diff --git a/queue-4.4/signal-only-reschedule-timers-on-signals-timers-have-sent.patch b/queue-4.4/signal-only-reschedule-timers-on-signals-timers-have-sent.patch new file mode 100644 index 00000000000..928fe85a91b --- /dev/null +++ b/queue-4.4/signal-only-reschedule-timers-on-signals-timers-have-sent.patch @@ -0,0 +1,152 @@ +From 57db7e4a2d92c2d3dfbca4ef8057849b2682436b Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Tue, 13 Jun 2017 04:31:16 -0500 +Subject: signal: Only reschedule timers on signals timers have sent + +From: Eric W. Biederman + +commit 57db7e4a2d92c2d3dfbca4ef8057849b2682436b upstream. + +Thomas Gleixner wrote: +> The CRIU support added a 'feature' which allows a user space task to send +> arbitrary (kernel) signals to itself. The changelog says: +> +> The kernel prevents sending of siginfo with positive si_code, because +> these codes are reserved for kernel. I think we can allow a task to +> send such a siginfo to itself. This operation should not be dangerous. +> +> Quite contrary to that claim, it turns out that it is outright dangerous +> for signals with info->si_code == SI_TIMER. The following code sequence in +> a user space task allows to crash the kernel: +> +> id = timer_create(CLOCK_XXX, ..... signo = SIGX); +> timer_set(id, ....); +> info->si_signo = SIGX; +> info->si_code = SI_TIMER: +> info->_sifields._timer._tid = id; +> info->_sifields._timer._sys_private = 2; +> rt_[tg]sigqueueinfo(..., SIGX, info); +> sigemptyset(&sigset); +> sigaddset(&sigset, SIGX); +> rt_sigtimedwait(sigset, info); +> +> For timers based on CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID this +> results in a kernel crash because sigwait() dequeues the signal and the +> dequeue code observes: +> +> info->si_code == SI_TIMER && info->_sifields._timer._sys_private != 0 +> +> which triggers the following callchain: +> +> do_schedule_next_timer() -> posix_cpu_timer_schedule() -> arm_timer() +> +> arm_timer() executes a list_add() on the timer, which is already armed via +> the timer_set() syscall. That's a double list add which corrupts the posix +> cpu timer list. As a consequence the kernel crashes on the next operation +> touching the posix cpu timer list. +> +> Posix clocks which are internally implemented based on hrtimers are not +> affected by this because hrtimer_start() can handle already armed timers +> nicely, but it's a reliable way to trigger the WARN_ON() in +> hrtimer_forward(), which complains about calling that function on an +> already armed timer. + +This problem has existed since the posix timer code was merged into +2.5.63. A few releases earlier in 2.5.60 ptrace gained the ability to +inject not just a signal (which linux has supported since 1.0) but the +full siginfo of a signal. + +The core problem is that the code will reschedule in response to +signals getting dequeued not just for signals the timers sent but +for other signals that happen to a si_code of SI_TIMER. + +Avoid this confusion by testing to see if the queued signal was +preallocated as all timer signals are preallocated, and so far +only the timer code preallocates signals. + +Move the check for if a timer needs to be rescheduled up into +collect_signal where the preallocation check must be performed, +and pass the result back to dequeue_signal where the code reschedules +timers. This makes it clear why the code cares about preallocated +timers. + +Reported-by: Thomas Gleixner +History Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git +Reference: 66dd34ad31e5 ("signal: allow to send any siginfo to itself") +Reference: 1669ce53e2ff ("Add PTRACE_GETSIGINFO and PTRACE_SETSIGINFO") +Fixes: db8b50ba75f2 ("[PATCH] POSIX clocks & timers") +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/signal.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -503,7 +503,8 @@ int unhandled_signal(struct task_struct + return !tsk->ptrace; + } + +-static void collect_signal(int sig, struct sigpending *list, siginfo_t *info) ++static void collect_signal(int sig, struct sigpending *list, siginfo_t *info, ++ bool *resched_timer) + { + struct sigqueue *q, *first = NULL; + +@@ -525,6 +526,12 @@ static void collect_signal(int sig, stru + still_pending: + list_del_init(&first->list); + copy_siginfo(info, &first->info); ++ ++ *resched_timer = ++ (first->flags & SIGQUEUE_PREALLOC) && ++ (info->si_code == SI_TIMER) && ++ (info->si_sys_private); ++ + __sigqueue_free(first); + } else { + /* +@@ -541,12 +548,12 @@ still_pending: + } + + static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, +- siginfo_t *info) ++ siginfo_t *info, bool *resched_timer) + { + int sig = next_signal(pending, mask); + + if (sig) +- collect_signal(sig, pending, info); ++ collect_signal(sig, pending, info, resched_timer); + return sig; + } + +@@ -558,15 +565,16 @@ static int __dequeue_signal(struct sigpe + */ + int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) + { ++ bool resched_timer = false; + int signr; + + /* We only dequeue private signals from ourselves, we don't let + * signalfd steal them + */ +- signr = __dequeue_signal(&tsk->pending, mask, info); ++ signr = __dequeue_signal(&tsk->pending, mask, info, &resched_timer); + if (!signr) { + signr = __dequeue_signal(&tsk->signal->shared_pending, +- mask, info); ++ mask, info, &resched_timer); + /* + * itimer signal ? + * +@@ -611,7 +619,7 @@ int dequeue_signal(struct task_struct *t + */ + current->jobctl |= JOBCTL_STOP_DEQUEUED; + } +- if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) { ++ if (resched_timer) { + /* + * Release the siglock to ensure proper locking order + * of timer locks outside of siglocks. Note, we leave