--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
Please unblock package flatpak. This is a new upstream stable release;
notably, it includes use-after-free and memory leak fixes in the D-Bus
proxy (which is a security boundary), and protects against accidental
or malicious downgrades.
Filtered debdiff attached. The vast majority of the debdiff is
accounted for by the fixes mentioned above; the rest is described
in the changelog below.
unblock flatpak/0.8.5-1
flatpak (0.8.5-1) unstable; urgency=medium
* New upstream bugfix release
* Upstream security fixes:
- dbus-proxy: Fix a use-after-free (no specific exploit is known)
and several memory leaks
- system-helper: Correct the check that was meant to prevent
unprivileged users from downgrading system-wide-installed apps
- Do not allow downgrading apps to validly-signed older versions
unless a specific older version is requested, so that a
man-in-the-middle cannot cause a downgrade to an older app
version with a vulnerability
* Other upstream fixes:
- Increase GLib build-dependency to 2.44 (in practice this was
already required, there is a patch in jessie-backports to
relax this)
- Collect system extension references from all system directories,
not just the first that exists (upstream issue 654)
- Stop using ostree trivial-httpd, which is not available in
post-stretch ostree (upstream issues 658, 723)
- Be build-time compatible with post-stretch ostree (upstream
issue 756)
- Strip ?query suffix before detecting whether a URI points to a
.flatpakref or .flatpakrepo file (upstream issue 659)
- Fix a typo in help output
* d/tests/control: most tests now require python, for the
ostree-trivial-httpd replacement
-- Simon McVittie <smcv@debian.org> Mon, 03 Apr 2017 16:35:44 +0100
Thanks,
S
diffstat for flatpak-0.8.4 flatpak-0.8.5
NEWS | 30 ++++
app/flatpak-builtins-add-remote.c | 2
app/flatpak-builtins-install.c | 4
app/flatpak-builtins-update.c | 2
common/flatpak-dir.c | 49 ++++++-
common/flatpak-dir.h | 1
common/flatpak-utils.c | 49 +++----
common/flatpak-utils.h | 12 +
configure.ac | 8 -
dbus-proxy/flatpak-proxy.c | 251 +++++++++++++++++++++-----------------
debian/changelog | 30 ++++
debian/control | 2
debian/tests/control | 11 -
lib/flatpak-version-macros.h | 2
tests/Makefile.am.inc | 1
tests/libtest.sh | 5
tests/package_version.txt | 2
tests/test-oci.sh | 5
tests/test-run.sh | 15 ++
tests/test-webserver.sh | 21 +++
tests/testlibrary.c | 16 ++
21 files changed, 355 insertions(+), 163 deletions(-)
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/app/flatpak-builtins-add-remote.c flatpak-0.8.5/app/flatpak-builtins-add-remote.c
--- flatpak-0.8.4/app/flatpak-builtins-add-remote.c 2017-03-10 09:17:20.000000000 +0000
+++ flatpak-0.8.5/app/flatpak-builtins-add-remote.c 2017-04-03 12:44:34.000000000 +0100
@@ -398,7 +398,7 @@
}
if (opt_from ||
- g_str_has_suffix (location, ".flatpakrepo"))
+ flatpak_file_arg_has_suffix (location, ".flatpakrepo"))
{
load_options (location, &gpg_data);
if (opt_url == NULL)
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/app/flatpak-builtins-install.c flatpak-0.8.5/app/flatpak-builtins-install.c
--- flatpak-0.8.4/app/flatpak-builtins-install.c 2017-03-10 09:17:20.000000000 +0000
+++ flatpak-0.8.5/app/flatpak-builtins-install.c 2017-04-03 12:46:15.000000000 +0100
@@ -440,9 +440,9 @@
if (!opt_bundle && !opt_from && !opt_oci && argc >= 2)
{
- if (g_str_has_suffix (argv[1], ".flatpakref"))
+ if (flatpak_file_arg_has_suffix (argv[1], ".flatpakref"))
opt_from = TRUE;
- if (g_str_has_suffix (argv[1], ".flatpak"))
+ if (flatpak_file_arg_has_suffix (argv[1], ".flatpak"))
opt_bundle = TRUE;
}
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/app/flatpak-builtins-update.c flatpak-0.8.5/app/flatpak-builtins-update.c
--- flatpak-0.8.4/app/flatpak-builtins-update.c 2017-02-10 15:13:02.000000000 +0000
+++ flatpak-0.8.5/app/flatpak-builtins-update.c 2017-04-03 12:29:24.000000000 +0100
@@ -60,7 +60,7 @@
{ "app", 0, 0, G_OPTION_ARG_NONE, &opt_app, N_("Look for app with the specified name"), NULL },
{ "appstream", 0, 0, G_OPTION_ARG_NONE, &opt_appstream, N_("Update appstream for remote"), NULL },
{ "subpath", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_subpaths, N_("Only update this subpath"), N_("PATH") },
- { "assumeyes", 'y', 0, G_OPTION_ARG_NONE, &opt_yes, N_("OAutomatically answer yes for all questions"), NULL },
+ { "assumeyes", 'y', 0, G_OPTION_ARG_NONE, &opt_yes, N_("Automatically answer yes for all questions"), NULL },
{ NULL }
};
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/common/flatpak-dir.c flatpak-0.8.5/common/flatpak-dir.c
--- flatpak-0.8.4/common/flatpak-dir.c 2017-03-10 09:20:21.000000000 +0000
+++ flatpak-0.8.5/common/flatpak-dir.c 2017-04-03 12:44:28.000000000 +0100
@@ -1709,6 +1709,7 @@
const char **dirs_to_pull,
const char *ref_to_fetch,
const char *rev_to_fetch,
+ FlatpakPullFlags flatpak_flags,
OstreeRepoPullFlags flags,
OstreeAsyncProgress *progress,
GCancellable *cancellable,
@@ -1716,7 +1717,11 @@
{
GVariantBuilder builder;
gboolean force_disable_deltas = FALSE;
+ g_autofree char *remote_and_branch = NULL;
+ g_autofree char *current_checksum = NULL;
g_autoptr(GVariant) options = NULL;
+ g_autoptr(GVariant) old_commit = NULL;
+ g_autoptr(GVariant) new_commit = NULL;
const char *refs_to_fetch[2];
const char *revs_to_fetch[2];
gboolean res;
@@ -1751,9 +1756,33 @@
g_variant_new_variant (g_variant_new_strv ((const char * const *) revs_to_fetch, -1)));
options = g_variant_ref_sink (g_variant_builder_end (&builder));
+
+ remote_and_branch = g_strdup_printf ("%s:%s", remote_name, ref_to_fetch);
+ if (!ostree_repo_resolve_rev (self, remote_and_branch, TRUE, ¤t_checksum, error))
+ return FALSE;
+ if (current_checksum != NULL &&
+ !ostree_repo_load_commit (self, current_checksum, &old_commit, NULL, error))
+ return FALSE;
+
res = ostree_repo_pull_with_options (self, remote_name, options,
progress, cancellable, error);
+ if (old_commit &&
+ (flatpak_flags & FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE) == 0)
+ {
+ guint64 old_timestamp;
+ guint64 new_timestamp;
+
+ if (!ostree_repo_load_commit (self, rev_to_fetch, &new_commit, NULL, error))
+ return FALSE;
+
+ old_timestamp = ostree_commit_get_timestamp (old_commit);
+ new_timestamp = ostree_commit_get_timestamp (new_commit);
+
+ if (new_timestamp < old_timestamp)
+ return flatpak_fail (error, "Update is older then current version");
+ }
+
return res;
}
@@ -2154,7 +2183,7 @@
if (!repo_pull_one_dir (repo, repository,
subdirs_arg ? (const char **)subdirs_arg->pdata : NULL,
- ref, rev, flags,
+ ref, rev, flatpak_flags, flags,
progress,
cancellable, error))
{
@@ -2267,10 +2296,12 @@
g_autoptr(GFile) summary_sig_file = g_file_get_child (path_file, "summary.sig");
g_autofree char *url = g_file_get_uri (path_file);
g_autofree char *checksum = NULL;
+ g_autofree char *current_checksum = NULL;
gboolean gpg_verify_summary;
gboolean gpg_verify;
char *summary_data = NULL;
char *summary_sig_data = NULL;
+ g_autofree char *remote_and_branch = NULL;
gsize summary_data_size, summary_sig_data_size;
g_autoptr(GBytes) summary_bytes = NULL;
g_autoptr(GBytes) summary_sig_bytes = NULL;
@@ -2335,7 +2366,13 @@
return FALSE;
}
- (void) ostree_repo_load_commit (self->repo, checksum, &old_commit, NULL, NULL);
+ remote_and_branch = g_strdup_printf ("%s:%s", remote_name, ref);
+ if (!ostree_repo_resolve_rev (self->repo, remote_and_branch, TRUE, ¤t_checksum, error))
+ return FALSE;
+
+ if (current_checksum != NULL &&
+ !ostree_repo_load_commit (self->repo, current_checksum, &old_commit, NULL, NULL))
+ return FALSE;
src_repo = ostree_repo_new (path_file);
if (!ostree_repo_open (src_repo, cancellable, error))
@@ -4771,15 +4808,19 @@
/* We're pulling from a remote source, we do the network mirroring pull as a
user and hand back the resulting data to the system-helper, that trusts us
due to the GPG signatures in the repo */
+ FlatpakPullFlags flatpak_flags;
child_repo = flatpak_dir_create_system_child_repo (self, &child_repo_lock, error);
if (child_repo == NULL)
return FALSE;
+ flatpak_flags = FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA | FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA;
+ if (checksum_or_latest != NULL)
+ flatpak_flags |= FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE;
+
if (!flatpak_dir_pull (self, remote_name, ref, rev, subpaths,
child_repo,
- FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA | FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA,
- OSTREE_REPO_PULL_FLAGS_MIRROR,
+ flatpak_flags, OSTREE_REPO_PULL_FLAGS_MIRROR,
progress, cancellable, error))
return FALSE;
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/common/flatpak-dir.h flatpak-0.8.5/common/flatpak-dir.h
--- flatpak-0.8.4/common/flatpak-dir.h 2017-03-10 09:17:20.000000000 +0000
+++ flatpak-0.8.5/common/flatpak-dir.h 2017-04-03 12:44:28.000000000 +0100
@@ -98,6 +98,7 @@
FLATPAK_PULL_FLAGS_NONE = 0,
FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA = 1 << 0,
FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA = 1 << 1,
+ FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE = 1 << 2,
} FlatpakPullFlags;
typedef enum {
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/common/flatpak-utils.c flatpak-0.8.5/common/flatpak-utils.c
--- flatpak-0.8.4/common/flatpak-utils.c 2017-03-10 09:20:18.000000000 +0000
+++ flatpak-0.8.5/common/flatpak-utils.c 2017-04-03 12:45:21.000000000 +0100
@@ -1023,13 +1023,13 @@
GError **error)
{
gchar **ret = NULL;
-
g_autoptr(GPtrArray) names = NULL;
g_autoptr(GHashTable) hash = NULL;
g_autoptr(FlatpakDir) user_dir = NULL;
- g_autoptr(GError) my_error = NULL;
const char *key;
GHashTableIter iter;
+ g_autoptr(GPtrArray) system_dirs = NULL;
+ int i;
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
@@ -1037,28 +1037,21 @@
if (!flatpak_dir_collect_unmaintained_refs (user_dir, name_prefix,
branch, arch, hash, cancellable,
- &my_error))
- {
- g_autoptr(GPtrArray) system_dirs = NULL;
- int i;
+ error))
+ return NULL;
- system_dirs = flatpak_dir_get_system_list (cancellable, error);
- if (system_dirs == NULL)
- goto out;
+ system_dirs = flatpak_dir_get_system_list (cancellable, error);
+ if (system_dirs == NULL)
+ return NULL;
- for (i = 0; i < system_dirs->len; i++)
- {
- FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
+ for (i = 0; i < system_dirs->len; i++)
+ {
+ FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
- g_clear_error (&my_error);
- if (flatpak_dir_collect_unmaintained_refs (system_dir, name_prefix,
- branch, arch, hash, cancellable,
- &my_error))
- {
- /* Reference found in at least one of the system installations */
- break;
- }
- }
+ if (!flatpak_dir_collect_unmaintained_refs (system_dir, name_prefix,
+ branch, arch, hash, cancellable,
+ error))
+ return NULL;
}
names = g_ptr_array_new ();
@@ -1072,10 +1065,6 @@
ret = (char **) g_ptr_array_free (names, FALSE);
names = NULL;
- if (ret == NULL)
- g_propagate_error (error, g_steal_pointer (&my_error));
-
-out:
return ret;
}
@@ -1814,6 +1803,16 @@
spawn_data_exit (data);
}
+/* This is useful, because it handles escaped characters in uris, and ? arguments at the end of the uri */
+gboolean
+flatpak_file_arg_has_suffix (const char *arg, const char *suffix)
+{
+ g_autoptr(GFile) file = g_file_new_for_commandline_arg (arg);
+ g_autofree char *basename = g_file_get_basename (file);
+
+ return g_str_has_suffix (basename, suffix);
+}
+
gboolean
flatpak_spawn (GFile *dir,
char **output,
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/common/flatpak-utils.h flatpak-0.8.5/common/flatpak-utils.h
--- flatpak-0.8.4/common/flatpak-utils.h 2017-03-10 09:17:20.000000000 +0000
+++ flatpak-0.8.5/common/flatpak-utils.h 2017-04-03 12:45:09.000000000 +0100
@@ -343,6 +343,8 @@
const char *arch,
const char *branch);
+gboolean flatpak_file_arg_has_suffix (const char *arg, const char *suffix);
+
gboolean flatpak_spawn (GFile *dir,
char **output,
GError **error,
@@ -452,11 +454,21 @@
#define AUTOLOCK(name) G_GNUC_UNUSED __attribute__((cleanup (flatpak_auto_unlock_helper))) GMutex * G_PASTE (auto_unlock, __LINE__) = flatpak_auto_lock_helper (&G_LOCK_NAME (name))
+/* OSTREE_CHECK_VERSION was added immediately after the 2017.3 release */
+#ifndef OSTREE_CHECK_VERSION
+#define OSTREE_CHECK_VERSION(year, minor) (0)
+#endif
+/* Cleanups are always exported in 2017.4, and some git releases between 2017.3 and 2017.4.
+ We actually check against 2017.3 so that we work on the git releases *after* 2017.3
+ which is safe, because the real OSTREE_CHECK_VERSION macro was added after 2017.3
+ too. */
+#if !OSTREE_CHECK_VERSION(2017, 3)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepo, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeMutableTree, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeAsyncProgress, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeGpgVerifyResult, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoCommitModifier, ostree_repo_commit_modifier_unref)
+#endif
#ifndef SOUP_AUTOCLEANUPS_H
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SoupSession, g_object_unref)
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/configure.ac flatpak-0.8.5/configure.ac
--- flatpak-0.8.4/configure.ac 2017-03-10 09:43:27.000000000 +0000
+++ flatpak-0.8.5/configure.ac 2017-04-03 13:07:27.000000000 +0100
@@ -15,8 +15,8 @@
m4_define([flatpak_major_version], [0])
m4_define([flatpak_minor_version], [8])
-m4_define([flatpak_micro_version], [4])
-m4_define([flatpak_interface_age], [4])
+m4_define([flatpak_micro_version], [5])
+m4_define([flatpak_interface_age], [5])
m4_define([flatpak_binary_age],
[m4_eval(10000 * flatpak_major_version + 100 * flatpak_minor_version + flatpak_micro_version)])
m4_define([flatpak_version],
@@ -28,7 +28,7 @@
[flatpak],
[http://flatpak.org/])
-GLIB_REQS=2.40
+GLIB_REQS=2.44
SYSTEM_BWRAP_REQS=0.1.5
OSTREE_REQS=2016.14
@@ -44,7 +44,7 @@
AC_CONFIG_SRCDIR([common/flatpak-dir.c])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
-AM_INIT_AUTOMAKE([1.11 no-define no-dist-gzip dist-xz tar-ustar foreign subdir-objects])
+AM_INIT_AUTOMAKE([1.13.4 no-define no-dist-gzip dist-xz tar-ustar foreign subdir-objects])
AC_PROG_SED
AM_GNU_GETTEXT([external])
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/dbus-proxy/flatpak-proxy.c flatpak-0.8.5/dbus-proxy/flatpak-proxy.c
--- flatpak-0.8.4/dbus-proxy/flatpak-proxy.c 2016-10-28 09:41:14.000000000 +0100
+++ flatpak-0.8.5/dbus-proxy/flatpak-proxy.c 2017-04-03 12:44:16.000000000 +0100
@@ -193,6 +193,7 @@
{
gsize size;
gsize pos;
+ int refcount;
gboolean send_credentials;
GList *control_messages;
@@ -202,6 +203,7 @@
typedef struct
{
+ Buffer *buffer;
gboolean big_endian;
guchar type;
guchar flags;
@@ -219,6 +221,9 @@
guint32 unix_fds;
} Header;
+static void header_free (Header *header);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (Header, header_free)
+
typedef struct
{
gboolean got_first_byte; /* always true on bus side */
@@ -313,19 +318,35 @@
static void stop_reading (ProxySide *side);
static void
-buffer_free (Buffer *buffer)
+buffer_unref (Buffer *buffer)
{
- g_list_free_full (buffer->control_messages, g_object_unref);
- g_free (buffer);
+ g_assert (buffer->refcount > 0);
+ buffer->refcount--;
+
+ if (buffer->refcount == 0)
+ {
+ g_list_free_full (buffer->control_messages, g_object_unref);
+ g_free (buffer);
+ }
}
+static Buffer *
+buffer_ref (Buffer *buffer)
+{
+ g_assert (buffer->refcount > 0);
+ buffer->refcount++;
+ return buffer;
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (Buffer, buffer_unref)
+
static void
free_side (ProxySide *side)
{
g_clear_object (&side->connection);
g_clear_pointer (&side->extra_input_data, g_bytes_unref);
- g_list_free_full (side->buffers, (GDestroyNotify) buffer_free);
+ g_list_free_full (side->buffers, (GDestroyNotify) buffer_unref);
g_list_free_full (side->control_messages, (GDestroyNotify) g_object_unref);
if (side->in_source)
@@ -538,6 +559,7 @@
buffer->control_messages = NULL;
buffer->size = size;
+ buffer->refcount = 1;
if (old)
{
@@ -763,7 +785,7 @@
if (buffer->pos == buffer->size)
{
side->buffers = g_list_delete_link (side->buffers, side->buffers);
- buffer_free (buffer);
+ buffer_unref (buffer);
}
}
else
@@ -907,29 +929,38 @@
return str;
}
-static gboolean
-parse_header (Buffer *buffer, Header *header, guint32 serial_offset, guint32 reply_serial_offset, guint32 hello_serial)
+static void
+header_free (Header *header)
+{
+ if (header->buffer)
+ buffer_unref (header->buffer);
+ g_free (header);
+}
+
+static Header *
+parse_header (Buffer *buffer, guint32 serial_offset, guint32 reply_serial_offset, guint32 hello_serial)
{
guint32 array_len, header_len;
guint32 offset, end_offset;
guint8 header_type;
guint32 reply_serial_pos = 0;
const char *signature;
+ g_autoptr(Header) header = g_new0 (Header, 1);
- memset (header, 0, sizeof (Header));
+ header->buffer = buffer_ref (buffer);
if (buffer->size < 16)
- return FALSE;
+ return NULL;
if (buffer->data[3] != 1) /* Protocol version */
- return FALSE;
+ return NULL;
if (buffer->data[0] == 'B')
header->big_endian = TRUE;
else if (buffer->data[0] == 'l')
header->big_endian = FALSE;
else
- return FALSE;
+ return NULL;
header->type = buffer->data[1];
header->flags = buffer->data[2];
@@ -938,14 +969,14 @@
header->serial = read_uint32 (header, &buffer->data[8]);
if (header->serial == 0)
- return FALSE;
+ return NULL;
array_len = read_uint32 (header, &buffer->data[12]);
header_len = align_by_8 (12 + 4 + array_len);
g_assert (buffer->size >= header_len); /* We should have verified this when reading in the message */
if (header_len > buffer->size)
- return FALSE;
+ return NULL;
offset = 12 + 4;
end_offset = offset + array_len;
@@ -954,56 +985,56 @@
{
offset = align_by_8 (offset); /* Structs must be 8 byte aligned */
if (offset >= end_offset)
- return FALSE;
+ return NULL;
header_type = buffer->data[offset++];
if (offset >= end_offset)
- return FALSE;
+ return NULL;
signature = get_signature (buffer, &offset, end_offset);
if (signature == NULL)
- return FALSE;
+ return NULL;
switch (header_type)
{
case G_DBUS_MESSAGE_HEADER_FIELD_INVALID:
- return FALSE;
+ return NULL;
case G_DBUS_MESSAGE_HEADER_FIELD_PATH:
if (strcmp (signature, "o") != 0)
- return FALSE;
+ return NULL;
header->path = get_string (buffer, header, &offset, end_offset);
if (header->path == NULL)
- return FALSE;
+ return NULL;
break;
case G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE:
if (strcmp (signature, "s") != 0)
- return FALSE;
+ return NULL;
header->interface = get_string (buffer, header, &offset, end_offset);
if (header->interface == NULL)
- return FALSE;
+ return NULL;
break;
case G_DBUS_MESSAGE_HEADER_FIELD_MEMBER:
if (strcmp (signature, "s") != 0)
- return FALSE;
+ return NULL;
header->member = get_string (buffer, header, &offset, end_offset);
if (header->member == NULL)
- return FALSE;
+ return NULL;
break;
case G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME:
if (strcmp (signature, "s") != 0)
- return FALSE;
+ return NULL;
header->error_name = get_string (buffer, header, &offset, end_offset);
if (header->error_name == NULL)
- return FALSE;
+ return NULL;
break;
case G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL:
if (offset + 4 > end_offset)
- return FALSE;
+ return NULL;
header->has_reply_serial = TRUE;
reply_serial_pos = offset;
@@ -1013,31 +1044,31 @@
case G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION:
if (strcmp (signature, "s") != 0)
- return FALSE;
+ return NULL;
header->destination = get_string (buffer, header, &offset, end_offset);
if (header->destination == NULL)
- return FALSE;
+ return NULL;
break;
case G_DBUS_MESSAGE_HEADER_FIELD_SENDER:
if (strcmp (signature, "s") != 0)
- return FALSE;
+ return NULL;
header->sender = get_string (buffer, header, &offset, end_offset);
if (header->sender == NULL)
- return FALSE;
+ return NULL;
break;
case G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE:
if (strcmp (signature, "g") != 0)
- return FALSE;
+ return NULL;
header->signature = get_signature (buffer, &offset, end_offset);
if (header->signature == NULL)
- return FALSE;
+ return NULL;
break;
case G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS:
if (offset + 4 > end_offset)
- return FALSE;
+ return NULL;
header->unix_fds = read_uint32 (header, &buffer->data[offset]);
offset += 4;
@@ -1045,7 +1076,7 @@
default:
/* Unknown header field, for safety, fail parse */
- return FALSE;
+ return NULL;
}
}
@@ -1053,32 +1084,32 @@
{
case G_DBUS_MESSAGE_TYPE_METHOD_CALL:
if (header->path == NULL || header->member == NULL)
- return FALSE;
+ return NULL;
break;
case G_DBUS_MESSAGE_TYPE_METHOD_RETURN:
if (!header->has_reply_serial)
- return FALSE;
+ return NULL;
break;
case G_DBUS_MESSAGE_TYPE_ERROR:
if (header->error_name == NULL || !header->has_reply_serial)
- return FALSE;
+ return NULL;
break;
case G_DBUS_MESSAGE_TYPE_SIGNAL:
if (header->path == NULL ||
header->interface == NULL ||
header->member == NULL)
- return FALSE;
+ return NULL;
if (strcmp (header->path, "/org/freedesktop/DBus/Local") == 0 ||
strcmp (header->interface, "org.freedesktop.DBus.Local") == 0)
- return FALSE;
+ return NULL;
break;
default:
/* Unknown message type, for safety, fail parse */
- return FALSE;
+ return NULL;
}
if (serial_offset > 0)
@@ -1092,7 +1123,7 @@
header->reply_serial > hello_serial + reply_serial_offset)
write_uint32 (header, &buffer->data[reply_serial_pos], header->reply_serial - reply_serial_offset);
- return TRUE;
+ return g_steal_pointer (&header);
}
static void
@@ -1456,7 +1487,8 @@
get_arg0_string (Buffer *buffer)
{
GDBusMessage *message = g_dbus_message_new_from_blob (buffer->data, buffer->size, 0, NULL);
- GVariant *body, *arg0;
+ GVariant *body;
+ g_autoptr(GVariant) arg0 = NULL;
char *name = NULL;
if (message != NULL &&
@@ -1644,7 +1676,7 @@
{
g_warning ("Not enough fds for message");
side_closed (side);
- buffer_free (buffer);
+ buffer_unref (buffer);
return FALSE;
}
}
@@ -1794,46 +1826,47 @@
if (client->authenticated && client->proxy->filter)
{
- Header header;
+ g_autoptr(Header) header = NULL;;
BusHandler handler;
/* Filter and rewrite outgoing messages as needed */
- if (!parse_header (buffer, &header, client->serial_offset, 0, 0))
+ header = parse_header (buffer, client->serial_offset, 0, 0);
+ if (header == NULL)
{
g_warning ("Invalid message header format");
side_closed (side);
- buffer_free (buffer);
+ buffer_unref (buffer);
return;
}
- if (!update_socket_messages (side, buffer, &header))
+ if (!update_socket_messages (side, buffer, header))
return;
/* Make sure the client is not playing games with the serials, as that
could confuse us. */
- if (header.serial <= client->last_serial)
+ if (header->serial <= client->last_serial)
{
g_warning ("Invalid client serial");
side_closed (side);
- buffer_free (buffer);
+ buffer_unref (buffer);
return;
}
- client->last_serial = header.serial;
+ client->last_serial = header->serial;
if (client->proxy->log_messages)
- print_outgoing_header (&header);
+ print_outgoing_header (header);
/* Keep track of the initial Hello request so that we can read
the reply which has our assigned unique id */
- if (is_dbus_method_call (&header) &&
- g_strcmp0 (header.member, "Hello") == 0)
+ if (is_dbus_method_call (header) &&
+ g_strcmp0 (header->member, "Hello") == 0)
{
expecting_reply = EXPECTED_REPLY_HELLO;
- client->hello_serial = header.serial;
+ client->hello_serial = header->serial;
}
- handler = get_dbus_method_handler (client, &header);
+ handler = get_dbus_method_handler (client, header);
switch (handler)
{
@@ -1841,12 +1874,12 @@
case HANDLE_FILTER_GET_OWNER_REPLY:
if (!validate_arg0_name (client, buffer, FLATPAK_POLICY_SEE, NULL))
{
- g_clear_pointer (&buffer, buffer_free);
+ g_clear_pointer (&buffer, buffer_unref);
if (handler == HANDLE_FILTER_GET_OWNER_REPLY)
- buffer = get_error_for_roundtrip (client, &header,
+ buffer = get_error_for_roundtrip (client, header,
"org.freedesktop.DBus.Error.NameHasNoOwner");
else
- buffer = get_bool_reply_for_roundtrip (client, &header, FALSE);
+ buffer = get_bool_reply_for_roundtrip (client, header, FALSE);
expecting_reply = EXPECTED_REPLY_REWRITE;
break;
@@ -1874,7 +1907,7 @@
case HANDLE_PASS:
handle_pass:
- if (client_message_generates_reply (&header))
+ if (client_message_generates_reply (header))
{
if (expecting_reply == EXPECTED_REPLY_NONE)
expecting_reply = EXPECTED_REPLY_NORMAL;
@@ -1884,22 +1917,22 @@
case HANDLE_HIDE:
handle_hide:
- g_clear_pointer (&buffer, buffer_free);
+ g_clear_pointer (&buffer, buffer_unref);
- if (client_message_generates_reply (&header))
+ if (client_message_generates_reply (header))
{
const char *error;
if (client->proxy->log_messages)
g_print ("*HIDDEN* (ping)\n");
- if ((header.destination != NULL && header.destination[0] == ':') ||
- (header.flags & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) != 0)
+ if ((header->destination != NULL && header->destination[0] == ':') ||
+ (header->flags & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) != 0)
error = "org.freedesktop.DBus.Error.NameHasNoOwner";
else
error = "org.freedesktop.DBus.Error.ServiceUnknown";
- buffer = get_error_for_roundtrip (client, &header, error);
+ buffer = get_error_for_roundtrip (client, header, error);
expecting_reply = EXPECTED_REPLY_REWRITE;
}
else
@@ -1912,14 +1945,14 @@
default:
case HANDLE_DENY:
handle_deny:
- g_clear_pointer (&buffer, buffer_free);
+ g_clear_pointer (&buffer, buffer_unref);
- if (client_message_generates_reply (&header))
+ if (client_message_generates_reply (header))
{
if (client->proxy->log_messages)
g_print ("*DENIED* (ping)\n");
- buffer = get_error_for_roundtrip (client, &header,
+ buffer = get_error_for_roundtrip (client, header,
"org.freedesktop.DBus.Error.AccessDenied");
expecting_reply = EXPECTED_REPLY_REWRITE;
}
@@ -1932,7 +1965,7 @@
}
if (buffer != NULL && expecting_reply != EXPECTED_REPLY_NONE)
- queue_expected_reply (side, header.serial, expecting_reply);
+ queue_expected_reply (side, header->serial, expecting_reply);
}
if (buffer)
@@ -1947,37 +1980,38 @@
{
if (client->authenticated && client->proxy->filter)
{
- Header header;
+ g_autoptr(Header) header = NULL;;
GDBusMessage *rewritten;
FlatpakPolicy policy;
ExpectedReplyType expected_reply;
/* Filter and rewrite incoming messages as needed */
- if (!parse_header (buffer, &header, 0, client->serial_offset, client->hello_serial))
+ header = parse_header (buffer, 0, client->serial_offset, client->hello_serial);
+ if (header == NULL)
{
g_warning ("Invalid message header format");
- buffer_free (buffer);
+ buffer_unref (buffer);
side_closed (side);
return;
}
- if (!update_socket_messages (side, buffer, &header))
+ if (!update_socket_messages (side, buffer, header))
return;
if (client->proxy->log_messages)
- print_incoming_header (&header);
+ print_incoming_header (header);
- if (header.has_reply_serial)
+ if (header->has_reply_serial)
{
- expected_reply = steal_expected_reply (get_other_side (side), header.reply_serial);
+ expected_reply = steal_expected_reply (get_other_side (side), header->reply_serial);
/* We only allow replies we expect */
if (expected_reply == EXPECTED_REPLY_NONE)
{
if (client->proxy->log_messages)
g_print ("*Unexpected reply*\n");
- buffer_free (buffer);
+ buffer_unref (buffer);
return;
}
@@ -1986,9 +2020,9 @@
case EXPECTED_REPLY_HELLO:
/* When we get the initial reply to Hello, allow all
further communications to our own unique id. */
- if (header.type == G_DBUS_MESSAGE_TYPE_METHOD_RETURN)
+ if (header->type == G_DBUS_MESSAGE_TYPE_METHOD_RETURN)
{
- char *my_id = get_arg0_string (buffer);
+ g_autofree char *my_id = get_arg0_string (buffer);
flatpak_proxy_client_update_unique_id_policy (client, my_id, FLATPAK_POLICY_TALK);
break;
}
@@ -1997,17 +2031,17 @@
/* Replace a roundtrip ping with the rewritten message */
rewritten = g_hash_table_lookup (client->rewrite_reply,
- GINT_TO_POINTER (header.reply_serial));
+ GINT_TO_POINTER (header->reply_serial));
if (client->proxy->log_messages)
g_print ("*REWRITTEN*\n");
- g_dbus_message_set_serial (rewritten, header.serial);
- g_clear_pointer (&buffer, buffer_free);
+ g_dbus_message_set_serial (rewritten, header->serial);
+ g_clear_pointer (&buffer, buffer_unref);
buffer = message_to_buffer (rewritten);
g_hash_table_remove (client->rewrite_reply,
- GINT_TO_POINTER (header.reply_serial));
+ GINT_TO_POINTER (header->reply_serial));
break;
case EXPECTED_REPLY_FAKE_LIST_NAMES:
@@ -2015,12 +2049,12 @@
request, request ownership of any name matching a
wildcard policy */
- queue_wildcard_initial_name_ops (client, &header, buffer);
+ queue_wildcard_initial_name_ops (client, header, buffer);
/* Don't forward fake replies to the app */
if (client->proxy->log_messages)
g_print ("*SKIPPED*\n");
- g_clear_pointer (&buffer, buffer_free);
+ g_clear_pointer (&buffer, buffer_unref);
/* Start reading the clients requests now that we are done with the names */
start_reading (&client->client_side);
@@ -2031,39 +2065,38 @@
request, update the policy for this unique name based on
the policy */
{
- char *requested_name = g_hash_table_lookup (client->get_owner_reply, GINT_TO_POINTER (header.reply_serial));
+ char *requested_name = g_hash_table_lookup (client->get_owner_reply, GINT_TO_POINTER (header->reply_serial));
- if (header.type == G_DBUS_MESSAGE_TYPE_METHOD_RETURN)
+ if (header->type == G_DBUS_MESSAGE_TYPE_METHOD_RETURN)
{
- char *owner = get_arg0_string (buffer);
+ g_autofree char *owner = get_arg0_string (buffer);
flatpak_proxy_client_update_unique_id_policy_from_name (client, owner, requested_name);
- g_free (owner);
}
- g_hash_table_remove (client->get_owner_reply, GINT_TO_POINTER (header.reply_serial));
+ g_hash_table_remove (client->get_owner_reply, GINT_TO_POINTER (header->reply_serial));
/* Don't forward fake replies to the app */
if (client->proxy->log_messages)
g_print ("*SKIPPED*\n");
- g_clear_pointer (&buffer, buffer_free);
+ g_clear_pointer (&buffer, buffer_unref);
break;
}
case EXPECTED_REPLY_FILTER:
if (client->proxy->log_messages)
g_print ("*SKIPPED*\n");
- g_clear_pointer (&buffer, buffer_free);
+ g_clear_pointer (&buffer, buffer_unref);
break;
case EXPECTED_REPLY_LIST_NAMES:
/* This is a reply from the bus to a ListNames request, filter
it according to the policy */
- if (header.type == G_DBUS_MESSAGE_TYPE_METHOD_RETURN)
+ if (header->type == G_DBUS_MESSAGE_TYPE_METHOD_RETURN)
{
Buffer *filtered_buffer;
filtered_buffer = filter_names_list (client, buffer);
- g_clear_pointer (&buffer, buffer_free);
+ g_clear_pointer (&buffer, buffer_unref);
buffer = filtered_buffer;
}
@@ -2080,41 +2113,41 @@
{
/* Don't allow reply types with no reply_serial */
- if (header.type == G_DBUS_MESSAGE_TYPE_METHOD_RETURN ||
- header.type == G_DBUS_MESSAGE_TYPE_ERROR)
+ if (header->type == G_DBUS_MESSAGE_TYPE_METHOD_RETURN ||
+ header->type == G_DBUS_MESSAGE_TYPE_ERROR)
{
if (client->proxy->log_messages)
g_print ("*Invalid reply*\n");
- g_clear_pointer (&buffer, buffer_free);
+ g_clear_pointer (&buffer, buffer_unref);
}
/* We filter all NameOwnerChanged signal according to the policy */
- if (message_is_name_owner_changed (client, &header))
+ if (message_is_name_owner_changed (client, header))
{
if (should_filter_name_owner_changed (client, buffer))
- g_clear_pointer (&buffer, buffer_free);
+ g_clear_pointer (&buffer, buffer_unref);
}
}
/* All incoming broadcast signals are filtered according to policy */
- if (header.type == G_DBUS_MESSAGE_TYPE_SIGNAL && header.destination == NULL)
+ if (header->type == G_DBUS_MESSAGE_TYPE_SIGNAL && header->destination == NULL)
{
- policy = flatpak_proxy_client_get_policy (client, header.sender);
+ policy = flatpak_proxy_client_get_policy (client, header->sender);
if (policy < FLATPAK_POLICY_TALK)
{
if (client->proxy->log_messages)
g_print ("*FILTERED IN*\n");
- g_clear_pointer (&buffer, buffer_free);
+ g_clear_pointer (&buffer, buffer_unref);
}
}
/* We received and forwarded a message from a trusted peer. Make the policy for
this unique id SEE so that the client can track its lifetime. */
- if (buffer && header.sender && header.sender[0] == ':')
- flatpak_proxy_client_update_unique_id_policy (client, header.sender, FLATPAK_POLICY_SEE);
+ if (buffer && header->sender && header->sender[0] == ':')
+ flatpak_proxy_client_update_unique_id_policy (client, header->sender, FLATPAK_POLICY_SEE);
- if (buffer && client_message_generates_reply (&header))
- queue_expected_reply (side, header.serial, EXPECTED_REPLY_NORMAL);
+ if (buffer && client_message_generates_reply (header))
+ queue_expected_reply (side, header->serial, EXPECTED_REPLY_NORMAL);
}
if (buffer)
@@ -2200,7 +2233,11 @@
buffer = side->current_read_buffer;
if (!buffer_read (side, buffer, socket))
- break;
+ {
+ if (buffer != side->current_read_buffer)
+ buffer_unref (buffer);
+ break;
+ }
if (!client->authenticated)
{
@@ -2240,7 +2277,7 @@
}
else
{
- buffer_free (buffer);
+ buffer_unref (buffer);
}
}
else if (buffer->pos == buffer->size)
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/debian/changelog flatpak-0.8.5/debian/changelog
--- flatpak-0.8.4/debian/changelog 2017-03-15 18:43:51.000000000 +0000
+++ flatpak-0.8.5/debian/changelog 2017-04-03 16:35:44.000000000 +0100
@@ -1,3 +1,33 @@
+flatpak (0.8.5-1) unstable; urgency=medium
+
+ * New upstream bugfix release
+ * Upstream security fixes:
+ - dbus-proxy: Fix a use-after-free (no specific exploit is known)
+ and several memory leaks
+ - system-helper: Correct the check that was meant to prevent
+ unprivileged users from downgrading system-wide-installed apps
+ - Do not allow downgrading apps to validly-signed older versions
+ unless a specific older version is requested, so that a
+ man-in-the-middle cannot cause a downgrade to an older app
+ version with a vulnerability
+ * Other upstream fixes:
+ - Increase GLib build-dependency to 2.44 (in practice this was
+ already required, there is a patch in jessie-backports to
+ relax this)
+ - Collect system extension references from all system directories,
+ not just the first that exists (upstream issue 654)
+ - Stop using ostree trivial-httpd, which is not available in
+ post-stretch ostree (upstream issues 658, 723)
+ - Be build-time compatible with post-stretch ostree (upstream
+ issue 756)
+ - Strip ?query suffix before detecting whether a URI points to a
+ .flatpakref or .flatpakrepo file (upstream issue 659)
+ - Fix a typo in help output
+ * d/tests/control: most tests now require python, for the
+ ostree-trivial-httpd replacement
+
+ -- Simon McVittie <smcv@debian.org> Mon, 03 Apr 2017 16:35:44 +0100
+
flatpak (0.8.4-3) unstable; urgency=medium
* Mark the one remaining patch as applied in 0.9.1
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/debian/control flatpak-0.8.5/debian/control
--- flatpak-0.8.4/debian/control 2017-03-15 18:43:51.000000000 +0000
+++ flatpak-0.8.5/debian/control 2017-04-03 16:35:44.000000000 +0100
@@ -30,7 +30,7 @@
libelf-dev,
libfuse-dev,
libgirepository1.0-dev,
- libglib2.0-dev,
+ libglib2.0-dev (>= 2.44),
libjson-glib-dev,
libostree-dev (>= 2016.15),
libpolkit-gobject-1-dev,
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/debian/tests/control flatpak-0.8.5/debian/tests/control
--- flatpak-0.8.4/debian/tests/control 2017-03-15 18:43:51.000000000 +0000
+++ flatpak-0.8.5/debian/tests/control 2017-04-03 16:35:44.000000000 +0100
@@ -3,7 +3,7 @@
build-essential,
libflatpak-dev,
-Tests: builder
+Tests: builder builder-python
Restrictions: isolation-machine
Depends:
flatpak-builder,
@@ -11,14 +11,6 @@
git,
gnome-desktop-testing,
make,
-
-Tests: builder-python
-Restrictions: isolation-machine
-Depends:
- flatpak-builder,
- flatpak-tests,
- gnome-desktop-testing,
- make,
python,
Tests: gnome-desktop-testing
@@ -26,3 +18,4 @@
Depends:
flatpak-tests,
gnome-desktop-testing,
+ python,
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/lib/flatpak-version-macros.h flatpak-0.8.5/lib/flatpak-version-macros.h
--- flatpak-0.8.4/lib/flatpak-version-macros.h 2017-03-10 09:43:54.000000000 +0000
+++ flatpak-0.8.5/lib/flatpak-version-macros.h 2017-04-03 13:07:52.000000000 +0100
@@ -27,7 +27,7 @@
#define FLATPAK_MAJOR_VERSION (0)
#define FLATPAK_MINOR_VERSION (8)
-#define FLATPAK_MICRO_VERSION (4)
+#define FLATPAK_MICRO_VERSION (5)
#define FLATPAK_CHECK_VERSION(major,minor,micro) \
(FLATPAK_MAJOR_VERSION > (major) || \
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/NEWS flatpak-0.8.5/NEWS
--- flatpak-0.8.4/NEWS 2017-03-10 09:35:30.000000000 +0000
+++ flatpak-0.8.5/NEWS 2017-04-03 13:06:41.000000000 +0100
@@ -1,3 +1,33 @@
+Major changes in 0.8.5
+======================
+
+This is a security update for the stable branch, and all users are
+recommended to update.
+
+ * Fixed a use-after-free and some leaks in the dbus-proxy. This
+ is not currently believed to be exploitable, but the proxy is a
+ security boundary, so we still recommend to update.
+ * Regular updates now never allow updates to an older version
+ than what is currently installed (unless you explicitly specify
+ an old commit id). This closes a hole where a MITM attacker can
+ force clients to downgrade to an earlier (gpg-signed) version of
+ the application.
+ * The automatic detection of --from in flatpak install now detects
+ flatpakref extensions even in URIs that end in a query string such as
+ https://git.gnome.org/browse/gnome-apps-nightly/plain/gedit.flatpakref?h=stable
+ * The detection of "unmaintained" system extensions was broken, and
+ in some cases these extensions were not found. This now always
+ works.
+ * Flatpak now builds with latest OSTree. This required some fixing for
+ multiple definitions of the g_auto* macros as OSTree now exports
+ those.
+ * We no longer rely on ostree trivial-httpd for the tests, because
+ this is optional in later versions of ostree. Instead we use
+ they python SimpleHTTPServer.
+ * The minimum glib version has been corrected to 2.44.
+ * The minumum automake version has been increased to 1.13.4
+ because some older version didn't work.
+
Major changes in 0.8.4
======================
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/tests/libtest.sh flatpak-0.8.5/tests/libtest.sh
--- flatpak-0.8.4/tests/libtest.sh 2017-02-16 08:48:14.000000000 +0000
+++ flatpak-0.8.5/tests/libtest.sh 2017-04-03 12:31:25.000000000 +0100
@@ -180,8 +180,9 @@
GPGARGS="$FL_GPGARGS" . $(dirname $0)/make-test-runtime.sh org.test.Platform bash ls cat echo readlink > /dev/null
GPGARGS="$FL_GPGARGS" . $(dirname $0)/make-test-app.sh > /dev/null
update_repo
- ostree trivial-httpd --autoexit --daemonize -p httpd-port repos
+ $(dirname $0)/test-webserver.sh repos
port=$(cat httpd-port)
+ FLATPAK_HTTP_PID=$(cat httpd-pid)
flatpak remote-add ${U} --gpg-import=${FL_GPG_HOMEDIR}/pubring.gpg test-repo "http://127.0.0.1:${port}/test"
}
@@ -266,7 +267,7 @@
fi
cleanup () {
- /bin/kill $DBUS_SESSION_BUS_PID
+ /bin/kill $DBUS_SESSION_BUS_PID ${FLATPAK_HTTP_PID:-}
gpg-connect-agent --homedir "${FL_GPG_HOMEDIR}" killagent /bye || true
fusermount -u $XDG_RUNTIME_DIR/doc || :
rm -rf $TEST_DATA_DIR
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/tests/Makefile.am.inc flatpak-0.8.5/tests/Makefile.am.inc
--- flatpak-0.8.4/tests/Makefile.am.inc 2017-02-10 15:13:02.000000000 +0000
+++ flatpak-0.8.5/tests/Makefile.am.inc 2017-04-03 12:31:25.000000000 +0100
@@ -80,6 +80,7 @@
tests/make-test-runtime.sh \
tests/make-test-bundles.sh \
tests/testpython.py \
+ tests/test-webserver.sh \
$(NULL)
dist_installed_test_data = \
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/tests/package_version.txt flatpak-0.8.5/tests/package_version.txt
--- flatpak-0.8.4/tests/package_version.txt 2017-03-10 09:43:54.000000000 +0000
+++ flatpak-0.8.5/tests/package_version.txt 2017-04-03 13:08:08.000000000 +0100
@@ -1 +1 @@
-0.8.4
+0.8.5
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/tests/testlibrary.c flatpak-0.8.5/tests/testlibrary.c
--- flatpak-0.8.4/tests/testlibrary.c 2017-02-21 17:54:09.000000000 +0000
+++ flatpak-0.8.5/tests/testlibrary.c 2017-04-03 12:31:25.000000000 +0100
@@ -12,6 +12,7 @@
static char *gpg_homedir;
static char *gpg_args;
static char *repo_url;
+int httpd_pid = -1;
static const char *gpg_id = "7B0961FD";
const char *repo_name = "test-repo";
@@ -605,7 +606,8 @@
{
int status;
g_autoptr(GError) error = NULL;
- char *argv[] = { "ostree", "trivial-httpd", "--autoexit", "--daemonize", "-p", "http-port", "repos", NULL };
+ g_autofree char *path = g_test_build_filename (G_TEST_DIST, "test-webserver.sh", NULL);
+ char *argv[] = {path , "repos", NULL };
GSpawnFlags flags = G_SPAWN_SEARCH_PATH;
if (g_test_verbose ())
@@ -629,11 +631,18 @@
char *argv[] = { "flatpak", "remote-add", "--user", "--gpg-import=", "name", "url", NULL };
g_autofree char *gpgimport = NULL;
g_autofree char *port = NULL;
+ g_autofree char *pid = NULL;
GSpawnFlags flags = G_SPAWN_SEARCH_PATH;
launch_httpd ();
- g_file_get_contents ("http-port", &port, NULL, &error);
+ g_file_get_contents ("httpd-pid", &pid, NULL, &error);
+ g_assert_no_error (error);
+
+ httpd_pid = atoi (pid);
+ g_assert_cmpint (httpd_pid, !=, 0);
+
+ g_file_get_contents ("httpd-port", &port, NULL, &error);
g_assert_no_error (error);
if (port[strlen (port) - 1] == '\n')
@@ -824,6 +833,9 @@
flags |= G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL;
}
+ if (httpd_pid != -1)
+ kill (httpd_pid, SIGKILL);
+
/* mostly ignore failure here */
if (!g_spawn_sync (NULL, (char **)argv, NULL, flags, NULL, NULL, NULL, NULL, &status, &error) ||
!g_spawn_check_exit_status (status, &error))
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/tests/test-oci.sh flatpak-0.8.5/tests/test-oci.sh
--- flatpak-0.8.4/tests/test-oci.sh 2017-02-10 15:13:02.000000000 +0000
+++ flatpak-0.8.5/tests/test-oci.sh 2017-04-03 12:43:56.000000000 +0100
@@ -77,8 +77,9 @@
make_updated_app HTTP
${FLATPAK} build-bundle --oci repos/test oci-dir org.test.Hello
-ostree trivial-httpd --autoexit --daemonize -p oci-port `pwd`/oci-dir
-ociport=$(cat oci-port)
+$(dirname $0)/test-webserver.sh `pwd`/oci-dir
+ociport=$(cat httpd-port)
+FLATPAK_HTTP_PID="${FLATPAK_HTTP_PID} $(cat httpd-pid)"
${FLATPAK} install -v ${U} --oci http://127.0.0.1:${ociport} latest
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/tests/test-run.sh flatpak-0.8.5/tests/test-run.sh
--- flatpak-0.8.4/tests/test-run.sh 2017-02-10 15:13:02.000000000 +0000
+++ flatpak-0.8.5/tests/test-run.sh 2017-04-03 12:44:28.000000000 +0100
@@ -24,7 +24,7 @@
skip_without_bwrap
skip_without_user_xattrs
-echo "1..9"
+echo "1..10"
setup_repo
install_repo
@@ -206,6 +206,19 @@
echo "ok update"
+ostree --repo=repos/test reset app/org.test.Hello/$ARCH/master "$OLD_COMMIT"
+update_repo
+
+if ${FLATPAK} ${U} update org.test.Hello; then
+ assert_not_reached "Should not be able to update to older commit"
+fi
+
+NEW_NEW_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`
+
+assert_streq "$NEW_COMMIT" "$NEW_NEW_COMMIT"
+
+echo "ok backwards update"
+
DIR=`mktemp -d`
${FLATPAK} build-init ${DIR} org.test.Split org.test.Platform org.test.Platform
diff -Nru --exclude po --exclude Makefile.in --exclude html --exclude configure flatpak-0.8.4/tests/test-webserver.sh flatpak-0.8.5/tests/test-webserver.sh
--- flatpak-0.8.4/tests/test-webserver.sh 1970-01-01 01:00:00.000000000 +0100
+++ flatpak-0.8.5/tests/test-webserver.sh 2017-04-03 12:34:49.000000000 +0100
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+set -euo pipefail
+
+dir=$1
+test_tmpdir=$(pwd)
+
+cd ${dir}
+env PYTHONUNBUFFERED=1 setsid python -m SimpleHTTPServer 0 >${test_tmpdir}/httpd-output &
+child_pid=$!
+
+for x in $(seq 50); do
+ sed -e 's,Serving HTTP on 0.0.0.0 port \([0-9]*\) \.\.\.,\1,' < ${test_tmpdir}/httpd-output > ${test_tmpdir}/httpd-port
+ if ! cmp ${test_tmpdir}/httpd-output ${test_tmpdir}/httpd-port 1>/dev/null; then
+ break
+ fi
+ sleep 0.1
+done
+port=$(cat ${test_tmpdir}/httpd-port)
+echo "http://127.0.0.1:${port}" > ${test_tmpdir}/httpd-address
+echo "$child_pid" > ${test_tmpdir}/httpd-pid
--- End Message ---