1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2003-2008 Takahiro Hirofuchi
4 * Copyright (C) 2015-2016 Nobuo Iwata
7 #include <linux/kthread.h>
8 #include <linux/file.h>
10 #include <linux/platform_device.h>
11 #include <linux/slab.h>
13 /* Hardening for Spectre-v1 */
14 #include <linux/nospec.h>
16 #include "usbip_common.h"
19 /* TODO: refine locking ?*/
23 * hub port sta spd dev sockfd local_busid
24 * hs 0000 004 000 00000000 000003 1-2.3
25 * ................................................
26 * ss 0008 004 000 00000000 000004 2-3.4
27 * ................................................
29 * Output includes socket fd instead of socket pointer address to avoid
30 * leaking kernel memory address in:
31 * /sys/devices/platform/vhci_hcd.0/status and in debug output.
32 * The socket pointer address is not used at the moment and it was made
33 * visible as a convenient way to find IP address from socket pointer
34 * address by looking up /proc/net/{tcp,tcp6}. As this opens a security
35 * hole, the change is made to use sockfd instead.
38 static void port_show_vhci(char **out
, int hub
, int port
, struct vhci_device
*vdev
)
40 if (hub
== HUB_SPEED_HIGH
)
41 *out
+= sprintf(*out
, "hs %04u %03u ",
42 port
, vdev
->ud
.status
);
43 else /* hub == HUB_SPEED_SUPER */
44 *out
+= sprintf(*out
, "ss %04u %03u ",
45 port
, vdev
->ud
.status
);
47 if (vdev
->ud
.status
== VDEV_ST_USED
) {
48 *out
+= sprintf(*out
, "%03u %08x ",
49 vdev
->speed
, vdev
->devid
);
50 *out
+= sprintf(*out
, "%06u %s",
52 dev_name(&vdev
->udev
->dev
));
55 *out
+= sprintf(*out
, "000 00000000 ");
56 *out
+= sprintf(*out
, "000000 0-0");
59 *out
+= sprintf(*out
, "\n");
62 /* Sysfs entry to show port status */
63 static ssize_t
status_show_vhci(int pdev_nr
, char *out
)
65 struct platform_device
*pdev
= vhcis
[pdev_nr
].pdev
;
68 struct vhci_hcd
*vhci_hcd
;
74 usbip_dbg_vhci_sysfs("show status error\n");
78 hcd
= platform_get_drvdata(pdev
);
79 vhci_hcd
= hcd_to_vhci_hcd(hcd
);
80 vhci
= vhci_hcd
->vhci
;
82 spin_lock_irqsave(&vhci
->lock
, flags
);
84 for (i
= 0; i
< VHCI_HC_PORTS
; i
++) {
85 struct vhci_device
*vdev
= &vhci
->vhci_hcd_hs
->vdev
[i
];
87 spin_lock(&vdev
->ud
.lock
);
88 port_show_vhci(&out
, HUB_SPEED_HIGH
,
89 pdev_nr
* VHCI_PORTS
+ i
, vdev
);
90 spin_unlock(&vdev
->ud
.lock
);
93 for (i
= 0; i
< VHCI_HC_PORTS
; i
++) {
94 struct vhci_device
*vdev
= &vhci
->vhci_hcd_ss
->vdev
[i
];
96 spin_lock(&vdev
->ud
.lock
);
97 port_show_vhci(&out
, HUB_SPEED_SUPER
,
98 pdev_nr
* VHCI_PORTS
+ VHCI_HC_PORTS
+ i
, vdev
);
99 spin_unlock(&vdev
->ud
.lock
);
102 spin_unlock_irqrestore(&vhci
->lock
, flags
);
107 static ssize_t
status_show_not_ready(int pdev_nr
, char *out
)
112 for (i
= 0; i
< VHCI_HC_PORTS
; i
++) {
113 out
+= sprintf(out
, "hs %04u %03u ",
114 (pdev_nr
* VHCI_PORTS
) + i
,
115 VDEV_ST_NOTASSIGNED
);
116 out
+= sprintf(out
, "000 00000000 0000000000000000 0-0");
117 out
+= sprintf(out
, "\n");
120 for (i
= 0; i
< VHCI_HC_PORTS
; i
++) {
121 out
+= sprintf(out
, "ss %04u %03u ",
122 (pdev_nr
* VHCI_PORTS
) + VHCI_HC_PORTS
+ i
,
123 VDEV_ST_NOTASSIGNED
);
124 out
+= sprintf(out
, "000 00000000 0000000000000000 0-0");
125 out
+= sprintf(out
, "\n");
130 static int status_name_to_id(const char *name
)
136 c
= strchr(name
, '.');
140 ret
= kstrtol(c
+1, 10, &val
);
147 static ssize_t
status_show(struct device
*dev
,
148 struct device_attribute
*attr
, char *out
)
154 "hub port sta spd dev sockfd local_busid\n");
156 pdev_nr
= status_name_to_id(attr
->attr
.name
);
158 out
+= status_show_not_ready(pdev_nr
, out
);
160 out
+= status_show_vhci(pdev_nr
, out
);
165 static ssize_t
nports_show(struct device
*dev
, struct device_attribute
*attr
,
171 * Half the ports are for SPEED_HIGH and half for SPEED_SUPER,
174 out
+= sprintf(out
, "%d\n", VHCI_PORTS
* vhci_num_controllers
);
177 static DEVICE_ATTR_RO(nports
);
179 /* Sysfs entry to shutdown a virtual connection */
180 static int vhci_port_disconnect(struct vhci_hcd
*vhci_hcd
, __u32 rhport
)
182 struct vhci_device
*vdev
= &vhci_hcd
->vdev
[rhport
];
183 struct vhci
*vhci
= vhci_hcd
->vhci
;
186 usbip_dbg_vhci_sysfs("enter\n");
189 spin_lock_irqsave(&vhci
->lock
, flags
);
190 spin_lock(&vdev
->ud
.lock
);
192 if (vdev
->ud
.status
== VDEV_ST_NULL
) {
193 pr_err("not connected %d\n", vdev
->ud
.status
);
196 spin_unlock(&vdev
->ud
.lock
);
197 spin_unlock_irqrestore(&vhci
->lock
, flags
);
203 spin_unlock(&vdev
->ud
.lock
);
204 spin_unlock_irqrestore(&vhci
->lock
, flags
);
206 usbip_event_add(&vdev
->ud
, VDEV_EVENT_DOWN
);
211 static int valid_port(__u32
*pdev_nr
, __u32
*rhport
)
213 if (*pdev_nr
>= vhci_num_controllers
) {
214 pr_err("pdev %u\n", *pdev_nr
);
217 *pdev_nr
= array_index_nospec(*pdev_nr
, vhci_num_controllers
);
219 if (*rhport
>= VHCI_HC_PORTS
) {
220 pr_err("rhport %u\n", *rhport
);
223 *rhport
= array_index_nospec(*rhport
, VHCI_HC_PORTS
);
228 static ssize_t
detach_store(struct device
*dev
, struct device_attribute
*attr
,
229 const char *buf
, size_t count
)
231 __u32 port
= 0, pdev_nr
= 0, rhport
= 0;
233 struct vhci_hcd
*vhci_hcd
;
236 if (kstrtoint(buf
, 10, &port
) < 0)
239 pdev_nr
= port_to_pdev_nr(port
);
240 rhport
= port_to_rhport(port
);
242 if (!valid_port(&pdev_nr
, &rhport
))
245 hcd
= platform_get_drvdata(vhcis
[pdev_nr
].pdev
);
247 dev_err(dev
, "port is not ready %u\n", port
);
251 usbip_dbg_vhci_sysfs("rhport %d\n", rhport
);
253 if ((port
/ VHCI_HC_PORTS
) % 2)
254 vhci_hcd
= hcd_to_vhci_hcd(hcd
)->vhci
->vhci_hcd_ss
;
256 vhci_hcd
= hcd_to_vhci_hcd(hcd
)->vhci
->vhci_hcd_hs
;
258 ret
= vhci_port_disconnect(vhci_hcd
, rhport
);
262 usbip_dbg_vhci_sysfs("Leave\n");
266 static DEVICE_ATTR_WO(detach
);
268 static int valid_args(__u32
*pdev_nr
, __u32
*rhport
,
269 enum usb_device_speed speed
)
271 if (!valid_port(pdev_nr
, rhport
)) {
279 case USB_SPEED_WIRELESS
:
280 case USB_SPEED_SUPER
:
283 pr_err("Failed attach request for unsupported USB speed: %s\n",
284 usb_speed_string(speed
));
291 /* Sysfs entry to establish a virtual connection */
293 * To start a new USB/IP attachment, a userland program needs to setup a TCP
294 * connection and then write its socket descriptor with remote device
295 * information into this sysfs file.
297 * A remote device is virtually attached to the root-hub port of @rhport with
298 * @speed. @devid is embedded into a request to specify the remote device in a
301 * write() returns 0 on success, else negative errno.
303 static ssize_t
attach_store(struct device
*dev
, struct device_attribute
*attr
,
304 const char *buf
, size_t count
)
306 struct socket
*socket
;
308 __u32 port
= 0, pdev_nr
= 0, rhport
= 0, devid
= 0, speed
= 0;
310 struct vhci_hcd
*vhci_hcd
;
311 struct vhci_device
*vdev
;
317 * @rhport: port number of vhci_hcd
318 * @sockfd: socket descriptor of an established TCP connection
319 * @devid: unique device identifier in a remote host
320 * @speed: usb device speed in a remote host
322 if (sscanf(buf
, "%u %u %u %u", &port
, &sockfd
, &devid
, &speed
) != 4)
324 pdev_nr
= port_to_pdev_nr(port
);
325 rhport
= port_to_rhport(port
);
327 usbip_dbg_vhci_sysfs("port(%u) pdev(%d) rhport(%u)\n",
328 port
, pdev_nr
, rhport
);
329 usbip_dbg_vhci_sysfs("sockfd(%u) devid(%u) speed(%u)\n",
330 sockfd
, devid
, speed
);
332 /* check received parameters */
333 if (!valid_args(&pdev_nr
, &rhport
, speed
))
336 hcd
= platform_get_drvdata(vhcis
[pdev_nr
].pdev
);
338 dev_err(dev
, "port %d is not ready\n", port
);
342 vhci_hcd
= hcd_to_vhci_hcd(hcd
);
343 vhci
= vhci_hcd
->vhci
;
345 if (speed
== USB_SPEED_SUPER
)
346 vdev
= &vhci
->vhci_hcd_ss
->vdev
[rhport
];
348 vdev
= &vhci
->vhci_hcd_hs
->vdev
[rhport
];
350 /* Extract socket from fd. */
351 socket
= sockfd_lookup(sockfd
, &err
);
355 /* now need lock until setting vdev status as used */
358 spin_lock_irqsave(&vhci
->lock
, flags
);
359 spin_lock(&vdev
->ud
.lock
);
361 if (vdev
->ud
.status
!= VDEV_ST_NULL
) {
362 /* end of the lock */
363 spin_unlock(&vdev
->ud
.lock
);
364 spin_unlock_irqrestore(&vhci
->lock
, flags
);
368 dev_err(dev
, "port %d already used\n", rhport
);
370 * Will be retried from userspace
371 * if there's another free port.
376 dev_info(dev
, "pdev(%u) rhport(%u) sockfd(%d)\n",
377 pdev_nr
, rhport
, sockfd
);
378 dev_info(dev
, "devid(%u) speed(%u) speed_str(%s)\n",
379 devid
, speed
, usb_speed_string(speed
));
383 vdev
->ud
.sockfd
= sockfd
;
384 vdev
->ud
.tcp_socket
= socket
;
385 vdev
->ud
.status
= VDEV_ST_NOTASSIGNED
;
387 spin_unlock(&vdev
->ud
.lock
);
388 spin_unlock_irqrestore(&vhci
->lock
, flags
);
391 vdev
->ud
.tcp_rx
= kthread_get_run(vhci_rx_loop
, &vdev
->ud
, "vhci_rx");
392 vdev
->ud
.tcp_tx
= kthread_get_run(vhci_tx_loop
, &vdev
->ud
, "vhci_tx");
394 rh_port_connect(vdev
, speed
);
398 static DEVICE_ATTR_WO(attach
);
400 #define MAX_STATUS_NAME 16
403 struct device_attribute attr
;
404 char name
[MAX_STATUS_NAME
+1];
407 static struct status_attr
*status_attrs
;
409 static void set_status_attr(int id
)
411 struct status_attr
*status
;
413 status
= status_attrs
+ id
;
415 strcpy(status
->name
, "status");
417 snprintf(status
->name
, MAX_STATUS_NAME
+1, "status.%d", id
);
418 status
->attr
.attr
.name
= status
->name
;
419 status
->attr
.attr
.mode
= S_IRUGO
;
420 status
->attr
.show
= status_show
;
421 sysfs_attr_init(&status
->attr
.attr
);
424 static int init_status_attrs(void)
428 status_attrs
= kcalloc(vhci_num_controllers
, sizeof(struct status_attr
),
430 if (status_attrs
== NULL
)
433 for (id
= 0; id
< vhci_num_controllers
; id
++)
439 static void finish_status_attrs(void)
444 struct attribute_group vhci_attr_group
= {
448 int vhci_init_attr_group(void)
450 struct attribute
**attrs
;
453 attrs
= kcalloc((vhci_num_controllers
+ 5), sizeof(struct attribute
*),
458 ret
= init_status_attrs();
463 *attrs
= &dev_attr_nports
.attr
;
464 *(attrs
+ 1) = &dev_attr_detach
.attr
;
465 *(attrs
+ 2) = &dev_attr_attach
.attr
;
466 *(attrs
+ 3) = &dev_attr_usbip_debug
.attr
;
467 for (i
= 0; i
< vhci_num_controllers
; i
++)
468 *(attrs
+ i
+ 4) = &((status_attrs
+ i
)->attr
.attr
);
469 vhci_attr_group
.attrs
= attrs
;
473 void vhci_finish_attr_group(void)
475 finish_status_attrs();
476 kfree(vhci_attr_group
.attrs
);