提交 3866e6be 编写于 作者: P Peter Maydell

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: NPeter Maydell <peter.maydell@linaro.org>
...@@ -653,13 +653,18 @@ static void usb_mtp_object_readdir(MTPState *s, MTPObject *o) ...@@ -653,13 +653,18 @@ static void usb_mtp_object_readdir(MTPState *s, MTPObject *o)
{ {
struct dirent *entry; struct dirent *entry;
DIR *dir; DIR *dir;
int fd;
if (o->have_children) { if (o->have_children) {
return; return;
} }
o->have_children = true; 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) { if (!dir) {
return; return;
} }
...@@ -1007,7 +1012,7 @@ static MTPData *usb_mtp_get_object(MTPState *s, MTPControl *c, ...@@ -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); 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) { if (d->fd == -1) {
usb_mtp_data_free(d); usb_mtp_data_free(d);
return NULL; return NULL;
...@@ -1031,7 +1036,7 @@ static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c, ...@@ -1031,7 +1036,7 @@ static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c,
c->argv[1], c->argv[2]); c->argv[1], c->argv[2]);
d = usb_mtp_data_alloc(c); 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) { if (d->fd == -1) {
usb_mtp_data_free(d); usb_mtp_data_free(d);
return NULL; return NULL;
...@@ -1658,7 +1663,7 @@ static void usb_mtp_write_data(MTPState *s) ...@@ -1658,7 +1663,7 @@ static void usb_mtp_write_data(MTPState *s)
0, 0, 0, 0); 0, 0, 0, 0);
goto done; 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) { if (d->fd == -1) {
usb_mtp_queue_result(s, RES_STORE_FULL, d->trans, usb_mtp_queue_result(s, RES_STORE_FULL, d->trans,
0, 0, 0, 0); 0, 0, 0, 0);
...@@ -1705,7 +1710,7 @@ free: ...@@ -1705,7 +1710,7 @@ free:
s->write_pending = false; 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; MTPData *d = s->data_out;
ObjectInfo *dataset = (ObjectInfo *)d->data; ObjectInfo *dataset = (ObjectInfo *)d->data;
...@@ -1717,7 +1722,9 @@ static void usb_mtp_write_metadata(MTPState *s) ...@@ -1717,7 +1722,9 @@ static void usb_mtp_write_metadata(MTPState *s)
assert(!s->write_pending); assert(!s->write_pending);
assert(p != NULL); 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, '/')) { if (strchr(filename, '/')) {
usb_mtp_queue_result(s, RES_PARAMETER_NOT_SUPPORTED, d->trans, usb_mtp_queue_result(s, RES_PARAMETER_NOT_SUPPORTED, d->trans,
...@@ -1733,7 +1740,6 @@ static void usb_mtp_write_metadata(MTPState *s) ...@@ -1733,7 +1740,6 @@ static void usb_mtp_write_metadata(MTPState *s)
s->dataset.filename = filename; s->dataset.filename = filename;
s->dataset.format = dataset->format; s->dataset.format = dataset->format;
s->dataset.size = dataset->size; s->dataset.size = dataset->size;
s->dataset.filename = filename;
s->write_pending = true; s->write_pending = true;
if (s->dataset.format == FMT_ASSOCIATION) { if (s->dataset.format == FMT_ASSOCIATION) {
...@@ -1802,7 +1808,7 @@ static void usb_mtp_get_data(MTPState *s, mtp_container *container, ...@@ -1802,7 +1808,7 @@ static void usb_mtp_get_data(MTPState *s, mtp_container *container,
if (d->offset == d->length) { if (d->offset == d->length) {
/* The operation might have already failed */ /* The operation might have already failed */
if (!s->result) { if (!s->result) {
usb_mtp_write_metadata(s); usb_mtp_write_metadata(s, dlen);
} }
usb_mtp_data_free(s->data_out); usb_mtp_data_free(s->data_out);
s->data_out = NULL; s->data_out = NULL;
......
...@@ -1783,9 +1783,17 @@ static int ehci_state_fetchqtd(EHCIQueue *q) ...@@ -1783,9 +1783,17 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
EHCIqtd qtd; EHCIqtd qtd;
EHCIPacket *p; EHCIPacket *p;
int again = 1; int again = 1;
uint32_t addr;
if (get_dwords(q->ehci, NLPTR_GET(q->qtdaddr), (uint32_t *) &qtd, addr = NLPTR_GET(q->qtdaddr);
sizeof(EHCIqtd) >> 2) < 0) { 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; return 0;
} }
ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), &qtd); ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), &qtd);
......
...@@ -988,7 +988,9 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data) ...@@ -988,7 +988,9 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data)
if (s->dh) { if (s->dh) {
usb_host_release_interfaces(s); usb_host_release_interfaces(s);
libusb_reset_device(s->dh);
usb_host_attach_kernel(s); usb_host_attach_kernel(s);
libusb_close(s->dh);
} }
} }
......
...@@ -860,10 +860,14 @@ static int usbback_connect(struct XenDevice *xendev) ...@@ -860,10 +860,14 @@ static int usbback_connect(struct XenDevice *xendev)
struct usbif_conn_sring *conn_sring; struct usbif_conn_sring *conn_sring;
int urb_ring_ref; int urb_ring_ref;
int conn_ring_ref; int conn_ring_ref;
unsigned int i; unsigned int i, max_grants;
TR_BUS(xendev, "start\n"); 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); usbif = container_of(xendev, struct usbback_info, xendev);
if (xenstore_read_fe_int(xendev, "urb-ring-ref", &urb_ring_ref)) { if (xenstore_read_fe_int(xendev, "urb-ring-ref", &urb_ring_ref)) {
...@@ -1005,7 +1009,7 @@ static void usbback_alloc(struct XenDevice *xendev) ...@@ -1005,7 +1009,7 @@ static void usbback_alloc(struct XenDevice *xendev)
{ {
struct usbback_info *usbif; struct usbback_info *usbif;
USBPort *p; USBPort *p;
unsigned int i, max_grants; unsigned int i;
usbif = container_of(xendev, struct usbback_info, xendev); usbif = container_of(xendev, struct usbback_info, xendev);
...@@ -1021,10 +1025,6 @@ static void usbback_alloc(struct XenDevice *xendev) ...@@ -1021,10 +1025,6 @@ static void usbback_alloc(struct XenDevice *xendev)
QTAILQ_INIT(&usbif->req_free_q); QTAILQ_INIT(&usbif->req_free_q);
QSIMPLEQ_INIT(&usbif->hotplug_q); QSIMPLEQ_INIT(&usbif->hotplug_q);
usbif->bh = qemu_bh_new(usbback_bh, usbif); 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) static int usbback_free(struct XenDevice *xendev)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部