usb: fixes for mtp, ehci, usb-host and pvusb (xen).
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJcE4gpAAoJEEy22O7T6HE4iooQAIjiQJoz4K5/ClVtU/4y/nb9 GlqcC3q/KONbjgFGLVORVLx0hsclwApMN8TI7EyD37PpBcZ5sN3OqwNUt+wBTQUx hV1dX8ZJoduh23f71qkXPKI77t8g5AsxkCCRPdHTsKro480L1hj58GviT+pSqOvg 7SW9sJQA6IBYE5mpRkvwNqcC9jJrz5ri239iFpWvPFmYtDikIZkyE9Qp6fhBfW6d tuX9oFZCq4gB8aF8uTDjvlkDjltpNEDqJMFLHgy0l2lZnGGyHQNVIxOF5Ainr/0A IkWkd9eG6M9AQvAAZYPnptis4V5Cv+6y96ubNv0AyAc2BlY3v8p0lJyscoGno5bq E+4wQn7Rvx39uBC5qLYUZ2Q2QIWucRqFefx+AGbCPdmlu+Czp4rkv1exdrvZcqK3 HIj9MSV5Xzgvi/ChMRczPionhjxe/fe0GNSue0FFrPrePasz3xaEb7CjbU3VdzRW tVNg3T6XhTXEfVSs/PkRjoOZdIboKFkJxU8iILaZytsyyLfb6A6mQ50wdCHf8+xf iLOkSM5xgMvp39H8ueZHjNuJ46ojTu9+xuXB/8z8crWml5Hfv4sfN3X11whacxNB n11WOOTLaWbhalYoxSOawha/3reYNOWq1RN/hCab4dczDZ53BDjmGSdHfIYEpf4S Gnu3YL6l4STx/be52YVK =I8A+ -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/usb-20181214-pull-request' into staging usb: fixes for mtp, ehci, usb-host and pvusb (xen). # gpg: Signature made Fri 14 Dec 2018 10:38:33 GMT # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/usb-20181214-pull-request: usb-mtp: Limit filename to object information size usb-mtp: use O_NOFOLLOW and O_CLOEXEC. ehci: fix fetch qtd race usb-host: reset and close libusb_device_handle before qemu exit pvusb: set max grants only in initialise Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
3866e6bebd
|
@ -653,13 +653,18 @@ static void usb_mtp_object_readdir(MTPState *s, MTPObject *o)
|
|||
{
|
||||
struct dirent *entry;
|
||||
DIR *dir;
|
||||
int fd;
|
||||
|
||||
if (o->have_children) {
|
||||
return;
|
||||
}
|
||||
o->have_children = true;
|
||||
|
||||
dir = opendir(o->path);
|
||||
fd = open(o->path, O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
dir = fdopendir(fd);
|
||||
if (!dir) {
|
||||
return;
|
||||
}
|
||||
|
@ -1007,7 +1012,7 @@ static MTPData *usb_mtp_get_object(MTPState *s, MTPControl *c,
|
|||
|
||||
trace_usb_mtp_op_get_object(s->dev.addr, o->handle, o->path);
|
||||
|
||||
d->fd = open(o->path, O_RDONLY);
|
||||
d->fd = open(o->path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
|
||||
if (d->fd == -1) {
|
||||
usb_mtp_data_free(d);
|
||||
return NULL;
|
||||
|
@ -1031,7 +1036,7 @@ static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c,
|
|||
c->argv[1], c->argv[2]);
|
||||
|
||||
d = usb_mtp_data_alloc(c);
|
||||
d->fd = open(o->path, O_RDONLY);
|
||||
d->fd = open(o->path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
|
||||
if (d->fd == -1) {
|
||||
usb_mtp_data_free(d);
|
||||
return NULL;
|
||||
|
@ -1658,7 +1663,7 @@ static void usb_mtp_write_data(MTPState *s)
|
|||
0, 0, 0, 0);
|
||||
goto done;
|
||||
}
|
||||
d->fd = open(path, O_CREAT | O_WRONLY, mask);
|
||||
d->fd = open(path, O_CREAT | O_WRONLY | O_CLOEXEC | O_NOFOLLOW, mask);
|
||||
if (d->fd == -1) {
|
||||
usb_mtp_queue_result(s, RES_STORE_FULL, d->trans,
|
||||
0, 0, 0, 0);
|
||||
|
@ -1705,7 +1710,7 @@ free:
|
|||
s->write_pending = false;
|
||||
}
|
||||
|
||||
static void usb_mtp_write_metadata(MTPState *s)
|
||||
static void usb_mtp_write_metadata(MTPState *s, uint64_t dlen)
|
||||
{
|
||||
MTPData *d = s->data_out;
|
||||
ObjectInfo *dataset = (ObjectInfo *)d->data;
|
||||
|
@ -1717,7 +1722,9 @@ static void usb_mtp_write_metadata(MTPState *s)
|
|||
assert(!s->write_pending);
|
||||
assert(p != NULL);
|
||||
|
||||
filename = utf16_to_str(dataset->length, dataset->filename);
|
||||
filename = utf16_to_str(MIN(dataset->length,
|
||||
dlen - offsetof(ObjectInfo, filename)),
|
||||
dataset->filename);
|
||||
|
||||
if (strchr(filename, '/')) {
|
||||
usb_mtp_queue_result(s, RES_PARAMETER_NOT_SUPPORTED, d->trans,
|
||||
|
@ -1733,7 +1740,6 @@ static void usb_mtp_write_metadata(MTPState *s)
|
|||
s->dataset.filename = filename;
|
||||
s->dataset.format = dataset->format;
|
||||
s->dataset.size = dataset->size;
|
||||
s->dataset.filename = filename;
|
||||
s->write_pending = true;
|
||||
|
||||
if (s->dataset.format == FMT_ASSOCIATION) {
|
||||
|
@ -1802,7 +1808,7 @@ static void usb_mtp_get_data(MTPState *s, mtp_container *container,
|
|||
if (d->offset == d->length) {
|
||||
/* The operation might have already failed */
|
||||
if (!s->result) {
|
||||
usb_mtp_write_metadata(s);
|
||||
usb_mtp_write_metadata(s, dlen);
|
||||
}
|
||||
usb_mtp_data_free(s->data_out);
|
||||
s->data_out = NULL;
|
||||
|
|
|
@ -1783,9 +1783,17 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
|
|||
EHCIqtd qtd;
|
||||
EHCIPacket *p;
|
||||
int again = 1;
|
||||
uint32_t addr;
|
||||
|
||||
if (get_dwords(q->ehci, NLPTR_GET(q->qtdaddr), (uint32_t *) &qtd,
|
||||
sizeof(EHCIqtd) >> 2) < 0) {
|
||||
addr = NLPTR_GET(q->qtdaddr);
|
||||
if (get_dwords(q->ehci, addr + 8, &qtd.token, 1) < 0) {
|
||||
return 0;
|
||||
}
|
||||
barrier();
|
||||
if (get_dwords(q->ehci, addr + 0, &qtd.next, 1) < 0 ||
|
||||
get_dwords(q->ehci, addr + 4, &qtd.altnext, 1) < 0 ||
|
||||
get_dwords(q->ehci, addr + 12, qtd.bufptr,
|
||||
ARRAY_SIZE(qtd.bufptr)) < 0) {
|
||||
return 0;
|
||||
}
|
||||
ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), &qtd);
|
||||
|
|
|
@ -988,7 +988,9 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data)
|
|||
|
||||
if (s->dh) {
|
||||
usb_host_release_interfaces(s);
|
||||
libusb_reset_device(s->dh);
|
||||
usb_host_attach_kernel(s);
|
||||
libusb_close(s->dh);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -860,10 +860,14 @@ static int usbback_connect(struct XenDevice *xendev)
|
|||
struct usbif_conn_sring *conn_sring;
|
||||
int urb_ring_ref;
|
||||
int conn_ring_ref;
|
||||
unsigned int i;
|
||||
unsigned int i, max_grants;
|
||||
|
||||
TR_BUS(xendev, "start\n");
|
||||
|
||||
/* max_grants: for each request and for the rings (request and connect). */
|
||||
max_grants = USBIF_MAX_SEGMENTS_PER_REQUEST * USB_URB_RING_SIZE + 2;
|
||||
xen_be_set_max_grant_refs(xendev, max_grants);
|
||||
|
||||
usbif = container_of(xendev, struct usbback_info, xendev);
|
||||
|
||||
if (xenstore_read_fe_int(xendev, "urb-ring-ref", &urb_ring_ref)) {
|
||||
|
@ -1005,7 +1009,7 @@ static void usbback_alloc(struct XenDevice *xendev)
|
|||
{
|
||||
struct usbback_info *usbif;
|
||||
USBPort *p;
|
||||
unsigned int i, max_grants;
|
||||
unsigned int i;
|
||||
|
||||
usbif = container_of(xendev, struct usbback_info, xendev);
|
||||
|
||||
|
@ -1021,10 +1025,6 @@ static void usbback_alloc(struct XenDevice *xendev)
|
|||
QTAILQ_INIT(&usbif->req_free_q);
|
||||
QSIMPLEQ_INIT(&usbif->hotplug_q);
|
||||
usbif->bh = qemu_bh_new(usbback_bh, usbif);
|
||||
|
||||
/* max_grants: for each request and for the rings (request and connect). */
|
||||
max_grants = USBIF_MAX_SEGMENTS_PER_REQUEST * USB_URB_RING_SIZE + 2;
|
||||
xen_be_set_max_grant_refs(xendev, max_grants);
|
||||
}
|
||||
|
||||
static int usbback_free(struct XenDevice *xendev)
|
||||
|
|
Loading…
Reference in a new issue