* [Qemu-devel] [PATCH for-3.1 0/2] usb-mtp: two bugfixes (one security fix).
@ 2018-11-30 11:12 Gerd Hoffmann
2018-11-30 11:12 ` [Qemu-devel] [PATCH for-3.1 1/2] usb-mtp: fix utf16_to_str Gerd Hoffmann
2018-11-30 11:12 ` [Qemu-devel] [PATCH for-3.1 2/2] usb-mtp: outlaw slashes in filenames Gerd Hoffmann
0 siblings, 2 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2018-11-30 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Gerd Hoffmann (2):
usb-mtp: fix utf16_to_str
usb-mtp: outlaw slashes in filenames
hw/usb/dev-mtp.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
--
2.9.3
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH for-3.1 1/2] usb-mtp: fix utf16_to_str
2018-11-30 11:12 [Qemu-devel] [PATCH for-3.1 0/2] usb-mtp: two bugfixes (one security fix) Gerd Hoffmann
@ 2018-11-30 11:12 ` Gerd Hoffmann
2018-11-30 13:13 ` Markus Armbruster
2018-11-30 11:12 ` [Qemu-devel] [PATCH for-3.1 2/2] usb-mtp: outlaw slashes in filenames Gerd Hoffmann
1 sibling, 1 reply; 10+ messages in thread
From: Gerd Hoffmann @ 2018-11-30 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Make utf16_to_str return an allocated string. Remove the assumtion that
the number of string bytes equals the number of utf16 chars (which is
only true for ascii chars). Instead call wcstombs twice, once to figure
the storage size and once for the actual conversion (as suggested by the
wcstombs manpage).
Reported-by: Michael Hanselmann (hansmi.ch)
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/dev-mtp.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 00a3691bae..fbe1ace035 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -1593,17 +1593,22 @@ static void usb_mtp_cancel_packet(USBDevice *dev, USBPacket *p)
fprintf(stderr, "%s\n", __func__);
}
-static void utf16_to_str(uint8_t len, uint16_t *arr, char *name)
+static char *utf16_to_str(uint8_t len, uint16_t *arr)
{
- int count;
- wchar_t *wstr = g_new0(wchar_t, len);
+ wchar_t *wstr = g_new0(wchar_t, len + 1);
+ int count, dlen;
+ char *dest;
for (count = 0; count < len; count++) {
wstr[count] = (wchar_t)arr[count];
}
+ wstr[count] = 0;
- wcstombs(name, wstr, len);
+ dlen = wcstombs(NULL, wstr, 0) + 1;
+ dest = g_malloc(dlen);
+ wcstombs(dest, wstr, dlen);
g_free(wstr);
+ return dest;
}
/* Wrapper around write, returns 0 on failure */
@@ -1703,7 +1708,7 @@ static void usb_mtp_write_metadata(MTPState *s)
{
MTPData *d = s->data_out;
ObjectInfo *dataset = (ObjectInfo *)d->data;
- char *filename = g_new0(char, dataset->length);
+ char *filename;
MTPObject *o;
MTPObject *p = usb_mtp_object_lookup(s, s->dataset.parent_handle);
uint32_t next_handle = s->next_handle;
@@ -1711,7 +1716,7 @@ static void usb_mtp_write_metadata(MTPState *s)
assert(!s->write_pending);
assert(p != NULL);
- utf16_to_str(dataset->length, dataset->filename, filename);
+ filename = utf16_to_str(dataset->length, dataset->filename);
o = usb_mtp_object_lookup_name(p, filename, dataset->length);
if (o != NULL) {
--
2.9.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH for-3.1 2/2] usb-mtp: outlaw slashes in filenames
2018-11-30 11:12 [Qemu-devel] [PATCH for-3.1 0/2] usb-mtp: two bugfixes (one security fix) Gerd Hoffmann
2018-11-30 11:12 ` [Qemu-devel] [PATCH for-3.1 1/2] usb-mtp: fix utf16_to_str Gerd Hoffmann
@ 2018-11-30 11:12 ` Gerd Hoffmann
2018-11-30 19:08 ` Philippe Mathieu-Daudé
2018-11-30 20:08 ` Bandan Das
1 sibling, 2 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2018-11-30 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Slash is unix directory separator, so they are not allowed in filenames.
Note this also stops the classic escape via "../".
Fixes: CVE-2018-16867
Reported-by: Michael Hanselmann (hansmi.ch)
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/dev-mtp.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index fbe1ace035..87eeac1084 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -1718,6 +1718,12 @@ static void usb_mtp_write_metadata(MTPState *s)
filename = utf16_to_str(dataset->length, dataset->filename);
+ if (strchr(filename, '/')) {
+ usb_mtp_queue_result(s, RES_INVALID_PARAMETER, d->trans,
+ 0, 0, 0, 0);
+ return;
+ }
+
o = usb_mtp_object_lookup_name(p, filename, dataset->length);
if (o != NULL) {
next_handle = o->handle;
--
2.9.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH for-3.1 1/2] usb-mtp: fix utf16_to_str
2018-11-30 11:12 ` [Qemu-devel] [PATCH for-3.1 1/2] usb-mtp: fix utf16_to_str Gerd Hoffmann
@ 2018-11-30 13:13 ` Markus Armbruster
2018-11-30 19:58 ` Bandan Das
0 siblings, 1 reply; 10+ messages in thread
From: Markus Armbruster @ 2018-11-30 13:13 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann <kraxel@redhat.com> writes:
> Make utf16_to_str return an allocated string. Remove the assumtion that
> the number of string bytes equals the number of utf16 chars (which is
> only true for ascii chars). Instead call wcstombs twice, once to figure
> the storage size and once for the actual conversion (as suggested by the
> wcstombs manpage).
>
> Reported-by: Michael Hanselmann (hansmi.ch)
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> hw/usb/dev-mtp.c | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
> index 00a3691bae..fbe1ace035 100644
> --- a/hw/usb/dev-mtp.c
> +++ b/hw/usb/dev-mtp.c
> @@ -1593,17 +1593,22 @@ static void usb_mtp_cancel_packet(USBDevice *dev, USBPacket *p)
> fprintf(stderr, "%s\n", __func__);
> }
>
> -static void utf16_to_str(uint8_t len, uint16_t *arr, char *name)
> +static char *utf16_to_str(uint8_t len, uint16_t *arr)
> {
> - int count;
> - wchar_t *wstr = g_new0(wchar_t, len);
> + wchar_t *wstr = g_new0(wchar_t, len + 1);
> + int count, dlen;
> + char *dest;
>
> for (count = 0; count < len; count++) {
> wstr[count] = (wchar_t)arr[count];
> }
> + wstr[count] = 0;
>
> - wcstombs(name, wstr, len);
> + dlen = wcstombs(NULL, wstr, 0) + 1;
> + dest = g_malloc(dlen);
> + wcstombs(dest, wstr, dlen);
> g_free(wstr);
> + return dest;
> }
Preexisting: casting uint16_t to wchar_t is iffy for at least two
reasons:
* When wchar_t is UCS-4, things fall apart for surrogate pairs. For
instance, the surrogate pair
uint16_t arr = { 0xD834, 0xDD1E };
should map to the single wchar_t 0x1D11E.
* wchar_t needn't even be Unicode. It might well be on any host we care
for, but are you *sure*?
I guess g_utf16_to_utf8() would be differently wrong: it converts to
UTF-8, but we need to convert to the current locale's multibyte string.
>
> /* Wrapper around write, returns 0 on failure */
> @@ -1703,7 +1708,7 @@ static void usb_mtp_write_metadata(MTPState *s)
> {
> MTPData *d = s->data_out;
> ObjectInfo *dataset = (ObjectInfo *)d->data;
> - char *filename = g_new0(char, dataset->length);
> + char *filename;
> MTPObject *o;
> MTPObject *p = usb_mtp_object_lookup(s, s->dataset.parent_handle);
> uint32_t next_handle = s->next_handle;
> @@ -1711,7 +1716,7 @@ static void usb_mtp_write_metadata(MTPState *s)
> assert(!s->write_pending);
> assert(p != NULL);
>
> - utf16_to_str(dataset->length, dataset->filename, filename);
> + filename = utf16_to_str(dataset->length, dataset->filename);
>
> o = usb_mtp_object_lookup_name(p, filename, dataset->length);
> if (o != NULL) {
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH for-3.1 2/2] usb-mtp: outlaw slashes in filenames
2018-11-30 11:12 ` [Qemu-devel] [PATCH for-3.1 2/2] usb-mtp: outlaw slashes in filenames Gerd Hoffmann
@ 2018-11-30 19:08 ` Philippe Mathieu-Daudé
2018-11-30 19:58 ` Eric Blake
2018-11-30 20:08 ` Bandan Das
1 sibling, 1 reply; 10+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-11-30 19:08 UTC (permalink / raw)
To: Gerd Hoffmann, qemu-devel
On 30/11/18 12:12, Gerd Hoffmann wrote:
> Slash is unix directory separator, so they are not allowed in filenames.
> Note this also stops the classic escape via "../".
>
> Fixes: CVE-2018-16867
> Reported-by: Michael Hanselmann (hansmi.ch)
It's common for scripts to match '<email>', can you write this one as
Michael Hanselmann <hansmi.ch>?
(Same suggestion applies for patch 1/2).
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> hw/usb/dev-mtp.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
> index fbe1ace035..87eeac1084 100644
> --- a/hw/usb/dev-mtp.c
> +++ b/hw/usb/dev-mtp.c
> @@ -1718,6 +1718,12 @@ static void usb_mtp_write_metadata(MTPState *s)
>
> filename = utf16_to_str(dataset->length, dataset->filename);
>
> + if (strchr(filename, '/')) {
> + usb_mtp_queue_result(s, RES_INVALID_PARAMETER, d->trans,
> + 0, 0, 0, 0);
> + return;
> + }
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> +
> o = usb_mtp_object_lookup_name(p, filename, dataset->length);
> if (o != NULL) {
> next_handle = o->handle;
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH for-3.1 2/2] usb-mtp: outlaw slashes in filenames
2018-11-30 19:08 ` Philippe Mathieu-Daudé
@ 2018-11-30 19:58 ` Eric Blake
2018-12-01 11:55 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 10+ messages in thread
From: Eric Blake @ 2018-11-30 19:58 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, Gerd Hoffmann, qemu-devel
On 11/30/18 1:08 PM, Philippe Mathieu-Daudé wrote:
> On 30/11/18 12:12, Gerd Hoffmann wrote:
>> Slash is unix directory separator, so they are not allowed in filenames.
>> Note this also stops the classic escape via "../".
>>
>> Fixes: CVE-2018-16867
>> Reported-by: Michael Hanselmann (hansmi.ch)
>
> It's common for scripts to match '<email>', can you write this one as
> Michael Hanselmann <hansmi.ch>?
That's not an email address, though. Do we have an email for Michael, or
just a username?
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH for-3.1 1/2] usb-mtp: fix utf16_to_str
2018-11-30 13:13 ` Markus Armbruster
@ 2018-11-30 19:58 ` Bandan Das
0 siblings, 0 replies; 10+ messages in thread
From: Bandan Das @ 2018-11-30 19:58 UTC (permalink / raw)
To: Markus Armbruster; +Cc: Gerd Hoffmann, qemu-devel
Markus Armbruster <armbru@redhat.com> writes:
> Gerd Hoffmann <kraxel@redhat.com> writes:
>
>> Make utf16_to_str return an allocated string. Remove the assumtion that
>> the number of string bytes equals the number of utf16 chars (which is
>> only true for ascii chars). Instead call wcstombs twice, once to figure
>> the storage size and once for the actual conversion (as suggested by the
>> wcstombs manpage).
>>
>> Reported-by: Michael Hanselmann (hansmi.ch)
>> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>> ---
>> hw/usb/dev-mtp.c | 17 +++++++++++------
>> 1 file changed, 11 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
>> index 00a3691bae..fbe1ace035 100644
>> --- a/hw/usb/dev-mtp.c
>> +++ b/hw/usb/dev-mtp.c
>> @@ -1593,17 +1593,22 @@ static void usb_mtp_cancel_packet(USBDevice *dev, USBPacket *p)
>> fprintf(stderr, "%s\n", __func__);
>> }
>>
>> -static void utf16_to_str(uint8_t len, uint16_t *arr, char *name)
>> +static char *utf16_to_str(uint8_t len, uint16_t *arr)
>> {
>> - int count;
>> - wchar_t *wstr = g_new0(wchar_t, len);
>> + wchar_t *wstr = g_new0(wchar_t, len + 1);
>> + int count, dlen;
>> + char *dest;
>>
>> for (count = 0; count < len; count++) {
>> wstr[count] = (wchar_t)arr[count];
>> }
>> + wstr[count] = 0;
>>
>> - wcstombs(name, wstr, len);
>> + dlen = wcstombs(NULL, wstr, 0) + 1;
>> + dest = g_malloc(dlen);
>> + wcstombs(dest, wstr, dlen);
>> g_free(wstr);
>> + return dest;
>> }
>
> Preexisting: casting uint16_t to wchar_t is iffy for at least two
> reasons:
>
> * When wchar_t is UCS-4, things fall apart for surrogate pairs. For
> instance, the surrogate pair
>
> uint16_t arr = { 0xD834, 0xDD1E };
>
> should map to the single wchar_t 0x1D11E.
>
> * wchar_t needn't even be Unicode. It might well be on any host we care
> for, but are you *sure*?
>
> I guess g_utf16_to_utf8() would be differently wrong: it converts to
> UTF-8, but we need to convert to the current locale's multibyte string.
>
I couldn't find an existing function that I could safely reuse which was my first
preference. I will take a look at how to make this function better, maybe,
even see what other MTP implementations are doing in this regard.
Bandan
>>
>> /* Wrapper around write, returns 0 on failure */
>> @@ -1703,7 +1708,7 @@ static void usb_mtp_write_metadata(MTPState *s)
>> {
>> MTPData *d = s->data_out;
>> ObjectInfo *dataset = (ObjectInfo *)d->data;
>> - char *filename = g_new0(char, dataset->length);
>> + char *filename;
>> MTPObject *o;
>> MTPObject *p = usb_mtp_object_lookup(s, s->dataset.parent_handle);
>> uint32_t next_handle = s->next_handle;
>> @@ -1711,7 +1716,7 @@ static void usb_mtp_write_metadata(MTPState *s)
>> assert(!s->write_pending);
>> assert(p != NULL);
>>
>> - utf16_to_str(dataset->length, dataset->filename, filename);
>> + filename = utf16_to_str(dataset->length, dataset->filename);
>>
>> o = usb_mtp_object_lookup_name(p, filename, dataset->length);
>> if (o != NULL) {
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH for-3.1 2/2] usb-mtp: outlaw slashes in filenames
2018-11-30 11:12 ` [Qemu-devel] [PATCH for-3.1 2/2] usb-mtp: outlaw slashes in filenames Gerd Hoffmann
2018-11-30 19:08 ` Philippe Mathieu-Daudé
@ 2018-11-30 20:08 ` Bandan Das
1 sibling, 0 replies; 10+ messages in thread
From: Bandan Das @ 2018-11-30 20:08 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann <kraxel@redhat.com> writes:
> Slash is unix directory separator, so they are not allowed in filenames.
> Note this also stops the classic escape via "../".
>
> Fixes: CVE-2018-16867
> Reported-by: Michael Hanselmann (hansmi.ch)
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> hw/usb/dev-mtp.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
> index fbe1ace035..87eeac1084 100644
> --- a/hw/usb/dev-mtp.c
> +++ b/hw/usb/dev-mtp.c
> @@ -1718,6 +1718,12 @@ static void usb_mtp_write_metadata(MTPState *s)
>
> filename = utf16_to_str(dataset->length, dataset->filename);
>
> + if (strchr(filename, '/')) {
> + usb_mtp_queue_result(s, RES_INVALID_PARAMETER, d->trans,
> + 0, 0, 0, 0);
> + return;
> + }
> +
> o = usb_mtp_object_lookup_name(p, filename, dataset->length);
> if (o != NULL) {
> next_handle = o->handle;
Should we return PARAMETER_NOT_SUPPORTED instead of INVALID_PARAMETER ?
That's a valid response code for SendObjectInfo acc to the spec.
Bandan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH for-3.1 2/2] usb-mtp: outlaw slashes in filenames
2018-11-30 19:58 ` Eric Blake
@ 2018-12-01 11:55 ` Philippe Mathieu-Daudé
2018-12-01 13:49 ` Michael Hanselmann
0 siblings, 1 reply; 10+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-12-01 11:55 UTC (permalink / raw)
To: Eric Blake, Gerd Hoffmann, qemu-devel, Michael Hanselmann,
Michael Hanselmann
On 30/11/18 20:58, Eric Blake wrote:
> On 11/30/18 1:08 PM, Philippe Mathieu-Daudé wrote:
>> On 30/11/18 12:12, Gerd Hoffmann wrote:
>>> Slash is unix directory separator, so they are not allowed in filenames.
>>> Note this also stops the classic escape via "../".
>>>
>>> Fixes: CVE-2018-16867
>>> Reported-by: Michael Hanselmann (hansmi.ch)
>>
>> It's common for scripts to match '<email>', can you write this one as
>> Michael Hanselmann <hansmi.ch>?
>
> That's not an email address, though. Do we have an email for Michael, or
> just a username?
>
I did not notice hehe :)
Per the gpg key: Michael Hanselmann <public@hansmi.ch>
Per git commits: Michael Hanselmann <hansmi@vshn.ch>
Cc'ed him so he can decide/confirm.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH for-3.1 2/2] usb-mtp: outlaw slashes in filenames
2018-12-01 11:55 ` Philippe Mathieu-Daudé
@ 2018-12-01 13:49 ` Michael Hanselmann
0 siblings, 0 replies; 10+ messages in thread
From: Michael Hanselmann @ 2018-12-01 13:49 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, Eric Blake, Gerd Hoffmann,
qemu-devel, Michael Hanselmann
[-- Attachment #1: Type: text/plain, Size: 903 bytes --]
On 01.12.18 12:55, Philippe Mathieu-Daudé wrote:
> On 30/11/18 20:58, Eric Blake wrote:
>> On 11/30/18 1:08 PM, Philippe Mathieu-Daudé wrote:
>>> On 30/11/18 12:12, Gerd Hoffmann wrote:
>>>> Slash is unix directory separator, so they are not allowed in filenames.
>>>> Note this also stops the classic escape via "../".
>>>>
>>>> Fixes: CVE-2018-16867
>>>> Reported-by: Michael Hanselmann (hansmi.ch)
>>>
>>> It's common for scripts to match '<email>', can you write this one as
>>> Michael Hanselmann <hansmi.ch>?
>>
>> That's not an email address, though. Do we have an email for Michael, or
>> just a username?
>>
>
> I did not notice hehe :)
>
> Per the gpg key: Michael Hanselmann <public@hansmi.ch>
> Per git commits: Michael Hanselmann <hansmi@vshn.ch>
It'd be <public@hansmi.ch> for this one. Thanks for asking!
Best regards,
Michael
--
https://hansmi.ch/
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2018-12-01 13:50 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-30 11:12 [Qemu-devel] [PATCH for-3.1 0/2] usb-mtp: two bugfixes (one security fix) Gerd Hoffmann
2018-11-30 11:12 ` [Qemu-devel] [PATCH for-3.1 1/2] usb-mtp: fix utf16_to_str Gerd Hoffmann
2018-11-30 13:13 ` Markus Armbruster
2018-11-30 19:58 ` Bandan Das
2018-11-30 11:12 ` [Qemu-devel] [PATCH for-3.1 2/2] usb-mtp: outlaw slashes in filenames Gerd Hoffmann
2018-11-30 19:08 ` Philippe Mathieu-Daudé
2018-11-30 19:58 ` Eric Blake
2018-12-01 11:55 ` Philippe Mathieu-Daudé
2018-12-01 13:49 ` Michael Hanselmann
2018-11-30 20:08 ` Bandan Das
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).