From b9bd8cd47d14091429c89bf4a6f5e9850cbb7e08 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Mon, 16 Jul 2018 21:12:12 -0500 Subject: [PATCH 1/7] Improve code style in _xdg_mime_cache_get_mime_type_for_file This just adds a missing space. https://bugs.freedesktop.org/show_bug.cgi?id=100733 --- src/xdgmimecache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xdgmimecache.c b/src/xdgmimecache.c index 0ecaa4f..ef2d2d2 100644 --- a/src/xdgmimecache.c +++ b/src/xdgmimecache.c @@ -785,7 +785,7 @@ _xdg_mime_cache_get_mime_type_for_file (const char *file_name, mime_types, n); if (!mime_type) - mime_type = _xdg_binary_or_text_fallback(data, bytes_read); + mime_type = _xdg_binary_or_text_fallback (data, bytes_read); free (data); fclose (file); -- 2.17.1 From a3853c12b048958707b21b712e53b46c0c20cd5e Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Mon, 16 Jul 2018 21:12:35 -0500 Subject: [PATCH 2/7] Fix use after free in xdg_mime_get_mime_type_for_file Here we free data right before passing it to _xdg_binary_or_text_fallback(), which is not good. This fix aligns the code with _xdg_mime_cache_get_mime_type_for_file(), where it is duplicated but without this bug. This commit is based on a patch to Chromium's xdgmime from https://codereview.chromium.org/1037023002. https://bugs.freedesktop.org/show_bug.cgi?id=100733 --- src/xdgmime.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xdgmime.c b/src/xdgmime.c index c7b16bb..f99f09b 100644 --- a/src/xdgmime.c +++ b/src/xdgmime.c @@ -558,13 +558,13 @@ xdg_mime_get_mime_type_for_file (const char *file_name, mime_type = _xdg_mime_magic_lookup_data (global_magic, data, bytes_read, NULL, mime_types, n); + if (!mime_type) + mime_type = _xdg_binary_or_text_fallback (data, bytes_read); + free (data); fclose (file); - if (mime_type) - return mime_type; - - return _xdg_binary_or_text_fallback(data, bytes_read); + return mime_type; } const char * -- 2.17.1 From 6c400e95cbc1d64d77d7df46c51df1696373df50 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Mon, 16 Jul 2018 21:16:03 -0500 Subject: [PATCH 3/7] Fix invalid pointer arithmetic in cache_magic_matchlet_compare_to_data() It's illegal to perform pointer arithmetic on void* pointers, so cast it first. https://bugs.webkit.org/show_bug.cgi?id=171026 https://bugs.freedesktop.org/show_bug.cgi?id=100733 --- src/xdgmimecache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xdgmimecache.c b/src/xdgmimecache.c index ef2d2d2..6b198e3 100644 --- a/src/xdgmimecache.c +++ b/src/xdgmimecache.c @@ -194,7 +194,7 @@ cache_magic_matchlet_compare_to_data (XdgMimeCache *cache, } else { - valid_matchlet = memcmp(cache->buffer + data_offset, data + i, data_length) == 0; + valid_matchlet = memcmp(cache->buffer + data_offset, (unsigned char *)data + i, data_length) == 0; } if (valid_matchlet) -- 2.17.1 From 3b5b05fc11f4102cb87a88142037e63351cb9d3e Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Mon, 16 Jul 2018 21:24:14 -0500 Subject: [PATCH 4/7] Don't forget to free resources on an early return This just adds a missing free that Matthias noticed seven years ago in https://gitlab.gnome.org/GNOME/glib/commit/83d34f630939aa13539e03895bef87da738c4127. https://bugs.freedesktop.org/show_bug.cgi?id=100733 --- src/xdgmimemagic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/xdgmimemagic.c b/src/xdgmimemagic.c index a2320f5..6cfe4b4 100644 --- a/src/xdgmimemagic.c +++ b/src/xdgmimemagic.c @@ -272,7 +272,10 @@ _xdg_mime_magic_parse_header (FILE *magic_file, XdgMimeMagicMatch *match) buffer = (char *)_xdg_mime_magic_read_to_newline (magic_file, &end_of_file); if (end_of_file) - return XDG_MIME_MAGIC_EOF; + { + free (buffer); + return XDG_MIME_MAGIC_EOF; + } end_ptr = buffer; while (*end_ptr != ']' && *end_ptr != '\000' && *end_ptr != '\n') -- 2.17.1 From e7f0e67fbc45dca7818d964c1ff996be8fc0ec28 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Mon, 16 Jul 2018 21:28:45 -0500 Subject: [PATCH 5/7] Handle EINTR in open() As noted by Colin in https://gitlab.gnome.org/GNOME/glib/commit/2542b6f60492fadfb21f2c4a29976c3494c7e6c5, we must handle EINTR when calling open(). https://bugs.freedesktop.org/show_bug.cgi?id=100733 --- src/xdgmimecache.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/xdgmimecache.c b/src/xdgmimecache.c index 6b198e3..d88fc47 100644 --- a/src/xdgmimecache.c +++ b/src/xdgmimecache.c @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -120,7 +121,11 @@ _xdg_mime_cache_new_from_file (const char *file_name) int minor; /* Open the file and map it into memory */ - fd = open (file_name, O_RDONLY|_O_BINARY, 0); + do + { + fd = open (file_name, O_RDONLY|_O_BINARY, 0); + } + while (fd == -1 && errno == EINTR); if (fd < 0) return NULL; -- 2.17.1 From dc5724e2a9a470b6553cdcf0f13413683a3e1913 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Mon, 16 Jul 2018 21:36:06 -0500 Subject: [PATCH 6/7] Fix special case for mime_type_subclass As noted by Alexandru Pandelea in https://gitlab.gnome.org/GNOME/glib/commit/eb7b796bd206c31e336c89fb828a8a343ffb34ba, the inode/* mime types are not subclasses of application/octet-stream, unlike all other mime types. The code is missing this check. https://bugs.freedesktop.org/show_bug.cgi?id=100733 --- src/xdgmime.c | 3 ++- src/xdgmimecache.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/xdgmime.c b/src/xdgmime.c index f99f09b..d48d733 100644 --- a/src/xdgmime.c +++ b/src/xdgmime.c @@ -784,7 +784,8 @@ _xdg_mime_mime_type_subclass (const char *mime, strncmp (umime, "text/", 5) == 0) return 1; - if (strcmp (ubase, "application/octet-stream") == 0) + if (strcmp (ubase, "application/octet-stream") == 0 && + strncmp (umime, "inode/", 6) != 0) return 1; parents = _xdg_mime_parent_list_lookup (parent_list, umime); diff --git a/src/xdgmimecache.c b/src/xdgmimecache.c index d88fc47..53aaccc 100644 --- a/src/xdgmimecache.c +++ b/src/xdgmimecache.c @@ -863,7 +863,8 @@ _xdg_mime_cache_mime_type_subclass (const char *mime, strncmp (umime, "text/", 5) == 0) return 1; - if (strcmp (ubase, "application/octet-stream") == 0) + if (strcmp (ubase, "application/octet-stream") == 0 && + strncmp (umime, "inode/", 6) != 0) return 1; for (i = 0; _caches[i]; i++) -- 2.17.1 From 5203fb09e07836ce52c5744ea4579f42f2b185e4 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Mon, 16 Jul 2018 21:42:52 -0500 Subject: [PATCH 7/7] Fix buffer underflow in __gio_xdg_cache_mime_type_subclass() Kalev noted in https://gitlab.gnome.org/GNOME/glib/commit/be7f40185fb2ce884112c1f8a4b196ea65350466 that we have a buffer underflow here in case the length of the MIME type is less than two (in which case we wind up accessing negative indices of the mime string). https://bugzilla.gnome.org/show_bug.cgi?id=708529 https://bugs.freedesktop.org/show_bug.cgi?id=100733 --- src/xdgmime.c | 19 ++++++++++++++----- src/xdgmimecache.c | 19 ++++++++++++++----- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/xdgmime.c b/src/xdgmime.c index d48d733..845aee1 100644 --- a/src/xdgmime.c +++ b/src/xdgmime.c @@ -741,19 +741,28 @@ xdg_mime_media_type_equal (const char *mime_a, #if 1 static int -xdg_mime_is_super_type (const char *mime) +ends_with (const char *str, + const char *suffix) { int length; - const char *type; + int suffix_length; - length = strlen (mime); - type = &(mime[length - 2]); + length = strlen (str); + suffix_length = strlen (suffix); + if (length < suffix_length) + return 0; - if (strcmp (type, "/*") == 0) + if (strcmp (str + length - suffix_length, suffix) == 0) return 1; return 0; } + +static int +xdg_mime_is_super_type (const char *mime) +{ + return ends_with (mime, "/*"); +} #endif int diff --git a/src/xdgmimecache.c b/src/xdgmimecache.c index 53aaccc..8b7fb28 100644 --- a/src/xdgmimecache.c +++ b/src/xdgmimecache.c @@ -819,19 +819,28 @@ _xdg_mime_cache_get_mime_types_from_file_name (const char *file_name, #if 1 static int -is_super_type (const char *mime) +ends_with (const char *str, + const char *suffix) { int length; - const char *type; + int suffix_length; - length = strlen (mime); - type = &(mime[length - 2]); + length = strlen (str); + suffix_length = strlen (suffix); + if (length < suffix_length) + return 0; - if (strcmp (type, "/*") == 0) + if (strcmp (str + length - suffix_length, suffix) == 0) return 1; return 0; } + +static int +is_super_type (const char *mime) +{ + return ends_with (mime, "/*"); +} #endif int -- 2.17.1