8abcb1d6b2
Include security fixes and other recent "stable" fixes OBS-URL: https://build.opensuse.org/request/show/664459 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=445
80 lines
2.7 KiB
Diff
80 lines
2.7 KiB
Diff
From: Gerd Hoffmann <kraxel@redhat.com>
|
|
Date: Thu, 13 Dec 2018 13:25:11 +0100
|
|
Subject: usb-mtp: use O_NOFOLLOW and O_CLOEXEC.
|
|
|
|
Open files and directories with O_NOFOLLOW to avoid symlinks attacks.
|
|
While being at it also add O_CLOEXEC.
|
|
|
|
usb-mtp only handles regular files and directories and ignores
|
|
everything else, so users should not see a difference.
|
|
|
|
Because qemu ignores symlinks, carrying out a successful symlink attack
|
|
requires swapping an existing file or directory below rootdir for a
|
|
symlink and winning the race against the inotify notification to qemu.
|
|
|
|
Fixes: CVE-2018-16872
|
|
Cc: Prasad J Pandit <ppandit@redhat.com>
|
|
Cc: Bandan Das <bsd@redhat.com>
|
|
Reported-by: Michael Hanselmann <public@hansmi.ch>
|
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
Reviewed-by: Michael Hanselmann <public@hansmi.ch>
|
|
Message-id: 20181213122511.13853-1-kraxel@redhat.com
|
|
(cherry picked from commit bab9df35ce73d1c8e19a37e2737717ea1c984dc1)
|
|
[BR: BSC#1119493]
|
|
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
|
---
|
|
hw/usb/dev-mtp.c | 13 +++++++++----
|
|
1 file changed, 9 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
|
|
index 100b7171f4..36c43b8c20 100644
|
|
--- a/hw/usb/dev-mtp.c
|
|
+++ b/hw/usb/dev-mtp.c
|
|
@@ -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);
|