From: Greg Kroah-Hartman Date: Tue, 13 Feb 2018 16:19:13 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.15.4~47 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8f8d1f06a511fdfe25e54d8f613a063bac981e50;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: cifs-fix-autonegotiate-security-settings-mismatch.patch cifs-fix-missing-put_xid-in-cifs_file_strict_mmap.patch cifs-zero-sensitive-data-when-freeing.patch dccp-cve-2017-8824-use-after-free-in-dccp-code.patch dmaengine-dmatest-fix-container_of-member-in-dmatest_callback.patch kaiser-fix-compile-error-without-vsyscall.patch media-dvb-usb-v2-lmedm04-improve-logic-checking-of-warm-start.patch media-dvb-usb-v2-lmedm04-move-ts2020-attach-to-dm04_lme2510_tuner.patch media-hdpvr-fix-an-error-handling-path-in-hdpvr_probe.patch posix-timer-properly-check-sigevent-sigev_notify.patch powerpc-pseries-include-linux-types.h-in-asm-hvcall.h.patch sched-rt-up-the-root-domain-ref-count-when-passing-it-around-via-ipis.patch sched-rt-use-container_of-to-get-root-domain-in-rto_push_irq_work_func.patch usb-gadget-uvc-missing-files-for-configfs-interface.patch --- diff --git a/queue-4.9/cifs-fix-autonegotiate-security-settings-mismatch.patch b/queue-4.9/cifs-fix-autonegotiate-security-settings-mismatch.patch new file mode 100644 index 00000000000..1a3eb8aef31 --- /dev/null +++ b/queue-4.9/cifs-fix-autonegotiate-security-settings-mismatch.patch @@ -0,0 +1,47 @@ +From 9aca7e454415f7878b28524e76bebe1170911a88 Mon Sep 17 00:00:00 2001 +From: Daniel N Pettersson +Date: Thu, 11 Jan 2018 16:00:12 +0100 +Subject: cifs: Fix autonegotiate security settings mismatch + +From: Daniel N Pettersson + +commit 9aca7e454415f7878b28524e76bebe1170911a88 upstream. + +Autonegotiation gives a security settings mismatch error if the SMB +server selects an SMBv3 dialect that isn't SMB3.02. The exact error is +"protocol revalidation - security settings mismatch". +This can be tested using Samba v4.2 or by setting the global Samba +setting max protocol = SMB3_00. + +The check that fails in smb3_validate_negotiate is the dialect +verification of the negotiate info response. This is because it tries +to verify against the protocol_id in the global smbdefault_values. The +protocol_id in smbdefault_values is SMB3.02. +In SMB2_negotiate the protocol_id in smbdefault_values isn't updated, +it is global so it probably shouldn't be, but server->dialect is. + +This patch changes the check in smb3_validate_negotiate to use +server->dialect instead of server->vals->protocol_id. The patch works +with autonegotiate and when using a specific version in the vers mount +option. + +Signed-off-by: Daniel N Pettersson +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2pdu.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -585,8 +585,7 @@ int smb3_validate_negotiate(const unsign + } + + /* check validate negotiate info response matches what we got earlier */ +- if (pneg_rsp->Dialect != +- cpu_to_le16(tcon->ses->server->vals->protocol_id)) ++ if (pneg_rsp->Dialect != cpu_to_le16(tcon->ses->server->dialect)) + goto vneg_out; + + if (pneg_rsp->SecurityMode != cpu_to_le16(tcon->ses->server->sec_mode)) diff --git a/queue-4.9/cifs-fix-missing-put_xid-in-cifs_file_strict_mmap.patch b/queue-4.9/cifs-fix-missing-put_xid-in-cifs_file_strict_mmap.patch new file mode 100644 index 00000000000..08789b7e706 --- /dev/null +++ b/queue-4.9/cifs-fix-missing-put_xid-in-cifs_file_strict_mmap.patch @@ -0,0 +1,74 @@ +From f04a703c3d613845ae3141bfaf223489de8ab3eb Mon Sep 17 00:00:00 2001 +From: Matthew Wilcox +Date: Fri, 15 Dec 2017 12:48:32 -0800 +Subject: cifs: Fix missing put_xid in cifs_file_strict_mmap + +From: Matthew Wilcox + +commit f04a703c3d613845ae3141bfaf223489de8ab3eb upstream. + +If cifs_zap_mapping() returned an error, we would return without putting +the xid that we got earlier. Restructure cifs_file_strict_mmap() and +cifs_file_mmap() to be more similar to each other and have a single +point of return that always puts the xid. + +Signed-off-by: Matthew Wilcox +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/file.c | 26 ++++++++++++-------------- + 1 file changed, 12 insertions(+), 14 deletions(-) + +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -3285,20 +3285,18 @@ static const struct vm_operations_struct + + int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma) + { +- int rc, xid; ++ int xid, rc = 0; + struct inode *inode = file_inode(file); + + xid = get_xid(); + +- if (!CIFS_CACHE_READ(CIFS_I(inode))) { ++ if (!CIFS_CACHE_READ(CIFS_I(inode))) + rc = cifs_zap_mapping(inode); +- if (rc) +- return rc; +- } +- +- rc = generic_file_mmap(file, vma); +- if (rc == 0) ++ if (!rc) ++ rc = generic_file_mmap(file, vma); ++ if (!rc) + vma->vm_ops = &cifs_file_vm_ops; ++ + free_xid(xid); + return rc; + } +@@ -3308,16 +3306,16 @@ int cifs_file_mmap(struct file *file, st + int rc, xid; + + xid = get_xid(); ++ + rc = cifs_revalidate_file(file); +- if (rc) { ++ if (rc) + cifs_dbg(FYI, "Validation prior to mmap failed, error=%d\n", + rc); +- free_xid(xid); +- return rc; +- } +- rc = generic_file_mmap(file, vma); +- if (rc == 0) ++ if (!rc) ++ rc = generic_file_mmap(file, vma); ++ if (!rc) + vma->vm_ops = &cifs_file_vm_ops; ++ + free_xid(xid); + return rc; + } diff --git a/queue-4.9/cifs-zero-sensitive-data-when-freeing.patch b/queue-4.9/cifs-zero-sensitive-data-when-freeing.patch new file mode 100644 index 00000000000..569e042e4ec --- /dev/null +++ b/queue-4.9/cifs-zero-sensitive-data-when-freeing.patch @@ -0,0 +1,96 @@ +From 97f4b7276b829a8927ac903a119bef2f963ccc58 Mon Sep 17 00:00:00 2001 +From: Aurelien Aptel +Date: Thu, 25 Jan 2018 15:59:39 +0100 +Subject: CIFS: zero sensitive data when freeing + +From: Aurelien Aptel + +commit 97f4b7276b829a8927ac903a119bef2f963ccc58 upstream. + +also replaces memset()+kfree() by kzfree(). + +Signed-off-by: Aurelien Aptel +Signed-off-by: Steve French +Reviewed-by: Pavel Shilovsky +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifsencrypt.c | 3 +-- + fs/cifs/connect.c | 6 +++--- + fs/cifs/misc.c | 14 ++++---------- + 3 files changed, 8 insertions(+), 15 deletions(-) + +--- a/fs/cifs/cifsencrypt.c ++++ b/fs/cifs/cifsencrypt.c +@@ -318,9 +318,8 @@ int calc_lanman_hash(const char *passwor + { + int i; + int rc; +- char password_with_pad[CIFS_ENCPWD_SIZE]; ++ char password_with_pad[CIFS_ENCPWD_SIZE] = {0}; + +- memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); + if (password) + strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE); + +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -1667,7 +1667,7 @@ cifs_parse_mount_options(const char *mou + tmp_end++; + if (!(tmp_end < end && tmp_end[1] == delim)) { + /* No it is not. Set the password to NULL */ +- kfree(vol->password); ++ kzfree(vol->password); + vol->password = NULL; + break; + } +@@ -1705,7 +1705,7 @@ cifs_parse_mount_options(const char *mou + options = end; + } + +- kfree(vol->password); ++ kzfree(vol->password); + /* Now build new password string */ + temp_len = strlen(value); + vol->password = kzalloc(temp_len+1, GFP_KERNEL); +@@ -4159,7 +4159,7 @@ cifs_construct_tcon(struct cifs_sb_info + reset_cifs_unix_caps(0, tcon, NULL, vol_info); + out: + kfree(vol_info->username); +- kfree(vol_info->password); ++ kzfree(vol_info->password); + kfree(vol_info); + + return tcon; +--- a/fs/cifs/misc.c ++++ b/fs/cifs/misc.c +@@ -99,14 +99,11 @@ sesInfoFree(struct cifs_ses *buf_to_free + kfree(buf_to_free->serverOS); + kfree(buf_to_free->serverDomain); + kfree(buf_to_free->serverNOS); +- if (buf_to_free->password) { +- memset(buf_to_free->password, 0, strlen(buf_to_free->password)); +- kfree(buf_to_free->password); +- } ++ kzfree(buf_to_free->password); + kfree(buf_to_free->user_name); + kfree(buf_to_free->domainName); +- kfree(buf_to_free->auth_key.response); +- kfree(buf_to_free); ++ kzfree(buf_to_free->auth_key.response); ++ kzfree(buf_to_free); + } + + struct cifs_tcon * +@@ -137,10 +134,7 @@ tconInfoFree(struct cifs_tcon *buf_to_fr + } + atomic_dec(&tconInfoAllocCount); + kfree(buf_to_free->nativeFileSystem); +- if (buf_to_free->password) { +- memset(buf_to_free->password, 0, strlen(buf_to_free->password)); +- kfree(buf_to_free->password); +- } ++ kzfree(buf_to_free->password); + kfree(buf_to_free); + } + diff --git a/queue-4.9/dccp-cve-2017-8824-use-after-free-in-dccp-code.patch b/queue-4.9/dccp-cve-2017-8824-use-after-free-in-dccp-code.patch new file mode 100644 index 00000000000..9bf5883664d --- /dev/null +++ b/queue-4.9/dccp-cve-2017-8824-use-after-free-in-dccp-code.patch @@ -0,0 +1,43 @@ +From 69c64866ce072dea1d1e59a0d61e0f66c0dffb76 Mon Sep 17 00:00:00 2001 +From: Mohamed Ghannam +Date: Tue, 5 Dec 2017 20:58:35 +0000 +Subject: dccp: CVE-2017-8824: use-after-free in DCCP code + +From: Mohamed Ghannam + +commit 69c64866ce072dea1d1e59a0d61e0f66c0dffb76 upstream. + +Whenever the sock object is in DCCP_CLOSED state, +dccp_disconnect() must free dccps_hc_tx_ccid and +dccps_hc_rx_ccid and set to NULL. + +Signed-off-by: Mohamed Ghannam +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/dccp/proto.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/dccp/proto.c ++++ b/net/dccp/proto.c +@@ -259,6 +259,7 @@ int dccp_disconnect(struct sock *sk, int + { + struct inet_connection_sock *icsk = inet_csk(sk); + struct inet_sock *inet = inet_sk(sk); ++ struct dccp_sock *dp = dccp_sk(sk); + int err = 0; + const int old_state = sk->sk_state; + +@@ -278,6 +279,10 @@ int dccp_disconnect(struct sock *sk, int + sk->sk_err = ECONNRESET; + + dccp_clear_xmit_timers(sk); ++ ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk); ++ ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk); ++ dp->dccps_hc_rx_ccid = NULL; ++ dp->dccps_hc_tx_ccid = NULL; + + __skb_queue_purge(&sk->sk_receive_queue); + __skb_queue_purge(&sk->sk_write_queue); diff --git a/queue-4.9/dmaengine-dmatest-fix-container_of-member-in-dmatest_callback.patch b/queue-4.9/dmaengine-dmatest-fix-container_of-member-in-dmatest_callback.patch new file mode 100644 index 00000000000..bc7bec0bdc1 --- /dev/null +++ b/queue-4.9/dmaengine-dmatest-fix-container_of-member-in-dmatest_callback.patch @@ -0,0 +1,33 @@ +From 66b3bd2356e0a1531c71a3dcf96944621e25c17c Mon Sep 17 00:00:00 2001 +From: Yang Shunyong +Date: Mon, 29 Jan 2018 14:40:11 +0800 +Subject: dmaengine: dmatest: fix container_of member in dmatest_callback + +From: Yang Shunyong + +commit 66b3bd2356e0a1531c71a3dcf96944621e25c17c upstream. + +The type of arg passed to dmatest_callback is struct dmatest_done. +It refers to test_done in struct dmatest_thread, not done_wait. + +Fixes: 6f6a23a213be ("dmaengine: dmatest: move callback wait ...") +Signed-off-by: Yang Shunyong +Acked-by: Adam Wallis +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/dmatest.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/dma/dmatest.c ++++ b/drivers/dma/dmatest.c +@@ -339,7 +339,7 @@ static void dmatest_callback(void *arg) + { + struct dmatest_done *done = arg; + struct dmatest_thread *thread = +- container_of(arg, struct dmatest_thread, done_wait); ++ container_of(done, struct dmatest_thread, test_done); + if (!thread->done) { + done->done = true; + wake_up_all(done->wait); diff --git a/queue-4.9/kaiser-fix-compile-error-without-vsyscall.patch b/queue-4.9/kaiser-fix-compile-error-without-vsyscall.patch new file mode 100644 index 00000000000..1c5369d1ff6 --- /dev/null +++ b/queue-4.9/kaiser-fix-compile-error-without-vsyscall.patch @@ -0,0 +1,46 @@ +From foo@baz Tue Feb 13 16:45:20 CET 2018 +Date: Tue, 13 Feb 2018 16:45:20 +0100 +To: Greg KH +From: Hugh Dickins +Subject: kaiser: fix compile error without vsyscall + +From: Hugh Dickins + +Tobias noticed a compile error on 4.4.115, and it's the same on 4.9.80: +arch/x86/mm/kaiser.c: In function ‘kaiser_init’: +arch/x86/mm/kaiser.c:348:8: error: ‘vsyscall_pgprot’ undeclared + (first use in this function) + +It seems like his combination of kernel options doesn't work for KAISER. +X86_VSYSCALL_EMULATION is not set on his system, while LEGACY_VSYSCALL +is set to NONE (LEGACY_VSYSCALL_NONE=y). He managed to get things +compiling again, by moving the 'extern unsigned long vsyscall_pgprot' +outside of the preprocessor statement. This works because the optimizer +removes that code (vsyscall_enabled() is always false) - and that's how +it was done in some older backports. + +Reported-by: Tobias Jakobi +Signed-off-by: Hugh Dickins +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/vsyscall.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/include/asm/vsyscall.h ++++ b/arch/x86/include/asm/vsyscall.h +@@ -13,7 +13,6 @@ extern void map_vsyscall(void); + */ + extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address); + extern bool vsyscall_enabled(void); +-extern unsigned long vsyscall_pgprot; + #else + static inline void map_vsyscall(void) {} + static inline bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) +@@ -22,5 +21,6 @@ static inline bool emulate_vsyscall(stru + } + static inline bool vsyscall_enabled(void) { return false; } + #endif ++extern unsigned long vsyscall_pgprot; + + #endif /* _ASM_X86_VSYSCALL_H */ diff --git a/queue-4.9/media-dvb-usb-v2-lmedm04-improve-logic-checking-of-warm-start.patch b/queue-4.9/media-dvb-usb-v2-lmedm04-improve-logic-checking-of-warm-start.patch new file mode 100644 index 00000000000..ab7817a9ebc --- /dev/null +++ b/queue-4.9/media-dvb-usb-v2-lmedm04-improve-logic-checking-of-warm-start.patch @@ -0,0 +1,88 @@ +From 3d932ee27e852e4904647f15b64dedca51187ad7 Mon Sep 17 00:00:00 2001 +From: Malcolm Priestley +Date: Tue, 26 Sep 2017 17:10:20 -0400 +Subject: media: dvb-usb-v2: lmedm04: Improve logic checking of warm start + +From: Malcolm Priestley + +commit 3d932ee27e852e4904647f15b64dedca51187ad7 upstream. + +Warm start has no check as whether a genuine device has +connected and proceeds to next execution path. + +Check device should read 0x47 at offset of 2 on USB descriptor read +and it is the amount requested of 6 bytes. + +Fix for +kasan: CONFIG_KASAN_INLINE enabled +kasan: GPF could be caused by NULL-ptr deref or user memory access as + +Reported-by: Andrey Konovalov +Signed-off-by: Malcolm Priestley +Signed-off-by: Mauro Carvalho Chehab +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/dvb-usb-v2/lmedm04.c | 26 ++++++++++++++++++-------- + 1 file changed, 18 insertions(+), 8 deletions(-) + +--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c ++++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c +@@ -504,18 +504,23 @@ static int lme2510_pid_filter(struct dvb + + static int lme2510_return_status(struct dvb_usb_device *d) + { +- int ret = 0; ++ int ret; + u8 *data; + +- data = kzalloc(10, GFP_KERNEL); ++ data = kzalloc(6, GFP_KERNEL); + if (!data) + return -ENOMEM; + +- ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), +- 0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200); +- info("Firmware Status: %x (%x)", ret , data[2]); ++ ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), ++ 0x06, 0x80, 0x0302, 0x00, ++ data, 0x6, 200); ++ if (ret != 6) ++ ret = -EINVAL; ++ else ++ ret = data[2]; ++ ++ info("Firmware Status: %6ph", data); + +- ret = (ret < 0) ? -ENODEV : data[2]; + kfree(data); + return ret; + } +@@ -1200,6 +1205,7 @@ static int lme2510_get_adapter_count(str + static int lme2510_identify_state(struct dvb_usb_device *d, const char **name) + { + struct lme2510_state *st = d->priv; ++ int status; + + usb_reset_configuration(d->udev); + +@@ -1208,12 +1214,16 @@ static int lme2510_identify_state(struct + + st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware; + +- if (lme2510_return_status(d) == 0x44) { ++ status = lme2510_return_status(d); ++ if (status == 0x44) { + *name = lme_firmware_switch(d, 0); + return COLD; + } + +- return 0; ++ if (status != 0x47) ++ return -EINVAL; ++ ++ return WARM; + } + + static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type, diff --git a/queue-4.9/media-dvb-usb-v2-lmedm04-move-ts2020-attach-to-dm04_lme2510_tuner.patch b/queue-4.9/media-dvb-usb-v2-lmedm04-move-ts2020-attach-to-dm04_lme2510_tuner.patch new file mode 100644 index 00000000000..9d5c9546b6c --- /dev/null +++ b/queue-4.9/media-dvb-usb-v2-lmedm04-move-ts2020-attach-to-dm04_lme2510_tuner.patch @@ -0,0 +1,72 @@ +From 7bf7a7116ed313c601307f7e585419369926ab05 Mon Sep 17 00:00:00 2001 +From: Malcolm Priestley +Date: Tue, 26 Sep 2017 17:10:21 -0400 +Subject: media: dvb-usb-v2: lmedm04: move ts2020 attach to dm04_lme2510_tuner + +From: Malcolm Priestley + +commit 7bf7a7116ed313c601307f7e585419369926ab05 upstream. + +When the tuner was split from m88rs2000 the attach function is in wrong +place. + +Move to dm04_lme2510_tuner to trap errors on failure and removing +a call to lme_coldreset. + +Prevents driver starting up without any tuner connected. + +Fixes to trap for ts2020 fail. +LME2510(C): FE Found M88RS2000 +ts2020: probe of 0-0060 failed with error -11 +... +LME2510(C): TUN Found RS2000 tuner +kasan: CONFIG_KASAN_INLINE enabled +kasan: GPF could be caused by NULL-ptr deref or user memory access +general protection fault: 0000 [#1] PREEMPT SMP KASAN + +Reported-by: Andrey Konovalov +Signed-off-by: Malcolm Priestley +Tested-by: Andrey Konovalov +Signed-off-by: Mauro Carvalho Chehab +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/dvb-usb-v2/lmedm04.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c ++++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c +@@ -1084,8 +1084,6 @@ static int dm04_lme2510_frontend_attach( + + if (adap->fe[0]) { + info("FE Found M88RS2000"); +- dvb_attach(ts2020_attach, adap->fe[0], &ts2020_config, +- &d->i2c_adap); + st->i2c_tuner_gate_w = 5; + st->i2c_tuner_gate_r = 5; + st->i2c_tuner_addr = 0x60; +@@ -1151,17 +1149,18 @@ static int dm04_lme2510_tuner(struct dvb + ret = st->tuner_config; + break; + case TUNER_RS2000: +- ret = st->tuner_config; ++ if (dvb_attach(ts2020_attach, adap->fe[0], ++ &ts2020_config, &d->i2c_adap)) ++ ret = st->tuner_config; + break; + default: + break; + } + +- if (ret) ++ if (ret) { + info("TUN Found %s tuner", tun_msg[ret]); +- else { +- info("TUN No tuner found --- resetting device"); +- lme_coldreset(d); ++ } else { ++ info("TUN No tuner found"); + return -ENODEV; + } + diff --git a/queue-4.9/media-hdpvr-fix-an-error-handling-path-in-hdpvr_probe.patch b/queue-4.9/media-hdpvr-fix-an-error-handling-path-in-hdpvr_probe.patch new file mode 100644 index 00000000000..e57f9b56a7f --- /dev/null +++ b/queue-4.9/media-hdpvr-fix-an-error-handling-path-in-hdpvr_probe.patch @@ -0,0 +1,104 @@ +From c0f71bbb810237a38734607ca4599632f7f5d47f Mon Sep 17 00:00:00 2001 +From: Arvind Yadav +Date: Fri, 22 Sep 2017 09:07:06 -0400 +Subject: media: hdpvr: Fix an error handling path in hdpvr_probe() + +From: Arvind Yadav + +commit c0f71bbb810237a38734607ca4599632f7f5d47f upstream. + +Here, hdpvr_register_videodev() is responsible for setup and +register a video device. Also defining and initializing a worker. +hdpvr_register_videodev() is calling by hdpvr_probe at last. +So no need to flush any work here. +Unregister v4l2, free buffers and memory. If hdpvr_probe() will fail. + +Signed-off-by: Arvind Yadav +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/hdpvr/hdpvr-core.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +--- a/drivers/media/usb/hdpvr/hdpvr-core.c ++++ b/drivers/media/usb/hdpvr/hdpvr-core.c +@@ -295,7 +295,7 @@ static int hdpvr_probe(struct usb_interf + /* register v4l2_device early so it can be used for printks */ + if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) { + dev_err(&interface->dev, "v4l2_device_register failed\n"); +- goto error; ++ goto error_free_dev; + } + + mutex_init(&dev->io_mutex); +@@ -304,7 +304,7 @@ static int hdpvr_probe(struct usb_interf + dev->usbc_buf = kmalloc(64, GFP_KERNEL); + if (!dev->usbc_buf) { + v4l2_err(&dev->v4l2_dev, "Out of memory\n"); +- goto error; ++ goto error_v4l2_unregister; + } + + init_waitqueue_head(&dev->wait_buffer); +@@ -342,13 +342,13 @@ static int hdpvr_probe(struct usb_interf + } + if (!dev->bulk_in_endpointAddr) { + v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n"); +- goto error; ++ goto error_put_usb; + } + + /* init the device */ + if (hdpvr_device_init(dev)) { + v4l2_err(&dev->v4l2_dev, "device init failed\n"); +- goto error; ++ goto error_put_usb; + } + + mutex_lock(&dev->io_mutex); +@@ -356,7 +356,7 @@ static int hdpvr_probe(struct usb_interf + mutex_unlock(&dev->io_mutex); + v4l2_err(&dev->v4l2_dev, + "allocating transfer buffers failed\n"); +- goto error; ++ goto error_put_usb; + } + mutex_unlock(&dev->io_mutex); + +@@ -364,7 +364,7 @@ static int hdpvr_probe(struct usb_interf + retval = hdpvr_register_i2c_adapter(dev); + if (retval < 0) { + v4l2_err(&dev->v4l2_dev, "i2c adapter register failed\n"); +- goto error; ++ goto error_free_buffers; + } + + client = hdpvr_register_ir_rx_i2c(dev); +@@ -397,13 +397,17 @@ static int hdpvr_probe(struct usb_interf + reg_fail: + #if IS_ENABLED(CONFIG_I2C) + i2c_del_adapter(&dev->i2c_adapter); ++error_free_buffers: + #endif ++ hdpvr_free_buffers(dev); ++error_put_usb: ++ usb_put_dev(dev->udev); ++ kfree(dev->usbc_buf); ++error_v4l2_unregister: ++ v4l2_device_unregister(&dev->v4l2_dev); ++error_free_dev: ++ kfree(dev); + error: +- if (dev) { +- flush_work(&dev->worker); +- /* this frees allocated memory */ +- hdpvr_delete(dev); +- } + return retval; + } + diff --git a/queue-4.9/posix-timer-properly-check-sigevent-sigev_notify.patch b/queue-4.9/posix-timer-properly-check-sigevent-sigev_notify.patch new file mode 100644 index 00000000000..c5000c593f6 --- /dev/null +++ b/queue-4.9/posix-timer-properly-check-sigevent-sigev_notify.patch @@ -0,0 +1,110 @@ +From cef31d9af908243421258f1df35a4a644604efbe Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Fri, 15 Dec 2017 10:32:03 +0100 +Subject: posix-timer: Properly check sigevent->sigev_notify + +From: Thomas Gleixner + +commit cef31d9af908243421258f1df35a4a644604efbe upstream. + +timer_create() specifies via sigevent->sigev_notify the signal delivery for +the new timer. The valid modes are SIGEV_NONE, SIGEV_SIGNAL, SIGEV_THREAD +and (SIGEV_SIGNAL | SIGEV_THREAD_ID). + +The sanity check in good_sigevent() is only checking the valid combination +for the SIGEV_THREAD_ID bit, i.e. SIGEV_SIGNAL, but if SIGEV_THREAD_ID is +not set it accepts any random value. + +This has no real effects on the posix timer and signal delivery code, but +it affects show_timer() which handles the output of /proc/$PID/timers. That +function uses a string array to pretty print sigev_notify. The access to +that array has no bound checks, so random sigev_notify cause access beyond +the array bounds. + +Add proper checks for the valid notify modes and remove the SIGEV_THREAD_ID +masking from various code pathes as SIGEV_NONE can never be set in +combination with SIGEV_THREAD_ID. + +Reported-by: Eric Biggers +Reported-by: Dmitry Vyukov +Reported-by: Alexey Dobriyan +Signed-off-by: Thomas Gleixner +Cc: John Stultz +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/posix-timers.c | 34 +++++++++++++++++++--------------- + 1 file changed, 19 insertions(+), 15 deletions(-) + +--- a/kernel/time/posix-timers.c ++++ b/kernel/time/posix-timers.c +@@ -507,17 +507,22 @@ static struct pid *good_sigevent(sigeven + { + struct task_struct *rtn = current->group_leader; + +- if ((event->sigev_notify & SIGEV_THREAD_ID ) && +- (!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) || +- !same_thread_group(rtn, current) || +- (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL)) ++ switch (event->sigev_notify) { ++ case SIGEV_SIGNAL | SIGEV_THREAD_ID: ++ rtn = find_task_by_vpid(event->sigev_notify_thread_id); ++ if (!rtn || !same_thread_group(rtn, current)) ++ return NULL; ++ /* FALLTHRU */ ++ case SIGEV_SIGNAL: ++ case SIGEV_THREAD: ++ if (event->sigev_signo <= 0 || event->sigev_signo > SIGRTMAX) ++ return NULL; ++ /* FALLTHRU */ ++ case SIGEV_NONE: ++ return task_pid(rtn); ++ default: + return NULL; +- +- if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) && +- ((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX))) +- return NULL; +- +- return task_pid(rtn); ++ } + } + + void posix_timers_register_clock(const clockid_t clock_id, +@@ -745,8 +750,7 @@ common_timer_get(struct k_itimer *timr, + /* interval timer ? */ + if (iv.tv64) + cur_setting->it_interval = ktime_to_timespec(iv); +- else if (!hrtimer_active(timer) && +- (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) ++ else if (!hrtimer_active(timer) && timr->it_sigev_notify != SIGEV_NONE) + return; + + now = timer->base->get_time(); +@@ -757,7 +761,7 @@ common_timer_get(struct k_itimer *timr, + * expiry is > now. + */ + if (iv.tv64 && (timr->it_requeue_pending & REQUEUE_PENDING || +- (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) ++ timr->it_sigev_notify == SIGEV_NONE)) + timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv); + + remaining = __hrtimer_expires_remaining_adjusted(timer, now); +@@ -767,7 +771,7 @@ common_timer_get(struct k_itimer *timr, + * A single shot SIGEV_NONE timer must return 0, when + * it is expired ! + */ +- if ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) ++ if (timr->it_sigev_notify != SIGEV_NONE) + cur_setting->it_value.tv_nsec = 1; + } else + cur_setting->it_value = ktime_to_timespec(remaining); +@@ -865,7 +869,7 @@ common_timer_set(struct k_itimer *timr, + timr->it.real.interval = timespec_to_ktime(new_setting->it_interval); + + /* SIGEV_NONE timers are not queued ! See common_timer_get */ +- if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { ++ if (timr->it_sigev_notify == SIGEV_NONE) { + /* Setup correct expiry time for relative timers */ + if (mode == HRTIMER_MODE_REL) { + hrtimer_add_expires(timer, timer->base->get_time()); diff --git a/queue-4.9/powerpc-pseries-include-linux-types.h-in-asm-hvcall.h.patch b/queue-4.9/powerpc-pseries-include-linux-types.h-in-asm-hvcall.h.patch new file mode 100644 index 00000000000..fe53d0c06c4 --- /dev/null +++ b/queue-4.9/powerpc-pseries-include-linux-types.h-in-asm-hvcall.h.patch @@ -0,0 +1,33 @@ +From 1b689a95ce7427075f9ac9fb4aea1af530742b7f Mon Sep 17 00:00:00 2001 +From: Michal Suchanek +Date: Mon, 15 Jan 2018 14:30:03 +0100 +Subject: powerpc/pseries: include linux/types.h in asm/hvcall.h + +From: Michal Suchanek + +commit 1b689a95ce7427075f9ac9fb4aea1af530742b7f upstream. + +Commit 6e032b350cd1 ("powerpc/powernv: Check device-tree for RFI flush +settings") uses u64 in asm/hvcall.h without including linux/types.h + +This breaks hvcall.h users that do not include the header themselves. + +Fixes: 6e032b350cd1 ("powerpc/powernv: Check device-tree for RFI flush settings") +Signed-off-by: Michal Suchanek +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/hvcall.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/powerpc/include/asm/hvcall.h ++++ b/arch/powerpc/include/asm/hvcall.h +@@ -319,6 +319,7 @@ + #define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ull << 61) // IBM bit 2 + + #ifndef __ASSEMBLY__ ++#include + + /** + * plpar_hcall_norets: - Make a pseries hypervisor call with no return arguments diff --git a/queue-4.9/sched-rt-up-the-root-domain-ref-count-when-passing-it-around-via-ipis.patch b/queue-4.9/sched-rt-up-the-root-domain-ref-count-when-passing-it-around-via-ipis.patch new file mode 100644 index 00000000000..304ae623fb0 --- /dev/null +++ b/queue-4.9/sched-rt-up-the-root-domain-ref-count-when-passing-it-around-via-ipis.patch @@ -0,0 +1,101 @@ +From 364f56653708ba8bcdefd4f0da2a42904baa8eeb Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Tue, 23 Jan 2018 20:45:38 -0500 +Subject: sched/rt: Up the root domain ref count when passing it around via IPIs + +From: Steven Rostedt (VMware) + +commit 364f56653708ba8bcdefd4f0da2a42904baa8eeb upstream. + +When issuing an IPI RT push, where an IPI is sent to each CPU that has more +than one RT task scheduled on it, it references the root domain's rto_mask, +that contains all the CPUs within the root domain that has more than one RT +task in the runable state. The problem is, after the IPIs are initiated, the +rq->lock is released. This means that the root domain that is associated to +the run queue could be freed while the IPIs are going around. + +Add a sched_get_rd() and a sched_put_rd() that will increment and decrement +the root domain's ref count respectively. This way when initiating the IPIs, +the scheduler will up the root domain's ref count before releasing the +rq->lock, ensuring that the root domain does not go away until the IPI round +is complete. + +Reported-by: Pavan Kondeti +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Peter Zijlstra (Intel) +Cc: Andrew Morton +Cc: Linus Torvalds +Cc: Mike Galbraith +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Fixes: 4bdced5c9a292 ("sched/rt: Simplify the IPI based RT balancing logic") +Link: http://lkml.kernel.org/r/CAEU1=PkiHO35Dzna8EQqNSKW1fr1y1zRQ5y66X117MG06sQtNA@mail.gmail.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sched/core.c | 13 +++++++++++++ + kernel/sched/rt.c | 9 +++++++-- + kernel/sched/sched.h | 2 ++ + 3 files changed, 22 insertions(+), 2 deletions(-) + +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -5864,6 +5864,19 @@ static void rq_attach_root(struct rq *rq + call_rcu_sched(&old_rd->rcu, free_rootdomain); + } + ++void sched_get_rd(struct root_domain *rd) ++{ ++ atomic_inc(&rd->refcount); ++} ++ ++void sched_put_rd(struct root_domain *rd) ++{ ++ if (!atomic_dec_and_test(&rd->refcount)) ++ return; ++ ++ call_rcu_sched(&rd->rcu, free_rootdomain); ++} ++ + static int init_rootdomain(struct root_domain *rd) + { + memset(rd, 0, sizeof(*rd)); +--- a/kernel/sched/rt.c ++++ b/kernel/sched/rt.c +@@ -1978,8 +1978,11 @@ static void tell_cpu_to_push(struct rq * + + rto_start_unlock(&rq->rd->rto_loop_start); + +- if (cpu >= 0) ++ if (cpu >= 0) { ++ /* Make sure the rd does not get freed while pushing */ ++ sched_get_rd(rq->rd); + irq_work_queue_on(&rq->rd->rto_push_work, cpu); ++ } + } + + /* Called from hardirq context */ +@@ -2009,8 +2012,10 @@ void rto_push_irq_work_func(struct irq_w + + raw_spin_unlock(&rd->rto_lock); + +- if (cpu < 0) ++ if (cpu < 0) { ++ sched_put_rd(rd); + return; ++ } + + /* Try the next RT overloaded CPU */ + irq_work_queue_on(&rd->rto_push_work, cpu); +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -590,6 +590,8 @@ struct root_domain { + }; + + extern struct root_domain def_root_domain; ++extern void sched_get_rd(struct root_domain *rd); ++extern void sched_put_rd(struct root_domain *rd); + + #ifdef HAVE_RT_PUSH_IPI + extern void rto_push_irq_work_func(struct irq_work *work); diff --git a/queue-4.9/sched-rt-use-container_of-to-get-root-domain-in-rto_push_irq_work_func.patch b/queue-4.9/sched-rt-use-container_of-to-get-root-domain-in-rto_push_irq_work_func.patch new file mode 100644 index 00000000000..67dd3f7f483 --- /dev/null +++ b/queue-4.9/sched-rt-use-container_of-to-get-root-domain-in-rto_push_irq_work_func.patch @@ -0,0 +1,94 @@ +From ad0f1d9d65938aec72a698116cd73a980916895e Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Tue, 23 Jan 2018 20:45:37 -0500 +Subject: sched/rt: Use container_of() to get root domain in rto_push_irq_work_func() + +From: Steven Rostedt (VMware) + +commit ad0f1d9d65938aec72a698116cd73a980916895e upstream. + +When the rto_push_irq_work_func() is called, it looks at the RT overloaded +bitmask in the root domain via the runqueue (rq->rd). The problem is that +during CPU up and down, nothing here stops rq->rd from changing between +taking the rq->rd->rto_lock and releasing it. That means the lock that is +released is not the same lock that was taken. + +Instead of using this_rq()->rd to get the root domain, as the irq work is +part of the root domain, we can simply get the root domain from the irq work +that is passed to the routine: + + container_of(work, struct root_domain, rto_push_work) + +This keeps the root domain consistent. + +Reported-by: Pavan Kondeti +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Peter Zijlstra (Intel) +Cc: Andrew Morton +Cc: Linus Torvalds +Cc: Mike Galbraith +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Fixes: 4bdced5c9a292 ("sched/rt: Simplify the IPI based RT balancing logic") +Link: http://lkml.kernel.org/r/CAEU1=PkiHO35Dzna8EQqNSKW1fr1y1zRQ5y66X117MG06sQtNA@mail.gmail.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sched/rt.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +--- a/kernel/sched/rt.c ++++ b/kernel/sched/rt.c +@@ -1895,9 +1895,8 @@ static void push_rt_tasks(struct rq *rq) + * the rt_loop_next will cause the iterator to perform another scan. + * + */ +-static int rto_next_cpu(struct rq *rq) ++static int rto_next_cpu(struct root_domain *rd) + { +- struct root_domain *rd = rq->rd; + int next; + int cpu; + +@@ -1973,7 +1972,7 @@ static void tell_cpu_to_push(struct rq * + * Otherwise it is finishing up and an ipi needs to be sent. + */ + if (rq->rd->rto_cpu < 0) +- cpu = rto_next_cpu(rq); ++ cpu = rto_next_cpu(rq->rd); + + raw_spin_unlock(&rq->rd->rto_lock); + +@@ -1986,6 +1985,8 @@ static void tell_cpu_to_push(struct rq * + /* Called from hardirq context */ + void rto_push_irq_work_func(struct irq_work *work) + { ++ struct root_domain *rd = ++ container_of(work, struct root_domain, rto_push_work); + struct rq *rq; + int cpu; + +@@ -2001,18 +2002,18 @@ void rto_push_irq_work_func(struct irq_w + raw_spin_unlock(&rq->lock); + } + +- raw_spin_lock(&rq->rd->rto_lock); ++ raw_spin_lock(&rd->rto_lock); + + /* Pass the IPI to the next rt overloaded queue */ +- cpu = rto_next_cpu(rq); ++ cpu = rto_next_cpu(rd); + +- raw_spin_unlock(&rq->rd->rto_lock); ++ raw_spin_unlock(&rd->rto_lock); + + if (cpu < 0) + return; + + /* Try the next RT overloaded CPU */ +- irq_work_queue_on(&rq->rd->rto_push_work, cpu); ++ irq_work_queue_on(&rd->rto_push_work, cpu); + } + #endif /* HAVE_RT_PUSH_IPI */ + diff --git a/queue-4.9/series b/queue-4.9/series new file mode 100644 index 00000000000..a71b096575e --- /dev/null +++ b/queue-4.9/series @@ -0,0 +1,14 @@ +powerpc-pseries-include-linux-types.h-in-asm-hvcall.h.patch +cifs-fix-missing-put_xid-in-cifs_file_strict_mmap.patch +cifs-fix-autonegotiate-security-settings-mismatch.patch +cifs-zero-sensitive-data-when-freeing.patch +dmaengine-dmatest-fix-container_of-member-in-dmatest_callback.patch +kaiser-fix-compile-error-without-vsyscall.patch +posix-timer-properly-check-sigevent-sigev_notify.patch +usb-gadget-uvc-missing-files-for-configfs-interface.patch +sched-rt-use-container_of-to-get-root-domain-in-rto_push_irq_work_func.patch +sched-rt-up-the-root-domain-ref-count-when-passing-it-around-via-ipis.patch +dccp-cve-2017-8824-use-after-free-in-dccp-code.patch +media-dvb-usb-v2-lmedm04-improve-logic-checking-of-warm-start.patch +media-dvb-usb-v2-lmedm04-move-ts2020-attach-to-dm04_lme2510_tuner.patch +media-hdpvr-fix-an-error-handling-path-in-hdpvr_probe.patch diff --git a/queue-4.9/usb-gadget-uvc-missing-files-for-configfs-interface.patch b/queue-4.9/usb-gadget-uvc-missing-files-for-configfs-interface.patch new file mode 100644 index 00000000000..4e36b4195c7 --- /dev/null +++ b/queue-4.9/usb-gadget-uvc-missing-files-for-configfs-interface.patch @@ -0,0 +1,60 @@ +From c8cd751060b149997b9de53a494fb1490ded72c5 Mon Sep 17 00:00:00 2001 +From: Petr Cvek +Date: Tue, 7 Mar 2017 00:57:20 +0100 +Subject: usb: gadget: uvc: Missing files for configfs interface + +From: Petr Cvek + +commit c8cd751060b149997b9de53a494fb1490ded72c5 upstream. + +Commit 76e0da34c7ce ("usb-gadget/uvc: use per-attribute show and store +methods") caused a stringification of an undefined macro argument "aname", +so three UVC parameters (streaming_interval, streaming_maxpacket and +streaming_maxburst) were named "aname". + +Add the definition of "aname" to the main macro and name the filenames as +originaly intended. + +Signed-off-by: Petr Cvek +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/uvc_configfs.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/usb/gadget/function/uvc_configfs.c ++++ b/drivers/usb/gadget/function/uvc_configfs.c +@@ -2140,7 +2140,7 @@ static struct configfs_item_operations u + .release = uvc_attr_release, + }; + +-#define UVCG_OPTS_ATTR(cname, conv, str2u, uxx, vnoc, limit) \ ++#define UVCG_OPTS_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit) \ + static ssize_t f_uvc_opts_##cname##_show( \ + struct config_item *item, char *page) \ + { \ +@@ -2183,16 +2183,16 @@ end: \ + return ret; \ + } \ + \ +-UVC_ATTR(f_uvc_opts_, cname, aname) ++UVC_ATTR(f_uvc_opts_, cname, cname) + + #define identity_conv(x) (x) + +-UVCG_OPTS_ATTR(streaming_interval, identity_conv, kstrtou8, u8, identity_conv, +- 16); +-UVCG_OPTS_ATTR(streaming_maxpacket, le16_to_cpu, kstrtou16, u16, le16_to_cpu, +- 3072); +-UVCG_OPTS_ATTR(streaming_maxburst, identity_conv, kstrtou8, u8, identity_conv, +- 15); ++UVCG_OPTS_ATTR(streaming_interval, streaming_interval, identity_conv, ++ kstrtou8, u8, identity_conv, 16); ++UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, le16_to_cpu, ++ kstrtou16, u16, le16_to_cpu, 3072); ++UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, identity_conv, ++ kstrtou8, u8, identity_conv, 15); + + #undef identity_conv +