/* Hardening for Spectre-v1 */ #include <linux/nospec.h>
#include"usbip_common.h" #include"vhci.h"
/* TODO: refine locking ?*/
/* * output example: * hub port sta spd dev sockfd local_busid * hs 0000 004 000 00000000 000003 1-2.3 * ................................................ * ss 0008 004 000 00000000 000004 2-3.4 * ................................................ * * Output includes socket fd instead of socket pointer address to avoid * leaking kernel memory address in: * /sys/devices/platform/vhci_hcd.0/status and in debug output. * The socket pointer address is not used at the moment and it was made * visible as a convenient way to find IP address from socket pointer * address by looking up /proc/net/{tcp,tcp6}. As this opens a security * hole, the change is made to use sockfd instead. *
*/ staticvoid port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev)
{ if (hub == HUB_SPEED_HIGH)
*out += sprintf(*out, "hs %04u %03u ",
port, vdev->ud.status); else/* hub == HUB_SPEED_SUPER */
*out += sprintf(*out, "ss %04u %03u ",
port, vdev->ud.status);
static ssize_t status_show_not_ready(int pdev_nr, char *out)
{ char *s = out; int i = 0;
for (i = 0; i < VHCI_HC_PORTS; i++) {
out += sprintf(out, "hs %04u %03u ",
(pdev_nr * VHCI_PORTS) + i,
VDEV_ST_NOTASSIGNED);
out += sprintf(out, "000 00000000 0000000000000000 0-0");
out += sprintf(out, "\n");
}
for (i = 0; i < VHCI_HC_PORTS; i++) {
out += sprintf(out, "ss %04u %03u ",
(pdev_nr * VHCI_PORTS) + VHCI_HC_PORTS + i,
VDEV_ST_NOTASSIGNED);
out += sprintf(out, "000 00000000 0000000000000000 0-0");
out += sprintf(out, "\n");
} return out - s;
}
staticint status_name_to_id(constchar *name)
{ char *c; long val; int ret;
c = strchr(name, '.'); if (c == NULL) return 0;
ret = kstrtol(c+1, 10, &val); if (ret < 0) return ret;
/* * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, * thus the * 2.
*/
out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers); return out - s;
} static DEVICE_ATTR_RO(nports);
switch (speed) { case USB_SPEED_LOW: case USB_SPEED_FULL: case USB_SPEED_HIGH: case USB_SPEED_WIRELESS: case USB_SPEED_SUPER: case USB_SPEED_SUPER_PLUS: break; default:
pr_err("Failed attach request for unsupported USB speed: %s\n",
usb_speed_string(speed)); return 0;
}
return 1;
}
/* Sysfs entry to establish a virtual connection */ /* * To start a new USB/IP attachment, a userland program needs to setup a TCP * connection and then write its socket descriptor with remote device * information into this sysfs file. * * A remote device is virtually attached to the root-hub port of @rhport with * @speed. @devid is embedded into a request to specify the remote device in a * server host. * * write() returns 0 on success, else negative errno.
*/ static ssize_t attach_store(struct device *dev, struct device_attribute *attr, constchar *buf, size_t count)
{ struct socket *socket; int sockfd = 0;
__u32 port = 0, pdev_nr = 0, rhport = 0, devid = 0, speed = 0; struct usb_hcd *hcd; struct vhci_hcd *vhci_hcd; struct vhci_device *vdev; struct vhci *vhci; int err; unsignedlong flags; struct task_struct *tcp_rx = NULL; struct task_struct *tcp_tx = NULL;
/* * @rhport: port number of vhci_hcd * @sockfd: socket descriptor of an established TCP connection * @devid: unique device identifier in a remote host * @speed: usb device speed in a remote host
*/ if (sscanf(buf, "%u %u %u %u", &port, &sockfd, &devid, &speed) != 4) return -EINVAL;
pdev_nr = port_to_pdev_nr(port);
rhport = port_to_rhport(port);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.