GNU Linux-libre 4.14.266-gnu1
[releases.git] / drivers / usb / usbip / vhci_sysfs.c
1 /*
2  * Copyright (C) 2003-2008 Takahiro Hirofuchi
3  * Copyright (C) 2015-2016 Nobuo Iwata
4  *
5  * This is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18  * USA.
19  */
20
21 #include <linux/kthread.h>
22 #include <linux/file.h>
23 #include <linux/net.h>
24 #include <linux/platform_device.h>
25 #include <linux/slab.h>
26
27 /* Hardening for Spectre-v1 */
28 #include <linux/nospec.h>
29
30 #include "usbip_common.h"
31 #include "vhci.h"
32
33 /* TODO: refine locking ?*/
34
35 /*
36  * output example:
37  * hub port sta spd dev       sockfd local_busid
38  * hs  0000 004 000 00000000  000003 1-2.3
39  * ................................................
40  * ss  0008 004 000 00000000  000004 2-3.4
41  * ................................................
42  *
43  * Output includes socket fd instead of socket pointer address to avoid
44  * leaking kernel memory address in:
45  *      /sys/devices/platform/vhci_hcd.0/status and in debug output.
46  * The socket pointer address is not used at the moment and it was made
47  * visible as a convenient way to find IP address from socket pointer
48  * address by looking up /proc/net/{tcp,tcp6}. As this opens a security
49  * hole, the change is made to use sockfd instead.
50  *
51  */
52 static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev)
53 {
54         if (hub == HUB_SPEED_HIGH)
55                 *out += sprintf(*out, "hs  %04u %03u ",
56                                       port, vdev->ud.status);
57         else /* hub == HUB_SPEED_SUPER */
58                 *out += sprintf(*out, "ss  %04u %03u ",
59                                       port, vdev->ud.status);
60
61         if (vdev->ud.status == VDEV_ST_USED) {
62                 *out += sprintf(*out, "%03u %08x ",
63                                       vdev->speed, vdev->devid);
64                 *out += sprintf(*out, "%06u %s",
65                                       vdev->ud.sockfd,
66                                       dev_name(&vdev->udev->dev));
67
68         } else {
69                 *out += sprintf(*out, "000 00000000 ");
70                 *out += sprintf(*out, "000000 0-0");
71         }
72
73         *out += sprintf(*out, "\n");
74 }
75
76 /* Sysfs entry to show port status */
77 static ssize_t status_show_vhci(int pdev_nr, char *out)
78 {
79         struct platform_device *pdev = vhcis[pdev_nr].pdev;
80         struct vhci *vhci;
81         struct usb_hcd *hcd;
82         struct vhci_hcd *vhci_hcd;
83         char *s = out;
84         int i;
85         unsigned long flags;
86
87         if (!pdev || !out) {
88                 usbip_dbg_vhci_sysfs("show status error\n");
89                 return 0;
90         }
91
92         hcd = platform_get_drvdata(pdev);
93         vhci_hcd = hcd_to_vhci_hcd(hcd);
94         vhci = vhci_hcd->vhci;
95
96         spin_lock_irqsave(&vhci->lock, flags);
97
98         for (i = 0; i < VHCI_HC_PORTS; i++) {
99                 struct vhci_device *vdev = &vhci->vhci_hcd_hs->vdev[i];
100
101                 spin_lock(&vdev->ud.lock);
102                 port_show_vhci(&out, HUB_SPEED_HIGH,
103                                pdev_nr * VHCI_PORTS + i, vdev);
104                 spin_unlock(&vdev->ud.lock);
105         }
106
107         for (i = 0; i < VHCI_HC_PORTS; i++) {
108                 struct vhci_device *vdev = &vhci->vhci_hcd_ss->vdev[i];
109
110                 spin_lock(&vdev->ud.lock);
111                 port_show_vhci(&out, HUB_SPEED_SUPER,
112                                pdev_nr * VHCI_PORTS + VHCI_HC_PORTS + i, vdev);
113                 spin_unlock(&vdev->ud.lock);
114         }
115
116         spin_unlock_irqrestore(&vhci->lock, flags);
117
118         return out - s;
119 }
120
121 static ssize_t status_show_not_ready(int pdev_nr, char *out)
122 {
123         char *s = out;
124         int i = 0;
125
126         for (i = 0; i < VHCI_HC_PORTS; i++) {
127                 out += sprintf(out, "hs  %04u %03u ",
128                                     (pdev_nr * VHCI_PORTS) + i,
129                                     VDEV_ST_NOTASSIGNED);
130                 out += sprintf(out, "000 00000000 0000000000000000 0-0");
131                 out += sprintf(out, "\n");
132         }
133
134         for (i = 0; i < VHCI_HC_PORTS; i++) {
135                 out += sprintf(out, "ss  %04u %03u ",
136                                     (pdev_nr * VHCI_PORTS) + VHCI_HC_PORTS + i,
137                                     VDEV_ST_NOTASSIGNED);
138                 out += sprintf(out, "000 00000000 0000000000000000 0-0");
139                 out += sprintf(out, "\n");
140         }
141         return out - s;
142 }
143
144 static int status_name_to_id(const char *name)
145 {
146         char *c;
147         long val;
148         int ret;
149
150         c = strchr(name, '.');
151         if (c == NULL)
152                 return 0;
153
154         ret = kstrtol(c+1, 10, &val);
155         if (ret < 0)
156                 return ret;
157
158         return val;
159 }
160
161 static ssize_t status_show(struct device *dev,
162                            struct device_attribute *attr, char *out)
163 {
164         char *s = out;
165         int pdev_nr;
166
167         out += sprintf(out,
168                        "hub port sta spd dev      sockfd local_busid\n");
169
170         pdev_nr = status_name_to_id(attr->attr.name);
171         if (pdev_nr < 0)
172                 out += status_show_not_ready(pdev_nr, out);
173         else
174                 out += status_show_vhci(pdev_nr, out);
175
176         return out - s;
177 }
178
179 static ssize_t nports_show(struct device *dev, struct device_attribute *attr,
180                            char *out)
181 {
182         char *s = out;
183
184         /*
185          * Half the ports are for SPEED_HIGH and half for SPEED_SUPER,
186          * thus the * 2.
187          */
188         out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers);
189         return out - s;
190 }
191 static DEVICE_ATTR_RO(nports);
192
193 /* Sysfs entry to shutdown a virtual connection */
194 static int vhci_port_disconnect(struct vhci_hcd *vhci_hcd, __u32 rhport)
195 {
196         struct vhci_device *vdev = &vhci_hcd->vdev[rhport];
197         struct vhci *vhci = vhci_hcd->vhci;
198         unsigned long flags;
199
200         usbip_dbg_vhci_sysfs("enter\n");
201
202         mutex_lock(&vdev->ud.sysfs_lock);
203
204         /* lock */
205         spin_lock_irqsave(&vhci->lock, flags);
206         spin_lock(&vdev->ud.lock);
207
208         if (vdev->ud.status == VDEV_ST_NULL) {
209                 pr_err("not connected %d\n", vdev->ud.status);
210
211                 /* unlock */
212                 spin_unlock(&vdev->ud.lock);
213                 spin_unlock_irqrestore(&vhci->lock, flags);
214                 mutex_unlock(&vdev->ud.sysfs_lock);
215
216                 return -EINVAL;
217         }
218
219         /* unlock */
220         spin_unlock(&vdev->ud.lock);
221         spin_unlock_irqrestore(&vhci->lock, flags);
222
223         usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
224
225         mutex_unlock(&vdev->ud.sysfs_lock);
226
227         return 0;
228 }
229
230 static int valid_port(__u32 *pdev_nr, __u32 *rhport)
231 {
232         if (*pdev_nr >= vhci_num_controllers) {
233                 pr_err("pdev %u\n", *pdev_nr);
234                 return 0;
235         }
236         *pdev_nr = array_index_nospec(*pdev_nr, vhci_num_controllers);
237
238         if (*rhport >= VHCI_HC_PORTS) {
239                 pr_err("rhport %u\n", *rhport);
240                 return 0;
241         }
242         *rhport = array_index_nospec(*rhport, VHCI_HC_PORTS);
243
244         return 1;
245 }
246
247 static ssize_t store_detach(struct device *dev, struct device_attribute *attr,
248                             const char *buf, size_t count)
249 {
250         __u32 port = 0, pdev_nr = 0, rhport = 0;
251         struct usb_hcd *hcd;
252         struct vhci_hcd *vhci_hcd;
253         int ret;
254
255         if (kstrtoint(buf, 10, &port) < 0)
256                 return -EINVAL;
257
258         pdev_nr = port_to_pdev_nr(port);
259         rhport = port_to_rhport(port);
260
261         if (!valid_port(&pdev_nr, &rhport))
262                 return -EINVAL;
263
264         hcd = platform_get_drvdata(vhcis[pdev_nr].pdev);
265         if (hcd == NULL) {
266                 dev_err(dev, "port is not ready %u\n", port);
267                 return -EAGAIN;
268         }
269
270         usbip_dbg_vhci_sysfs("rhport %d\n", rhport);
271
272         if ((port / VHCI_HC_PORTS) % 2)
273                 vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_ss;
274         else
275                 vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_hs;
276
277         ret = vhci_port_disconnect(vhci_hcd, rhport);
278         if (ret < 0)
279                 return -EINVAL;
280
281         usbip_dbg_vhci_sysfs("Leave\n");
282
283         return count;
284 }
285 static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach);
286
287 static int valid_args(__u32 *pdev_nr, __u32 *rhport,
288                       enum usb_device_speed speed)
289 {
290         if (!valid_port(pdev_nr, rhport)) {
291                 return 0;
292         }
293
294         switch (speed) {
295         case USB_SPEED_LOW:
296         case USB_SPEED_FULL:
297         case USB_SPEED_HIGH:
298         case USB_SPEED_WIRELESS:
299         case USB_SPEED_SUPER:
300                 break;
301         default:
302                 pr_err("Failed attach request for unsupported USB speed: %s\n",
303                         usb_speed_string(speed));
304                 return 0;
305         }
306
307         return 1;
308 }
309
310 /* Sysfs entry to establish a virtual connection */
311 /*
312  * To start a new USB/IP attachment, a userland program needs to setup a TCP
313  * connection and then write its socket descriptor with remote device
314  * information into this sysfs file.
315  *
316  * A remote device is virtually attached to the root-hub port of @rhport with
317  * @speed. @devid is embedded into a request to specify the remote device in a
318  * server host.
319  *
320  * write() returns 0 on success, else negative errno.
321  */
322 static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
323                             const char *buf, size_t count)
324 {
325         struct socket *socket;
326         int sockfd = 0;
327         __u32 port = 0, pdev_nr = 0, rhport = 0, devid = 0, speed = 0;
328         struct usb_hcd *hcd;
329         struct vhci_hcd *vhci_hcd;
330         struct vhci_device *vdev;
331         struct vhci *vhci;
332         int err;
333         unsigned long flags;
334         struct task_struct *tcp_rx = NULL;
335         struct task_struct *tcp_tx = NULL;
336
337         /*
338          * @rhport: port number of vhci_hcd
339          * @sockfd: socket descriptor of an established TCP connection
340          * @devid: unique device identifier in a remote host
341          * @speed: usb device speed in a remote host
342          */
343         if (sscanf(buf, "%u %u %u %u", &port, &sockfd, &devid, &speed) != 4)
344                 return -EINVAL;
345         pdev_nr = port_to_pdev_nr(port);
346         rhport = port_to_rhport(port);
347
348         usbip_dbg_vhci_sysfs("port(%u) pdev(%d) rhport(%u)\n",
349                              port, pdev_nr, rhport);
350         usbip_dbg_vhci_sysfs("sockfd(%u) devid(%u) speed(%u)\n",
351                              sockfd, devid, speed);
352
353         /* check received parameters */
354         if (!valid_args(&pdev_nr, &rhport, speed))
355                 return -EINVAL;
356
357         hcd = platform_get_drvdata(vhcis[pdev_nr].pdev);
358         if (hcd == NULL) {
359                 dev_err(dev, "port %d is not ready\n", port);
360                 return -EAGAIN;
361         }
362
363         vhci_hcd = hcd_to_vhci_hcd(hcd);
364         vhci = vhci_hcd->vhci;
365
366         if (speed == USB_SPEED_SUPER)
367                 vdev = &vhci->vhci_hcd_ss->vdev[rhport];
368         else
369                 vdev = &vhci->vhci_hcd_hs->vdev[rhport];
370
371         mutex_lock(&vdev->ud.sysfs_lock);
372
373         /* Extract socket from fd. */
374         socket = sockfd_lookup(sockfd, &err);
375         if (!socket) {
376                 dev_err(dev, "failed to lookup sock");
377                 err = -EINVAL;
378                 goto unlock_mutex;
379         }
380         if (socket->type != SOCK_STREAM) {
381                 dev_err(dev, "Expecting SOCK_STREAM - found %d",
382                         socket->type);
383                 sockfd_put(socket);
384                 err = -EINVAL;
385                 goto unlock_mutex;
386         }
387
388         /* create threads before locking */
389         tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx");
390         if (IS_ERR(tcp_rx)) {
391                 sockfd_put(socket);
392                 err = -EINVAL;
393                 goto unlock_mutex;
394         }
395         tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx");
396         if (IS_ERR(tcp_tx)) {
397                 kthread_stop(tcp_rx);
398                 sockfd_put(socket);
399                 err = -EINVAL;
400                 goto unlock_mutex;
401         }
402
403         /* get task structs now */
404         get_task_struct(tcp_rx);
405         get_task_struct(tcp_tx);
406
407         /* now begin lock until setting vdev status set */
408         spin_lock_irqsave(&vhci->lock, flags);
409         spin_lock(&vdev->ud.lock);
410
411         if (vdev->ud.status != VDEV_ST_NULL) {
412                 /* end of the lock */
413                 spin_unlock(&vdev->ud.lock);
414                 spin_unlock_irqrestore(&vhci->lock, flags);
415
416                 sockfd_put(socket);
417                 kthread_stop_put(tcp_rx);
418                 kthread_stop_put(tcp_tx);
419
420                 dev_err(dev, "port %d already used\n", rhport);
421                 /*
422                  * Will be retried from userspace
423                  * if there's another free port.
424                  */
425                 err = -EBUSY;
426                 goto unlock_mutex;
427         }
428
429         dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n",
430                  pdev_nr, rhport, sockfd);
431         dev_info(dev, "devid(%u) speed(%u) speed_str(%s)\n",
432                  devid, speed, usb_speed_string(speed));
433
434         vdev->devid         = devid;
435         vdev->speed         = speed;
436         vdev->ud.sockfd     = sockfd;
437         vdev->ud.tcp_socket = socket;
438         vdev->ud.tcp_rx     = tcp_rx;
439         vdev->ud.tcp_tx     = tcp_tx;
440         vdev->ud.status     = VDEV_ST_NOTASSIGNED;
441
442         spin_unlock(&vdev->ud.lock);
443         spin_unlock_irqrestore(&vhci->lock, flags);
444         /* end the lock */
445
446         wake_up_process(vdev->ud.tcp_rx);
447         wake_up_process(vdev->ud.tcp_tx);
448
449         rh_port_connect(vdev, speed);
450
451         dev_info(dev, "Device attached\n");
452
453         mutex_unlock(&vdev->ud.sysfs_lock);
454
455         return count;
456
457 unlock_mutex:
458         mutex_unlock(&vdev->ud.sysfs_lock);
459         return err;
460 }
461 static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach);
462
463 #define MAX_STATUS_NAME 16
464
465 struct status_attr {
466         struct device_attribute attr;
467         char name[MAX_STATUS_NAME+1];
468 };
469
470 static struct status_attr *status_attrs;
471
472 static void set_status_attr(int id)
473 {
474         struct status_attr *status;
475
476         status = status_attrs + id;
477         if (id == 0)
478                 strcpy(status->name, "status");
479         else
480                 snprintf(status->name, MAX_STATUS_NAME+1, "status.%d", id);
481         status->attr.attr.name = status->name;
482         status->attr.attr.mode = S_IRUGO;
483         status->attr.show = status_show;
484         sysfs_attr_init(&status->attr.attr);
485 }
486
487 static int init_status_attrs(void)
488 {
489         int id;
490
491         status_attrs = kcalloc(vhci_num_controllers, sizeof(struct status_attr),
492                                GFP_KERNEL);
493         if (status_attrs == NULL)
494                 return -ENOMEM;
495
496         for (id = 0; id < vhci_num_controllers; id++)
497                 set_status_attr(id);
498
499         return 0;
500 }
501
502 static void finish_status_attrs(void)
503 {
504         kfree(status_attrs);
505 }
506
507 struct attribute_group vhci_attr_group = {
508         .attrs = NULL,
509 };
510
511 int vhci_init_attr_group(void)
512 {
513         struct attribute **attrs;
514         int ret, i;
515
516         attrs = kcalloc((vhci_num_controllers + 5), sizeof(struct attribute *),
517                         GFP_KERNEL);
518         if (attrs == NULL)
519                 return -ENOMEM;
520
521         ret = init_status_attrs();
522         if (ret) {
523                 kfree(attrs);
524                 return ret;
525         }
526         *attrs = &dev_attr_nports.attr;
527         *(attrs + 1) = &dev_attr_detach.attr;
528         *(attrs + 2) = &dev_attr_attach.attr;
529         *(attrs + 3) = &dev_attr_usbip_debug.attr;
530         for (i = 0; i < vhci_num_controllers; i++)
531                 *(attrs + i + 4) = &((status_attrs + i)->attr.attr);
532         vhci_attr_group.attrs = attrs;
533         return 0;
534 }
535
536 void vhci_finish_attr_group(void)
537 {
538         finish_status_attrs();
539         kfree(vhci_attr_group.attrs);
540 }