vhci_sysfs.c (12450B)
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 */ 38static 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 */ 63static 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 107static 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 130static 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 147static 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 165static 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} 177static DEVICE_ATTR_RO(nports); 178 179/* Sysfs entry to shutdown a virtual connection */ 180static 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 mutex_lock(&vdev->ud.sysfs_lock); 189 190 /* lock */ 191 spin_lock_irqsave(&vhci->lock, flags); 192 spin_lock(&vdev->ud.lock); 193 194 if (vdev->ud.status == VDEV_ST_NULL) { 195 pr_err("not connected %d\n", vdev->ud.status); 196 197 /* unlock */ 198 spin_unlock(&vdev->ud.lock); 199 spin_unlock_irqrestore(&vhci->lock, flags); 200 mutex_unlock(&vdev->ud.sysfs_lock); 201 202 return -EINVAL; 203 } 204 205 /* unlock */ 206 spin_unlock(&vdev->ud.lock); 207 spin_unlock_irqrestore(&vhci->lock, flags); 208 209 usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); 210 211 mutex_unlock(&vdev->ud.sysfs_lock); 212 213 return 0; 214} 215 216static int valid_port(__u32 *pdev_nr, __u32 *rhport) 217{ 218 if (*pdev_nr >= vhci_num_controllers) { 219 pr_err("pdev %u\n", *pdev_nr); 220 return 0; 221 } 222 *pdev_nr = array_index_nospec(*pdev_nr, vhci_num_controllers); 223 224 if (*rhport >= VHCI_HC_PORTS) { 225 pr_err("rhport %u\n", *rhport); 226 return 0; 227 } 228 *rhport = array_index_nospec(*rhport, VHCI_HC_PORTS); 229 230 return 1; 231} 232 233static ssize_t detach_store(struct device *dev, struct device_attribute *attr, 234 const char *buf, size_t count) 235{ 236 __u32 port = 0, pdev_nr = 0, rhport = 0; 237 struct usb_hcd *hcd; 238 struct vhci_hcd *vhci_hcd; 239 int ret; 240 241 if (kstrtoint(buf, 10, &port) < 0) 242 return -EINVAL; 243 244 pdev_nr = port_to_pdev_nr(port); 245 rhport = port_to_rhport(port); 246 247 if (!valid_port(&pdev_nr, &rhport)) 248 return -EINVAL; 249 250 hcd = platform_get_drvdata(vhcis[pdev_nr].pdev); 251 if (hcd == NULL) { 252 dev_err(dev, "port is not ready %u\n", port); 253 return -EAGAIN; 254 } 255 256 usbip_dbg_vhci_sysfs("rhport %d\n", rhport); 257 258 if ((port / VHCI_HC_PORTS) % 2) 259 vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_ss; 260 else 261 vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_hs; 262 263 ret = vhci_port_disconnect(vhci_hcd, rhport); 264 if (ret < 0) 265 return -EINVAL; 266 267 usbip_dbg_vhci_sysfs("Leave\n"); 268 269 return count; 270} 271static DEVICE_ATTR_WO(detach); 272 273static int valid_args(__u32 *pdev_nr, __u32 *rhport, 274 enum usb_device_speed speed) 275{ 276 if (!valid_port(pdev_nr, rhport)) { 277 return 0; 278 } 279 280 switch (speed) { 281 case USB_SPEED_LOW: 282 case USB_SPEED_FULL: 283 case USB_SPEED_HIGH: 284 case USB_SPEED_WIRELESS: 285 case USB_SPEED_SUPER: 286 break; 287 default: 288 pr_err("Failed attach request for unsupported USB speed: %s\n", 289 usb_speed_string(speed)); 290 return 0; 291 } 292 293 return 1; 294} 295 296/* Sysfs entry to establish a virtual connection */ 297/* 298 * To start a new USB/IP attachment, a userland program needs to setup a TCP 299 * connection and then write its socket descriptor with remote device 300 * information into this sysfs file. 301 * 302 * A remote device is virtually attached to the root-hub port of @rhport with 303 * @speed. @devid is embedded into a request to specify the remote device in a 304 * server host. 305 * 306 * write() returns 0 on success, else negative errno. 307 */ 308static ssize_t attach_store(struct device *dev, struct device_attribute *attr, 309 const char *buf, size_t count) 310{ 311 struct socket *socket; 312 int sockfd = 0; 313 __u32 port = 0, pdev_nr = 0, rhport = 0, devid = 0, speed = 0; 314 struct usb_hcd *hcd; 315 struct vhci_hcd *vhci_hcd; 316 struct vhci_device *vdev; 317 struct vhci *vhci; 318 int err; 319 unsigned long flags; 320 struct task_struct *tcp_rx = NULL; 321 struct task_struct *tcp_tx = NULL; 322 323 /* 324 * @rhport: port number of vhci_hcd 325 * @sockfd: socket descriptor of an established TCP connection 326 * @devid: unique device identifier in a remote host 327 * @speed: usb device speed in a remote host 328 */ 329 if (sscanf(buf, "%u %u %u %u", &port, &sockfd, &devid, &speed) != 4) 330 return -EINVAL; 331 pdev_nr = port_to_pdev_nr(port); 332 rhport = port_to_rhport(port); 333 334 usbip_dbg_vhci_sysfs("port(%u) pdev(%d) rhport(%u)\n", 335 port, pdev_nr, rhport); 336 usbip_dbg_vhci_sysfs("sockfd(%u) devid(%u) speed(%u)\n", 337 sockfd, devid, speed); 338 339 /* check received parameters */ 340 if (!valid_args(&pdev_nr, &rhport, speed)) 341 return -EINVAL; 342 343 hcd = platform_get_drvdata(vhcis[pdev_nr].pdev); 344 if (hcd == NULL) { 345 dev_err(dev, "port %d is not ready\n", port); 346 return -EAGAIN; 347 } 348 349 vhci_hcd = hcd_to_vhci_hcd(hcd); 350 vhci = vhci_hcd->vhci; 351 352 if (speed == USB_SPEED_SUPER) 353 vdev = &vhci->vhci_hcd_ss->vdev[rhport]; 354 else 355 vdev = &vhci->vhci_hcd_hs->vdev[rhport]; 356 357 mutex_lock(&vdev->ud.sysfs_lock); 358 359 /* Extract socket from fd. */ 360 socket = sockfd_lookup(sockfd, &err); 361 if (!socket) { 362 dev_err(dev, "failed to lookup sock"); 363 err = -EINVAL; 364 goto unlock_mutex; 365 } 366 if (socket->type != SOCK_STREAM) { 367 dev_err(dev, "Expecting SOCK_STREAM - found %d", 368 socket->type); 369 sockfd_put(socket); 370 err = -EINVAL; 371 goto unlock_mutex; 372 } 373 374 /* create threads before locking */ 375 tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx"); 376 if (IS_ERR(tcp_rx)) { 377 sockfd_put(socket); 378 err = -EINVAL; 379 goto unlock_mutex; 380 } 381 tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx"); 382 if (IS_ERR(tcp_tx)) { 383 kthread_stop(tcp_rx); 384 sockfd_put(socket); 385 err = -EINVAL; 386 goto unlock_mutex; 387 } 388 389 /* get task structs now */ 390 get_task_struct(tcp_rx); 391 get_task_struct(tcp_tx); 392 393 /* now begin lock until setting vdev status set */ 394 spin_lock_irqsave(&vhci->lock, flags); 395 spin_lock(&vdev->ud.lock); 396 397 if (vdev->ud.status != VDEV_ST_NULL) { 398 /* end of the lock */ 399 spin_unlock(&vdev->ud.lock); 400 spin_unlock_irqrestore(&vhci->lock, flags); 401 402 sockfd_put(socket); 403 kthread_stop_put(tcp_rx); 404 kthread_stop_put(tcp_tx); 405 406 dev_err(dev, "port %d already used\n", rhport); 407 /* 408 * Will be retried from userspace 409 * if there's another free port. 410 */ 411 err = -EBUSY; 412 goto unlock_mutex; 413 } 414 415 dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n", 416 pdev_nr, rhport, sockfd); 417 dev_info(dev, "devid(%u) speed(%u) speed_str(%s)\n", 418 devid, speed, usb_speed_string(speed)); 419 420 vdev->devid = devid; 421 vdev->speed = speed; 422 vdev->ud.sockfd = sockfd; 423 vdev->ud.tcp_socket = socket; 424 vdev->ud.tcp_rx = tcp_rx; 425 vdev->ud.tcp_tx = tcp_tx; 426 vdev->ud.status = VDEV_ST_NOTASSIGNED; 427 usbip_kcov_handle_init(&vdev->ud); 428 429 spin_unlock(&vdev->ud.lock); 430 spin_unlock_irqrestore(&vhci->lock, flags); 431 /* end the lock */ 432 433 wake_up_process(vdev->ud.tcp_rx); 434 wake_up_process(vdev->ud.tcp_tx); 435 436 rh_port_connect(vdev, speed); 437 438 dev_info(dev, "Device attached\n"); 439 440 mutex_unlock(&vdev->ud.sysfs_lock); 441 442 return count; 443 444unlock_mutex: 445 mutex_unlock(&vdev->ud.sysfs_lock); 446 return err; 447} 448static DEVICE_ATTR_WO(attach); 449 450#define MAX_STATUS_NAME 16 451 452struct status_attr { 453 struct device_attribute attr; 454 char name[MAX_STATUS_NAME+1]; 455}; 456 457static struct status_attr *status_attrs; 458 459static void set_status_attr(int id) 460{ 461 struct status_attr *status; 462 463 status = status_attrs + id; 464 if (id == 0) 465 strcpy(status->name, "status"); 466 else 467 snprintf(status->name, MAX_STATUS_NAME+1, "status.%d", id); 468 status->attr.attr.name = status->name; 469 status->attr.attr.mode = S_IRUGO; 470 status->attr.show = status_show; 471 sysfs_attr_init(&status->attr.attr); 472} 473 474static int init_status_attrs(void) 475{ 476 int id; 477 478 status_attrs = kcalloc(vhci_num_controllers, sizeof(struct status_attr), 479 GFP_KERNEL); 480 if (status_attrs == NULL) 481 return -ENOMEM; 482 483 for (id = 0; id < vhci_num_controllers; id++) 484 set_status_attr(id); 485 486 return 0; 487} 488 489static void finish_status_attrs(void) 490{ 491 kfree(status_attrs); 492} 493 494struct attribute_group vhci_attr_group = { 495 .attrs = NULL, 496}; 497 498int vhci_init_attr_group(void) 499{ 500 struct attribute **attrs; 501 int ret, i; 502 503 attrs = kcalloc((vhci_num_controllers + 5), sizeof(struct attribute *), 504 GFP_KERNEL); 505 if (attrs == NULL) 506 return -ENOMEM; 507 508 ret = init_status_attrs(); 509 if (ret) { 510 kfree(attrs); 511 return ret; 512 } 513 *attrs = &dev_attr_nports.attr; 514 *(attrs + 1) = &dev_attr_detach.attr; 515 *(attrs + 2) = &dev_attr_attach.attr; 516 *(attrs + 3) = &dev_attr_usbip_debug.attr; 517 for (i = 0; i < vhci_num_controllers; i++) 518 *(attrs + i + 4) = &((status_attrs + i)->attr.attr); 519 vhci_attr_group.attrs = attrs; 520 return 0; 521} 522 523void vhci_finish_attr_group(void) 524{ 525 finish_status_attrs(); 526 kfree(vhci_attr_group.attrs); 527}