lib/checkout: Ignore world-writable dirs for bare-user-only checkout
authorColin Walters <walters@verbum.org>
Wed, 7 Jun 2017 18:21:59 +0000 (14:21 -0400)
committerAtomic Bot <atomic-devel@projectatomic.io>
Mon, 12 Jun 2017 14:24:22 +0000 (14:24 +0000)
See https://github.com/ostreedev/ostree/pull/909 for more information on the
rationale. Basically there's no reason for flatpak (which uses `bare-user-only`)
to have world-writable dirs. Particularly with the presence of the system
helper.

An approach I considered instead was to parse and validate directory metadata
objects at commit time. We still may do that in addition; for file objects we *had*
to do it that way because the actual files would be laid down suid.  But directories
live only as inert `.dirmeta` objects until we do a checkout (i.e. `mkdir()`), so
we can solve the problem at checkout time.

Closes: #914
Approved by: alexlarsson

src/libostree/ostree-repo-checkout.c
tests/test-basic-user-only.sh

index bb7c17718243ff3280bd56d4f0fdb7fe5cfc9878..2b2594646f9e2e493562c8e2cfd48d2aad090a85 100644 (file)
@@ -749,8 +749,18 @@ checkout_tree_at_recurse (OstreeRepo                        *self,
    */
   if (!did_exist)
     {
-      if (TEMP_FAILURE_RETRY (fchmod (destination_dfd, mode)) < 0)
-        return glnx_throw_errno (error);
+      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.
+       * See also: https://github.com/ostreedev/ostree/pull/909 i.e. 0c4b3a2b6da950fd78e63f9afec602f6188f1ab0
+       */
+      if (self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY)
+        canonical_mode = (mode & 0775) | S_IFDIR;
+      else
+        canonical_mode = mode;
+      if (TEMP_FAILURE_RETRY (fchmod (destination_dfd, canonical_mode)) < 0)
+        return glnx_throw_errno_prefix (error, "fchmod");
     }
 
   if (!did_exist && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
index deca0e005d5245d3605d91b0704118808d21517a..29fbbdd3bf7b67acc2b728b5fb167fbf71e0b835 100755 (executable)
@@ -22,7 +22,7 @@ set -euo pipefail
 . $(dirname $0)/libtest.sh
 
 setup_test_repository "bare-user-only"
-extra_basic_tests=2
+extra_basic_tests=3
 . $(dirname $0)/basic-test.sh
 
 # Reset things so we don't inherit a lot of state from earlier tests
@@ -59,3 +59,15 @@ $CMD_PREFIX ostree pull-local --repo=repo repo-input
 $CMD_PREFIX ostree --repo=repo checkout -U -H content-with-group-writable groupwritable-co
 assert_file_has_mode groupwritable-co/some-group-writable 664
 echo "ok supported group writable"
+
+cd ${test_tmpdir}
+rm repo-input -rf
+ostree_repo_init repo-input init --mode=archive
+rm files -rf && mkdir files
+mkdir files/worldwritable-dir
+chmod a+w files/worldwritable-dir
+$CMD_PREFIX ostree --repo=repo-input commit -b content-with-dir-world-writable --tree=dir=files
+$CMD_PREFIX ostree pull-local --repo=repo repo-input
+$CMD_PREFIX ostree --repo=repo checkout -U -H content-with-dir-world-writable dir-co
+assert_file_has_mode dir-co/worldwritable-dir 775
+echo "ok didn't make world-writable dir"