sys-fs/mtpfs: a huge robustification patchset by W. Trevor King!
authorSergei Trofimovich <slyfox@gentoo.org>
Mon, 28 Sep 2015 21:30:23 +0000 (22:30 +0100)
committerSergei Trofimovich <slyfox@gentoo.org>
Mon, 28 Sep 2015 21:31:10 +0000 (22:31 +0100)
Package-Manager: portage-2.2.22

sys-fs/mtpfs/files/mtpfs-1.1-g_printf.patch [new file with mode: 0644]
sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0001-Use-GMutex-instead-of-GStaticMutex.patch [new file with mode: 0644]
sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0002-Free-rawdevices-after-opening-the-connected-device.patch [new file with mode: 0644]
sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0003-Allocate-additional-byte-for-trailing-null.patch [new file with mode: 0644]
sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0004-Use-storageid-to-access-storageArea.patch [new file with mode: 0644]
sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0005-Use-O_ACCMODE-to-pull-out-the-access-portion-of-the-.patch [new file with mode: 0644]
sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0006-Check-for-find_storage-failures.patch [new file with mode: 0644]
sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0007-Use-path-instead-of-fields-0-for-find_storage.patch [new file with mode: 0644]
sys-fs/mtpfs/mtpfs-1.1-r3.ebuild [new file with mode: 0644]

diff --git a/sys-fs/mtpfs/files/mtpfs-1.1-g_printf.patch b/sys-fs/mtpfs/files/mtpfs-1.1-g_printf.patch
new file mode 100644 (file)
index 0000000..21e08c8
--- /dev/null
@@ -0,0 +1,10 @@
+diff --git a/mtpfs.h b/mtpfs.h
+index f9532fa..1042a3d 100644
+--- a/mtpfs.h
++++ b/mtpfs.h
+@@ -32,2 +32,5 @@
+ #endif
++#ifdef DEBUG
++#include <glib/gprintf.h>
++#endif
diff --git a/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0001-Use-GMutex-instead-of-GStaticMutex.patch b/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0001-Use-GMutex-instead-of-GStaticMutex.patch
new file mode 100644 (file)
index 0000000..9c1970b
--- /dev/null
@@ -0,0 +1,49 @@
+From 39872d8ff354c40d881f416e3b8b6df911379d37 Mon Sep 17 00:00:00 2001
+From: "W. Trevor King" <wking@tremily.us>
+Date: Sun, 23 Aug 2015 12:05:35 -0700
+Subject: [PATCH 1/7] Use GMutex instead of GStaticMutex
+
+The static version was deprecated in GLib 2.32 [1], which was released
+on 2012-03-24 [2].  The difference between the two was that before
+2.32, GMutex could not be statically allocated.  Since 2.32, GMutex
+can be statically allocated, so there's no reason to use GStaticMutex
+anymore.
+
+[1]: https://developer.gnome.org/glib/unstable/glib-Deprecated-Thread-APIs.html#GStaticMutex
+[2]: https://git.gnome.org/browse/glib/tag/?h=glib-2-32&id=2.32.0
+---
+ mtpfs.c | 4 ++--
+ mtpfs.h | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/mtpfs.c b/mtpfs.c
+index 553d282..286cd24 100644
+--- a/mtpfs.c
++++ b/mtpfs.c
+@@ -28,8 +28,8 @@ static void dump_mtp_error()
+ #define dump_mtp_error()
+ #endif
+-#define enter_lock(a...)       do { DBG("lock"); DBG(a); g_static_mutex_lock(&device_lock); } while(0)
+-#define return_unlock(a)       do { DBG("return unlock"); g_static_mutex_unlock(&device_lock); return a; } while(0)
++#define enter_lock(a...)       do { DBG("lock"); DBG(a); g_mutex_lock(&device_lock); } while(0)
++#define return_unlock(a)       do { DBG("return unlock"); g_mutex_unlock(&device_lock); return a; } while(0)
+ void
+ free_files(LIBMTP_file_t *filelist)
+diff --git a/mtpfs.h b/mtpfs.h
+index 789eccb..f812ea6 100644
+--- a/mtpfs.h
++++ b/mtpfs.h
+@@ -73,7 +73,7 @@ static GSList *lostfiles = NULL;
+ static GSList *myfiles = NULL;
+ static LIBMTP_playlist_t *playlists = NULL;
+ static gboolean playlists_changed = FALSE;
+-static GStaticMutex device_lock = G_STATIC_MUTEX_INIT;
++static GMutex device_lock = G_STATIC_MUTEX_INIT;
+ #endif /* _MTPFS_H_ */
+-- 
+2.5.3
+
diff --git a/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0002-Free-rawdevices-after-opening-the-connected-device.patch b/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0002-Free-rawdevices-after-opening-the-connected-device.patch
new file mode 100644 (file)
index 0000000..42089d5
--- /dev/null
@@ -0,0 +1,28 @@
+From 2fb900e9e915f9ec6ac2f233255a0a527da164c2 Mon Sep 17 00:00:00 2001
+From: "W. Trevor King" <wking@tremily.us>
+Date: Sun, 23 Aug 2015 21:59:45 -0700
+Subject: [PATCH 2/7] Free rawdevices after opening the connected device
+
+Avoid leaking the raw-device memory.  For a similar example in the
+libmtp source, see LIBMTP_Get_First_Device [1].
+
+[1]: http://sourceforge.net/p/libmtp/code/ci/libmtp-1-1-9/tree/src/libmtp.c#l1690
+---
+ mtpfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/mtpfs.c b/mtpfs.c
+index 286cd24..bdd5f46 100644
+--- a/mtpfs.c
++++ b/mtpfs.c
+@@ -1390,6 +1390,7 @@ main (int argc, char *argv[])
+     fprintf(stdout, "Attempting to connect device\n");
+     device = LIBMTP_Open_Raw_Device(&rawdevices[i]);
++    free (rawdevices);
+     if (device == NULL) {
+         fprintf(stderr, "Unable to open raw device %d\n", i);
+         return 1;
+-- 
+2.5.3
+
diff --git a/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0003-Allocate-additional-byte-for-trailing-null.patch b/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0003-Allocate-additional-byte-for-trailing-null.patch
new file mode 100644 (file)
index 0000000..20cff00
--- /dev/null
@@ -0,0 +1,55 @@
+From 3929648c83910a45a37e84b4d3e5316631ce7c6b Mon Sep 17 00:00:00 2001
+From: "W. Trevor King" <wking@tremily.us>
+Date: Mon, 24 Aug 2015 00:08:24 -0700
+Subject: [PATCH 3/7] Allocate additional byte for trailing null
+
+These variables needs a byte for every character in the path and an
+additional trailing null, but the length returned by strlen excludes
+the trailing null.
+---
+ mtpfs.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/mtpfs.c b/mtpfs.c
+index bdd5f46..e31acd9 100644
+--- a/mtpfs.c
++++ b/mtpfs.c
+@@ -416,7 +416,7 @@ parse_path (const gchar * path)
+     LIBMTP_folder_t *folder;
+     gchar **fields;
+     gchar *directory;
+-    directory = (gchar *) g_malloc (strlen (path));
++  directory = (gchar *) g_malloc (strlen (path) + 1);
+     directory = strcpy (directory, "");
+     fields = g_strsplit (path, "/", -1);
+     res = -ENOENT;
+@@ -488,7 +488,7 @@ mtpfs_release (const char *path, struct fuse_file_info *fi)
+             gchar *filename = g_strdup("");
+             gchar **fields;
+             gchar *directory;
+-            directory = (gchar *) g_malloc (strlen (path));
++        directory = (gchar *) g_malloc (strlen (path) + 1);
+             directory = strcpy (directory, "/");
+             fields = g_strsplit (path, "/", -1);
+             int i;
+@@ -1089,7 +1089,7 @@ mtpfs_mkdir_real (const char *path, mode_t mode)
+         gchar **fields;
+         gchar *directory;
+       
+-        directory = (gchar *) g_malloc (strlen (path));
++      directory = (gchar *) g_malloc (strlen (path) + 1);
+         directory = strcpy (directory, "/");
+         fields = g_strsplit (path, "/", -1);
+         int i;
+@@ -1168,7 +1168,7 @@ mtpfs_rename (const char *oldname, const char *newname)
+     gchar *filename;
+     gchar **fields;
+     gchar *directory;
+-    directory = (gchar *) g_malloc (strlen (newname));
++    directory = (gchar *) g_malloc (strlen (newname) + 1);
+     directory = strcpy (directory, "/");
+     fields = g_strsplit (newname, "/", -1);
+     int i;
+-- 
+2.5.3
+
diff --git a/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0004-Use-storageid-to-access-storageArea.patch b/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0004-Use-storageid-to-access-storageArea.patch
new file mode 100644 (file)
index 0000000..755e290
--- /dev/null
@@ -0,0 +1,42 @@
+From 89ec461a73a2479fb5766b6b65a44e6e5b699b94 Mon Sep 17 00:00:00 2001
+From: "W. Trevor King" <wking@tremily.us>
+Date: Mon, 24 Aug 2015 00:34:41 -0700
+Subject: [PATCH 4/7] Use storageid to access storageArea
+
+'i' is indexing playlist->tracks here, and we don't want to look in a
+sequential storage areas for each track.
+
+I've also added a null-folder check.  I'm not sure if -ENOENT is the
+right code for "we can't find the parent directory in the storage area
+that contains the child", but it's the only non-success code that
+mtpfs_getattr_real returned before this commit.  And returning
+anything is probably better than segfaulting when we try and
+dereference folder with 'folder->parent_id'.  I've added a logging
+message to help debug things when we do get a null folder.
+---
+ mtpfs.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/mtpfs.c b/mtpfs.c
+index e31acd9..9f924a9 100644
+--- a/mtpfs.c
++++ b/mtpfs.c
+@@ -832,7 +832,14 @@ mtpfs_getattr_real (const gchar * path, struct stat *stbuf)
+                         filesize = filesize + strlen(file->filename) + 2;
+                         while (parent_id != 0) {
+                             check_folders();
+-                            folder = LIBMTP_Find_Folder(storageArea[i].folders,parent_id);
++                            folder =
++                              LIBMTP_Find_Folder
++                              (storageArea[storageid].folders, parent_id);
++                            if (folder == NULL) {
++                              DBG ("could not find %d in storage-area %d",
++                                   parent_id, storageid);
++                              return -ENOENT;
++                            }
+                             parent_id = folder->parent_id;
+                             filesize = filesize + strlen(folder->name) + 1;
+                         }
+-- 
+2.5.3
+
diff --git a/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0005-Use-O_ACCMODE-to-pull-out-the-access-portion-of-the-.patch b/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0005-Use-O_ACCMODE-to-pull-out-the-access-portion-of-the-.patch
new file mode 100644 (file)
index 0000000..03bfb4c
--- /dev/null
@@ -0,0 +1,46 @@
+From 00bd3be1310fb36a3b2eddc931eb48c89744b2b4 Mon Sep 17 00:00:00 2001
+From: "W. Trevor King" <wking@tremily.us>
+Date: Mon, 24 Aug 2015 01:31:17 -0700
+Subject: [PATCH 5/7] Use O_ACCMODE to pull out the access portion of the open
+ flags
+
+Following [1].  I'm using cp from GNU Coreutils 8.23, and it's setting
+my flags to 32769 (O_WRONLY + 0x8000).
+
+[1]: http://www.gnu.org/software/libc/manual/html_node/Access-Modes.html#index-0_005fACCMODE
+---
+ mtpfs.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/mtpfs.c b/mtpfs.c
+index 9f924a9..a82d479 100644
+--- a/mtpfs.c
++++ b/mtpfs.c
+@@ -949,12 +949,18 @@ mtpfs_open (const gchar * path, struct fuse_file_info *fi)
+     if (item_id < 0)
+         return_unlock(-ENOENT);
+-    if (fi->flags == O_RDONLY) {
+-        DBG("read");
+-    } else if (fi->flags == O_WRONLY) {
+-        DBG("write");
+-    } else if (fi->flags == O_RDWR) {
+-        DBG("rdwrite");
++    switch (fi->flags & O_ACCMODE) {
++    case O_RDONLY:
++      DBG ("read");
++      break;
++    case O_WRONLY:
++      DBG ("write");
++      break;
++    case O_RDWR:
++      DBG("rdwrite");
++      break;
++    default:
++      DBG ("unexpected access mode: %d", fi->flags & O_ACCMODE);
+     }
+     int storageid;
+-- 
+2.5.3
+
diff --git a/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0006-Check-for-find_storage-failures.patch b/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0006-Check-for-find_storage-failures.patch
new file mode 100644 (file)
index 0000000..84fb346
--- /dev/null
@@ -0,0 +1,109 @@
+From 8860e176c8fb38006dc58516a5e5d9a1aab7be49 Mon Sep 17 00:00:00 2001
+From: "W. Trevor King" <wking@tremily.us>
+Date: Mon, 24 Aug 2015 01:07:49 -0700
+Subject: [PATCH 6/7] Check for find_storage failures
+
+Instead of just blindly using storageArea[-1].
+---
+ mtpfs.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/mtpfs.c b/mtpfs.c
+index a82d479..3fe17b8 100644
+--- a/mtpfs.c
++++ b/mtpfs.c
+@@ -317,6 +317,7 @@ find_storage(const gchar * path)
+             }
+         }
+     }
++    DBG ("could not find storage for %s", path);
+     return -1;
+ }
+@@ -422,6 +423,9 @@ parse_path (const gchar * path)
+     res = -ENOENT;
+     int storageid;
+     storageid = find_storage(path);
++    if (storageid < 0) {
++        return res;
++    }
+     for (i = 0; fields[i] != NULL; i++) {
+         if (strlen (fields[i]) > 0) {
+             if (fields[i + 1] != NULL) {
+@@ -495,6 +499,9 @@ mtpfs_release (const char *path, struct fuse_file_info *fi)
+             int parent_id = 0;
+             int storageid;
+             storageid = find_storage(fields[0]);
++            if (storageid < 0) {
++                return_unlock (-ENOENT);
++            }
+             for (i = 0; fields[i] != NULL; i++) {
+                 if (strlen (fields[i]) > 0) {
+                     if (fields[i + 1] == NULL) {
+@@ -715,6 +722,9 @@ mtpfs_readdir (const gchar * path, void *buf, fuse_fill_dir_t filler,
+     int i;
+     int storageid = -1;
+     storageid=find_storage(path);
++    if (storageid < 0) {
++        return_unlock (-ENOENT);
++    }
+     // Get folder listing.
+     int folder_id = 0;
+     if (strcmp (path, "/") != 0) {
+@@ -812,6 +822,9 @@ mtpfs_getattr_real (const gchar * path, struct stat *stbuf)
+     int storageid;
+     storageid=find_storage(path);
++    if (storageid < 0) {
++        return -ENOENT;
++    }
+     if (g_ascii_strncasecmp (path, "/Playlists",10) == 0) {
+         LIBMTP_playlist_t *playlist;
+@@ -965,6 +978,9 @@ mtpfs_open (const gchar * path, struct fuse_file_info *fi)
+     int storageid;
+     storageid=find_storage(path);
++    if (storageid < 0) {
++        return_unlock (-ENOENT);
++    }
+     FILE *filetmp = tmpfile ();
+     int tmpfile = fileno (filetmp);
+     if (tmpfile != -1) {
+@@ -1096,6 +1112,9 @@ mtpfs_mkdir_real (const char *path, mode_t mode)
+     item = g_slist_find_custom (myfiles, path, (GCompareFunc) strcmp);
+     int item_id = parse_path (path);
+     int storageid = find_storage(path);
++    if (storageid < 0) {
++        return_unlock (-ENOENT);
++    }
+     if ((item == NULL) && (item_id < 0)) {
+         // Split path and find parent_id
+         gchar *filename = g_strdup("");
+@@ -1161,6 +1180,9 @@ mtpfs_rmdir (const char *path)
+         return_unlock(0);
+     }
+     int storageid=find_storage(path);
++    if (storageid < 0) {
++        return_unlock (-ENOENT);
++    }
+     folder_id = lookup_folder_id (storageArea[storageid].folders, (gchar *) path, NULL);
+     if (folder_id < 0)
+         return_unlock(-ENOENT);
+@@ -1223,7 +1245,13 @@ mtpfs_rename (const char *oldname, const char *newname)
+     LIBMTP_file_t *file;
+       
+     int storageid_old=find_storage(oldname);
++    if (storageid_old < 0) {
++        return_unlock (-ENOENT);
++    }
+     int storageid_new=find_storage(newname);
++    if (storageid_new < 0) {
++        return_unlock (-ENOENT);
++    }
+     if (strcmp (oldname, "/") != 0) {
+         folder_id = lookup_folder_id (storageArea[storageid_old].folders, (gchar *) oldname, NULL);
+     }
+-- 
+2.5.3
+
diff --git a/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0007-Use-path-instead-of-fields-0-for-find_storage.patch b/sys-fs/mtpfs/files/mtpfs-1.1-wking-patches/0007-Use-path-instead-of-fields-0-for-find_storage.patch
new file mode 100644 (file)
index 0000000..b524391
--- /dev/null
@@ -0,0 +1,29 @@
+From 76ff042e1334fdbef9803ea71b5d8b1d380efd7e Mon Sep 17 00:00:00 2001
+From: "W. Trevor King" <wking@tremily.us>
+Date: Mon, 24 Aug 2015 20:58:26 -0700
+Subject: [PATCH 7/7] Use 'path' instead of 'fields[0]' for find_storage
+
+When my path is '/Internal storage/Music/...', fields[0] will be an
+empty string, and find_storage will fail to find a storage area that
+matches that empty string.  All of our other find_storage calls use
+the full path, so follow that example here.
+---
+ mtpfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mtpfs.c b/mtpfs.c
+index 3fe17b8..291f49d 100644
+--- a/mtpfs.c
++++ b/mtpfs.c
+@@ -498,7 +498,7 @@ mtpfs_release (const char *path, struct fuse_file_info *fi)
+             int i;
+             int parent_id = 0;
+             int storageid;
+-            storageid = find_storage(fields[0]);
++            storageid = find_storage(path);
+             if (storageid < 0) {
+                 return_unlock (-ENOENT);
+             }
+-- 
+2.5.3
+
diff --git a/sys-fs/mtpfs/mtpfs-1.1-r3.ebuild b/sys-fs/mtpfs/mtpfs-1.1-r3.ebuild
new file mode 100644 (file)
index 0000000..d16925f
--- /dev/null
@@ -0,0 +1,57 @@
+# Copyright 1999-2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+EAPI=5
+
+inherit eutils
+
+DESCRIPTION="A FUSE filesystem providing access to MTP devices"
+HOMEPAGE="http://www.adebenham.com/mtpfs/"
+SRC_URI="http://www.adebenham.com/files/mtp/${P}.tar.gz"
+
+LICENSE="GPL-3"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+IUSE="debug mad"
+
+RDEPEND="dev-libs/glib:2
+       >=media-libs/libmtp-1.1.2
+       sys-fs/fuse
+       mad? (
+               media-libs/libid3tag
+               media-libs/libmad
+       )"
+DEPEND="${RDEPEND}
+       virtual/pkgconfig"
+
+DOCS=(AUTHORS NEWS README)
+
+src_prepare() {
+       sed -e "/#include <string.h>/ a\
+               #include <stdlib.h>" -i mtpfs.h id3read.c || die #implicit
+
+       epatch "${FILESDIR}"/${P}-fix-mutex-crash.patch
+       epatch "${FILESDIR}"/${P}-unitialized-variable.patch
+       epatch "${FILESDIR}"/${P}-wking-patches/*.patch
+       epatch "${FILESDIR}"/${P}-g_printf.patch
+}
+
+src_configure() {
+       econf $(use_enable debug) \
+               $(use_enable mad)
+}
+
+pkg_postinst() {
+       einfo "To mount your MTP device, issue:"
+       einfo "    /usr/bin/mtpfs <mountpoint>"
+       echo
+       einfo "To unmount your MTP device, issue:"
+       einfo "    /usr/bin/fusermount -u <mountpoint>"
+
+       if use debug; then
+               echo
+               einfo "You have enabled debugging output."
+               einfo "Please make sure you run mtpfs with the -d flag."
+       fi
+}