diff options
| -rw-r--r-- | drivers/usb/usbip/usbip_common.h | 1 | ||||
| -rw-r--r-- | drivers/usb/usbip/vhci_sysfs.c | 25 | ||||
| -rw-r--r-- | tools/usb/usbip/libsrc/vhci_driver.c | 8 |
3 files changed, 21 insertions, 13 deletions
diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h index e5de35c8c505..473fb8a87289 100644 --- a/drivers/usb/usbip/usbip_common.h +++ b/drivers/usb/usbip/usbip_common.h | |||
| @@ -256,6 +256,7 @@ struct usbip_device { | |||
| 256 | /* lock for status */ | 256 | /* lock for status */ |
| 257 | spinlock_t lock; | 257 | spinlock_t lock; |
| 258 | 258 | ||
| 259 | int sockfd; | ||
| 259 | struct socket *tcp_socket; | 260 | struct socket *tcp_socket; |
| 260 | 261 | ||
| 261 | struct task_struct *tcp_rx; | 262 | struct task_struct *tcp_rx; |
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index e78f7472cac4..091f76b7196d 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c | |||
| @@ -17,15 +17,20 @@ | |||
| 17 | 17 | ||
| 18 | /* | 18 | /* |
| 19 | * output example: | 19 | * output example: |
| 20 | * hub port sta spd dev socket local_busid | 20 | * hub port sta spd dev sockfd local_busid |
| 21 | * hs 0000 004 000 00000000 c5a7bb80 1-2.3 | 21 | * hs 0000 004 000 00000000 3 1-2.3 |
| 22 | * ................................................ | 22 | * ................................................ |
| 23 | * ss 0008 004 000 00000000 d8cee980 2-3.4 | 23 | * ss 0008 004 000 00000000 4 2-3.4 |
| 24 | * ................................................ | 24 | * ................................................ |
| 25 | * | 25 | * |
| 26 | * IP address can be retrieved from a socket pointer address by looking | 26 | * Output includes socket fd instead of socket pointer address to avoid |
| 27 | * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a | 27 | * leaking kernel memory address in: |
| 28 | * port number and its peer IP address. | 28 | * /sys/devices/platform/vhci_hcd.0/status and in debug output. |
| 29 | * The socket pointer address is not used at the moment and it was made | ||
| 30 | * visible as a convenient way to find IP address from socket pointer | ||
| 31 | * address by looking up /proc/net/{tcp,tcp6}. As this opens a security | ||
| 32 | * hole, the change is made to use sockfd instead. | ||
| 33 | * | ||
| 29 | */ | 34 | */ |
| 30 | static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev) | 35 | static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev) |
| 31 | { | 36 | { |
| @@ -39,8 +44,8 @@ static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vd | |||
| 39 | if (vdev->ud.status == VDEV_ST_USED) { | 44 | if (vdev->ud.status == VDEV_ST_USED) { |
| 40 | *out += sprintf(*out, "%03u %08x ", | 45 | *out += sprintf(*out, "%03u %08x ", |
| 41 | vdev->speed, vdev->devid); | 46 | vdev->speed, vdev->devid); |
| 42 | *out += sprintf(*out, "%16p %s", | 47 | *out += sprintf(*out, "%u %s", |
| 43 | vdev->ud.tcp_socket, | 48 | vdev->ud.sockfd, |
| 44 | dev_name(&vdev->udev->dev)); | 49 | dev_name(&vdev->udev->dev)); |
| 45 | 50 | ||
| 46 | } else { | 51 | } else { |
| @@ -160,7 +165,8 @@ static ssize_t nports_show(struct device *dev, struct device_attribute *attr, | |||
| 160 | char *s = out; | 165 | char *s = out; |
| 161 | 166 | ||
| 162 | /* | 167 | /* |
| 163 | * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, thus the * 2. | 168 | * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, |
| 169 | * thus the * 2. | ||
| 164 | */ | 170 | */ |
| 165 | out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers); | 171 | out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers); |
| 166 | return out - s; | 172 | return out - s; |
| @@ -366,6 +372,7 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, | |||
| 366 | 372 | ||
| 367 | vdev->devid = devid; | 373 | vdev->devid = devid; |
| 368 | vdev->speed = speed; | 374 | vdev->speed = speed; |
| 375 | vdev->ud.sockfd = sockfd; | ||
| 369 | vdev->ud.tcp_socket = socket; | 376 | vdev->ud.tcp_socket = socket; |
| 370 | vdev->ud.status = VDEV_ST_NOTASSIGNED; | 377 | vdev->ud.status = VDEV_ST_NOTASSIGNED; |
| 371 | 378 | ||
diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 627d1dfc332b..c9c81614a66a 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c | |||
| @@ -50,14 +50,14 @@ static int parse_status(const char *value) | |||
| 50 | 50 | ||
| 51 | while (*c != '\0') { | 51 | while (*c != '\0') { |
| 52 | int port, status, speed, devid; | 52 | int port, status, speed, devid; |
| 53 | unsigned long socket; | 53 | int sockfd; |
| 54 | char lbusid[SYSFS_BUS_ID_SIZE]; | 54 | char lbusid[SYSFS_BUS_ID_SIZE]; |
| 55 | struct usbip_imported_device *idev; | 55 | struct usbip_imported_device *idev; |
| 56 | char hub[3]; | 56 | char hub[3]; |
| 57 | 57 | ||
| 58 | ret = sscanf(c, "%2s %d %d %d %x %lx %31s\n", | 58 | ret = sscanf(c, "%2s %d %d %d %x %u %31s\n", |
| 59 | hub, &port, &status, &speed, | 59 | hub, &port, &status, &speed, |
| 60 | &devid, &socket, lbusid); | 60 | &devid, &sockfd, lbusid); |
| 61 | 61 | ||
| 62 | if (ret < 5) { | 62 | if (ret < 5) { |
| 63 | dbg("sscanf failed: %d", ret); | 63 | dbg("sscanf failed: %d", ret); |
| @@ -66,7 +66,7 @@ static int parse_status(const char *value) | |||
| 66 | 66 | ||
| 67 | dbg("hub %s port %d status %d speed %d devid %x", | 67 | dbg("hub %s port %d status %d speed %d devid %x", |
| 68 | hub, port, status, speed, devid); | 68 | hub, port, status, speed, devid); |
| 69 | dbg("socket %lx lbusid %s", socket, lbusid); | 69 | dbg("sockfd %u lbusid %s", sockfd, lbusid); |
| 70 | 70 | ||
| 71 | /* if a device is connected, look at it */ | 71 | /* if a device is connected, look at it */ |
| 72 | idev = &vhci_driver->idev[port]; | 72 | idev = &vhci_driver->idev[port]; |
