From 4370ea0b21a8bcc4cd14de38a6fe1b29cbc92816a9cea6a2d66aee9f694b652a Mon Sep 17 00:00:00 2001 From: Dominique Leuenberger Date: Tue, 21 Nov 2017 15:31:34 +0000 Subject: [PATCH 1/2] Accepting request 543980 from home:mgorse:branches:GNOME:Factory - Add gvfs-mtp-handle-read-past-eof.patch: fix hang when transferring on some Android devices (boo#1069030 bgo#784477). OBS-URL: https://build.opensuse.org/request/show/543980 OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/gvfs?expand=0&rev=291 --- gvfs-mtp-handle-read-past-eof.patch | 62 +++++++++++++++++++++++++++++ gvfs.changes | 6 +++ gvfs.spec | 3 ++ 3 files changed, 71 insertions(+) create mode 100644 gvfs-mtp-handle-read-past-eof.patch diff --git a/gvfs-mtp-handle-read-past-eof.patch b/gvfs-mtp-handle-read-past-eof.patch new file mode 100644 index 0000000..0a197f0 --- /dev/null +++ b/gvfs-mtp-handle-read-past-eof.patch @@ -0,0 +1,62 @@ +From 091ac25d59d0dc0f5fed17510b0593bcd86e9fc9 Mon Sep 17 00:00:00 2001 +From: Philip Langdale +Date: Fri, 10 Nov 2017 07:59:42 -0800 +Subject: mtp: Handle read-past-EOF in GetPartialObject(64) + ourselves + +Up until very recently, the Android MTP driver did not do bounds checking +on reads past EOF, leading to undefined behaviour, which includes +hanging the transfer on some devices. + +According to Google engineers, this is fixed in the kernels used by +the Pixel and Pixel 2 (and this has been verified in testing), but +that basically means that every other Android device in existence has +this bug, and is unlikely to ever be fixed. + +So, we need to enforce POSIX semantics ourselves and truncate reads +past EOF. libmtp has implemented a check, but we should validate as +well so that we have working behaviour without requiring a libmtp +update. + +https://bugzilla.gnome.org/show_bug.cgi?id=784477 +--- + daemon/gvfsbackendmtp.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/daemon/gvfsbackendmtp.c b/daemon/gvfsbackendmtp.c +index 2a418a2a..a606ec2c 100644 +--- a/daemon/gvfsbackendmtp.c ++++ b/daemon/gvfsbackendmtp.c +@@ -2444,6 +2444,21 @@ do_read (GVfsBackend *backend, + goto exit; + } + ++ /* ++ * Almost all android devices have a bug where they do not enforce ++ * POSIX semantics for read past EOF, leading to undefined ++ * behaviour including device-side hangs. We'd better handle it ++ * here. ++ */ ++ if (offset >= handle->size) { ++ g_debug ("(II) skipping read with offset past EOF\n"); ++ actual = 0; ++ goto finished; ++ } else if (offset + bytes_requested > handle->size) { ++ g_debug ("(II) reducing bytes_requested to avoid reading past EOF\n"); ++ bytes_requested = handle->size - offset; ++ } ++ + unsigned char *temp; + int ret = LIBMTP_GetPartialObject (G_VFS_BACKEND_MTP (backend)->device, id, offset, + bytes_requested, &temp, &actual); +@@ -2464,6 +2479,7 @@ do_read (GVfsBackend *backend, + memcpy (buffer, bytes->data + offset, actual); + } + ++ finished: + handle->offset = offset + actual; + g_vfs_job_read_set_size (job, actual); + g_vfs_job_succeeded (G_VFS_JOB (job)); +-- +2.15.0 + diff --git a/gvfs.changes b/gvfs.changes index c861b05..04d78d2 100644 --- a/gvfs.changes +++ b/gvfs.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Mon Nov 20 19:41:56 UTC 2017 - mgorse@suse.com + +- Add gvfs-mtp-handle-read-past-eof.patch: fix hang when + transferring on some Android devices (boo#1069030 bgo#784477). + ------------------------------------------------------------------- Wed Nov 15 12:23:18 UTC 2017 - zaitor@opensuse.org diff --git a/gvfs.spec b/gvfs.spec index 6b4e0fc..33505af 100644 --- a/gvfs.spec +++ b/gvfs.spec @@ -29,6 +29,8 @@ Source0: http://download.gnome.org/sources/gvfs/1.34/%{name}-%{version}.t Source99: baselibs.conf # PATCH-FIX-UPSTREAM gvfs-fix-mtp-volume-removal.patch bgo#789491 zaitor@opensuse.org -- Fix various mtp issues with volume management Patch0: gvfs-fix-mtp-volume-removal.patch +# PATCH-FIX-UPSTREAM gvfs-mtp-handle-read-past-eof.patch boo#1069030 bgo#784477 mgorse@suse.com -- fix hang when transferring on some Android devices. +Patch1: gvfs-mtp-handle-read-past-eof.patch # PATCH-FEATURE-SLE gvfs-nvvfs.patch ksamrat@novell.com -- Provides gvfs backend for novell nautilus plugin Patch5: gvfs-nvvfs.patch # PATCH-FEATURE-SLE gvfs-nds.patch ksamrat@novell.com -- Provides NDS browsing for nautilus @@ -170,6 +172,7 @@ gvfs plugins. %prep %setup -q %patch0 -p1 +%patch1 -p1 %if !0%{?is_opensuse} translation-update-upstream %patch5 -p1 From c9206dd81538e75fc73d810679ea4e1af401294c04b76841810bcb9c2928e8e1 Mon Sep 17 00:00:00 2001 From: Dominique Leuenberger Date: Wed, 22 Nov 2017 11:03:03 +0000 Subject: [PATCH 2/2] - Disable caps(cap_net_bind_service=+ep) from gvfsd-nfs: this is not acceptable from a security PoV, see boo#1065864#c6). OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/gvfs?expand=0&rev=292 --- gvfs.changes | 6 ++++++ gvfs.spec | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/gvfs.changes b/gvfs.changes index 04d78d2..426d9c6 100644 --- a/gvfs.changes +++ b/gvfs.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Wed Nov 22 11:01:59 UTC 2017 - dimstar@opensuse.org + +- Disable caps(cap_net_bind_service=+ep) from gvfsd-nfs: this is + not acceptable from a security PoV, see boo#1065864#c6). + ------------------------------------------------------------------- Mon Nov 20 19:41:56 UTC 2017 - mgorse@suse.com diff --git a/gvfs.spec b/gvfs.spec index 33505af..d84a298 100644 --- a/gvfs.spec +++ b/gvfs.spec @@ -328,8 +328,9 @@ find %{buildroot}%{_libdir} -type f -name '*.la' -delete -print %{_libexecdir}/%{name}/gvfsd-network %{_datadir}/%{name}/mounts/network.mount %if 0%{?is_opensuse} -# allow priv ports for mounting nfs . Otherwise the nfs-service requires insecure -%caps(cap_net_bind_service=+ep) %{_libexecdir}/%{name}/gvfsd-nfs +# allow priv ports for mounting nfs . Otherwise the nfs-service requires insecure, not approved by sec, see boo#1065864 +# %caps(cap_net_bind_service=+ep) %{_libexecdir}/%{name}/gvfsd-nfs +%{_libexecdir}/%{name}/gvfsd-nfs %{_datadir}/%{name}/mounts/nfs.mount %endif %if !0%{?is_opensuse}