xref: /openbmc/linux/drivers/usb/usbip/vhci_sysfs.c (revision 82e6fdd6)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2003-2008 Takahiro Hirofuchi
4  * Copyright (C) 2015-2016 Nobuo Iwata
5  */
6 
7 #include <linux/kthread.h>
8 #include <linux/file.h>
9 #include <linux/net.h>
10 #include <linux/platform_device.h>
11 #include <linux/slab.h>
12 
13 #include "usbip_common.h"
14 #include "vhci.h"
15 
16 /* TODO: refine locking ?*/
17 
18 /*
19  * output example:
20  * hub port sta spd dev       sockfd local_busid
21  * hs  0000 004 000 00000000  000003 1-2.3
22  * ................................................
23  * ss  0008 004 000 00000000  000004 2-3.4
24  * ................................................
25  *
26  * Output includes socket fd instead of socket pointer address to avoid
27  * leaking kernel memory address in:
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  *
34  */
35 static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev)
36 {
37 	if (hub == HUB_SPEED_HIGH)
38 		*out += sprintf(*out, "hs  %04u %03u ",
39 				      port, vdev->ud.status);
40 	else /* hub == HUB_SPEED_SUPER */
41 		*out += sprintf(*out, "ss  %04u %03u ",
42 				      port, vdev->ud.status);
43 
44 	if (vdev->ud.status == VDEV_ST_USED) {
45 		*out += sprintf(*out, "%03u %08x ",
46 				      vdev->speed, vdev->devid);
47 		*out += sprintf(*out, "%06u %s",
48 				      vdev->ud.sockfd,
49 				      dev_name(&vdev->udev->dev));
50 
51 	} else {
52 		*out += sprintf(*out, "000 00000000 ");
53 		*out += sprintf(*out, "000000 0-0");
54 	}
55 
56 	*out += sprintf(*out, "\n");
57 }
58 
59 /* Sysfs entry to show port status */
60 static ssize_t status_show_vhci(int pdev_nr, char *out)
61 {
62 	struct platform_device *pdev = vhcis[pdev_nr].pdev;
63 	struct vhci *vhci;
64 	struct usb_hcd *hcd;
65 	struct vhci_hcd *vhci_hcd;
66 	char *s = out;
67 	int i;
68 	unsigned long flags;
69 
70 	if (!pdev || !out) {
71 		usbip_dbg_vhci_sysfs("show status error\n");
72 		return 0;
73 	}
74 
75 	hcd = platform_get_drvdata(pdev);
76 	vhci_hcd = hcd_to_vhci_hcd(hcd);
77 	vhci = vhci_hcd->vhci;
78 
79 	spin_lock_irqsave(&vhci->lock, flags);
80 
81 	for (i = 0; i < VHCI_HC_PORTS; i++) {
82 		struct vhci_device *vdev = &vhci->vhci_hcd_hs->vdev[i];
83 
84 		spin_lock(&vdev->ud.lock);
85 		port_show_vhci(&out, HUB_SPEED_HIGH,
86 			       pdev_nr * VHCI_PORTS + i, vdev);
87 		spin_unlock(&vdev->ud.lock);
88 	}
89 
90 	for (i = 0; i < VHCI_HC_PORTS; i++) {
91 		struct vhci_device *vdev = &vhci->vhci_hcd_ss->vdev[i];
92 
93 		spin_lock(&vdev->ud.lock);
94 		port_show_vhci(&out, HUB_SPEED_SUPER,
95 			       pdev_nr * VHCI_PORTS + VHCI_HC_PORTS + i, vdev);
96 		spin_unlock(&vdev->ud.lock);
97 	}
98 
99 	spin_unlock_irqrestore(&vhci->lock, flags);
100 
101 	return out - s;
102 }
103 
104 static ssize_t status_show_not_ready(int pdev_nr, char *out)
105 {
106 	char *s = out;
107 	int i = 0;
108 
109 	for (i = 0; i < VHCI_HC_PORTS; i++) {
110 		out += sprintf(out, "hs  %04u %03u ",
111 				    (pdev_nr * VHCI_PORTS) + i,
112 				    VDEV_ST_NOTASSIGNED);
113 		out += sprintf(out, "000 00000000 0000000000000000 0-0");
114 		out += sprintf(out, "\n");
115 	}
116 
117 	for (i = 0; i < VHCI_HC_PORTS; i++) {
118 		out += sprintf(out, "ss  %04u %03u ",
119 				    (pdev_nr * VHCI_PORTS) + VHCI_HC_PORTS + i,
120 				    VDEV_ST_NOTASSIGNED);
121 		out += sprintf(out, "000 00000000 0000000000000000 0-0");
122 		out += sprintf(out, "\n");
123 	}
124 	return out - s;
125 }
126 
127 static int status_name_to_id(const char *name)
128 {
129 	char *c;
130 	long val;
131 	int ret;
132 
133 	c = strchr(name, '.');
134 	if (c == NULL)
135 		return 0;
136 
137 	ret = kstrtol(c+1, 10, &val);
138 	if (ret < 0)
139 		return ret;
140 
141 	return val;
142 }
143 
144 static ssize_t status_show(struct device *dev,
145 			   struct device_attribute *attr, char *out)
146 {
147 	char *s = out;
148 	int pdev_nr;
149 
150 	out += sprintf(out,
151 		       "hub port sta spd dev      sockfd local_busid\n");
152 
153 	pdev_nr = status_name_to_id(attr->attr.name);
154 	if (pdev_nr < 0)
155 		out += status_show_not_ready(pdev_nr, out);
156 	else
157 		out += status_show_vhci(pdev_nr, out);
158 
159 	return out - s;
160 }
161 
162 static ssize_t nports_show(struct device *dev, struct device_attribute *attr,
163 			   char *out)
164 {
165 	char *s = out;
166 
167 	/*
168 	 * Half the ports are for SPEED_HIGH and half for SPEED_SUPER,
169 	 * thus the * 2.
170 	 */
171 	out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers);
172 	return out - s;
173 }
174 static DEVICE_ATTR_RO(nports);
175 
176 /* Sysfs entry to shutdown a virtual connection */
177 static int vhci_port_disconnect(struct vhci_hcd *vhci_hcd, __u32 rhport)
178 {
179 	struct vhci_device *vdev = &vhci_hcd->vdev[rhport];
180 	struct vhci *vhci = vhci_hcd->vhci;
181 	unsigned long flags;
182 
183 	usbip_dbg_vhci_sysfs("enter\n");
184 
185 	/* lock */
186 	spin_lock_irqsave(&vhci->lock, flags);
187 	spin_lock(&vdev->ud.lock);
188 
189 	if (vdev->ud.status == VDEV_ST_NULL) {
190 		pr_err("not connected %d\n", vdev->ud.status);
191 
192 		/* unlock */
193 		spin_unlock(&vdev->ud.lock);
194 		spin_unlock_irqrestore(&vhci->lock, flags);
195 
196 		return -EINVAL;
197 	}
198 
199 	/* unlock */
200 	spin_unlock(&vdev->ud.lock);
201 	spin_unlock_irqrestore(&vhci->lock, flags);
202 
203 	usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
204 
205 	return 0;
206 }
207 
208 static int valid_port(__u32 pdev_nr, __u32 rhport)
209 {
210 	if (pdev_nr >= vhci_num_controllers) {
211 		pr_err("pdev %u\n", pdev_nr);
212 		return 0;
213 	}
214 	if (rhport >= VHCI_HC_PORTS) {
215 		pr_err("rhport %u\n", rhport);
216 		return 0;
217 	}
218 	return 1;
219 }
220 
221 static ssize_t detach_store(struct device *dev, struct device_attribute *attr,
222 			    const char *buf, size_t count)
223 {
224 	__u32 port = 0, pdev_nr = 0, rhport = 0;
225 	struct usb_hcd *hcd;
226 	struct vhci_hcd *vhci_hcd;
227 	int ret;
228 
229 	if (kstrtoint(buf, 10, &port) < 0)
230 		return -EINVAL;
231 
232 	pdev_nr = port_to_pdev_nr(port);
233 	rhport = port_to_rhport(port);
234 
235 	if (!valid_port(pdev_nr, rhport))
236 		return -EINVAL;
237 
238 	hcd = platform_get_drvdata(vhcis[pdev_nr].pdev);
239 	if (hcd == NULL) {
240 		dev_err(dev, "port is not ready %u\n", port);
241 		return -EAGAIN;
242 	}
243 
244 	usbip_dbg_vhci_sysfs("rhport %d\n", rhport);
245 
246 	if ((port / VHCI_HC_PORTS) % 2)
247 		vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_ss;
248 	else
249 		vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_hs;
250 
251 	ret = vhci_port_disconnect(vhci_hcd, rhport);
252 	if (ret < 0)
253 		return -EINVAL;
254 
255 	usbip_dbg_vhci_sysfs("Leave\n");
256 
257 	return count;
258 }
259 static DEVICE_ATTR_WO(detach);
260 
261 static int valid_args(__u32 pdev_nr, __u32 rhport, enum usb_device_speed speed)
262 {
263 	if (!valid_port(pdev_nr, rhport)) {
264 		return 0;
265 	}
266 
267 	switch (speed) {
268 	case USB_SPEED_LOW:
269 	case USB_SPEED_FULL:
270 	case USB_SPEED_HIGH:
271 	case USB_SPEED_WIRELESS:
272 	case USB_SPEED_SUPER:
273 		break;
274 	default:
275 		pr_err("Failed attach request for unsupported USB speed: %s\n",
276 			usb_speed_string(speed));
277 		return 0;
278 	}
279 
280 	return 1;
281 }
282 
283 /* Sysfs entry to establish a virtual connection */
284 /*
285  * To start a new USB/IP attachment, a userland program needs to setup a TCP
286  * connection and then write its socket descriptor with remote device
287  * information into this sysfs file.
288  *
289  * A remote device is virtually attached to the root-hub port of @rhport with
290  * @speed. @devid is embedded into a request to specify the remote device in a
291  * server host.
292  *
293  * write() returns 0 on success, else negative errno.
294  */
295 static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
296 			    const char *buf, size_t count)
297 {
298 	struct socket *socket;
299 	int sockfd = 0;
300 	__u32 port = 0, pdev_nr = 0, rhport = 0, devid = 0, speed = 0;
301 	struct usb_hcd *hcd;
302 	struct vhci_hcd *vhci_hcd;
303 	struct vhci_device *vdev;
304 	struct vhci *vhci;
305 	int err;
306 	unsigned long flags;
307 
308 	/*
309 	 * @rhport: port number of vhci_hcd
310 	 * @sockfd: socket descriptor of an established TCP connection
311 	 * @devid: unique device identifier in a remote host
312 	 * @speed: usb device speed in a remote host
313 	 */
314 	if (sscanf(buf, "%u %u %u %u", &port, &sockfd, &devid, &speed) != 4)
315 		return -EINVAL;
316 	pdev_nr = port_to_pdev_nr(port);
317 	rhport = port_to_rhport(port);
318 
319 	usbip_dbg_vhci_sysfs("port(%u) pdev(%d) rhport(%u)\n",
320 			     port, pdev_nr, rhport);
321 	usbip_dbg_vhci_sysfs("sockfd(%u) devid(%u) speed(%u)\n",
322 			     sockfd, devid, speed);
323 
324 	/* check received parameters */
325 	if (!valid_args(pdev_nr, rhport, speed))
326 		return -EINVAL;
327 
328 	hcd = platform_get_drvdata(vhcis[pdev_nr].pdev);
329 	if (hcd == NULL) {
330 		dev_err(dev, "port %d is not ready\n", port);
331 		return -EAGAIN;
332 	}
333 
334 	vhci_hcd = hcd_to_vhci_hcd(hcd);
335 	vhci = vhci_hcd->vhci;
336 
337 	if (speed == USB_SPEED_SUPER)
338 		vdev = &vhci->vhci_hcd_ss->vdev[rhport];
339 	else
340 		vdev = &vhci->vhci_hcd_hs->vdev[rhport];
341 
342 	/* Extract socket from fd. */
343 	socket = sockfd_lookup(sockfd, &err);
344 	if (!socket)
345 		return -EINVAL;
346 
347 	/* now need lock until setting vdev status as used */
348 
349 	/* begin a lock */
350 	spin_lock_irqsave(&vhci->lock, flags);
351 	spin_lock(&vdev->ud.lock);
352 
353 	if (vdev->ud.status != VDEV_ST_NULL) {
354 		/* end of the lock */
355 		spin_unlock(&vdev->ud.lock);
356 		spin_unlock_irqrestore(&vhci->lock, flags);
357 
358 		sockfd_put(socket);
359 
360 		dev_err(dev, "port %d already used\n", rhport);
361 		/*
362 		 * Will be retried from userspace
363 		 * if there's another free port.
364 		 */
365 		return -EBUSY;
366 	}
367 
368 	dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n",
369 		 pdev_nr, rhport, sockfd);
370 	dev_info(dev, "devid(%u) speed(%u) speed_str(%s)\n",
371 		 devid, speed, usb_speed_string(speed));
372 
373 	vdev->devid         = devid;
374 	vdev->speed         = speed;
375 	vdev->ud.sockfd     = sockfd;
376 	vdev->ud.tcp_socket = socket;
377 	vdev->ud.status     = VDEV_ST_NOTASSIGNED;
378 
379 	spin_unlock(&vdev->ud.lock);
380 	spin_unlock_irqrestore(&vhci->lock, flags);
381 	/* end the lock */
382 
383 	vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx");
384 	vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx");
385 
386 	rh_port_connect(vdev, speed);
387 
388 	return count;
389 }
390 static DEVICE_ATTR_WO(attach);
391 
392 #define MAX_STATUS_NAME 16
393 
394 struct status_attr {
395 	struct device_attribute attr;
396 	char name[MAX_STATUS_NAME+1];
397 };
398 
399 static struct status_attr *status_attrs;
400 
401 static void set_status_attr(int id)
402 {
403 	struct status_attr *status;
404 
405 	status = status_attrs + id;
406 	if (id == 0)
407 		strcpy(status->name, "status");
408 	else
409 		snprintf(status->name, MAX_STATUS_NAME+1, "status.%d", id);
410 	status->attr.attr.name = status->name;
411 	status->attr.attr.mode = S_IRUGO;
412 	status->attr.show = status_show;
413 	sysfs_attr_init(&status->attr.attr);
414 }
415 
416 static int init_status_attrs(void)
417 {
418 	int id;
419 
420 	status_attrs = kcalloc(vhci_num_controllers, sizeof(struct status_attr),
421 			       GFP_KERNEL);
422 	if (status_attrs == NULL)
423 		return -ENOMEM;
424 
425 	for (id = 0; id < vhci_num_controllers; id++)
426 		set_status_attr(id);
427 
428 	return 0;
429 }
430 
431 static void finish_status_attrs(void)
432 {
433 	kfree(status_attrs);
434 }
435 
436 struct attribute_group vhci_attr_group = {
437 	.attrs = NULL,
438 };
439 
440 int vhci_init_attr_group(void)
441 {
442 	struct attribute **attrs;
443 	int ret, i;
444 
445 	attrs = kcalloc((vhci_num_controllers + 5), sizeof(struct attribute *),
446 			GFP_KERNEL);
447 	if (attrs == NULL)
448 		return -ENOMEM;
449 
450 	ret = init_status_attrs();
451 	if (ret) {
452 		kfree(attrs);
453 		return ret;
454 	}
455 	*attrs = &dev_attr_nports.attr;
456 	*(attrs + 1) = &dev_attr_detach.attr;
457 	*(attrs + 2) = &dev_attr_attach.attr;
458 	*(attrs + 3) = &dev_attr_usbip_debug.attr;
459 	for (i = 0; i < vhci_num_controllers; i++)
460 		*(attrs + i + 4) = &((status_attrs + i)->attr.attr);
461 	vhci_attr_group.attrs = attrs;
462 	return 0;
463 }
464 
465 void vhci_finish_attr_group(void)
466 {
467 	finish_status_attrs();
468 	kfree(vhci_attr_group.attrs);
469 }
470