From 4e0f62fe2c64a9f87a69ad6fe9e1575b9f64a21b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 13 Feb 2018 17:30:29 +0100 Subject: [PATCH] 3.18-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 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 posix-timer-properly-check-sigevent-sigev_notify.patch usb-usbip-fix-possible-deadlocks-reported-by-lockdep.patch usbip-fix-potential-format-overflow-in-userspace-tools.patch usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch usbip-prevent-leaking-socket-pointer-address-in-messages.patch usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch usbip-stub-stop-printing-kernel-pointer-addresses-in-messages.patch usbip-vhci-hcd-add-usb3-superspeed-support.patch usbip-vhci-stop-printing-kernel-pointer-addresses-in-messages.patch --- ...negotiate-security-settings-mismatch.patch | 47 ++ ...ing-put_xid-in-cifs_file_strict_mmap.patch | 74 +++ ...ifs-zero-sensitive-data-when-freeing.patch | 96 +++ ...017-8824-use-after-free-in-dccp-code.patch | 43 ++ ...improve-logic-checking-of-warm-start.patch | 88 +++ ...-ts2020-attach-to-dm04_lme2510_tuner.patch | 72 ++ ...properly-check-sigevent-sigev_notify.patch | 110 +++ queue-3.18/series | 16 + ...ssible-deadlocks-reported-by-lockdep.patch | 626 ++++++++++++++++++ ...l-format-overflow-in-userspace-tools.patch | 107 +++ ...get_pipe-to-validate-endpoint-number.patch | 71 ++ ...ubmit-path-to-handle-malicious-input.patch | 95 +++ ...g-socket-pointer-address-in-messages.patch | 82 +++ ...rom-leaking-a-socket-pointer-address.patch | 124 ++++ ...kernel-pointer-addresses-in-messages.patch | 74 +++ ...vhci-hcd-add-usb3-superspeed-support.patch | 41 ++ ...kernel-pointer-addresses-in-messages.patch | 144 ++++ 17 files changed, 1910 insertions(+) create mode 100644 queue-3.18/cifs-fix-autonegotiate-security-settings-mismatch.patch create mode 100644 queue-3.18/cifs-fix-missing-put_xid-in-cifs_file_strict_mmap.patch create mode 100644 queue-3.18/cifs-zero-sensitive-data-when-freeing.patch create mode 100644 queue-3.18/dccp-cve-2017-8824-use-after-free-in-dccp-code.patch create mode 100644 queue-3.18/media-dvb-usb-v2-lmedm04-improve-logic-checking-of-warm-start.patch create mode 100644 queue-3.18/media-dvb-usb-v2-lmedm04-move-ts2020-attach-to-dm04_lme2510_tuner.patch create mode 100644 queue-3.18/posix-timer-properly-check-sigevent-sigev_notify.patch create mode 100644 queue-3.18/usb-usbip-fix-possible-deadlocks-reported-by-lockdep.patch create mode 100644 queue-3.18/usbip-fix-potential-format-overflow-in-userspace-tools.patch create mode 100644 queue-3.18/usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch create mode 100644 queue-3.18/usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch create mode 100644 queue-3.18/usbip-prevent-leaking-socket-pointer-address-in-messages.patch create mode 100644 queue-3.18/usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch create mode 100644 queue-3.18/usbip-stub-stop-printing-kernel-pointer-addresses-in-messages.patch create mode 100644 queue-3.18/usbip-vhci-hcd-add-usb3-superspeed-support.patch create mode 100644 queue-3.18/usbip-vhci-stop-printing-kernel-pointer-addresses-in-messages.patch diff --git a/queue-3.18/cifs-fix-autonegotiate-security-settings-mismatch.patch b/queue-3.18/cifs-fix-autonegotiate-security-settings-mismatch.patch new file mode 100644 index 00000000000..be3f3d74584 --- /dev/null +++ b/queue-3.18/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 +@@ -507,8 +507,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-3.18/cifs-fix-missing-put_xid-in-cifs_file_strict_mmap.patch b/queue-3.18/cifs-fix-missing-put_xid-in-cifs_file_strict_mmap.patch new file mode 100644 index 00000000000..14a370bd3d0 --- /dev/null +++ b/queue-3.18/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 +@@ -3261,20 +3261,18 @@ static struct vm_operations_struct cifs_ + + 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; + } +@@ -3284,16 +3282,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-3.18/cifs-zero-sensitive-data-when-freeing.patch b/queue-3.18/cifs-zero-sensitive-data-when-freeing.patch new file mode 100644 index 00000000000..5840aa37200 --- /dev/null +++ b/queue-3.18/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 +@@ -303,9 +303,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 +@@ -1650,7 +1650,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; + } +@@ -1688,7 +1688,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); +@@ -4046,7 +4046,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 * +@@ -136,10 +133,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-3.18/dccp-cve-2017-8824-use-after-free-in-dccp-code.patch b/queue-3.18/dccp-cve-2017-8824-use-after-free-in-dccp-code.patch new file mode 100644 index 00000000000..9bf5883664d --- /dev/null +++ b/queue-3.18/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-3.18/media-dvb-usb-v2-lmedm04-improve-logic-checking-of-warm-start.patch b/queue-3.18/media-dvb-usb-v2-lmedm04-improve-logic-checking-of-warm-start.patch new file mode 100644 index 00000000000..b4ba247c36e --- /dev/null +++ b/queue-3.18/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 +@@ -438,18 +438,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; + } +@@ -1231,6 +1236,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); + +@@ -1239,12 +1245,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-3.18/media-dvb-usb-v2-lmedm04-move-ts2020-attach-to-dm04_lme2510_tuner.patch b/queue-3.18/media-dvb-usb-v2-lmedm04-move-ts2020-attach-to-dm04_lme2510_tuner.patch new file mode 100644 index 00000000000..2a4ae548340 --- /dev/null +++ b/queue-3.18/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 +@@ -1118,8 +1118,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; +@@ -1182,17 +1180,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-3.18/posix-timer-properly-check-sigevent-sigev_notify.patch b/queue-3.18/posix-timer-properly-check-sigevent-sigev_notify.patch new file mode 100644 index 00000000000..e64904f260a --- /dev/null +++ b/queue-3.18/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 +@@ -500,17 +500,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, +@@ -738,8 +743,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(); +@@ -750,7 +754,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 = ktime_sub(hrtimer_get_expires(timer), now); +@@ -760,7 +764,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); +@@ -858,7 +862,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-3.18/series b/queue-3.18/series index 05033e53de2..4c60f07ed5e 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -8,3 +8,19 @@ arm-exynos_defconfig-enable-options-to-mount-a-rootfs-via-nfs.patch arm-exynos_defconfig-enable-nfsv4-client.patch keys-encrypted-fix-buffer-overread-in-valid_master_desc.patch ipv4-map-neigh-lookup-keys-in-__ipv4_neigh_lookup_noref.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 +posix-timer-properly-check-sigevent-sigev_notify.patch +usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch +usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch +usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch +usbip-fix-potential-format-overflow-in-userspace-tools.patch +usb-usbip-fix-possible-deadlocks-reported-by-lockdep.patch +usbip-vhci-hcd-add-usb3-superspeed-support.patch +usbip-prevent-leaking-socket-pointer-address-in-messages.patch +usbip-stub-stop-printing-kernel-pointer-addresses-in-messages.patch +usbip-vhci-stop-printing-kernel-pointer-addresses-in-messages.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 diff --git a/queue-3.18/usb-usbip-fix-possible-deadlocks-reported-by-lockdep.patch b/queue-3.18/usb-usbip-fix-possible-deadlocks-reported-by-lockdep.patch new file mode 100644 index 00000000000..f84d8174490 --- /dev/null +++ b/queue-3.18/usb-usbip-fix-possible-deadlocks-reported-by-lockdep.patch @@ -0,0 +1,626 @@ +From 21619792d1eca7e772ca190ba68588e57f29595b Mon Sep 17 00:00:00 2001 +From: Andrew Goodbody +Date: Tue, 2 Feb 2016 17:36:39 +0000 +Subject: usb: usbip: Fix possible deadlocks reported by lockdep + +From: Andrew Goodbody + +commit 21619792d1eca7e772ca190ba68588e57f29595b upstream. + +Change spin_lock calls to spin_lock_irqsave to prevent +attmpted recursive lock taking in interrupt context. + +This patch fixes Bug 109351 + https://bugzilla.kernel.org/show_bug.cgi?id=109351 + +Signed-off-by: Andrew Goodbody +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/usbip/usbip_event.c | 5 +- + drivers/usb/usbip/vhci_hcd.c | 88 +++++++++++++++++++++++----------------- + drivers/usb/usbip/vhci_rx.c | 30 +++++++------ + drivers/usb/usbip/vhci_sysfs.c | 19 +++++--- + drivers/usb/usbip/vhci_tx.c | 14 +++--- + 5 files changed, 91 insertions(+), 65 deletions(-) + +--- a/drivers/usb/usbip/usbip_event.c ++++ b/drivers/usb/usbip/usbip_event.c +@@ -117,11 +117,12 @@ EXPORT_SYMBOL_GPL(usbip_event_add); + int usbip_event_happened(struct usbip_device *ud) + { + int happened = 0; ++ unsigned long flags; + +- spin_lock(&ud->lock); ++ spin_lock_irqsave(&ud->lock, flags); + if (ud->event != 0) + happened = 1; +- spin_unlock(&ud->lock); ++ spin_unlock_irqrestore(&ud->lock, flags); + + return happened; + } +--- a/drivers/usb/usbip/vhci_hcd.c ++++ b/drivers/usb/usbip/vhci_hcd.c +@@ -121,9 +121,11 @@ static void dump_port_status_diff(u32 pr + + void rh_port_connect(int rhport, enum usb_device_speed speed) + { ++ unsigned long flags; ++ + usbip_dbg_vhci_rh("rh_port_connect %d\n", rhport); + +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + + the_controller->port_status[rhport] |= USB_PORT_STAT_CONNECTION + | (1 << USB_PORT_FEAT_C_CONNECTION); +@@ -139,22 +141,24 @@ void rh_port_connect(int rhport, enum us + break; + } + +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + + usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); + } + + static void rh_port_disconnect(int rhport) + { ++ unsigned long flags; ++ + usbip_dbg_vhci_rh("rh_port_disconnect %d\n", rhport); + +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + + the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION; + the_controller->port_status[rhport] |= + (1 << USB_PORT_FEAT_C_CONNECTION); + +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); + } + +@@ -182,13 +186,14 @@ static int vhci_hub_status(struct usb_hc + int retval; + int rhport; + int changed = 0; ++ unsigned long flags; + + retval = DIV_ROUND_UP(VHCI_NPORTS + 1, 8); + memset(buf, 0, retval); + + vhci = hcd_to_vhci(hcd); + +- spin_lock(&vhci->lock); ++ spin_lock_irqsave(&vhci->lock, flags); + if (!HCD_HW_ACCESSIBLE(hcd)) { + usbip_dbg_vhci_rh("hw accessible flag not on?\n"); + goto done; +@@ -209,7 +214,7 @@ static int vhci_hub_status(struct usb_hc + usb_hcd_resume_root_hub(hcd); + + done: +- spin_unlock(&vhci->lock); ++ spin_unlock_irqrestore(&vhci->lock, flags); + return changed ? retval : 0; + } + +@@ -230,6 +235,7 @@ static int vhci_hub_control(struct usb_h + struct vhci_hcd *dum; + int retval = 0; + int rhport; ++ unsigned long flags; + + u32 prev_port_status[VHCI_NPORTS]; + +@@ -248,7 +254,7 @@ static int vhci_hub_control(struct usb_h + + dum = hcd_to_vhci(hcd); + +- spin_lock(&dum->lock); ++ spin_lock_irqsave(&dum->lock, flags); + + /* store old status and compare now and old later */ + if (usbip_dbg_flag_vhci_rh) { +@@ -402,7 +408,7 @@ static int vhci_hub_control(struct usb_h + } + usbip_dbg_vhci_rh(" bye\n"); + +- spin_unlock(&dum->lock); ++ spin_unlock_irqrestore(&dum->lock, flags); + + return retval; + } +@@ -425,6 +431,7 @@ static void vhci_tx_urb(struct urb *urb) + { + struct vhci_device *vdev = get_vdev(urb->dev); + struct vhci_priv *priv; ++ unsigned long flags; + + if (!vdev) { + pr_err("could not get virtual device"); +@@ -437,7 +444,7 @@ static void vhci_tx_urb(struct urb *urb) + return; + } + +- spin_lock(&vdev->priv_lock); ++ spin_lock_irqsave(&vdev->priv_lock, flags); + + priv->seqnum = atomic_inc_return(&the_controller->seqnum); + if (priv->seqnum == 0xffff) +@@ -451,7 +458,7 @@ static void vhci_tx_urb(struct urb *urb) + list_add_tail(&priv->list, &vdev->priv_tx); + + wake_up(&vdev->waitq_tx); +- spin_unlock(&vdev->priv_lock); ++ spin_unlock_irqrestore(&vdev->priv_lock, flags); + } + + static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, +@@ -460,6 +467,7 @@ static int vhci_urb_enqueue(struct usb_h + struct device *dev = &urb->dev->dev; + int ret = 0; + struct vhci_device *vdev; ++ unsigned long flags; + + usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", + hcd, urb, mem_flags); +@@ -467,11 +475,11 @@ static int vhci_urb_enqueue(struct usb_h + /* patch to usb_sg_init() is in 2.5.60 */ + BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length); + +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + + if (urb->status != -EINPROGRESS) { + dev_err(dev, "URB already unlinked!, status %d\n", urb->status); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + return urb->status; + } + +@@ -483,7 +491,7 @@ static int vhci_urb_enqueue(struct usb_h + vdev->ud.status == VDEV_ST_ERROR) { + dev_err(dev, "enqueue for inactive port %d\n", vdev->rhport); + spin_unlock(&vdev->ud.lock); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + return -ENODEV; + } + spin_unlock(&vdev->ud.lock); +@@ -558,14 +566,14 @@ static int vhci_urb_enqueue(struct usb_h + + out: + vhci_tx_urb(urb); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + + return 0; + + no_need_xmit: + usb_hcd_unlink_urb_from_ep(hcd, urb); + no_need_unlink: +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); + return ret; + } +@@ -620,16 +628,17 @@ static int vhci_urb_dequeue(struct usb_h + { + struct vhci_priv *priv; + struct vhci_device *vdev; ++ unsigned long flags; + + pr_info("dequeue a urb %p\n", urb); + +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + + priv = urb->hcpriv; + if (!priv) { + /* URB was never linked! or will be soon given back by + * vhci_rx. */ +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + return 0; + } + +@@ -638,7 +647,7 @@ static int vhci_urb_dequeue(struct usb_h + + ret = usb_hcd_check_unlink_urb(hcd, urb, status); + if (ret) { +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + return ret; + } + } +@@ -666,10 +675,10 @@ static int vhci_urb_dequeue(struct usb_h + + usb_hcd_unlink_urb_from_ep(hcd, urb); + +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, + urb->status); +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + + } else { + /* tcp connection is alive */ +@@ -681,7 +690,7 @@ static int vhci_urb_dequeue(struct usb_h + unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC); + if (!unlink) { + spin_unlock(&vdev->priv_lock); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); + return -ENOMEM; + } +@@ -702,7 +711,7 @@ static int vhci_urb_dequeue(struct usb_h + spin_unlock(&vdev->priv_lock); + } + +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + + usbip_dbg_vhci_hc("leave\n"); + return 0; +@@ -711,8 +720,9 @@ static int vhci_urb_dequeue(struct usb_h + static void vhci_device_unlink_cleanup(struct vhci_device *vdev) + { + struct vhci_unlink *unlink, *tmp; ++ unsigned long flags; + +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + spin_lock(&vdev->priv_lock); + + list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { +@@ -746,19 +756,19 @@ static void vhci_device_unlink_cleanup(s + list_del(&unlink->list); + + spin_unlock(&vdev->priv_lock); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + + usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, + urb->status); + +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + spin_lock(&vdev->priv_lock); + + kfree(unlink); + } + + spin_unlock(&vdev->priv_lock); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + } + + /* +@@ -825,8 +835,9 @@ static void vhci_shutdown_connection(str + static void vhci_device_reset(struct usbip_device *ud) + { + struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); ++ unsigned long flags; + +- spin_lock(&ud->lock); ++ spin_lock_irqsave(&ud->lock, flags); + + vdev->speed = 0; + vdev->devid = 0; +@@ -841,14 +852,16 @@ static void vhci_device_reset(struct usb + } + ud->status = VDEV_ST_NULL; + +- spin_unlock(&ud->lock); ++ spin_unlock_irqrestore(&ud->lock, flags); + } + + static void vhci_device_unusable(struct usbip_device *ud) + { +- spin_lock(&ud->lock); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ud->lock, flags); + ud->status = VDEV_ST_ERROR; +- spin_unlock(&ud->lock); ++ spin_unlock_irqrestore(&ud->lock, flags); + } + + static void vhci_device_init(struct vhci_device *vdev) +@@ -938,12 +951,13 @@ static int vhci_get_frame_number(struct + static int vhci_bus_suspend(struct usb_hcd *hcd) + { + struct vhci_hcd *vhci = hcd_to_vhci(hcd); ++ unsigned long flags; + + dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); + +- spin_lock(&vhci->lock); ++ spin_lock_irqsave(&vhci->lock, flags); + hcd->state = HC_STATE_SUSPENDED; +- spin_unlock(&vhci->lock); ++ spin_unlock_irqrestore(&vhci->lock, flags); + + return 0; + } +@@ -952,15 +966,16 @@ static int vhci_bus_resume(struct usb_hc + { + struct vhci_hcd *vhci = hcd_to_vhci(hcd); + int rc = 0; ++ unsigned long flags; + + dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); + +- spin_lock(&vhci->lock); ++ spin_lock_irqsave(&vhci->lock, flags); + if (!HCD_HW_ACCESSIBLE(hcd)) + rc = -ESHUTDOWN; + else + hcd->state = HC_STATE_RUNNING; +- spin_unlock(&vhci->lock); ++ spin_unlock_irqrestore(&vhci->lock, flags); + + return rc; + } +@@ -1058,17 +1073,18 @@ static int vhci_hcd_suspend(struct platf + int rhport = 0; + int connected = 0; + int ret = 0; ++ unsigned long flags; + + hcd = platform_get_drvdata(pdev); + +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + + for (rhport = 0; rhport < VHCI_NPORTS; rhport++) + if (the_controller->port_status[rhport] & + USB_PORT_STAT_CONNECTION) + connected += 1; + +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + + if (connected > 0) { + dev_info(&pdev->dev, +--- a/drivers/usb/usbip/vhci_rx.c ++++ b/drivers/usb/usbip/vhci_rx.c +@@ -72,10 +72,11 @@ static void vhci_recv_ret_submit(struct + { + struct usbip_device *ud = &vdev->ud; + struct urb *urb; ++ unsigned long flags; + +- spin_lock(&vdev->priv_lock); ++ spin_lock_irqsave(&vdev->priv_lock, flags); + urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum); +- spin_unlock(&vdev->priv_lock); ++ spin_unlock_irqrestore(&vdev->priv_lock, flags); + + if (!urb) { + pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum); +@@ -104,9 +105,9 @@ static void vhci_recv_ret_submit(struct + + usbip_dbg_vhci_rx("now giveback urb %p\n", urb); + +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + + usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); + +@@ -117,8 +118,9 @@ static struct vhci_unlink *dequeue_pendi + struct usbip_header *pdu) + { + struct vhci_unlink *unlink, *tmp; ++ unsigned long flags; + +- spin_lock(&vdev->priv_lock); ++ spin_lock_irqsave(&vdev->priv_lock, flags); + + list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) { + pr_info("unlink->seqnum %lu\n", unlink->seqnum); +@@ -127,12 +129,12 @@ static struct vhci_unlink *dequeue_pendi + unlink->seqnum); + list_del(&unlink->list); + +- spin_unlock(&vdev->priv_lock); ++ spin_unlock_irqrestore(&vdev->priv_lock, flags); + return unlink; + } + } + +- spin_unlock(&vdev->priv_lock); ++ spin_unlock_irqrestore(&vdev->priv_lock, flags); + + return NULL; + } +@@ -142,6 +144,7 @@ static void vhci_recv_ret_unlink(struct + { + struct vhci_unlink *unlink; + struct urb *urb; ++ unsigned long flags; + + usbip_dump_header(pdu); + +@@ -152,9 +155,9 @@ static void vhci_recv_ret_unlink(struct + return; + } + +- spin_lock(&vdev->priv_lock); ++ spin_lock_irqsave(&vdev->priv_lock, flags); + urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum); +- spin_unlock(&vdev->priv_lock); ++ spin_unlock_irqrestore(&vdev->priv_lock, flags); + + if (!urb) { + /* +@@ -171,9 +174,9 @@ static void vhci_recv_ret_unlink(struct + urb->status = pdu->u.ret_unlink.status; + pr_info("urb->status %d\n", urb->status); + +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + + usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, + urb->status); +@@ -185,10 +188,11 @@ static void vhci_recv_ret_unlink(struct + static int vhci_priv_tx_empty(struct vhci_device *vdev) + { + int empty = 0; ++ unsigned long flags; + +- spin_lock(&vdev->priv_lock); ++ spin_lock_irqsave(&vdev->priv_lock, flags); + empty = list_empty(&vdev->priv_rx); +- spin_unlock(&vdev->priv_lock); ++ spin_unlock_irqrestore(&vdev->priv_lock, flags); + + return empty; + } +--- a/drivers/usb/usbip/vhci_sysfs.c ++++ b/drivers/usb/usbip/vhci_sysfs.c +@@ -32,10 +32,11 @@ static ssize_t status_show(struct device + { + char *s = out; + int i = 0; ++ unsigned long flags; + + BUG_ON(!the_controller || !out); + +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + + /* + * output example: +@@ -73,7 +74,7 @@ static ssize_t status_show(struct device + spin_unlock(&vdev->ud.lock); + } + +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + + return out - s; + } +@@ -83,11 +84,12 @@ static DEVICE_ATTR_RO(status); + static int vhci_port_disconnect(__u32 rhport) + { + struct vhci_device *vdev; ++ unsigned long flags; + + usbip_dbg_vhci_sysfs("enter\n"); + + /* lock */ +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + + vdev = port_to_vdev(rhport); + +@@ -97,14 +99,14 @@ static int vhci_port_disconnect(__u32 rh + + /* unlock */ + spin_unlock(&vdev->ud.lock); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + + return -EINVAL; + } + + /* unlock */ + spin_unlock(&vdev->ud.lock); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + + usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); + +@@ -180,6 +182,7 @@ static ssize_t store_attach(struct devic + int sockfd = 0; + __u32 rhport = 0, devid = 0, speed = 0; + int err; ++ unsigned long flags; + + /* + * @rhport: port number of vhci_hcd +@@ -205,14 +208,14 @@ static ssize_t store_attach(struct devic + /* now need lock until setting vdev status as used */ + + /* begin a lock */ +- spin_lock(&the_controller->lock); ++ spin_lock_irqsave(&the_controller->lock, flags); + vdev = port_to_vdev(rhport); + spin_lock(&vdev->ud.lock); + + if (vdev->ud.status != VDEV_ST_NULL) { + /* end of the lock */ + spin_unlock(&vdev->ud.lock); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + + sockfd_put(socket); + +@@ -231,7 +234,7 @@ static ssize_t store_attach(struct devic + vdev->ud.status = VDEV_ST_NOTASSIGNED; + + spin_unlock(&vdev->ud.lock); +- spin_unlock(&the_controller->lock); ++ spin_unlock_irqrestore(&the_controller->lock, flags); + /* end the lock */ + + vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); +--- a/drivers/usb/usbip/vhci_tx.c ++++ b/drivers/usb/usbip/vhci_tx.c +@@ -47,16 +47,17 @@ static void setup_cmd_submit_pdu(struct + static struct vhci_priv *dequeue_from_priv_tx(struct vhci_device *vdev) + { + struct vhci_priv *priv, *tmp; ++ unsigned long flags; + +- spin_lock(&vdev->priv_lock); ++ spin_lock_irqsave(&vdev->priv_lock, flags); + + list_for_each_entry_safe(priv, tmp, &vdev->priv_tx, list) { + list_move_tail(&priv->list, &vdev->priv_rx); +- spin_unlock(&vdev->priv_lock); ++ spin_unlock_irqrestore(&vdev->priv_lock, flags); + return priv; + } + +- spin_unlock(&vdev->priv_lock); ++ spin_unlock_irqrestore(&vdev->priv_lock, flags); + + return NULL; + } +@@ -136,16 +137,17 @@ static int vhci_send_cmd_submit(struct v + static struct vhci_unlink *dequeue_from_unlink_tx(struct vhci_device *vdev) + { + struct vhci_unlink *unlink, *tmp; ++ unsigned long flags; + +- spin_lock(&vdev->priv_lock); ++ spin_lock_irqsave(&vdev->priv_lock, flags); + + list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { + list_move_tail(&unlink->list, &vdev->unlink_rx); +- spin_unlock(&vdev->priv_lock); ++ spin_unlock_irqrestore(&vdev->priv_lock, flags); + return unlink; + } + +- spin_unlock(&vdev->priv_lock); ++ spin_unlock_irqrestore(&vdev->priv_lock, flags); + + return NULL; + } diff --git a/queue-3.18/usbip-fix-potential-format-overflow-in-userspace-tools.patch b/queue-3.18/usbip-fix-potential-format-overflow-in-userspace-tools.patch new file mode 100644 index 00000000000..f3f956f6a5d --- /dev/null +++ b/queue-3.18/usbip-fix-potential-format-overflow-in-userspace-tools.patch @@ -0,0 +1,107 @@ +From e5dfa3f902b9a642ae8c6997d57d7c41e384a90b Mon Sep 17 00:00:00 2001 +From: Jonathan Dieter +Date: Mon, 27 Feb 2017 10:31:03 +0200 +Subject: usbip: Fix potential format overflow in userspace tools + +From: Jonathan Dieter + +commit e5dfa3f902b9a642ae8c6997d57d7c41e384a90b upstream. + +The usbip userspace tools call sprintf()/snprintf() and don't check for +the return value which can lead the paths to overflow, truncating the +final file in the path. + +More urgently, GCC 7 now warns that these aren't checked with +-Wformat-overflow, and with -Werror enabled in configure.ac, that makes +these tools unbuildable. + +This patch fixes these problems by replacing sprintf() with snprintf() in +one place and adding checks for the return value of snprintf(). + +Reviewed-by: Peter Senna Tschudin +Signed-off-by: Jonathan Dieter +Acked-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + + +--- + tools/usb/usbip/libsrc/usbip_common.c | 9 ++++++++- + tools/usb/usbip/libsrc/usbip_host_driver.c | 27 ++++++++++++++++++++++----- + 2 files changed, 30 insertions(+), 6 deletions(-) + +--- a/tools/usb/usbip/libsrc/usbip_common.c ++++ b/tools/usb/usbip/libsrc/usbip_common.c +@@ -215,9 +215,16 @@ int read_usb_interface(struct usbip_usb_ + struct usbip_usb_interface *uinf) + { + char busid[SYSFS_BUS_ID_SIZE]; ++ int size; + struct udev_device *sif; + +- sprintf(busid, "%s:%d.%d", udev->busid, udev->bConfigurationValue, i); ++ size = snprintf(busid, sizeof(busid), "%s:%d.%d", ++ udev->busid, udev->bConfigurationValue, i); ++ if (size < 0 || (unsigned int)size >= sizeof(busid)) { ++ err("busid length %i >= %lu or < 0", size, ++ (unsigned long)sizeof(busid)); ++ return -1; ++ } + + sif = udev_device_new_from_subsystem_sysname(udev_context, "usb", busid); + if (!sif) { +--- a/tools/usb/usbip/libsrc/usbip_host_driver.c ++++ b/tools/usb/usbip/libsrc/usbip_host_driver.c +@@ -39,13 +39,19 @@ struct udev *udev_context; + static int32_t read_attr_usbip_status(struct usbip_usb_device *udev) + { + char status_attr_path[SYSFS_PATH_MAX]; ++ int size; + int fd; + int length; + char status; + int value = 0; + +- snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status", +- udev->path); ++ size = snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status", ++ udev->path); ++ if (size < 0 || (unsigned int)size >= sizeof(status_attr_path)) { ++ err("usbip_status path length %i >= %lu or < 0", size, ++ (unsigned long)sizeof(status_attr_path)); ++ return -1; ++ } + + fd = open(status_attr_path, O_RDONLY); + if (fd < 0) { +@@ -225,6 +231,7 @@ int usbip_host_export_device(struct usbi + { + char attr_name[] = "usbip_sockfd"; + char sockfd_attr_path[SYSFS_PATH_MAX]; ++ int size; + char sockfd_buff[30]; + int ret; + +@@ -244,10 +251,20 @@ int usbip_host_export_device(struct usbi + } + + /* only the first interface is true */ +- snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s", +- edev->udev.path, attr_name); ++ size = snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s", ++ edev->udev.path, attr_name); ++ if (size < 0 || (unsigned int)size >= sizeof(sockfd_attr_path)) { ++ err("exported device path length %i >= %lu or < 0", size, ++ (unsigned long)sizeof(sockfd_attr_path)); ++ return -1; ++ } + +- snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd); ++ size = snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd); ++ if (size < 0 || (unsigned int)size >= sizeof(sockfd_buff)) { ++ err("socket length %i >= %lu or < 0", size, ++ (unsigned long)sizeof(sockfd_buff)); ++ return -1; ++ } + + ret = write_sysfs_attribute(sockfd_attr_path, sockfd_buff, + strlen(sockfd_buff)); diff --git a/queue-3.18/usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch b/queue-3.18/usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch new file mode 100644 index 00000000000..b9cfda15389 --- /dev/null +++ b/queue-3.18/usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch @@ -0,0 +1,71 @@ +From 635f545a7e8be7596b9b2b6a43cab6bbd5a88e43 Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Thu, 7 Dec 2017 14:16:47 -0700 +Subject: usbip: fix stub_rx: get_pipe() to validate endpoint number + +From: Shuah Khan + +commit 635f545a7e8be7596b9b2b6a43cab6bbd5a88e43 upstream. + +get_pipe() routine doesn't validate the input endpoint number +and uses to reference ep_in and ep_out arrays. Invalid endpoint +number can trigger BUG(). Range check the epnum and returning +error instead of calling BUG(). + +Change caller stub_recv_cmd_submit() to handle the get_pipe() +error return. + +Reported-by: Secunia Research +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/usb/usbip/stub_rx.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +--- a/drivers/usb/usbip/stub_rx.c ++++ b/drivers/usb/usbip/stub_rx.c +@@ -347,15 +347,15 @@ static int get_pipe(struct stub_device * + struct usb_host_endpoint *ep; + struct usb_endpoint_descriptor *epd = NULL; + ++ if (epnum < 0 || epnum > 15) ++ goto err_ret; ++ + if (dir == USBIP_DIR_IN) + ep = udev->ep_in[epnum & 0x7f]; + else + ep = udev->ep_out[epnum & 0x7f]; +- if (!ep) { +- dev_err(&sdev->interface->dev, "no such endpoint?, %d\n", +- epnum); +- BUG(); +- } ++ if (!ep) ++ goto err_ret; + + epd = &ep->desc; + if (usb_endpoint_xfer_control(epd)) { +@@ -386,9 +386,10 @@ static int get_pipe(struct stub_device * + return usb_rcvisocpipe(udev, epnum); + } + ++err_ret: + /* NOT REACHED */ + dev_err(&sdev->interface->dev, "get pipe, epnum %d\n", epnum); +- return 0; ++ return -1; + } + + static void masking_bogus_flags(struct urb *urb) +@@ -454,6 +455,9 @@ static void stub_recv_cmd_submit(struct + struct usb_device *udev = sdev->udev; + int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction); + ++ if (pipe == -1) ++ return; ++ + priv = stub_priv_alloc(sdev, pdu); + if (!priv) + return; diff --git a/queue-3.18/usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch b/queue-3.18/usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch new file mode 100644 index 00000000000..a0861de9a1a --- /dev/null +++ b/queue-3.18/usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch @@ -0,0 +1,95 @@ +From c6688ef9f29762e65bce325ef4acd6c675806366 Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Thu, 7 Dec 2017 14:16:48 -0700 +Subject: usbip: fix stub_rx: harden CMD_SUBMIT path to handle malicious input + +From: Shuah Khan + +commit c6688ef9f29762e65bce325ef4acd6c675806366 upstream. + +Harden CMD_SUBMIT path to handle malicious input that could trigger +large memory allocations. Add checks to validate transfer_buffer_length +and number_of_packets to protect against bad input requesting for +unbounded memory allocations. Validate early in get_pipe() and return +failure. + +Reported-by: Secunia Research +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/usb/usbip/stub_rx.c | 30 +++++++++++++++++++++++++++--- + 1 file changed, 27 insertions(+), 3 deletions(-) + +--- a/drivers/usb/usbip/stub_rx.c ++++ b/drivers/usb/usbip/stub_rx.c +@@ -341,11 +341,13 @@ static struct stub_priv *stub_priv_alloc + return priv; + } + +-static int get_pipe(struct stub_device *sdev, int epnum, int dir) ++static int get_pipe(struct stub_device *sdev, struct usbip_header *pdu) + { + struct usb_device *udev = sdev->udev; + struct usb_host_endpoint *ep; + struct usb_endpoint_descriptor *epd = NULL; ++ int epnum = pdu->base.ep; ++ int dir = pdu->base.direction; + + if (epnum < 0 || epnum > 15) + goto err_ret; +@@ -358,6 +360,7 @@ static int get_pipe(struct stub_device * + goto err_ret; + + epd = &ep->desc; ++ + if (usb_endpoint_xfer_control(epd)) { + if (dir == USBIP_DIR_OUT) + return usb_sndctrlpipe(udev, epnum); +@@ -380,6 +383,27 @@ static int get_pipe(struct stub_device * + } + + if (usb_endpoint_xfer_isoc(epd)) { ++ /* validate packet size and number of packets */ ++ unsigned int maxp, packets, bytes; ++ ++#define USB_EP_MAXP_MULT_SHIFT 11 ++#define USB_EP_MAXP_MULT_MASK (3 << USB_EP_MAXP_MULT_SHIFT) ++#define USB_EP_MAXP_MULT(m) \ ++ (((m) & USB_EP_MAXP_MULT_MASK) >> USB_EP_MAXP_MULT_SHIFT) ++ ++ maxp = usb_endpoint_maxp(epd); ++ maxp *= (USB_EP_MAXP_MULT( ++ __le16_to_cpu(epd->wMaxPacketSize)) + 1); ++ bytes = pdu->u.cmd_submit.transfer_buffer_length; ++ packets = DIV_ROUND_UP(bytes, maxp); ++ ++ if (pdu->u.cmd_submit.number_of_packets < 0 || ++ pdu->u.cmd_submit.number_of_packets > packets) { ++ dev_err(&sdev->udev->dev, ++ "CMD_SUBMIT: isoc invalid num packets %d\n", ++ pdu->u.cmd_submit.number_of_packets); ++ return -1; ++ } + if (dir == USBIP_DIR_OUT) + return usb_sndisocpipe(udev, epnum); + else +@@ -388,7 +412,7 @@ static int get_pipe(struct stub_device * + + err_ret: + /* NOT REACHED */ +- dev_err(&sdev->interface->dev, "get pipe, epnum %d\n", epnum); ++ dev_err(&sdev->udev->dev, "CMD_SUBMIT: invalid epnum %d\n", epnum); + return -1; + } + +@@ -453,7 +477,7 @@ static void stub_recv_cmd_submit(struct + struct stub_priv *priv; + struct usbip_device *ud = &sdev->ud; + struct usb_device *udev = sdev->udev; +- int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction); ++ int pipe = get_pipe(sdev, pdu); + + if (pipe == -1) + return; diff --git a/queue-3.18/usbip-prevent-leaking-socket-pointer-address-in-messages.patch b/queue-3.18/usbip-prevent-leaking-socket-pointer-address-in-messages.patch new file mode 100644 index 00000000000..96cc3ae1c4d --- /dev/null +++ b/queue-3.18/usbip-prevent-leaking-socket-pointer-address-in-messages.patch @@ -0,0 +1,82 @@ +From 90120d15f4c397272aaf41077960a157fc4212bf Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Fri, 15 Dec 2017 10:50:09 -0700 +Subject: usbip: prevent leaking socket pointer address in messages + +From: Shuah Khan + +commit 90120d15f4c397272aaf41077960a157fc4212bf upstream. + +usbip driver is leaking socket pointer address in messages. Remove +the messages that aren't useful and print sockfd in the ones that +are useful for debugging. + +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/usbip/stub_dev.c | 3 +-- + drivers/usb/usbip/usbip_common.c | 15 ++++----------- + drivers/usb/usbip/vhci_hcd.c | 2 +- + 3 files changed, 6 insertions(+), 14 deletions(-) + +--- a/drivers/usb/usbip/stub_dev.c ++++ b/drivers/usb/usbip/stub_dev.c +@@ -163,8 +163,7 @@ static void stub_shutdown_connection(str + * step 1? + */ + if (ud->tcp_socket) { +- dev_dbg(&sdev->udev->dev, "shutdown tcp_socket %p\n", +- ud->tcp_socket); ++ dev_dbg(&sdev->udev->dev, "shutdown sockfd %d\n", ud->sockfd); + kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); + } + +--- a/drivers/usb/usbip/usbip_common.c ++++ b/drivers/usb/usbip/usbip_common.c +@@ -317,18 +317,14 @@ int usbip_recv(struct socket *sock, void + struct msghdr msg; + struct kvec iov; + int total = 0; +- + /* for blocks of if (usbip_dbg_flag_xmit) */ + char *bp = buf; + int osize = size; + +- usbip_dbg_xmit("enter\n"); +- +- if (!sock || !buf || !size) { +- pr_err("invalid arg, sock %p buff %p size %d\n", sock, buf, +- size); ++ if (!sock || !buf || !size) + return -EINVAL; +- } ++ ++ usbip_dbg_xmit("enter\n"); + + do { + sock->sk->sk_allocation = GFP_NOIO; +@@ -341,11 +337,8 @@ int usbip_recv(struct socket *sock, void + msg.msg_flags = MSG_NOSIGNAL; + + result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL); +- if (result <= 0) { +- pr_debug("receive sock %p buf %p size %u ret %d total %d\n", +- sock, buf, size, result, total); ++ if (result <= 0) + goto err; +- } + + size -= result; + buf += result; +--- a/drivers/usb/usbip/vhci_hcd.c ++++ b/drivers/usb/usbip/vhci_hcd.c +@@ -782,7 +782,7 @@ static void vhci_shutdown_connection(str + + /* need this? see stub_dev.c */ + if (ud->tcp_socket) { +- pr_debug("shutdown tcp_socket %p\n", ud->tcp_socket); ++ pr_debug("shutdown sockfd %d\n", ud->sockfd); + kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); + } + diff --git a/queue-3.18/usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch b/queue-3.18/usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch new file mode 100644 index 00000000000..3223e12f428 --- /dev/null +++ b/queue-3.18/usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch @@ -0,0 +1,124 @@ +From 2f2d0088eb93db5c649d2a5e34a3800a8a935fc5 Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Thu, 7 Dec 2017 14:16:49 -0700 +Subject: usbip: prevent vhci_hcd driver from leaking a socket pointer address + +From: Shuah Khan + +commit 2f2d0088eb93db5c649d2a5e34a3800a8a935fc5 upstream. + +When a client has a USB device attached over IP, the vhci_hcd driver is +locally leaking a socket pointer address via the + +/sys/devices/platform/vhci_hcd/status file (world-readable) and in debug +output when "usbip --debug port" is run. + +Fix it to not leak. The socket pointer address is not used at the moment +and it was made visible as a convenient way to find IP address from socket +pointer address by looking up /proc/net/{tcp,tcp6}. + +As this opens a security hole, the fix replaces socket pointer address with +sockfd. + +Reported-by: Secunia Research +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/usb/usbip/usbip_common.h | 1 + + drivers/usb/usbip/vhci_sysfs.c | 26 +++++++++++++++----------- + tools/usb/usbip/libsrc/vhci_driver.c | 8 ++++---- + 3 files changed, 20 insertions(+), 15 deletions(-) + +--- a/drivers/usb/usbip/usbip_common.h ++++ b/drivers/usb/usbip/usbip_common.h +@@ -261,6 +261,7 @@ struct usbip_device { + /* lock for status */ + spinlock_t lock; + ++ int sockfd; + struct socket *tcp_socket; + + struct task_struct *tcp_rx; +--- a/drivers/usb/usbip/vhci_sysfs.c ++++ b/drivers/usb/usbip/vhci_sysfs.c +@@ -39,16 +39,20 @@ static ssize_t status_show(struct device + + /* + * output example: +- * prt sta spd dev socket local_busid +- * 000 004 000 000 c5a7bb80 1-2.3 +- * 001 004 000 000 d8cee980 2-3.4 ++ * prt sta spd dev sockfd local_busid ++ * 0000 004 000 00000000 000003 1-2.3 ++ * 0001 004 000 00000000 000004 2-3.4 + * +- * IP address can be retrieved from a socket pointer address by looking +- * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a +- * port number and its peer IP address. ++ * Output includes socket fd instead of socket pointer address to ++ * avoid leaking kernel memory address in: ++ * /sys/devices/platform/vhci_hcd.0/status and in debug output. ++ * The socket pointer address is not used at the moment and it was ++ * made visible as a convenient way to find IP address from socket ++ * pointer address by looking up /proc/net/{tcp,tcp6}. As this opens ++ * a security hole, the change is made to use sockfd instead. + */ + out += sprintf(out, +- "prt sta spd bus dev socket local_busid\n"); ++ "prt sta spd dev sockfd local_busid\n"); + + for (i = 0; i < VHCI_NPORTS; i++) { + struct vhci_device *vdev = port_to_vdev(i); +@@ -59,12 +63,11 @@ static ssize_t status_show(struct device + if (vdev->ud.status == VDEV_ST_USED) { + out += sprintf(out, "%03u %08x ", + vdev->speed, vdev->devid); +- out += sprintf(out, "%16p ", vdev->ud.tcp_socket); ++ out += sprintf(out, "%06u ", vdev->ud.sockfd); + out += sprintf(out, "%s", dev_name(&vdev->udev->dev)); + +- } else { +- out += sprintf(out, "000 000 000 0000000000000000 0-0"); +- } ++ } else ++ out += sprintf(out, "000 00000000 000000 0-0"); + + out += sprintf(out, "\n"); + spin_unlock(&vdev->ud.lock); +@@ -223,6 +226,7 @@ static ssize_t store_attach(struct devic + + vdev->devid = devid; + vdev->speed = speed; ++ vdev->ud.sockfd = sockfd; + vdev->ud.tcp_socket = socket; + vdev->ud.status = VDEV_ST_NOTASSIGNED; + +--- a/tools/usb/usbip/libsrc/vhci_driver.c ++++ b/tools/usb/usbip/libsrc/vhci_driver.c +@@ -55,12 +55,12 @@ static int parse_status(const char *valu + + while (*c != '\0') { + int port, status, speed, devid; +- unsigned long socket; ++ int sockfd; + char lbusid[SYSFS_BUS_ID_SIZE]; + +- ret = sscanf(c, "%d %d %d %x %lx %31s\n", ++ ret = sscanf(c, "%d %d %d %x %u %31s\n", + &port, &status, &speed, +- &devid, &socket, lbusid); ++ &devid, &sockfd, lbusid); + + if (ret < 5) { + dbg("sscanf failed: %d", ret); +@@ -69,7 +69,7 @@ static int parse_status(const char *valu + + dbg("port %d status %d speed %d devid %x", + port, status, speed, devid); +- dbg("socket %lx lbusid %s", socket, lbusid); ++ dbg("sockfd %u lbusid %s", sockfd, lbusid); + + + /* if a device is connected, look at it */ diff --git a/queue-3.18/usbip-stub-stop-printing-kernel-pointer-addresses-in-messages.patch b/queue-3.18/usbip-stub-stop-printing-kernel-pointer-addresses-in-messages.patch new file mode 100644 index 00000000000..24c120705a0 --- /dev/null +++ b/queue-3.18/usbip-stub-stop-printing-kernel-pointer-addresses-in-messages.patch @@ -0,0 +1,74 @@ +From 248a22044366f588d46754c54dfe29ffe4f8b4df Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Mon, 18 Dec 2017 17:23:37 -0700 +Subject: usbip: stub: stop printing kernel pointer addresses in messages + +From: Shuah Khan + +commit 248a22044366f588d46754c54dfe29ffe4f8b4df upstream. + +Remove and/or change debug, info. and error messages to not print +kernel pointer addresses. + +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/usbip/stub_main.c | 5 +++-- + drivers/usb/usbip/stub_rx.c | 7 ++----- + drivers/usb/usbip/stub_tx.c | 4 ++-- + 3 files changed, 7 insertions(+), 9 deletions(-) + +--- a/drivers/usb/usbip/stub_main.c ++++ b/drivers/usb/usbip/stub_main.c +@@ -252,11 +252,12 @@ void stub_device_cleanup_urbs(struct stu + struct stub_priv *priv; + struct urb *urb; + +- dev_dbg(&sdev->udev->dev, "free sdev %p\n", sdev); ++ dev_dbg(&sdev->udev->dev, "Stub device cleaning up urbs\n"); + + while ((priv = stub_priv_pop(sdev))) { + urb = priv->urb; +- dev_dbg(&sdev->udev->dev, "free urb %p\n", urb); ++ dev_dbg(&sdev->udev->dev, "free urb seqnum %lu\n", ++ priv->seqnum); + usb_kill_urb(urb); + + kmem_cache_free(stub_priv_cache, priv); +--- a/drivers/usb/usbip/stub_rx.c ++++ b/drivers/usb/usbip/stub_rx.c +@@ -230,9 +230,6 @@ static int stub_recv_cmd_unlink(struct s + if (priv->seqnum != pdu->u.cmd_unlink.seqnum) + continue; + +- dev_info(&priv->urb->dev->dev, "unlink urb %p\n", +- priv->urb); +- + /* + * This matched urb is not completed yet (i.e., be in + * flight in usb hcd hardware/driver). Now we are +@@ -271,8 +268,8 @@ static int stub_recv_cmd_unlink(struct s + ret = usb_unlink_urb(priv->urb); + if (ret != -EINPROGRESS) + dev_err(&priv->urb->dev->dev, +- "failed to unlink a urb %p, ret %d\n", +- priv->urb, ret); ++ "failed to unlink a urb # %lu, ret %d\n", ++ priv->seqnum, ret); + + return 0; + } +--- a/drivers/usb/usbip/stub_tx.c ++++ b/drivers/usb/usbip/stub_tx.c +@@ -201,8 +201,8 @@ static int stub_send_ret_submit(struct s + + /* 1. setup usbip_header */ + setup_ret_submit_pdu(&pdu_header, urb); +- usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n", +- pdu_header.base.seqnum, urb); ++ usbip_dbg_stub_tx("setup txdata seqnum: %d\n", ++ pdu_header.base.seqnum); + usbip_header_correct_endian(&pdu_header, 1); + + iov[iovnum].iov_base = &pdu_header; diff --git a/queue-3.18/usbip-vhci-hcd-add-usb3-superspeed-support.patch b/queue-3.18/usbip-vhci-hcd-add-usb3-superspeed-support.patch new file mode 100644 index 00000000000..733dca0280a --- /dev/null +++ b/queue-3.18/usbip-vhci-hcd-add-usb3-superspeed-support.patch @@ -0,0 +1,41 @@ +From 1c9de5bf428612458427943b724bea51abde520a Mon Sep 17 00:00:00 2001 +From: Yuyang Du +Date: Thu, 8 Jun 2017 13:04:10 +0800 +Subject: usbip: vhci-hcd: Add USB3 SuperSpeed support + +From: Yuyang Du + +commit 1c9de5bf428612458427943b724bea51abde520a upstream. + +This patch adds a USB3 HCD to an existing USB2 HCD and provides +the support of SuperSpeed, in case the device can only be enumerated +with SuperSpeed. + +The bulk of the added code in usb3_bos_desc and hub_control to support +SuperSpeed is borrowed from the commit 1cd8fd2887e162ad ("usb: gadget: +dummy_hcd: add SuperSpeed support"). + +With this patch, each vhci will have VHCI_HC_PORTS HighSpeed ports +and VHCI_HC_PORTS SuperSpeed ports. + +Suggested-by: Krzysztof Opasiak +Signed-off-by: Yuyang Du +Acked-by: Shuah Khan +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/usbip/vhci_hcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/usbip/vhci_hcd.c ++++ b/drivers/usb/usbip/vhci_hcd.c +@@ -279,7 +279,7 @@ static int vhci_hub_control(struct usb_h + case USB_PORT_FEAT_POWER: + usbip_dbg_vhci_rh( + " ClearPortFeature: USB_PORT_FEAT_POWER\n"); +- dum->port_status[rhport] = 0; ++ dum->port_status[rhport] &= ~USB_PORT_STAT_POWER; + dum->resuming = 0; + break; + case USB_PORT_FEAT_C_RESET: diff --git a/queue-3.18/usbip-vhci-stop-printing-kernel-pointer-addresses-in-messages.patch b/queue-3.18/usbip-vhci-stop-printing-kernel-pointer-addresses-in-messages.patch new file mode 100644 index 00000000000..fbccc3cc3e0 --- /dev/null +++ b/queue-3.18/usbip-vhci-stop-printing-kernel-pointer-addresses-in-messages.patch @@ -0,0 +1,144 @@ +From 8272d099d05f7ab2776cf56a2ab9f9443be18907 Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Mon, 18 Dec 2017 17:24:22 -0700 +Subject: usbip: vhci: stop printing kernel pointer addresses in messages + +From: Shuah Khan + +commit 8272d099d05f7ab2776cf56a2ab9f9443be18907 upstream. + +Remove and/or change debug, info. and error messages to not print +kernel pointer addresses. + +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/usb/usbip/vhci_hcd.c | 10 ---------- + drivers/usb/usbip/vhci_rx.c | 23 +++++++++++------------ + drivers/usb/usbip/vhci_tx.c | 3 ++- + 3 files changed, 13 insertions(+), 23 deletions(-) + +--- a/drivers/usb/usbip/vhci_hcd.c ++++ b/drivers/usb/usbip/vhci_hcd.c +@@ -469,9 +469,6 @@ static int vhci_urb_enqueue(struct usb_h + struct vhci_device *vdev; + unsigned long flags; + +- usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", +- hcd, urb, mem_flags); +- + /* patch to usb_sg_init() is in 2.5.60 */ + BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length); + +@@ -630,8 +627,6 @@ static int vhci_urb_dequeue(struct usb_h + struct vhci_device *vdev; + unsigned long flags; + +- pr_info("dequeue a urb %p\n", urb); +- + spin_lock_irqsave(&the_controller->lock, flags); + + priv = urb->hcpriv; +@@ -659,7 +654,6 @@ static int vhci_urb_dequeue(struct usb_h + /* tcp connection is closed */ + spin_lock(&vdev->priv_lock); + +- pr_info("device %p seems to be disconnected\n", vdev); + list_del(&priv->list); + kfree(priv); + urb->hcpriv = NULL; +@@ -671,8 +665,6 @@ static int vhci_urb_dequeue(struct usb_h + * vhci_rx will receive RET_UNLINK and give back the URB. + * Otherwise, we give back it here. + */ +- pr_info("gives back urb %p\n", urb); +- + usb_hcd_unlink_urb_from_ep(hcd, urb); + + spin_unlock_irqrestore(&the_controller->lock, flags); +@@ -701,8 +693,6 @@ static int vhci_urb_dequeue(struct usb_h + + unlink->unlink_seqnum = priv->seqnum; + +- pr_info("device %p seems to be still connected\n", vdev); +- + /* send cmd_unlink and try to cancel the pending URB in the + * peer */ + list_add_tail(&unlink->list, &vdev->unlink_tx); +--- a/drivers/usb/usbip/vhci_rx.c ++++ b/drivers/usb/usbip/vhci_rx.c +@@ -37,24 +37,23 @@ struct urb *pickup_urb_and_free_priv(str + urb = priv->urb; + status = urb->status; + +- usbip_dbg_vhci_rx("find urb %p vurb %p seqnum %u\n", +- urb, priv, seqnum); ++ usbip_dbg_vhci_rx("find urb seqnum %u\n", seqnum); + + switch (status) { + case -ENOENT: + /* fall through */ + case -ECONNRESET: +- dev_info(&urb->dev->dev, +- "urb %p was unlinked %ssynchronuously.\n", urb, +- status == -ENOENT ? "" : "a"); ++ dev_dbg(&urb->dev->dev, ++ "urb seq# %u was unlinked %ssynchronuously\n", ++ seqnum, status == -ENOENT ? "" : "a"); + break; + case -EINPROGRESS: + /* no info output */ + break; + default: +- dev_info(&urb->dev->dev, +- "urb %p may be in a error, status %d\n", urb, +- status); ++ dev_dbg(&urb->dev->dev, ++ "urb seq# %u may be in a error, status %d\n", ++ seqnum, status); + } + + list_del(&priv->list); +@@ -79,8 +78,8 @@ static void vhci_recv_ret_submit(struct + spin_unlock_irqrestore(&vdev->priv_lock, flags); + + if (!urb) { +- pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum); +- pr_info("max seqnum %d\n", ++ pr_err("cannot find a urb of seqnum %u max seqnum %d\n", ++ pdu->base.seqnum, + atomic_read(&the_controller->seqnum)); + usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); + return; +@@ -103,7 +102,7 @@ static void vhci_recv_ret_submit(struct + if (usbip_dbg_flag_vhci_rx) + usbip_dump_urb(urb); + +- usbip_dbg_vhci_rx("now giveback urb %p\n", urb); ++ usbip_dbg_vhci_rx("now giveback urb %u\n", pdu->base.seqnum); + + spin_lock_irqsave(&the_controller->lock, flags); + usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); +@@ -168,7 +167,7 @@ static void vhci_recv_ret_unlink(struct + pr_info("the urb (seqnum %d) was already given back\n", + pdu->base.seqnum); + } else { +- usbip_dbg_vhci_rx("now giveback urb %p\n", urb); ++ usbip_dbg_vhci_rx("now giveback urb %d\n", pdu->base.seqnum); + + /* If unlink is successful, status is -ECONNRESET */ + urb->status = pdu->u.ret_unlink.status; +--- a/drivers/usb/usbip/vhci_tx.c ++++ b/drivers/usb/usbip/vhci_tx.c +@@ -83,7 +83,8 @@ static int vhci_send_cmd_submit(struct v + memset(&msg, 0, sizeof(msg)); + memset(&iov, 0, sizeof(iov)); + +- usbip_dbg_vhci_tx("setup txdata urb %p\n", urb); ++ usbip_dbg_vhci_tx("setup txdata urb seqnum %lu\n", ++ priv->seqnum); + + /* 1. setup usbip_header */ + setup_cmd_submit_pdu(&pdu_header, urb); -- 2.47.2