Skip to content

Commit b547d6a

Browse files
zetafunctionmibrunin
authored andcommitted
[Backport] Security bug 1184294
Manual backport (subdirectory update) of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/2803936: Roll xdg-mime to 722325fba8968a26eb243642cbe89a044d6dfd6c. $ git log 2cdd8d36d..722325fba --date=short --no-merges --format='%ad %ae %s' 2021-03-18 kdudka@redhat.com Fix fd leak in error path 2021-01-06 hadess@hadess.net ci: Add CI 2020-11-21 emmanuel.fleury@u-bordeaux.fr Fix signedness warnings in src/xdgmimecache.c 2020-11-21 emmanuel.fleury@u-bordeaux.fr Fix signedness warnings in src/xdgmimecache.c:__gio_xdg_cache_list_mime_parents() 2020-11-21 emmanuel.fleury@u-bordeaux.fr Fix signedness warning in src/xdgmimecache.c:__gio_xdg_cache_mime_type_subclass() 2020-11-21 emmanuel.fleury@u-bordeaux.fr Fix signedness warning in src/xdgmimecache.c:cache_glob_node_lookup_suffix() 2020-11-21 emmanuel.fleury@u-bordeaux.fr Fix signedness warning in rc/xdgmimecache.c:cache_glob_lookup_fnmatch() 2020-11-21 emmanuel.fleury@u-bordeaux.fr Fix signedness warning in src/xdgmimecache.c:cache_magic_compare_to_data() 2020-11-21 emmanuel.fleury@u-bordeaux.fr Fix signedness warning in src/xdgmimecache.c:cache_magic_matchlet_compare() 2020-11-21 emmanuel.fleury@u-bordeaux.fr Fix signedness warnings in src/xdgmimecache.c:cache_magic_matchlet_compare_to_data() 2020-11-21 emmanuel.fleury@u-bordeaux.fr Fix signedness warnings in src/xdgmimemagic.c:_xdg_mime_magic_matchlet_compare_to_data() 2020-11-21 emmanuel.fleury@u-bordeaux.fr Fix signedness warnings in src/xdgmimemagic.c:_xdg_mime_magic_parse_magic_line() 2020-11-21 emmanuel.fleury@u-bordeaux.fr Fix signedness warning in src/xdgmimeint.c 2020-12-27 faure@kde.org Fix fallback after multiple matching globs 2020-12-27 faure@kde.org Fix usage information for print-mime-data 2019-06-03 withnall@endlessm.com xdgmime: Don’t set an out argument if it’s NULL 2018-11-19 ville.skytta@iki.fi Comment grammar fix 2018-07-16 mcatanzaro@igalia.com Fix buffer underflow in __gio_xdg_cache_mime_type_subclass() 2018-07-16 mcatanzaro@igalia.com Fix special case for mime_type_subclass 2018-07-16 mcatanzaro@igalia.com Handle EINTR in open() 2018-07-16 mcatanzaro@igalia.com Don't forget to free resources on an early return 2018-07-16 mcatanzaro@igalia.com Fix void pointer arithmetic in cache_magic_matchlet_compare_to_data() 2018-07-16 mcatanzaro@igalia.com Fix use after free in xdg_mime_get_mime_type_for_file 2018-07-16 mcatanzaro@igalia.com Add space before paren in _xdg_mime_cache_get_mime_type_for_file 2018-06-30 mcatanzaro@igalia.com build: Add a .gitignore 2018-06-17 ville.skytta@iki.fi Spelling fixes 2017-09-05 hadess@hadess.net Check further into the file whether it is text or binary 2013-01-07 hadess@hadess.net tests: Fix current test-mime failures 2013-01-07 hadess@hadess.net tests: Make test-mime failures fatal 2013-01-07 hadess@hadess.net tests: Mime-types are not case-sensitive 2012-09-27 hadess@hadess.net Ignore non-regular files in print-mime-data 2012-09-25 hadess@hadess.net Add print-mime-data program Fixed: 1184294 Change-Id: I74717bb13d49088b18bd88404c7cf7b8032a7d99 Reviewed-by: Adrian Taylor <adetaylor@chromium.org> Reviewed-by: Thomas Anderson <thomasanderson@chromium.org> Commit-Queue: Daniel Cheng <dcheng@chromium.org> Cr-Commit-Position: refs/heads/master@{#871055} Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> (cherry picked from commit 2327f83)
1 parent 9753b96 commit b547d6a

File tree

7 files changed

+96
-79
lines changed

7 files changed

+96
-79
lines changed

chromium/base/third_party/xdg_mime/README

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
This module is a simple module that parses the proposed MIME spec listed
2-
at http://freedesktop.org/. It is currently targetted at version 0.12.
2+
at http://freedesktop.org/. It is currently targeted at version 0.12.
33
There are no formal releases planned for this module, and it is not
44
intended to be installed at this time. Rather, it is meant to be used
55
by other libraries or applications to add support for the MIME system.
Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
Name: xdg-mime
2-
URL: http://freedesktop.org
2+
URL: https://gitlab.freedesktop.org/xdg/xdgmime
3+
Version: 722325fba8968a26eb243642cbe89a044d6dfd6c
4+
CPEPrefix: unknown
35
License: Academic Free License version 2.0 or LGPL v2
6+
Security critical: yes
47

5-
The code in this directory is synced from:
6-
git://anongit.freedesktop.org/xdg/xdgmime
7-
@ 2cdd8d36d7930d5a594587286cb1949ff62f7027 on 2012/08/06.
8+
Run //base/third_party/xdg_mime/roll.py to update this dependency.
89

9-
In addition, we have the following patch(es):
10-
- compile.patch: small tweaks to make the code compile.
11-
- free_pointer_later.patch: small patch that fixes potential crash in
12-
xdg_mime_get_mime_type_for_file() - use of pointer after being freed.
13-
- function_casts.patch: fix bad function casts.
14-
- Added a LICENSE file.
10+
Patches:
11+
- 000-have-mmap.patch: enable code guarded with HAVE_MMAP since
12+
Chrome does not run autoconf.

chromium/base/third_party/xdg_mime/xdgmime.c

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ xdg_dir_time_list_free (XdgDirTimeList *list)
136136
}
137137

138138
static int
139-
xdg_mime_init_from_directory (const char *directory, void *user_data)
139+
xdg_mime_init_from_directory (const char *directory)
140140
{
141141
char *file_name;
142142
struct stat st;
@@ -340,9 +340,8 @@ xdg_check_file (const char *file_path,
340340

341341
static int
342342
xdg_check_dir (const char *directory,
343-
void *user_data)
343+
int *invalid_dir_list)
344344
{
345-
int *invalid_dir_list = user_data;
346345
int invalid, exists;
347346
char *file_name;
348347

@@ -399,7 +398,8 @@ xdg_check_dirs (void)
399398
for (list = dir_time_list; list; list = list->next)
400399
list->checked = XDG_CHECKED_UNCHECKED;
401400

402-
xdg_run_command_on_dirs (xdg_check_dir, &invalid_dir_list);
401+
xdg_run_command_on_dirs ((XdgDirectoryFunc) xdg_check_dir,
402+
&invalid_dir_list);
403403

404404
if (invalid_dir_list)
405405
return TRUE;
@@ -455,7 +455,8 @@ xdg_mime_init (void)
455455
icon_list = _xdg_mime_icon_list_new ();
456456
generic_icon_list = _xdg_mime_icon_list_new ();
457457

458-
xdg_run_command_on_dirs (xdg_mime_init_from_directory, NULL);
458+
xdg_run_command_on_dirs ((XdgDirectoryFunc) xdg_mime_init_from_directory,
459+
NULL);
459460

460461
need_reread = FALSE;
461462
}
@@ -470,7 +471,8 @@ xdg_mime_get_mime_type_for_data (const void *data,
470471

471472
if (len == 0)
472473
{
473-
*result_prio = 100;
474+
if (result_prio != NULL)
475+
*result_prio = 100;
474476
return XDG_MIME_TYPE_EMPTY;
475477
}
476478

@@ -557,12 +559,12 @@ xdg_mime_get_mime_type_for_file (const char *file_name,
557559
mime_type = _xdg_mime_magic_lookup_data (global_magic, data, bytes_read, NULL,
558560
mime_types, n);
559561

560-
fclose (file);
561-
562562
if (!mime_type)
563-
mime_type = _xdg_binary_or_text_fallback(data, bytes_read);
563+
mime_type = _xdg_binary_or_text_fallback (data, bytes_read);
564564

565565
free (data);
566+
fclose (file);
567+
566568
return mime_type;
567569
}
568570

@@ -740,19 +742,28 @@ xdg_mime_media_type_equal (const char *mime_a,
740742

741743
#if 1
742744
static int
743-
xdg_mime_is_super_type (const char *mime)
745+
ends_with (const char *str,
746+
const char *suffix)
744747
{
745748
int length;
746-
const char *type;
749+
int suffix_length;
747750

748-
length = strlen (mime);
749-
type = &(mime[length - 2]);
751+
length = strlen (str);
752+
suffix_length = strlen (suffix);
753+
if (length < suffix_length)
754+
return 0;
750755

751-
if (strcmp (type, "/*") == 0)
756+
if (strcmp (str + length - suffix_length, suffix) == 0)
752757
return 1;
753758

754759
return 0;
755760
}
761+
762+
static int
763+
xdg_mime_is_super_type (const char *mime)
764+
{
765+
return ends_with (mime, "/*");
766+
}
756767
#endif
757768

758769
int
@@ -783,7 +794,8 @@ _xdg_mime_mime_type_subclass (const char *mime,
783794
strncmp (umime, "text/", 5) == 0)
784795
return 1;
785796

786-
if (strcmp (ubase, "application/octet-stream") == 0)
797+
if (strcmp (ubase, "application/octet-stream") == 0 &&
798+
strncmp (umime, "inode/", 6) != 0)
787799
return 1;
788800

789801
parents = _xdg_mime_parent_list_lookup (parent_list, umime);

chromium/base/third_party/xdg_mime/xdgmimecache.c

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
#include <fcntl.h>
3636
#include <unistd.h>
37+
#include <errno.h>
3738
#include <fnmatch.h>
3839
#include <assert.h>
3940

@@ -122,7 +123,9 @@ _xdg_mime_cache_new_from_file (const char *file_name)
122123
int minor;
123124

124125
/* Open the file and map it into memory */
125-
fd = open (file_name, O_RDONLY|_O_BINARY, 0);
126+
do {
127+
fd = open (file_name, O_RDONLY|_O_BINARY, 0);
128+
} while (fd == -1 && errno == EINTR);
126129

127130
if (fd < 0)
128131
return NULL;
@@ -173,7 +176,7 @@ cache_magic_matchlet_compare_to_data (XdgMimeCache *cache,
173176
xdg_uint32_t data_offset = GET_UINT32 (cache->buffer, offset + 16);
174177
xdg_uint32_t mask_offset = GET_UINT32 (cache->buffer, offset + 20);
175178

176-
int i, j;
179+
xdg_uint32_t i, j;
177180

178181
for (i = range_start; i < range_start + range_length; i++)
179182
{
@@ -196,7 +199,7 @@ cache_magic_matchlet_compare_to_data (XdgMimeCache *cache,
196199
}
197200
else
198201
{
199-
valid_matchlet = memcmp(cache->buffer + data_offset, data + i, data_length) == 0;
202+
valid_matchlet = memcmp(cache->buffer + data_offset, (unsigned char *)data + i, data_length) == 0;
200203
}
201204

202205
if (valid_matchlet)
@@ -215,7 +218,7 @@ cache_magic_matchlet_compare (XdgMimeCache *cache,
215218
xdg_uint32_t n_children = GET_UINT32 (cache->buffer, offset + 24);
216219
xdg_uint32_t child_offset = GET_UINT32 (cache->buffer, offset + 28);
217220

218-
int i;
221+
xdg_uint32_t i;
219222

220223
if (cache_magic_matchlet_compare_to_data (cache, offset, data, len))
221224
{
@@ -245,7 +248,7 @@ cache_magic_compare_to_data (XdgMimeCache *cache,
245248
xdg_uint32_t n_matchlets = GET_UINT32 (cache->buffer, offset + 8);
246249
xdg_uint32_t matchlet_offset = GET_UINT32 (cache->buffer, offset + 12);
247250

248-
int i;
251+
xdg_uint32_t i;
249252

250253
for (i = 0; i < n_matchlets; i++)
251254
{
@@ -265,15 +268,13 @@ static const char *
265268
cache_magic_lookup_data (XdgMimeCache *cache,
266269
const void *data,
267270
size_t len,
268-
int *prio,
269-
const char *mime_types[],
270-
int n_mime_types)
271+
int *prio)
271272
{
272273
xdg_uint32_t list_offset;
273274
xdg_uint32_t n_entries;
274275
xdg_uint32_t offset;
275276

276-
int j, n;
277+
xdg_uint32_t j;
277278

278279
*prio = 0;
279280

@@ -289,21 +290,6 @@ cache_magic_lookup_data (XdgMimeCache *cache,
289290
data, len, prio);
290291
if (match)
291292
return match;
292-
else
293-
{
294-
xdg_uint32_t mimetype_offset;
295-
const char *non_match;
296-
297-
mimetype_offset = GET_UINT32 (cache->buffer, offset + 16 * j + 4);
298-
non_match = cache->buffer + mimetype_offset;
299-
300-
for (n = 0; n < n_mime_types; n++)
301-
{
302-
if (mime_types[n] &&
303-
_xdg_mime_mime_type_equal (mime_types[n], non_match))
304-
mime_types[n] = NULL;
305-
}
306-
}
307293
}
308294

309295
return NULL;
@@ -412,7 +398,8 @@ cache_glob_lookup_fnmatch (const char *file_name,
412398
const char *mime_type;
413399
const char *ptr;
414400

415-
int i, j, n;
401+
int i, n;
402+
xdg_uint32_t j;
416403

417404
n = 0;
418405
for (i = 0; _caches[i]; i++)
@@ -468,7 +455,8 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
468455
int weight;
469456
int case_sensitive;
470457

471-
int min, max, mid, n, i;
458+
xdg_uint32_t i;
459+
int min, max, mid, n;
472460

473461
character = file_name[len - 1];
474462

@@ -677,8 +665,7 @@ cache_get_mime_type_for_data (const void *data,
677665
int prio;
678666
const char *match;
679667

680-
match = cache_magic_lookup_data (cache, data, len, &prio,
681-
mime_types, n_mime_types);
668+
match = cache_magic_lookup_data (cache, data, len, &prio);
682669
if (prio > priority)
683670
{
684671
priority = prio;
@@ -697,9 +684,11 @@ cache_get_mime_type_for_data (const void *data,
697684
if (mime_types[n] && _xdg_mime_cache_mime_type_subclass(mime_types[n], mime_type))
698685
return mime_types[n];
699686
}
700-
701-
/* Return magic match */
702-
return mime_type;
687+
if (n == 0)
688+
{
689+
/* No globs: return magic match */
690+
return mime_type;
691+
}
703692
}
704693

705694
/* Pick first glob result, as fallback */
@@ -787,7 +776,7 @@ _xdg_mime_cache_get_mime_type_for_file (const char *file_name,
787776
mime_types, n);
788777

789778
if (!mime_type)
790-
mime_type = _xdg_binary_or_text_fallback(data, bytes_read);
779+
mime_type = _xdg_binary_or_text_fallback (data, bytes_read);
791780

792781
free (data);
793782
fclose (file);
@@ -816,19 +805,28 @@ _xdg_mime_cache_get_mime_types_from_file_name (const char *file_name,
816805

817806
#if 1
818807
static int
819-
is_super_type (const char *mime)
808+
ends_with (const char *str,
809+
const char *suffix)
820810
{
821811
int length;
822-
const char *type;
812+
int suffix_length;
823813

824-
length = strlen (mime);
825-
type = &(mime[length - 2]);
814+
length = strlen (str);
815+
suffix_length = strlen (suffix);
816+
if (length < suffix_length)
817+
return 0;
826818

827-
if (strcmp (type, "/*") == 0)
819+
if (strcmp (str + length - suffix_length, suffix) == 0)
828820
return 1;
829821

830822
return 0;
831823
}
824+
825+
static int
826+
is_super_type (const char *mime)
827+
{
828+
return ends_with (mime, "/*");
829+
}
832830
#endif
833831

834832
int
@@ -837,7 +835,8 @@ _xdg_mime_cache_mime_type_subclass (const char *mime,
837835
{
838836
const char *umime, *ubase;
839837

840-
int i, j, min, max, med, cmp;
838+
xdg_uint32_t j;
839+
int i, min, max, med, cmp;
841840

842841
umime = _xdg_mime_cache_unalias_mime_type (mime);
843842
ubase = _xdg_mime_cache_unalias_mime_type (base);
@@ -860,7 +859,8 @@ _xdg_mime_cache_mime_type_subclass (const char *mime,
860859
strncmp (umime, "text/", 5) == 0)
861860
return 1;
862861

863-
if (strcmp (ubase, "application/octet-stream") == 0)
862+
if (strcmp (ubase, "application/octet-stream") == 0 &&
863+
strncmp (umime, "inode/", 6) != 0)
864864
return 1;
865865

866866
for (i = 0; _caches[i]; i++)
@@ -919,7 +919,8 @@ _xdg_mime_cache_unalias_mime_type (const char *mime)
919919
char **
920920
_xdg_mime_cache_list_mime_parents (const char *mime)
921921
{
922-
int i, j, k, l, p;
922+
int i, l, p;
923+
xdg_uint32_t j, k;
923924
char *all_parents[128]; /* we'll stop at 128 */
924925
char **result;
925926

@@ -1031,6 +1032,7 @@ dump_glob_node (XdgMimeCache *cache,
10311032
xdg_uint32_t mime_offset;
10321033
xdg_uint32_t n_children;
10331034
xdg_uint32_t child_offset;
1035+
xdg_uint32_t k;
10341036
int i;
10351037

10361038
character = GET_UINT32 (cache->buffer, offset);
@@ -1045,15 +1047,15 @@ dump_glob_node (XdgMimeCache *cache,
10451047
printf ("\n");
10461048
if (child_offset)
10471049
{
1048-
for (i = 0; i < n_children; i++)
1049-
dump_glob_node (cache, child_offset + 20 * i, depth + 1);
1050+
for (k = 0; k < n_children; k++)
1051+
dump_glob_node (cache, child_offset + 20 * k, depth + 1);
10501052
}
10511053
}
10521054

10531055
void
10541056
_xdg_mime_cache_glob_dump (void)
10551057
{
1056-
int i, j;
1058+
xdg_uint32_t i, j;
10571059
for (i = 0; _caches[i]; i++)
10581060
{
10591061
XdgMimeCache *cache = _caches[i];
@@ -1067,3 +1069,5 @@ _xdg_mime_cache_glob_dump (void)
10671069
dump_glob_node (cache, offset + 20 * j, 0);
10681070
}
10691071
}
1072+
1073+

chromium/base/third_party/xdg_mime/xdgmimeglob.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ _xdg_glob_list_new (void)
8686
return new_element;
8787
}
8888

89-
/* Frees glob_list and all of it's children */
89+
/* Frees glob_list and all of its children */
9090
static void
9191
_xdg_glob_list_free (XdgGlobList *glob_list)
9292
{

0 commit comments

Comments
 (0)