lib/checkout: Add bareuseronly_dirs option
authorColin Walters <walters@verbum.org>
Tue, 13 Jun 2017 17:26:33 +0000 (13:26 -0400)
committerAtomic Bot <atomic-devel@projectatomic.io>
Tue, 13 Jun 2017 20:05:31 +0000 (20:05 +0000)
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
src/libostree/ostree-repo.h
src/ostree/ot-builtin-checkout.c
tests/basic-test.sh

index 2b2594646f9e2e493562c8e2cfd48d2aad090a85..4b14dcdb31787eadc53b8c0e204e93969c2b3282 100644 (file)
@@ -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;
index beacbd588ea3ab5e67fea669e53285c736820096..ed73d4a29872ad155b31427702866355442fc1bc 100644 (file)
@@ -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;
 
index 8ffe5bb7ae7e7bc219c59b76a228abcbbbb0bd42..937c5b965893039da3420cc42a6da31f9da3ef01 100644 (file)
@@ -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,
index ba051e0397e31387d5d27639e57eeb85832ba4a9..d9b2093862170fa5b5490490cc9a05776486ba46 100644 (file)
@@ -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