New upstream version 2018.1
This commit is contained in:
commit
e91328b9e9
64 files changed
+1078
-363
No files matched your search
@@ -18,8 +18,8 @@
|
||||
***/
|
||||
|
||||
/* Add new symbols here. Release commits should copy this section into -released.sym. */
|
||||
LIBOSTREE_2017.16 {
|
||||
} LIBOSTREE_2017.15;
|
||||
LIBOSTREE_2018.2 {
|
||||
} LIBOSTREE_2018.1;
|
||||
|
||||
/* Stub section for the stable release *after* this development one; don't
|
||||
* edit this other than to update the last number. This is just a copy/paste
|
||||
|
||||
@@ -451,6 +451,9 @@ LIBOSTREE_2017.15 {
|
||||
ostree_break_hardlink;
|
||||
} LIBOSTREE_2017.14;
|
||||
|
||||
LIBOSTREE_2018.1 {
|
||||
} LIBOSTREE_2017.15;
|
||||
|
||||
/* NOTE: Only add more content here in release commits! See the
|
||||
* comments at the top of this file.
|
||||
*/
|
||||
@@ -164,6 +164,17 @@ _ostree_loose_path (char *buf,
|
||||
OstreeObjectType objtype,
|
||||
OstreeRepoMode repo_mode);
|
||||
|
||||
gboolean _ostree_validate_structureof_metadata (OstreeObjectType objtype,
|
||||
GVariant *commit,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_ostree_verify_metadata_object (OstreeObjectType objtype,
|
||||
const char *expected_checksum,
|
||||
GVariant *metadata,
|
||||
GError **error);
|
||||
|
||||
|
||||
#define _OSTREE_METADATA_GPGSIGS_NAME "ostree.gpgsigs"
|
||||
#define _OSTREE_METADATA_GPGSIGS_TYPE G_VARIANT_TYPE ("aay")
|
||||
|
||||
|
||||
@@ -2071,6 +2071,74 @@ validate_variant (GVariant *variant,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* TODO: make this public later; just wraps the previously public
|
||||
* commit/dirtree/dirmeta verifiers.
|
||||
*/
|
||||
gboolean
|
||||
_ostree_validate_structureof_metadata (OstreeObjectType objtype,
|
||||
GVariant *metadata,
|
||||
GError **error)
|
||||
{
|
||||
g_assert (OSTREE_OBJECT_TYPE_IS_META (objtype));
|
||||
|
||||
switch (objtype)
|
||||
{
|
||||
case OSTREE_OBJECT_TYPE_COMMIT:
|
||||
if (!ostree_validate_structureof_commit (metadata, error))
|
||||
return FALSE;
|
||||
break;
|
||||
case OSTREE_OBJECT_TYPE_DIR_TREE:
|
||||
if (!ostree_validate_structureof_dirtree (metadata, error))
|
||||
return FALSE;
|
||||
break;
|
||||
case OSTREE_OBJECT_TYPE_DIR_META:
|
||||
if (!ostree_validate_structureof_dirmeta (metadata, error))
|
||||
return FALSE;
|
||||
break;
|
||||
case OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT:
|
||||
case OSTREE_OBJECT_TYPE_COMMIT_META:
|
||||
/* TODO */
|
||||
break;
|
||||
case OSTREE_OBJECT_TYPE_FILE:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Used by fsck as well as pull. Verify the checksum of a metadata object
|
||||
* and its "structure" or the additional schema we impose on GVariants such
|
||||
* as ensuring the "ay" checksum entries are of length 32. Another important
|
||||
* one is checking for path traversal in dirtree objects.
|
||||
*/
|
||||
gboolean
|
||||
_ostree_verify_metadata_object (OstreeObjectType objtype,
|
||||
const char *expected_checksum,
|
||||
GVariant *metadata,
|
||||
GError **error)
|
||||
{
|
||||
g_assert (expected_checksum);
|
||||
|
||||
g_auto(OtChecksum) hasher = { 0, };
|
||||
ot_checksum_init (&hasher);
|
||||
ot_checksum_update (&hasher, g_variant_get_data (metadata), g_variant_get_size (metadata));
|
||||
|
||||
char actual_checksum[OSTREE_SHA256_STRING_LEN+1];
|
||||
ot_checksum_get_hexdigest (&hasher, actual_checksum, sizeof (actual_checksum));
|
||||
if (!_ostree_compare_object_checksum (objtype, expected_checksum, actual_checksum, error))
|
||||
return FALSE;
|
||||
|
||||
/* Add the checksum + objtype prefix here */
|
||||
{ const char *error_prefix = glnx_strjoina (expected_checksum, ".", ostree_object_type_to_string (objtype));
|
||||
GLNX_AUTO_PREFIX_ERROR(error_prefix, error);
|
||||
if (!_ostree_validate_structureof_metadata (objtype, metadata, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_validate_structureof_commit:
|
||||
* @commit: A commit object, %OSTREE_OBJECT_TYPE_COMMIT
|
||||
|
||||
@@ -714,7 +714,7 @@ initiate_next_curl_request (FetcherRequest *req,
|
||||
curl_easy_setopt (req->easy, CURLOPT_URL, uri);
|
||||
}
|
||||
|
||||
curl_easy_setopt (req->easy, CURLOPT_USERAGENT, "ostree ");
|
||||
curl_easy_setopt (req->easy, CURLOPT_USERAGENT, OSTREE_FETCHER_USERAGENT_STRING);
|
||||
if (self->extra_headers)
|
||||
curl_easy_setopt (req->easy, CURLOPT_HTTPHEADER, self->extra_headers);
|
||||
|
||||
|
||||
@@ -479,7 +479,7 @@ ostree_fetcher_session_thread (gpointer data)
|
||||
g_main_context_push_thread_default (mainctx);
|
||||
|
||||
/* We retain ownership of the SoupSession reference. */
|
||||
closure->session = soup_session_async_new_with_options (SOUP_SESSION_USER_AGENT, "ostree ",
|
||||
closure->session = soup_session_async_new_with_options (SOUP_SESSION_USER_AGENT, OSTREE_FETCHER_USERAGENT_STRING,
|
||||
SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
|
||||
SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
|
||||
SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_REQUESTER,
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* We used to only send "ostree/" but now include the version
|
||||
* https://github.com/ostreedev/ostree/issues/1405
|
||||
* This came up in allowing Fedora infrastructure to work around a libcurl bug with HTTP2.
|
||||
*/
|
||||
#define OSTREE_FETCHER_USERAGENT_STRING (PACKAGE_NAME "/" PACKAGE_VERSION)
|
||||
|
||||
static inline gboolean
|
||||
_ostree_fetcher_tmpf_from_flags (OstreeFetcherRequestFlags flags,
|
||||
int dfd,
|
||||
|
||||
@@ -535,6 +535,10 @@ checkout_one_file_at (OstreeRepo *repo,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
/* Validate this up front to prevent path traversal attacks */
|
||||
if (!ot_util_filename_validate (destination_name, error))
|
||||
return FALSE;
|
||||
|
||||
gboolean need_copy = TRUE;
|
||||
gboolean is_bare_user_symlink = FALSE;
|
||||
char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
|
||||
@@ -897,6 +901,15 @@ checkout_tree_at_recurse (OstreeRepo *self,
|
||||
while (g_variant_iter_loop (&viter, "(&s@ay@ay)", &dname,
|
||||
&subdirtree_csum_v, &subdirmeta_csum_v))
|
||||
{
|
||||
/* Validate this up front to prevent path traversal attacks. Note that
|
||||
* we don't validate at the top of this function like we do for
|
||||
* checkout_one_file_at() becuase I believe in some cases this function
|
||||
* can be called *initially* with user-specified paths for the root
|
||||
* directory.
|
||||
*/
|
||||
if (!ot_util_filename_validate (dname, error))
|
||||
return FALSE;
|
||||
|
||||
const size_t origlen = selabel_path_buf ? selabel_path_buf->len : 0;
|
||||
if (selabel_path_buf)
|
||||
{
|
||||
|
||||
@@ -2027,6 +2027,13 @@ ostree_repo_write_metadata (OstreeRepo *self,
|
||||
if (!metadata_size_valid (objtype, g_variant_get_size (normalized), error))
|
||||
return FALSE;
|
||||
|
||||
/* For untrusted objects, verify their structure here */
|
||||
if (expected_checksum)
|
||||
{
|
||||
if (!_ostree_validate_structureof_metadata (objtype, object, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_autoptr(GBytes) vdata = g_variant_get_data_as_bytes (normalized);
|
||||
if (!write_metadata_object (self, objtype, expected_checksum,
|
||||
vdata, out_csum, cancellable, error))
|
||||
@@ -4101,6 +4108,7 @@ _ostree_repo_import_object (OstreeRepo *self,
|
||||
&variant, error))
|
||||
return FALSE;
|
||||
|
||||
/* Note this one also now verifies structure in the !trusted case */
|
||||
g_autofree guchar *real_csum = NULL;
|
||||
if (!ostree_repo_write_metadata (self, objtype,
|
||||
checksum, variant,
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
#include "libglnx.h"
|
||||
#include "ostree.h"
|
||||
#include "otutil.h"
|
||||
#include "ostree-repo-pull-private.h"
|
||||
|
||||
#ifdef HAVE_LIBCURL_OR_LIBSOUP
|
||||
|
||||
#include "ostree-core-private.h"
|
||||
#include "ostree-repo-private.h"
|
||||
#include "ostree-repo-pull-private.h"
|
||||
#include "ostree-repo-static-delta-private.h"
|
||||
#include "ostree-metalink.h"
|
||||
#include "ostree-fetcher-util.h"
|
||||
@@ -736,6 +736,12 @@ scan_dirtree_object (OtPullData *pull_data,
|
||||
|
||||
g_variant_get_child (files_variant, i, "(&s@ay)", &filename, &csum);
|
||||
|
||||
/* Note this is now obsoleted by the _ostree_validate_structureof_metadata()
|
||||
* but I'm keeping this since:
|
||||
* 1) It's cheap
|
||||
* 2) We want to continue to do validation for objects written to disk
|
||||
* before libostree's validation was strengthened.
|
||||
*/
|
||||
if (!ot_util_filename_validate (filename, error))
|
||||
return FALSE;
|
||||
|
||||
@@ -810,6 +816,7 @@ scan_dirtree_object (OtPullData *pull_data,
|
||||
g_variant_get_child (dirs_variant, i, "(&s@ay@ay)",
|
||||
&dirname, &tree_csum, &meta_csum);
|
||||
|
||||
/* See comment above for files */
|
||||
if (!ot_util_filename_validate (dirname, error))
|
||||
return FALSE;
|
||||
|
||||
@@ -1222,24 +1229,20 @@ meta_fetch_on_complete (GObject *object,
|
||||
FALSE, &metadata, error))
|
||||
goto out;
|
||||
|
||||
/* For commit objects, compute the hash and check the GPG signature before
|
||||
* writing to the repo, and also write the .commitpartial to say that
|
||||
* we're still processing this commit.
|
||||
/* Compute checksum and verify structure now. Note this is a recent change
|
||||
* (Jan 2018) - we used to verify the checksum only when writing down
|
||||
* below. But we want to do "structure" verification early on as well
|
||||
* before the object is written even to the staging directory.
|
||||
*/
|
||||
if (!_ostree_verify_metadata_object (objtype, checksum, metadata, error))
|
||||
goto out;
|
||||
|
||||
/* For commit objects, check the GPG signature before writing to the repo,
|
||||
* and also write the .commitpartial to say that we're still processing
|
||||
* this commit.
|
||||
*/
|
||||
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
|
||||
{
|
||||
/* Verify checksum */
|
||||
OtChecksum hasher = { 0, };
|
||||
ot_checksum_init (&hasher);
|
||||
{ g_autoptr(GBytes) bytes = g_variant_get_data_as_bytes (metadata);
|
||||
ot_checksum_update_bytes (&hasher, bytes);
|
||||
}
|
||||
char hexdigest[OSTREE_SHA256_STRING_LEN+1];
|
||||
ot_checksum_get_hexdigest (&hasher, hexdigest, sizeof (hexdigest));
|
||||
|
||||
if (!_ostree_compare_object_checksum (objtype, checksum, hexdigest, error))
|
||||
goto out;
|
||||
|
||||
/* Do GPG verification. `detached_data` may be NULL if no detached
|
||||
* metadata was found during pull; that's handled by
|
||||
* gpg_verify_unwritten_commit(). If we ever change the pull code to
|
||||
@@ -1256,7 +1259,13 @@ meta_fetch_on_complete (GObject *object,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ostree_repo_write_metadata_async (pull_data->repo, objtype, checksum, metadata,
|
||||
/* Note that we now (Jan 2018) pass NULL for checksum, which means "don't
|
||||
* verify checksum", since we just did it above. Related to this...now
|
||||
* that we're doing all the verification here, one thing we could do later
|
||||
* just `glnx_link_tmpfile_at()` into the repository, like the content
|
||||
* fetch path does for trusted commits.
|
||||
*/
|
||||
ostree_repo_write_metadata_async (pull_data->repo, objtype, NULL, metadata,
|
||||
pull_data->cancellable,
|
||||
on_metadata_written, fetch_data);
|
||||
pull_data->n_outstanding_metadata_write_requests++;
|
||||
|
||||
@@ -497,8 +497,13 @@ dispatch_open_splice_and_close (OstreeRepo *repo,
|
||||
goto out;
|
||||
}
|
||||
|
||||
metadata = g_variant_new_from_data (ostree_metadata_variant_type (state->output_objtype),
|
||||
state->payload_data + offset, length, TRUE, NULL, NULL);
|
||||
/* Unfortunately we need a copy because GVariant wants pointer-alignment
|
||||
* and we didn't guarantee that in static deltas. We can do so in the
|
||||
* future.
|
||||
*/
|
||||
g_autoptr(GBytes) metadata_copy = g_bytes_new (state->payload_data + offset, length);
|
||||
metadata = g_variant_new_from_bytes (ostree_metadata_variant_type (state->output_objtype),
|
||||
metadata_copy, FALSE);
|
||||
|
||||
{
|
||||
g_autofree guchar *actual_csum = NULL;
|
||||
|
||||
@@ -3941,6 +3941,7 @@ ostree_repo_delete_object (OstreeRepo *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Thin wrapper for _ostree_verify_metadata_object() */
|
||||
static gboolean
|
||||
fsck_metadata_object (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
@@ -3956,39 +3957,7 @@ fsck_metadata_object (OstreeRepo *self,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
g_auto(OtChecksum) hasher = { 0, };
|
||||
ot_checksum_init (&hasher);
|
||||
ot_checksum_update (&hasher, g_variant_get_data (metadata), g_variant_get_size (metadata));
|
||||
|
||||
char actual_checksum[OSTREE_SHA256_STRING_LEN+1];
|
||||
ot_checksum_get_hexdigest (&hasher, actual_checksum, sizeof (actual_checksum));
|
||||
if (!_ostree_compare_object_checksum (objtype, sha256, actual_checksum, error))
|
||||
return FALSE;
|
||||
|
||||
switch (objtype)
|
||||
{
|
||||
case OSTREE_OBJECT_TYPE_COMMIT:
|
||||
if (!ostree_validate_structureof_commit (metadata, error))
|
||||
return FALSE;
|
||||
break;
|
||||
case OSTREE_OBJECT_TYPE_DIR_TREE:
|
||||
if (!ostree_validate_structureof_dirtree (metadata, error))
|
||||
return FALSE;
|
||||
break;
|
||||
case OSTREE_OBJECT_TYPE_DIR_META:
|
||||
if (!ostree_validate_structureof_dirmeta (metadata, error))
|
||||
return FALSE;
|
||||
break;
|
||||
case OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT:
|
||||
case OSTREE_OBJECT_TYPE_COMMIT_META:
|
||||
/* TODO */
|
||||
break;
|
||||
case OSTREE_OBJECT_TYPE_FILE:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return _ostree_verify_metadata_object (objtype, sha256, metadata, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -1700,21 +1700,29 @@ install_deployment_kernel (OstreeSysroot *sysroot,
|
||||
g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", kernel_layout->kernel_namever, NULL);
|
||||
ostree_bootconfig_parser_set (bootconfig, "linux", boot_relpath);
|
||||
|
||||
val = ostree_bootconfig_parser_get (bootconfig, "options");
|
||||
g_autoptr(OstreeKernelArgs) kargs = _ostree_kernel_args_from_string (val);
|
||||
|
||||
if (kernel_layout->initramfs_namever)
|
||||
{
|
||||
g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", kernel_layout->initramfs_namever, NULL);
|
||||
ostree_bootconfig_parser_set (bootconfig, "initrd", boot_relpath);
|
||||
}
|
||||
|
||||
val = ostree_bootconfig_parser_get (bootconfig, "options");
|
||||
else
|
||||
{
|
||||
g_autofree char *prepare_root_arg = NULL;
|
||||
prepare_root_arg = g_strdup_printf ("init=/ostree/boot.%d/%s/%s/%d/usr/lib/ostree/ostree-prepare-root",
|
||||
new_bootversion, osname, bootcsum,
|
||||
ostree_deployment_get_bootserial (deployment));
|
||||
_ostree_kernel_args_replace_take (kargs, g_steal_pointer (&prepare_root_arg));
|
||||
}
|
||||
|
||||
/* Note this is parsed in ostree-impl-system-generator.c */
|
||||
g_autofree char *ostree_kernel_arg = g_strdup_printf ("ostree=/ostree/boot.%d/%s/%s/%d",
|
||||
new_bootversion, osname, bootcsum,
|
||||
ostree_deployment_get_bootserial (deployment));
|
||||
g_autoptr(OstreeKernelArgs) kargs = _ostree_kernel_args_from_string (val);
|
||||
_ostree_kernel_args_replace_take (kargs, ostree_kernel_arg);
|
||||
ostree_kernel_arg = NULL;
|
||||
_ostree_kernel_args_replace_take (kargs, g_steal_pointer (&ostree_kernel_arg));
|
||||
|
||||
g_autofree char *options_key = _ostree_kernel_args_to_string (kargs);
|
||||
ostree_bootconfig_parser_set (bootconfig, "options", options_key);
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
*
|
||||
* Since: 2017.4
|
||||
*/
|
||||
#define OSTREE_YEAR_VERSION (2017)
|
||||
#define OSTREE_YEAR_VERSION (2018)
|
||||
|
||||
/**
|
||||
* OSTREE_RELEASE_VERSION:
|
||||
@@ -43,7 +43,7 @@
|
||||
*
|
||||
* Since: 2017.4
|
||||
*/
|
||||
#define OSTREE_RELEASE_VERSION (15)
|
||||
#define OSTREE_RELEASE_VERSION (1)
|
||||
|
||||
/**
|
||||
* OSTREE_VERSION
|
||||
@@ -52,7 +52,7 @@
|
||||
*
|
||||
* Since: 2017.4
|
||||
*/
|
||||
#define OSTREE_VERSION (2017.15)
|
||||
#define OSTREE_VERSION (2018.1)
|
||||
|
||||
/**
|
||||
* OSTREE_VERSION_S:
|
||||
@@ -62,7 +62,7 @@
|
||||
*
|
||||
* Since: 2017.4
|
||||
*/
|
||||
#define OSTREE_VERSION_S "2017.15"
|
||||
#define OSTREE_VERSION_S "2018.1"
|
||||
|
||||
#define OSTREE_ENCODE_VERSION(year,release) \
|
||||
((year) << 16 | (release))
|
||||
|
||||
Reference in new issue
Block a user