Skip to content

Commit 7e4a25f

Browse files
committed
New upstream version 1.14.4
2 parents e8c9c3d + 8a1edce commit 7e4a25f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2888
-2514
lines changed

NEWS

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
Changes in 1.14.4
2+
~~~~~~~~~~~~~~~~~
3+
Released: 2023-03-16
4+
5+
Security fixes:
6+
7+
* Escape special characters when displaying permissions and metadata,
8+
preventing malicious apps from manipulating the appearance of the
9+
permissions list using crafted metadata (CVE-2023-28101).
10+
11+
* If a Flatpak app is run on a Linux virtual console (tty1, tty2, etc.),
12+
don't allow copy/paste via the TIOCLINUX ioctl (CVE-2023-28100).
13+
Note that this is specific to virtual consoles: Flatpak is not
14+
vulnerable to this if run from a graphical terminal emulator such as
15+
xterm, gnome-terminal or Konsole.
16+
17+
Other bug fixes:
18+
19+
* Translation update: pl
20+
121
Changes in 1.14.3
222
~~~~~~~~~~~~~~~~~
323
Released: 2023-02-27

app/flatpak-builtins-info.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,9 @@ flatpak_builtin_info (int argc, char **argv, GCancellable *cancellable, GError *
400400
if (!g_file_load_contents (file, cancellable, &data, &data_size, NULL, error))
401401
return FALSE;
402402

403-
g_print ("%s", data);
403+
flatpak_print_escaped_string (data,
404+
FLATPAK_ESCAPE_ALLOW_NEWLINES
405+
| FLATPAK_ESCAPE_DO_NOT_QUOTE);
404406
}
405407

406408
if (opt_show_permissions || opt_file_access)
@@ -421,7 +423,9 @@ flatpak_builtin_info (int argc, char **argv, GCancellable *cancellable, GError *
421423
if (contents == NULL)
422424
return FALSE;
423425

424-
g_print ("%s", contents);
426+
flatpak_print_escaped_string (contents,
427+
FLATPAK_ESCAPE_ALLOW_NEWLINES
428+
| FLATPAK_ESCAPE_DO_NOT_QUOTE);
425429
}
426430

427431
if (opt_file_access)

app/flatpak-builtins-remote-info.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,10 @@ flatpak_builtin_remote_info (int argc, char **argv, GCancellable *cancellable, G
431431

432432
if (opt_show_metadata)
433433
{
434-
g_print ("%s", xa_metadata ? xa_metadata : "");
434+
if (xa_metadata != NULL)
435+
flatpak_print_escaped_string (xa_metadata,
436+
FLATPAK_ESCAPE_ALLOW_NEWLINES
437+
| FLATPAK_ESCAPE_DO_NOT_QUOTE);
435438
if (xa_metadata == NULL || !g_str_has_suffix (xa_metadata, "\n"))
436439
g_print ("\n");
437440
}

app/flatpak-cli-transaction.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,9 @@ print_eol_info_message (FlatpakDir *dir,
755755
}
756756
else if (reason)
757757
{
758+
g_autofree char *escaped_reason = flatpak_escape_string (reason,
759+
FLATPAK_ESCAPE_ALLOW_NEWLINES |
760+
FLATPAK_ESCAPE_DO_NOT_QUOTE);
758761
if (is_pinned)
759762
{
760763
/* Only runtimes can be pinned */
@@ -770,7 +773,7 @@ print_eol_info_message (FlatpakDir *dir,
770773
g_print (_("\nInfo: app %s%s%s branch %s%s%s is end-of-life, with reason:\n"),
771774
on, ref_name, off, on, ref_branch, off);
772775
}
773-
g_print (" %s\n", reason);
776+
g_print (" %s\n", escaped_reason);
774777
}
775778
}
776779

@@ -1121,12 +1124,16 @@ print_perm_line (int idx,
11211124
int cols)
11221125
{
11231126
g_autoptr(GString) res = g_string_new (NULL);
1127+
g_autofree char *escaped_first_perm = NULL;
11241128
int i;
11251129

1126-
g_string_append_printf (res, " [%d] %s", idx, (char *) items->pdata[0]);
1130+
escaped_first_perm = flatpak_escape_string (items->pdata[0], FLATPAK_ESCAPE_DEFAULT);
1131+
g_string_append_printf (res, " [%d] %s", idx, escaped_first_perm);
11271132

11281133
for (i = 1; i < items->len; i++)
11291134
{
1135+
g_autofree char *escaped = flatpak_escape_string (items->pdata[i],
1136+
FLATPAK_ESCAPE_DEFAULT);
11301137
char *p;
11311138
int len;
11321139

@@ -1135,10 +1142,10 @@ print_perm_line (int idx,
11351142
p = res->str;
11361143

11371144
len = (res->str + strlen (res->str)) - p;
1138-
if (len + strlen ((char *) items->pdata[i]) + 2 >= cols)
1139-
g_string_append_printf (res, ",\n %s", (char *) items->pdata[i]);
1145+
if (len + strlen (escaped) + 2 >= cols)
1146+
g_string_append_printf (res, ",\n %s", escaped);
11401147
else
1141-
g_string_append_printf (res, ", %s", (char *) items->pdata[i]);
1148+
g_string_append_printf (res, ", %s", escaped);
11421149
}
11431150

11441151
g_print ("%s\n", res->str);

common/flatpak-context.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -488,11 +488,17 @@ flatpak_context_apply_generic_policy (FlatpakContext *context,
488488
g_ptr_array_free (new, FALSE));
489489
}
490490

491-
static void
491+
492+
static gboolean
492493
flatpak_context_set_persistent (FlatpakContext *context,
493-
const char *path)
494+
const char *path,
495+
GError **error)
494496
{
497+
if (!flatpak_validate_path_characters (path, error))
498+
return FALSE;
499+
495500
g_hash_table_insert (context->persistent, g_strdup (path), GINT_TO_POINTER (1));
501+
return TRUE;
496502
}
497503

498504
static gboolean
@@ -854,6 +860,9 @@ flatpak_context_parse_filesystem (const char *filesystem_and_mode,
854860
g_autofree char *filesystem = NULL;
855861
char *slash;
856862

863+
if (!flatpak_validate_path_characters (filesystem_and_mode, error))
864+
return FALSE;
865+
857866
filesystem = parse_filesystem_flags (filesystem_and_mode, negated, mode_out, error);
858867
if (filesystem == NULL)
859868
return FALSE;
@@ -1510,8 +1519,7 @@ option_persist_cb (const gchar *option_name,
15101519
{
15111520
FlatpakContext *context = data;
15121521

1513-
flatpak_context_set_persistent (context, value);
1514-
return TRUE;
1522+
return flatpak_context_set_persistent (context, value, error);
15151523
}
15161524

15171525
static gboolean option_no_desktop_deprecated;
@@ -1703,11 +1711,24 @@ flatpak_context_load_metadata (FlatpakContext *context,
17031711
{
17041712
const char *fs = parse_negated (filesystems[i], &remove);
17051713
g_autofree char *filesystem = NULL;
1714+
g_autoptr(GError) local_error = NULL;
17061715
FlatpakFilesystemMode mode;
17071716

17081717
if (!flatpak_context_parse_filesystem (fs, remove,
1709-
&filesystem, &mode, NULL))
1710-
g_debug ("Unknown filesystem type %s", filesystems[i]);
1718+
&filesystem, &mode, &local_error))
1719+
{
1720+
if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA))
1721+
{
1722+
/* Invalid characters, so just hard-fail. */
1723+
g_propagate_error (error, g_steal_pointer (&local_error));
1724+
return FALSE;
1725+
}
1726+
else
1727+
{
1728+
g_debug ("Unknown filesystem type %s", filesystems[i]);
1729+
g_clear_error (&local_error);
1730+
}
1731+
}
17111732
else
17121733
{
17131734
g_assert (mode == FLATPAK_FILESYSTEM_MODE_NONE || !remove);
@@ -1724,7 +1745,8 @@ flatpak_context_load_metadata (FlatpakContext *context,
17241745
return FALSE;
17251746

17261747
for (i = 0; persistent[i] != NULL; i++)
1727-
flatpak_context_set_persistent (context, persistent[i]);
1748+
if (!flatpak_context_set_persistent (context, persistent[i], error))
1749+
return FALSE;
17281750
}
17291751

17301752
if (g_key_file_has_group (metakey, FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY))

common/flatpak-run.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3210,6 +3210,10 @@ setup_seccomp (FlatpakBwrap *bwrap,
32103210

32113211
/* Don't allow faking input to the controlling tty (CVE-2017-5226) */
32123212
{SCMP_SYS (ioctl), EPERM, &SCMP_A1 (SCMP_CMP_MASKED_EQ, 0xFFFFFFFFu, (int) TIOCSTI)},
3213+
/* In the unlikely event that the controlling tty is a Linux virtual
3214+
* console (/dev/tty2 or similar), copy/paste operations have an effect
3215+
* similar to TIOCSTI (CVE-2023-28100) */
3216+
{SCMP_SYS (ioctl), EPERM, &SCMP_A1 (SCMP_CMP_MASKED_EQ, 0xFFFFFFFFu, (int) TIOCLINUX)},
32133217

32143218
/* seccomp can't look into clone3()'s struct clone_args to check whether
32153219
* the flags are OK, so we have no choice but to block clone3().

common/flatpak-utils-private.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,20 @@ gboolean flatpak_str_is_integer (const char *s);
928928
gboolean flatpak_uri_equal (const char *uri1,
929929
const char *uri2);
930930

931+
typedef enum {
932+
FLATPAK_ESCAPE_DEFAULT = 0,
933+
FLATPAK_ESCAPE_ALLOW_NEWLINES = 1 << 0,
934+
FLATPAK_ESCAPE_DO_NOT_QUOTE = 1 << 1,
935+
} FlatpakEscapeFlags;
936+
937+
char * flatpak_escape_string (const char *s,
938+
FlatpakEscapeFlags flags);
939+
void flatpak_print_escaped_string (const char *s,
940+
FlatpakEscapeFlags flags);
941+
942+
gboolean flatpak_validate_path_characters (const char *path,
943+
GError **error);
944+
931945
gboolean running_under_sudo (void);
932946

933947
#define FLATPAK_MESSAGE_ID "c7b39b1e006b464599465e105b361485"

common/flatpak-utils.c

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ load_kernel_module_list (void)
625625
g_autofree char *modules_data = NULL;
626626
g_autoptr(GError) error = NULL;
627627
char *start, *end;
628-
628+
629629
if (!g_file_get_contents ("/proc/modules", &modules_data, NULL, &error))
630630
{
631631
g_debug ("Failed to read /proc/modules: %s", error->message);
@@ -9221,6 +9221,125 @@ flatpak_uri_equal (const char *uri1,
92219221
return g_strcmp0 (uri1_norm, uri2_norm) == 0;
92229222
}
92239223

9224+
static gboolean
9225+
is_char_safe (gunichar c)
9226+
{
9227+
return g_unichar_isgraph (c) || c == ' ';
9228+
}
9229+
9230+
static gboolean
9231+
should_hex_escape (gunichar c,
9232+
FlatpakEscapeFlags flags)
9233+
{
9234+
if ((flags & FLATPAK_ESCAPE_ALLOW_NEWLINES) && c == '\n')
9235+
return FALSE;
9236+
9237+
return !is_char_safe (c);
9238+
}
9239+
9240+
static void
9241+
append_hex_escaped_character (GString *result,
9242+
gunichar c)
9243+
{
9244+
if (c <= 0xFF)
9245+
g_string_append_printf (result, "\\x%02X", c);
9246+
else if (c <= 0xFFFF)
9247+
g_string_append_printf (result, "\\u%04X", c);
9248+
else
9249+
g_string_append_printf (result, "\\U%08X", c);
9250+
}
9251+
9252+
static char *
9253+
escape_character (gunichar c)
9254+
{
9255+
g_autoptr(GString) res = g_string_new ("");
9256+
append_hex_escaped_character (res, c);
9257+
return g_string_free (g_steal_pointer (&res), FALSE);
9258+
}
9259+
9260+
char *
9261+
flatpak_escape_string (const char *s,
9262+
FlatpakEscapeFlags flags)
9263+
{
9264+
g_autoptr(GString) res = g_string_new ("");
9265+
gboolean did_escape = FALSE;
9266+
9267+
while (*s)
9268+
{
9269+
gunichar c = g_utf8_get_char_validated (s, -1);
9270+
if (c == (gunichar)-2 || c == (gunichar)-1)
9271+
{
9272+
/* Need to convert to unsigned first, to avoid negative chars becoming
9273+
huge gunichars. */
9274+
append_hex_escaped_character (res, (unsigned char)*s++);
9275+
did_escape = TRUE;
9276+
continue;
9277+
}
9278+
else if (should_hex_escape (c, flags))
9279+
{
9280+
append_hex_escaped_character (res, c);
9281+
did_escape = TRUE;
9282+
}
9283+
else if (c == '\\' || (!(flags & FLATPAK_ESCAPE_DO_NOT_QUOTE) && c == '\''))
9284+
{
9285+
g_string_append_printf (res, "\\%c", (char) c);
9286+
did_escape = TRUE;
9287+
}
9288+
else
9289+
g_string_append_unichar (res, c);
9290+
9291+
s = g_utf8_find_next_char (s, NULL);
9292+
}
9293+
9294+
if (did_escape && !(flags & FLATPAK_ESCAPE_DO_NOT_QUOTE))
9295+
{
9296+
g_string_prepend_c (res, '\'');
9297+
g_string_append_c (res, '\'');
9298+
}
9299+
9300+
return g_string_free (g_steal_pointer (&res), FALSE);
9301+
}
9302+
9303+
void
9304+
flatpak_print_escaped_string (const char *s,
9305+
FlatpakEscapeFlags flags)
9306+
{
9307+
g_autofree char *escaped = flatpak_escape_string (s, flags);
9308+
g_print ("%s", escaped);
9309+
}
9310+
9311+
gboolean
9312+
flatpak_validate_path_characters (const char *path,
9313+
GError **error)
9314+
{
9315+
while (*path)
9316+
{
9317+
gunichar c = g_utf8_get_char_validated (path, -1);
9318+
if (c == (gunichar)-1 || c == (gunichar)-2)
9319+
{
9320+
/* Need to convert to unsigned first, to avoid negative chars becoming
9321+
huge gunichars. */
9322+
g_autofree char *escaped_char = escape_character ((unsigned char)*path);
9323+
g_autofree char *escaped = flatpak_escape_string (path, FLATPAK_ESCAPE_DEFAULT);
9324+
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
9325+
"Non-UTF8 byte %s in path %s", escaped_char, escaped);
9326+
return FALSE;
9327+
}
9328+
else if (!is_char_safe (c))
9329+
{
9330+
g_autofree char *escaped_char = escape_character (c);
9331+
g_autofree char *escaped = flatpak_escape_string (path, FLATPAK_ESCAPE_DEFAULT);
9332+
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
9333+
"Non-graphical character %s in path %s", escaped_char, escaped);
9334+
return FALSE;
9335+
}
9336+
9337+
path = g_utf8_find_next_char (path, NULL);
9338+
}
9339+
9340+
return TRUE;
9341+
}
9342+
92249343
gboolean
92259344
running_under_sudo (void)
92269345
{

common/flatpak-version-macros.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
*
4646
* The micro version.
4747
*/
48-
#define FLATPAK_MICRO_VERSION (3)
48+
#define FLATPAK_MICRO_VERSION (4)
4949

5050
/**
5151
* FLATPAK_CHECK_VERSION:

0 commit comments

Comments
 (0)