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 /* Hardening for Spectre-v1 */ 14 #include <linux/nospec.h> 15 16 #include "usbip_common.h" 17 #include "vhci.h" 18 19 /* TODO: refine locking ?*/ 20 21 /* 22 * output example: 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 * ................................................ 28 * 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. 36 * 37 */ 38 static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev) 39 { 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); 46 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", 51 vdev->ud.sockfd, 52 dev_name(&vdev->udev->dev)); 53 54 } else { 55 *out += sprintf(*out, "000 00000000 "); 56 *out += sprintf(*out, "000000 0-0"); 57 } 58 59 *out += sprintf(*out, "\n"); 60 } 61 62 /* Sysfs entry to show port status */ 63 static ssize_t status_show_vhci(int pdev_nr, char *out) 64 { 65 struct platform_device *pdev = vhcis[pdev_nr].pdev; 66 struct vhci *vhci; 67 struct usb_hcd *hcd; 68 struct vhci_hcd *vhci_hcd; 69 char *s = out; 70 int i; 71 unsigned long flags; 72 73 if (!pdev || !out) { 74 usbip_dbg_vhci_sysfs("show status error\n"); 75 return 0; 76 } 77 78 hcd = platform_get_drvdata(pdev); 79 vhci_hcd = hcd_to_vhci_hcd(hcd); 80 vhci = vhci_hcd->vhci; 81 82 spin_lock_irqsave(&vhci->lock, flags); 83 84 for (i = 0; i < VHCI_HC_PORTS; i++) { 85 struct vhci_device *vdev = &vhci->vhci_hcd_hs->vdev[i]; 86 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); 91 } 92 93 for (i = 0; i < VHCI_HC_PORTS; i++) { 94 struct vhci_device *vdev = &vhci->vhci_hcd_ss->vdev[i]; 95 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); 100 } 101 102 spin_unlock_irqrestore(&vhci->lock, flags); 103 104 return out - s; 105 } 106 107 static ssize_t status_show_not_ready(int pdev_nr, char *out) 108 { 109 char *s = out; 110 int i = 0; 111 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"); 118 } 119 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"); 126 } 127 return out - s; 128 } 129 130 static int status_name_to_id(const char *name) 131 { 132 char *c; 133 long val; 134 int ret; 135 136 c = strchr(name, '.'); 137 if (c == NULL) 138 return 0; 139 140 ret = kstrtol(c+1, 10, &val); 141 if (ret < 0) 142 return ret; 143 144 return val; 145 } 146 147 static ssize_t status_show(struct device *dev, 148 struct device_attribute *attr, char *out) 149 { 150 char *s = out; 151 int pdev_nr; 152 153 out += sprintf(out, 154 "hub port sta spd dev sockfd local_busid\n"); 155 156 pdev_nr = status_name_to_id(attr->attr.name); 157 if (pdev_nr < 0) 158 out += status_show_not_ready(pdev_nr, out); 159 else 160 out += status_show_vhci(pdev_nr, out); 161 162 return out - s; 163 } 164 165 static ssize_t nports_show(struct device *dev, struct device_attribute *attr, 166 char *out) 167 { 168 char *s = out; 169 170 /* 171 * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, 172 * thus the * 2. 173 */ 174 out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers); 175 return out - s; 176 } 177 static DEVICE_ATTR_RO(nports); 178 179 /* Sysfs entry to shutdown a virtual connection */ 180 static int vhci_port_disconnect(struct vhci_hcd *vhci_hcd, __u32 rhport) 181 { 182 struct vhci_device *vdev = &vhci_hcd->vdev[rhport]; 183 struct vhci *vhci = vhci_hcd->vhci; 184 unsigned long flags; 185 186 usbip_dbg_vhci_sysfs("enter\n"); 187 188 /* lock */ 189 spin_lock_irqsave(&vhci->lock, flags); 190 spin_lock(&vdev->ud.lock); 191 192 if (vdev->ud.status == VDEV_ST_NULL) { 193 pr_err("not connected %d\n", vdev->ud.status); 194 195 /* unlock */ 196 spin_unlock(&vdev->ud.lock); 197 spin_unlock_irqrestore(&vhci->lock, flags); 198 199 return -EINVAL; 200 } 201 202 /* unlock */ 203 spin_unlock(&vdev->ud.lock); 204 spin_unlock_irqrestore(&vhci->lock, flags); 205 206 usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); 207 208 return 0; 209 } 210 211 static int valid_port(__u32 *pdev_nr, __u32 *rhport) 212 { 213 if (*pdev_nr >= vhci_num_controllers) { 214 pr_err("pdev %u\n", *pdev_nr); 215 return 0; 216 } 217 *pdev_nr = array_index_nospec(*pdev_nr, vhci_num_controllers); 218 219 if (*rhport >= VHCI_HC_PORTS) { 220 pr_err("rhport %u\n", *rhport); 221 return 0; 222 } 223 *rhport = array_index_nospec(*rhport, VHCI_HC_PORTS); 224 225 return 1; 226 } 227 228 static ssize_t detach_store(struct device *dev, struct device_attribute *attr, 229 const char *buf, size_t count) 230 { 231 __u32 port = 0, pdev_nr = 0, rhport = 0; 232 struct usb_hcd *hcd; 233 struct vhci_hcd *vhci_hcd; 234 int ret; 235 236 if (kstrtoint(buf, 10, &port) < 0) 237 return -EINVAL; 238 239 pdev_nr = port_to_pdev_nr(port); 240 rhport = port_to_rhport(port); 241 242 if (!valid_port(&pdev_nr, &rhport)) 243 return -EINVAL; 244 245 hcd = platform_get_drvdata(vhcis[pdev_nr].pdev); 246 if (hcd == NULL) { 247 dev_err(dev, "port is not ready %u\n", port); 248 return -EAGAIN; 249 } 250 251 usbip_dbg_vhci_sysfs("rhport %d\n", rhport); 252 253 if ((port / VHCI_HC_PORTS) % 2) 254 vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_ss; 255 else 256 vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_hs; 257 258 ret = vhci_port_disconnect(vhci_hcd, rhport); 259 if (ret < 0) 260 return -EINVAL; 261 262 usbip_dbg_vhci_sysfs("Leave\n"); 263 264 return count; 265 } 266 static DEVICE_ATTR_WO(detach); 267 268 static int valid_args(__u32 *pdev_nr, __u32 *rhport, 269 enum usb_device_speed speed) 270 { 271 if (!valid_port(pdev_nr, rhport)) { 272 return 0; 273 } 274 275 switch (speed) { 276 case USB_SPEED_LOW: 277 case USB_SPEED_FULL: 278 case USB_SPEED_HIGH: 279 case USB_SPEED_WIRELESS: 280 case USB_SPEED_SUPER: 281 break; 282 default: 283 pr_err("Failed attach request for unsupported USB speed: %s\n", 284 usb_speed_string(speed)); 285 return 0; 286 } 287 288 return 1; 289 } 290 291 /* Sysfs entry to establish a virtual connection */ 292 /* 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. 296 * 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 299 * server host. 300 * 301 * write() returns 0 on success, else negative errno. 302 */ 303 static ssize_t attach_store(struct device *dev, struct device_attribute *attr, 304 const char *buf, size_t count) 305 { 306 struct socket *socket; 307 int sockfd = 0; 308 __u32 port = 0, pdev_nr = 0, rhport = 0, devid = 0, speed = 0; 309 struct usb_hcd *hcd; 310 struct vhci_hcd *vhci_hcd; 311 struct vhci_device *vdev; 312 struct vhci *vhci; 313 int err; 314 unsigned long flags; 315 316 /* 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 321 */ 322 if (sscanf(buf, "%u %u %u %u", &port, &sockfd, &devid, &speed) != 4) 323 return -EINVAL; 324 pdev_nr = port_to_pdev_nr(port); 325 rhport = port_to_rhport(port); 326 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); 331 332 /* check received parameters */ 333 if (!valid_args(&pdev_nr, &rhport, speed)) 334 return -EINVAL; 335 336 hcd = platform_get_drvdata(vhcis[pdev_nr].pdev); 337 if (hcd == NULL) { 338 dev_err(dev, "port %d is not ready\n", port); 339 return -EAGAIN; 340 } 341 342 vhci_hcd = hcd_to_vhci_hcd(hcd); 343 vhci = vhci_hcd->vhci; 344 345 if (speed == USB_SPEED_SUPER) 346 vdev = &vhci->vhci_hcd_ss->vdev[rhport]; 347 else 348 vdev = &vhci->vhci_hcd_hs->vdev[rhport]; 349 350 /* Extract socket from fd. */ 351 socket = sockfd_lookup(sockfd, &err); 352 if (!socket) 353 return -EINVAL; 354 355 /* now need lock until setting vdev status as used */ 356 357 /* begin a lock */ 358 spin_lock_irqsave(&vhci->lock, flags); 359 spin_lock(&vdev->ud.lock); 360 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); 365 366 sockfd_put(socket); 367 368 dev_err(dev, "port %d already used\n", rhport); 369 /* 370 * Will be retried from userspace 371 * if there's another free port. 372 */ 373 return -EBUSY; 374 } 375 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)); 380 381 vdev->devid = devid; 382 vdev->speed = speed; 383 vdev->ud.sockfd = sockfd; 384 vdev->ud.tcp_socket = socket; 385 vdev->ud.status = VDEV_ST_NOTASSIGNED; 386 usbip_kcov_handle_init(&vdev->ud); 387 388 spin_unlock(&vdev->ud.lock); 389 spin_unlock_irqrestore(&vhci->lock, flags); 390 /* end the lock */ 391 392 vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); 393 vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); 394 395 rh_port_connect(vdev, speed); 396 397 return count; 398 } 399 static DEVICE_ATTR_WO(attach); 400 401 #define MAX_STATUS_NAME 16 402 403 struct status_attr { 404 struct device_attribute attr; 405 char name[MAX_STATUS_NAME+1]; 406 }; 407 408 static struct status_attr *status_attrs; 409 410 static void set_status_attr(int id) 411 { 412 struct status_attr *status; 413 414 status = status_attrs + id; 415 if (id == 0) 416 strcpy(status->name, "status"); 417 else 418 snprintf(status->name, MAX_STATUS_NAME+1, "status.%d", id); 419 status->attr.attr.name = status->name; 420 status->attr.attr.mode = S_IRUGO; 421 status->attr.show = status_show; 422 sysfs_attr_init(&status->attr.attr); 423 } 424 425 static int init_status_attrs(void) 426 { 427 int id; 428 429 status_attrs = kcalloc(vhci_num_controllers, sizeof(struct status_attr), 430 GFP_KERNEL); 431 if (status_attrs == NULL) 432 return -ENOMEM; 433 434 for (id = 0; id < vhci_num_controllers; id++) 435 set_status_attr(id); 436 437 return 0; 438 } 439 440 static void finish_status_attrs(void) 441 { 442 kfree(status_attrs); 443 } 444 445 struct attribute_group vhci_attr_group = { 446 .attrs = NULL, 447 }; 448 449 int vhci_init_attr_group(void) 450 { 451 struct attribute **attrs; 452 int ret, i; 453 454 attrs = kcalloc((vhci_num_controllers + 5), sizeof(struct attribute *), 455 GFP_KERNEL); 456 if (attrs == NULL) 457 return -ENOMEM; 458 459 ret = init_status_attrs(); 460 if (ret) { 461 kfree(attrs); 462 return ret; 463 } 464 *attrs = &dev_attr_nports.attr; 465 *(attrs + 1) = &dev_attr_detach.attr; 466 *(attrs + 2) = &dev_attr_attach.attr; 467 *(attrs + 3) = &dev_attr_usbip_debug.attr; 468 for (i = 0; i < vhci_num_controllers; i++) 469 *(attrs + i + 4) = &((status_attrs + i)->attr.attr); 470 vhci_attr_group.attrs = attrs; 471 return 0; 472 } 473 474 void vhci_finish_attr_group(void) 475 { 476 finish_status_attrs(); 477 kfree(vhci_attr_group.attrs); 478 } 479