From: Greg Kroah-Hartman Date: Wed, 24 Jan 2018 09:12:17 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v4.4.114~52 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b43a22d726f6b346ebe4e10aae9c02dc21c57fb3;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: usbip-fix-implicit-fallthrough-warning.patch usbip-fix-potential-format-overflow-in-userspace-tools.patch usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch --- diff --git a/queue-4.4/series b/queue-4.4/series index e2d6ad978ed..86a0b29f1fe 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -1 +1,4 @@ x86-asm-32-make-sync_core-handle-missing-cpuid-on-all-32-bit-kernels.patch +usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch +usbip-fix-implicit-fallthrough-warning.patch +usbip-fix-potential-format-overflow-in-userspace-tools.patch diff --git a/queue-4.4/usbip-fix-implicit-fallthrough-warning.patch b/queue-4.4/usbip-fix-implicit-fallthrough-warning.patch new file mode 100644 index 00000000000..da83c9c39ce --- /dev/null +++ b/queue-4.4/usbip-fix-implicit-fallthrough-warning.patch @@ -0,0 +1,35 @@ +From cfd6ed4537a9e938fa76facecd4b9cd65b6d1563 Mon Sep 17 00:00:00 2001 +From: Jonathan Dieter +Date: Mon, 27 Feb 2017 10:31:04 +0200 +Subject: usbip: Fix implicit fallthrough warning + +From: Jonathan Dieter + +commit cfd6ed4537a9e938fa76facecd4b9cd65b6d1563 upstream. + +GCC 7 now warns when switch statements fall through implicitly, and with +-Werror enabled in configure.ac, that makes these tools unbuildable. + +We fix this by notifying the compiler that this particular case statement +is meant to fall through. + +Reviewed-by: Peter Senna Tschudin +Signed-off-by: Jonathan Dieter +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + tools/usb/usbip/src/usbip.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/tools/usb/usbip/src/usbip.c ++++ b/tools/usb/usbip/src/usbip.c +@@ -176,6 +176,8 @@ int main(int argc, char *argv[]) + break; + case '?': + printf("usbip: invalid option\n"); ++ /* Terminate after printing error */ ++ /* FALLTHRU */ + default: + usbip_usage(); + goto out; diff --git a/queue-4.4/usbip-fix-potential-format-overflow-in-userspace-tools.patch b/queue-4.4/usbip-fix-potential-format-overflow-in-userspace-tools.patch new file mode 100644 index 00000000000..f3f956f6a5d --- /dev/null +++ b/queue-4.4/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-4.4/usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch b/queue-4.4/usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch new file mode 100644 index 00000000000..9c38b4864a3 --- /dev/null +++ b/queue-4.4/usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch @@ -0,0 +1,123 @@ +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 | 25 +++++++++++++++---------- + tools/usb/usbip/libsrc/vhci_driver.c | 8 ++++---- + 3 files changed, 20 insertions(+), 14 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 ++ * port 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 bus dev sockfd local_busid\n"); + + for (i = 0; i < VHCI_NPORTS; i++) { + struct vhci_device *vdev = port_to_vdev(i); +@@ -60,11 +64,11 @@ static ssize_t status_show(struct device + 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 000 000 000000 0-0"); + + out += sprintf(out, "\n"); + spin_unlock(&vdev->ud.lock); +@@ -223,6 +227,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 */