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