summaryrefslogtreecommitdiffstats
path: root/hw/usb/dev-mtp.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/usb/dev-mtp.c')
-rw-r--r--hw/usb/dev-mtp.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 100b7171f4..68c5eb8eaa 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -191,7 +191,7 @@ struct MTPState {
#ifdef CONFIG_INOTIFY1
/* inotify descriptor */
int inotifyfd;
- QTAILQ_HEAD(events, MTPMonEntry) events;
+ QTAILQ_HEAD(, MTPMonEntry) events;
#endif
/* Responder is expecting a write operation */
bool write_pending;
@@ -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,11 +1722,14 @@ 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,
0, 0, 0, 0);
+ g_free(filename);
return;
}
@@ -1733,7 +1741,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 +1809,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;
@@ -1982,7 +1989,7 @@ static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p)
case EP_EVENT:
#ifdef CONFIG_INOTIFY1
if (!QTAILQ_EMPTY(&s->events)) {
- struct MTPMonEntry *e = QTAILQ_LAST(&s->events, events);
+ struct MTPMonEntry *e = QTAILQ_LAST(&s->events);
uint32_t handle;
int len = sizeof(container) + sizeof(uint32_t);