From 0635fcbfd9d1efa298ffc08a4a8d346e740292fd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 13 Jun 2017 13:26:33 -0400 Subject: [PATCH] lib/checkout: Add bareuseronly_dirs option This is a continuation of https://github.com/ostreedev/ostree/pull/926 for directories instead of files. See: https://github.com/flatpak/flatpak/issues/845 This option suppresses mode bits outside of `0775` for directory checkouts. I think most people should start doing this by default, and use explicit overrides for e.g. `/tmp` if doing a recommit based on a checkout. Closes: #927 Approved by: alexlarsson --- src/libostree/ostree-repo-checkout.c | 6 +++--- src/libostree/ostree-repo.h | 3 ++- src/ostree/ot-builtin-checkout.c | 6 +++++- tests/basic-test.sh | 18 +++++++++++++++++- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/libostree/ostree-repo-checkout.c b/src/libostree/ostree-repo-checkout.c index 2b259464..4b14dcdb 100644 --- a/src/libostree/ostree-repo-checkout.c +++ b/src/libostree/ostree-repo-checkout.c @@ -751,11 +751,11 @@ checkout_tree_at_recurse (OstreeRepo *self, { guint32 canonical_mode; /* Silently ignore world-writable directories (plus sticky, suid bits, - * etc.) when doing a checkout for bare-user-only repos. This is related - * to the logic in ostree-repo-commit.c for files. + * etc.) when doing a checkout for bare-user-only repos, or if requested explicitly. + * This is related to the logic in ostree-repo-commit.c for files. * See also: https://github.com/ostreedev/ostree/pull/909 i.e. 0c4b3a2b6da950fd78e63f9afec602f6188f1ab0 */ - if (self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY) + if (self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY || options->bareuseronly_dirs) canonical_mode = (mode & 0775) | S_IFDIR; else canonical_mode = mode; diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index beacbd58..ed73d4a2 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -768,7 +768,8 @@ typedef struct { gboolean process_whiteouts; gboolean no_copy_fallback; gboolean force_copy; /* Since: 2017.6 */ - gboolean unused_bools[6]; + gboolean bareuseronly_dirs; /* Since: 2017.7 */ + gboolean unused_bools[5]; const char *subpath; diff --git a/src/ostree/ot-builtin-checkout.c b/src/ostree/ot-builtin-checkout.c index 8ffe5bb7..937c5b96 100644 --- a/src/ostree/ot-builtin-checkout.c +++ b/src/ostree/ot-builtin-checkout.c @@ -43,6 +43,7 @@ static char *opt_from_file; static gboolean opt_disable_fsync; static gboolean opt_require_hardlinks; static gboolean opt_force_copy; +static gboolean opt_bareuseronly_dirs; static gboolean parse_fsync_cb (const char *option_name, @@ -73,6 +74,7 @@ static GOptionEntry options[] = { { "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" }, { "require-hardlinks", 'H', 0, G_OPTION_ARG_NONE, &opt_require_hardlinks, "Do not fall back to full copies if hardlinking fails", NULL }, { "force-copy", 'C', 0, G_OPTION_ARG_NONE, &opt_force_copy, "Never hardlink (but may reflink if available)", NULL }, + { "bareuseronly-dirs", 'M', 0, G_OPTION_ARG_NONE, &opt_bareuseronly_dirs, "Suppress mode bits outside of 0775 for directories (suid, world writable, etc.)", NULL }, { NULL } }; @@ -91,7 +93,8 @@ process_one_checkout (OstreeRepo *repo, * `ostree_repo_checkout_at` until such time as we have a more * convenient infrastructure for testing C APIs with data. */ - if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks || opt_union_add || opt_force_copy) + if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks || + opt_union_add || opt_force_copy || opt_bareuseronly_dirs) { OstreeRepoCheckoutAtOptions options = { 0, }; @@ -119,6 +122,7 @@ process_one_checkout (OstreeRepo *repo, options.subpath = subpath; options.no_copy_fallback = opt_require_hardlinks; options.force_copy = opt_force_copy; + options.bareuseronly_dirs = opt_bareuseronly_dirs; if (!ostree_repo_checkout_at (repo, &options, AT_FDCWD, destination, diff --git a/tests/basic-test.sh b/tests/basic-test.sh index ba051e03..d9b20938 100644 --- a/tests/basic-test.sh +++ b/tests/basic-test.sh @@ -19,7 +19,7 @@ set -euo pipefail -echo "1..$((68 + ${extra_basic_tests:-0}))" +echo "1..$((69 + ${extra_basic_tests:-0}))" $CMD_PREFIX ostree --version > version.yaml python -c 'import yaml; yaml.safe_load(open("version.yaml"))' @@ -445,6 +445,22 @@ assert_file_has_content checkout-test-union-add/union-add-test 'existing file fo assert_file_has_content checkout-test-union-add/union-add-test2 'another file for union add testing' echo "ok checkout union add" +cd ${test_tmpdir} +rm files -rf && mkdir files +mkdir files/worldwritable-dir +chmod a+w files/worldwritable-dir +$CMD_PREFIX ostree --repo=repo commit -b content-with-dir-world-writable --tree=dir=files +rm dir-co -rf +$CMD_PREFIX ostree --repo=repo checkout -U -H -M content-with-dir-world-writable dir-co +assert_file_has_mode dir-co/worldwritable-dir 775 +if ! is_bare_user_only_repo repo; then + rm dir-co -rf + $CMD_PREFIX ostree --repo=repo checkout -U -H content-with-dir-world-writable dir-co + assert_file_has_mode dir-co/worldwritable-dir 777 +fi +rm dir-co -rf +echo "ok checkout bareuseronly dir" + cd ${test_tmpdir} rm -rf shadow-repo mkdir shadow-repo