]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Jan 2018 09:12:17 +0000 (10:12 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Jan 2018 09:12:17 +0000 (10:12 +0100)
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

queue-4.4/series
queue-4.4/usbip-fix-implicit-fallthrough-warning.patch [new file with mode: 0644]
queue-4.4/usbip-fix-potential-format-overflow-in-userspace-tools.patch [new file with mode: 0644]
queue-4.4/usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch [new file with mode: 0644]

index e2d6ad978ed050de03282729f54909148ebf85b1..86a0b29f1fe1769e93b0f936facc574c3a59a565 100644 (file)
@@ -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 (file)
index 0000000..da83c9c
--- /dev/null
@@ -0,0 +1,35 @@
+From cfd6ed4537a9e938fa76facecd4b9cd65b6d1563 Mon Sep 17 00:00:00 2001
+From: Jonathan Dieter <jdieter@lesbg.com>
+Date: Mon, 27 Feb 2017 10:31:04 +0200
+Subject: usbip: Fix implicit fallthrough warning
+
+From: Jonathan Dieter <jdieter@lesbg.com>
+
+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 <peter.senna@gmail.com>
+Signed-off-by: Jonathan Dieter <jdieter@lesbg.com>
+Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..f3f956f
--- /dev/null
@@ -0,0 +1,107 @@
+From e5dfa3f902b9a642ae8c6997d57d7c41e384a90b Mon Sep 17 00:00:00 2001
+From: Jonathan Dieter <jdieter@lesbg.com>
+Date: Mon, 27 Feb 2017 10:31:03 +0200
+Subject: usbip: Fix potential format overflow in userspace tools
+
+From: Jonathan Dieter <jdieter@lesbg.com>
+
+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 <peter.senna@gmail.com>
+Signed-off-by: Jonathan Dieter <jdieter@lesbg.com>
+Acked-by: Shuah Khan <shuahkh@osg.samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ 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 (file)
index 0000000..9c38b48
--- /dev/null
@@ -0,0 +1,123 @@
+From 2f2d0088eb93db5c649d2a5e34a3800a8a935fc5 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <shuahkh@osg.samsung.com>
+Date: Thu, 7 Dec 2017 14:16:49 -0700
+Subject: usbip: prevent vhci_hcd driver from leaking a socket pointer address
+
+From: Shuah Khan <shuahkh@osg.samsung.com>
+
+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 <vuln@secunia.com>
+Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ 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 */