Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright (C) 2003-2008 Takahiro Hirofuchi
0004  * Copyright (C) 2015-2016 Nobuo Iwata
0005  */
0006 
0007 #include <linux/kthread.h>
0008 #include <linux/file.h>
0009 #include <linux/net.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/slab.h>
0012 
0013 /* Hardening for Spectre-v1 */
0014 #include <linux/nospec.h>
0015 
0016 #include "usbip_common.h"
0017 #include "vhci.h"
0018 
0019 /* TODO: refine locking ?*/
0020 
0021 /*
0022  * output example:
0023  * hub port sta spd dev       sockfd local_busid
0024  * hs  0000 004 000 00000000  000003 1-2.3
0025  * ................................................
0026  * ss  0008 004 000 00000000  000004 2-3.4
0027  * ................................................
0028  *
0029  * Output includes socket fd instead of socket pointer address to avoid
0030  * leaking kernel memory address in:
0031  *  /sys/devices/platform/vhci_hcd.0/status and in debug output.
0032  * The socket pointer address is not used at the moment and it was made
0033  * visible as a convenient way to find IP address from socket pointer
0034  * address by looking up /proc/net/{tcp,tcp6}. As this opens a security
0035  * hole, the change is made to use sockfd instead.
0036  *
0037  */
0038 static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev)
0039 {
0040     if (hub == HUB_SPEED_HIGH)
0041         *out += sprintf(*out, "hs  %04u %03u ",
0042                       port, vdev->ud.status);
0043     else /* hub == HUB_SPEED_SUPER */
0044         *out += sprintf(*out, "ss  %04u %03u ",
0045                       port, vdev->ud.status);
0046 
0047     if (vdev->ud.status == VDEV_ST_USED) {
0048         *out += sprintf(*out, "%03u %08x ",
0049                       vdev->speed, vdev->devid);
0050         *out += sprintf(*out, "%06u %s",
0051                       vdev->ud.sockfd,
0052                       dev_name(&vdev->udev->dev));
0053 
0054     } else {
0055         *out += sprintf(*out, "000 00000000 ");
0056         *out += sprintf(*out, "000000 0-0");
0057     }
0058 
0059     *out += sprintf(*out, "\n");
0060 }
0061 
0062 /* Sysfs entry to show port status */
0063 static ssize_t status_show_vhci(int pdev_nr, char *out)
0064 {
0065     struct platform_device *pdev = vhcis[pdev_nr].pdev;
0066     struct vhci *vhci;
0067     struct usb_hcd *hcd;
0068     struct vhci_hcd *vhci_hcd;
0069     char *s = out;
0070     int i;
0071     unsigned long flags;
0072 
0073     if (!pdev || !out) {
0074         usbip_dbg_vhci_sysfs("show status error\n");
0075         return 0;
0076     }
0077 
0078     hcd = platform_get_drvdata(pdev);
0079     vhci_hcd = hcd_to_vhci_hcd(hcd);
0080     vhci = vhci_hcd->vhci;
0081 
0082     spin_lock_irqsave(&vhci->lock, flags);
0083 
0084     for (i = 0; i < VHCI_HC_PORTS; i++) {
0085         struct vhci_device *vdev = &vhci->vhci_hcd_hs->vdev[i];
0086 
0087         spin_lock(&vdev->ud.lock);
0088         port_show_vhci(&out, HUB_SPEED_HIGH,
0089                    pdev_nr * VHCI_PORTS + i, vdev);
0090         spin_unlock(&vdev->ud.lock);
0091     }
0092 
0093     for (i = 0; i < VHCI_HC_PORTS; i++) {
0094         struct vhci_device *vdev = &vhci->vhci_hcd_ss->vdev[i];
0095 
0096         spin_lock(&vdev->ud.lock);
0097         port_show_vhci(&out, HUB_SPEED_SUPER,
0098                    pdev_nr * VHCI_PORTS + VHCI_HC_PORTS + i, vdev);
0099         spin_unlock(&vdev->ud.lock);
0100     }
0101 
0102     spin_unlock_irqrestore(&vhci->lock, flags);
0103 
0104     return out - s;
0105 }
0106 
0107 static ssize_t status_show_not_ready(int pdev_nr, char *out)
0108 {
0109     char *s = out;
0110     int i = 0;
0111 
0112     for (i = 0; i < VHCI_HC_PORTS; i++) {
0113         out += sprintf(out, "hs  %04u %03u ",
0114                     (pdev_nr * VHCI_PORTS) + i,
0115                     VDEV_ST_NOTASSIGNED);
0116         out += sprintf(out, "000 00000000 0000000000000000 0-0");
0117         out += sprintf(out, "\n");
0118     }
0119 
0120     for (i = 0; i < VHCI_HC_PORTS; i++) {
0121         out += sprintf(out, "ss  %04u %03u ",
0122                     (pdev_nr * VHCI_PORTS) + VHCI_HC_PORTS + i,
0123                     VDEV_ST_NOTASSIGNED);
0124         out += sprintf(out, "000 00000000 0000000000000000 0-0");
0125         out += sprintf(out, "\n");
0126     }
0127     return out - s;
0128 }
0129 
0130 static int status_name_to_id(const char *name)
0131 {
0132     char *c;
0133     long val;
0134     int ret;
0135 
0136     c = strchr(name, '.');
0137     if (c == NULL)
0138         return 0;
0139 
0140     ret = kstrtol(c+1, 10, &val);
0141     if (ret < 0)
0142         return ret;
0143 
0144     return val;
0145 }
0146 
0147 static ssize_t status_show(struct device *dev,
0148                struct device_attribute *attr, char *out)
0149 {
0150     char *s = out;
0151     int pdev_nr;
0152 
0153     out += sprintf(out,
0154                "hub port sta spd dev      sockfd local_busid\n");
0155 
0156     pdev_nr = status_name_to_id(attr->attr.name);
0157     if (pdev_nr < 0)
0158         out += status_show_not_ready(pdev_nr, out);
0159     else
0160         out += status_show_vhci(pdev_nr, out);
0161 
0162     return out - s;
0163 }
0164 
0165 static ssize_t nports_show(struct device *dev, struct device_attribute *attr,
0166                char *out)
0167 {
0168     char *s = out;
0169 
0170     /*
0171      * Half the ports are for SPEED_HIGH and half for SPEED_SUPER,
0172      * thus the * 2.
0173      */
0174     out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers);
0175     return out - s;
0176 }
0177 static DEVICE_ATTR_RO(nports);
0178 
0179 /* Sysfs entry to shutdown a virtual connection */
0180 static int vhci_port_disconnect(struct vhci_hcd *vhci_hcd, __u32 rhport)
0181 {
0182     struct vhci_device *vdev = &vhci_hcd->vdev[rhport];
0183     struct vhci *vhci = vhci_hcd->vhci;
0184     unsigned long flags;
0185 
0186     usbip_dbg_vhci_sysfs("enter\n");
0187 
0188     mutex_lock(&vdev->ud.sysfs_lock);
0189 
0190     /* lock */
0191     spin_lock_irqsave(&vhci->lock, flags);
0192     spin_lock(&vdev->ud.lock);
0193 
0194     if (vdev->ud.status == VDEV_ST_NULL) {
0195         pr_err("not connected %d\n", vdev->ud.status);
0196 
0197         /* unlock */
0198         spin_unlock(&vdev->ud.lock);
0199         spin_unlock_irqrestore(&vhci->lock, flags);
0200         mutex_unlock(&vdev->ud.sysfs_lock);
0201 
0202         return -EINVAL;
0203     }
0204 
0205     /* unlock */
0206     spin_unlock(&vdev->ud.lock);
0207     spin_unlock_irqrestore(&vhci->lock, flags);
0208 
0209     usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
0210 
0211     mutex_unlock(&vdev->ud.sysfs_lock);
0212 
0213     return 0;
0214 }
0215 
0216 static int valid_port(__u32 *pdev_nr, __u32 *rhport)
0217 {
0218     if (*pdev_nr >= vhci_num_controllers) {
0219         pr_err("pdev %u\n", *pdev_nr);
0220         return 0;
0221     }
0222     *pdev_nr = array_index_nospec(*pdev_nr, vhci_num_controllers);
0223 
0224     if (*rhport >= VHCI_HC_PORTS) {
0225         pr_err("rhport %u\n", *rhport);
0226         return 0;
0227     }
0228     *rhport = array_index_nospec(*rhport, VHCI_HC_PORTS);
0229 
0230     return 1;
0231 }
0232 
0233 static ssize_t detach_store(struct device *dev, struct device_attribute *attr,
0234                 const char *buf, size_t count)
0235 {
0236     __u32 port = 0, pdev_nr = 0, rhport = 0;
0237     struct usb_hcd *hcd;
0238     struct vhci_hcd *vhci_hcd;
0239     int ret;
0240 
0241     if (kstrtoint(buf, 10, &port) < 0)
0242         return -EINVAL;
0243 
0244     pdev_nr = port_to_pdev_nr(port);
0245     rhport = port_to_rhport(port);
0246 
0247     if (!valid_port(&pdev_nr, &rhport))
0248         return -EINVAL;
0249 
0250     hcd = platform_get_drvdata(vhcis[pdev_nr].pdev);
0251     if (hcd == NULL) {
0252         dev_err(dev, "port is not ready %u\n", port);
0253         return -EAGAIN;
0254     }
0255 
0256     usbip_dbg_vhci_sysfs("rhport %d\n", rhport);
0257 
0258     if ((port / VHCI_HC_PORTS) % 2)
0259         vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_ss;
0260     else
0261         vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_hs;
0262 
0263     ret = vhci_port_disconnect(vhci_hcd, rhport);
0264     if (ret < 0)
0265         return -EINVAL;
0266 
0267     usbip_dbg_vhci_sysfs("Leave\n");
0268 
0269     return count;
0270 }
0271 static DEVICE_ATTR_WO(detach);
0272 
0273 static int valid_args(__u32 *pdev_nr, __u32 *rhport,
0274               enum usb_device_speed speed)
0275 {
0276     if (!valid_port(pdev_nr, rhport)) {
0277         return 0;
0278     }
0279 
0280     switch (speed) {
0281     case USB_SPEED_LOW:
0282     case USB_SPEED_FULL:
0283     case USB_SPEED_HIGH:
0284     case USB_SPEED_WIRELESS:
0285     case USB_SPEED_SUPER:
0286         break;
0287     default:
0288         pr_err("Failed attach request for unsupported USB speed: %s\n",
0289             usb_speed_string(speed));
0290         return 0;
0291     }
0292 
0293     return 1;
0294 }
0295 
0296 /* Sysfs entry to establish a virtual connection */
0297 /*
0298  * To start a new USB/IP attachment, a userland program needs to setup a TCP
0299  * connection and then write its socket descriptor with remote device
0300  * information into this sysfs file.
0301  *
0302  * A remote device is virtually attached to the root-hub port of @rhport with
0303  * @speed. @devid is embedded into a request to specify the remote device in a
0304  * server host.
0305  *
0306  * write() returns 0 on success, else negative errno.
0307  */
0308 static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
0309                 const char *buf, size_t count)
0310 {
0311     struct socket *socket;
0312     int sockfd = 0;
0313     __u32 port = 0, pdev_nr = 0, rhport = 0, devid = 0, speed = 0;
0314     struct usb_hcd *hcd;
0315     struct vhci_hcd *vhci_hcd;
0316     struct vhci_device *vdev;
0317     struct vhci *vhci;
0318     int err;
0319     unsigned long flags;
0320     struct task_struct *tcp_rx = NULL;
0321     struct task_struct *tcp_tx = NULL;
0322 
0323     /*
0324      * @rhport: port number of vhci_hcd
0325      * @sockfd: socket descriptor of an established TCP connection
0326      * @devid: unique device identifier in a remote host
0327      * @speed: usb device speed in a remote host
0328      */
0329     if (sscanf(buf, "%u %u %u %u", &port, &sockfd, &devid, &speed) != 4)
0330         return -EINVAL;
0331     pdev_nr = port_to_pdev_nr(port);
0332     rhport = port_to_rhport(port);
0333 
0334     usbip_dbg_vhci_sysfs("port(%u) pdev(%d) rhport(%u)\n",
0335                  port, pdev_nr, rhport);
0336     usbip_dbg_vhci_sysfs("sockfd(%u) devid(%u) speed(%u)\n",
0337                  sockfd, devid, speed);
0338 
0339     /* check received parameters */
0340     if (!valid_args(&pdev_nr, &rhport, speed))
0341         return -EINVAL;
0342 
0343     hcd = platform_get_drvdata(vhcis[pdev_nr].pdev);
0344     if (hcd == NULL) {
0345         dev_err(dev, "port %d is not ready\n", port);
0346         return -EAGAIN;
0347     }
0348 
0349     vhci_hcd = hcd_to_vhci_hcd(hcd);
0350     vhci = vhci_hcd->vhci;
0351 
0352     if (speed == USB_SPEED_SUPER)
0353         vdev = &vhci->vhci_hcd_ss->vdev[rhport];
0354     else
0355         vdev = &vhci->vhci_hcd_hs->vdev[rhport];
0356 
0357     mutex_lock(&vdev->ud.sysfs_lock);
0358 
0359     /* Extract socket from fd. */
0360     socket = sockfd_lookup(sockfd, &err);
0361     if (!socket) {
0362         dev_err(dev, "failed to lookup sock");
0363         err = -EINVAL;
0364         goto unlock_mutex;
0365     }
0366     if (socket->type != SOCK_STREAM) {
0367         dev_err(dev, "Expecting SOCK_STREAM - found %d",
0368             socket->type);
0369         sockfd_put(socket);
0370         err = -EINVAL;
0371         goto unlock_mutex;
0372     }
0373 
0374     /* create threads before locking */
0375     tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx");
0376     if (IS_ERR(tcp_rx)) {
0377         sockfd_put(socket);
0378         err = -EINVAL;
0379         goto unlock_mutex;
0380     }
0381     tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx");
0382     if (IS_ERR(tcp_tx)) {
0383         kthread_stop(tcp_rx);
0384         sockfd_put(socket);
0385         err = -EINVAL;
0386         goto unlock_mutex;
0387     }
0388 
0389     /* get task structs now */
0390     get_task_struct(tcp_rx);
0391     get_task_struct(tcp_tx);
0392 
0393     /* now begin lock until setting vdev status set */
0394     spin_lock_irqsave(&vhci->lock, flags);
0395     spin_lock(&vdev->ud.lock);
0396 
0397     if (vdev->ud.status != VDEV_ST_NULL) {
0398         /* end of the lock */
0399         spin_unlock(&vdev->ud.lock);
0400         spin_unlock_irqrestore(&vhci->lock, flags);
0401 
0402         sockfd_put(socket);
0403         kthread_stop_put(tcp_rx);
0404         kthread_stop_put(tcp_tx);
0405 
0406         dev_err(dev, "port %d already used\n", rhport);
0407         /*
0408          * Will be retried from userspace
0409          * if there's another free port.
0410          */
0411         err = -EBUSY;
0412         goto unlock_mutex;
0413     }
0414 
0415     dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n",
0416          pdev_nr, rhport, sockfd);
0417     dev_info(dev, "devid(%u) speed(%u) speed_str(%s)\n",
0418          devid, speed, usb_speed_string(speed));
0419 
0420     vdev->devid         = devid;
0421     vdev->speed         = speed;
0422     vdev->ud.sockfd     = sockfd;
0423     vdev->ud.tcp_socket = socket;
0424     vdev->ud.tcp_rx     = tcp_rx;
0425     vdev->ud.tcp_tx     = tcp_tx;
0426     vdev->ud.status     = VDEV_ST_NOTASSIGNED;
0427     usbip_kcov_handle_init(&vdev->ud);
0428 
0429     spin_unlock(&vdev->ud.lock);
0430     spin_unlock_irqrestore(&vhci->lock, flags);
0431     /* end the lock */
0432 
0433     wake_up_process(vdev->ud.tcp_rx);
0434     wake_up_process(vdev->ud.tcp_tx);
0435 
0436     rh_port_connect(vdev, speed);
0437 
0438     dev_info(dev, "Device attached\n");
0439 
0440     mutex_unlock(&vdev->ud.sysfs_lock);
0441 
0442     return count;
0443 
0444 unlock_mutex:
0445     mutex_unlock(&vdev->ud.sysfs_lock);
0446     return err;
0447 }
0448 static DEVICE_ATTR_WO(attach);
0449 
0450 #define MAX_STATUS_NAME 16
0451 
0452 struct status_attr {
0453     struct device_attribute attr;
0454     char name[MAX_STATUS_NAME+1];
0455 };
0456 
0457 static struct status_attr *status_attrs;
0458 
0459 static void set_status_attr(int id)
0460 {
0461     struct status_attr *status;
0462 
0463     status = status_attrs + id;
0464     if (id == 0)
0465         strcpy(status->name, "status");
0466     else
0467         snprintf(status->name, MAX_STATUS_NAME+1, "status.%d", id);
0468     status->attr.attr.name = status->name;
0469     status->attr.attr.mode = S_IRUGO;
0470     status->attr.show = status_show;
0471     sysfs_attr_init(&status->attr.attr);
0472 }
0473 
0474 static int init_status_attrs(void)
0475 {
0476     int id;
0477 
0478     status_attrs = kcalloc(vhci_num_controllers, sizeof(struct status_attr),
0479                    GFP_KERNEL);
0480     if (status_attrs == NULL)
0481         return -ENOMEM;
0482 
0483     for (id = 0; id < vhci_num_controllers; id++)
0484         set_status_attr(id);
0485 
0486     return 0;
0487 }
0488 
0489 static void finish_status_attrs(void)
0490 {
0491     kfree(status_attrs);
0492 }
0493 
0494 struct attribute_group vhci_attr_group = {
0495     .attrs = NULL,
0496 };
0497 
0498 int vhci_init_attr_group(void)
0499 {
0500     struct attribute **attrs;
0501     int ret, i;
0502 
0503     attrs = kcalloc((vhci_num_controllers + 5), sizeof(struct attribute *),
0504             GFP_KERNEL);
0505     if (attrs == NULL)
0506         return -ENOMEM;
0507 
0508     ret = init_status_attrs();
0509     if (ret) {
0510         kfree(attrs);
0511         return ret;
0512     }
0513     *attrs = &dev_attr_nports.attr;
0514     *(attrs + 1) = &dev_attr_detach.attr;
0515     *(attrs + 2) = &dev_attr_attach.attr;
0516     *(attrs + 3) = &dev_attr_usbip_debug.attr;
0517     for (i = 0; i < vhci_num_controllers; i++)
0518         *(attrs + i + 4) = &((status_attrs + i)->attr.attr);
0519     vhci_attr_group.attrs = attrs;
0520     return 0;
0521 }
0522 
0523 void vhci_finish_attr_group(void)
0524 {
0525     finish_status_attrs();
0526     kfree(vhci_attr_group.attrs);
0527 }