summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca BRUNO <luca.bruno@coreos.com>2021-08-20 10:58:24 +0000
committerLuca BRUNO <luca.bruno@coreos.com>2021-08-20 16:11:04 +0000
commit8a5241dd6a6bc4d30195c9d461f50248b0230fc5 (patch)
tree797cc3ee699bf9a9c585e6eba497f1a626df63fc
parent3209acbdbe9d4e0ea45c1ed711655c9ddb55a8b3 (diff)
downloadostree-8a5241dd6a6bc4d30195c9d461f50248b0230fc5.tar.gz
lib/commit: autofix permissions for bare-user-only
This tweaks commit logic to detect bare-user-only repositories and canonicalize permissions automatically.
-rw-r--r--src/libostree/ostree-repo-commit.c29
-rw-r--r--src/libostree/ostree-repo.h6
-rw-r--r--tests/basic-test.sh2
-rwxr-xr-xtests/test-basic-user-only.sh14
4 files changed, 40 insertions, 11 deletions
diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c
index c07526fc..249e792c 100644
--- a/src/libostree/ostree-repo-commit.c
+++ b/src/libostree/ostree-repo-commit.c
@@ -3286,22 +3286,35 @@ _ostree_repo_commit_modifier_apply (OstreeRepo *self,
GFileInfo *file_info,
GFileInfo **out_modified_info)
{
+ gboolean canonicalize_perms = FALSE;
+ gboolean has_filter = FALSE;
OstreeRepoCommitFilterResult result = OSTREE_REPO_COMMIT_FILTER_ALLOW;
GFileInfo *modified_info;
- if (modifier == NULL ||
- (modifier->filter == NULL &&
- (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS) == 0))
+ /* Auto-detect bare-user-only repo, force canonical permissions. */
+ if (self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY)
+ canonicalize_perms = TRUE;
+
+ if (modifier != NULL)
+ {
+ if ((modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS) != 0)
+ canonicalize_perms = TRUE;
+ if (modifier->filter != NULL)
+ has_filter = TRUE;
+ }
+
+ if (!(canonicalize_perms || has_filter))
{
*out_modified_info = g_object_ref (file_info);
- return OSTREE_REPO_COMMIT_FILTER_ALLOW;
+ return OSTREE_REPO_COMMIT_FILTER_ALLOW; /* Note: early return (no actions needed) */
}
modified_info = g_file_info_dup (file_info);
- if (modifier->filter)
+
+ if (has_filter)
result = modifier->filter (self, path, modified_info, modifier->user_data);
- if ((modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS) != 0)
+ if (canonicalize_perms)
{
guint mode = g_file_info_get_attribute_uint32 (modified_info, "unix::mode");
switch (g_file_info_get_file_type (file_info))
@@ -3618,8 +3631,8 @@ write_content_to_mtree_internal (OstreeRepo *self,
/* Load flags into boolean constants for ease of readability (we also need to
* NULL-check modifier)
*/
- const gboolean canonical_permissions = modifier &&
- (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS);
+ const gboolean canonical_permissions = self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY ||
+ (modifier && (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS));
const gboolean devino_canonical = modifier &&
(modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_DEVINO_CANONICAL);
/* We currently only honor the CONSUME flag in the dfd_iter case to avoid even
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index 08d3d408..1a9aa325 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -678,10 +678,14 @@ typedef OstreeRepoCommitFilterResult (*OstreeRepoCommitFilter) (OstreeRepo *r
* @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_NONE: No special flags
* @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS: Do not process extended attributes
* @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES: Generate size information.
- * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS: Canonicalize permissions for bare-user-only mode.
+ * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS: Canonicalize permissions.
* @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_ERROR_ON_UNLABELED: Emit an error if configured SELinux policy does not provide a label
* @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME: Delete added files/directories after commit; Since: 2017.13
* @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_DEVINO_CANONICAL: If a devino cache hit is found, skip modifier filters (non-directories only); Since: 2017.14
+ *
+ * Flags modifying commit behavior. In bare-user-only mode, @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS
+ * is automatically enabled.
+ *
*/
typedef enum {
OSTREE_REPO_COMMIT_MODIFIER_FLAGS_NONE = 0,
diff --git a/tests/basic-test.sh b/tests/basic-test.sh
index 89d35273..7946ffa3 100644
--- a/tests/basic-test.sh
+++ b/tests/basic-test.sh
@@ -31,7 +31,7 @@ if is_bare_user_only_repo repo; then
# In bare-user-only repos we can only represent files with uid/gid 0, no
# xattrs and canonical permissions, so we need to commit them as such, or
# we end up with repos that don't pass fsck
- COMMIT_ARGS="--canonical-permissions --no-xattrs"
+ COMMIT_ARGS="--no-xattrs"
DIFF_ARGS="--owner-uid=0 --owner-gid=0 --no-xattrs"
# Also, since we can't check out uid=0 files we need to check out in user mode
CHECKOUT_U_ARG="-U"
diff --git a/tests/test-basic-user-only.sh b/tests/test-basic-user-only.sh
index 02129b28..7ef153c3 100755
--- a/tests/test-basic-user-only.sh
+++ b/tests/test-basic-user-only.sh
@@ -25,7 +25,7 @@ set -euo pipefail
mode="bare-user-only"
setup_test_repository "$mode"
-extra_basic_tests=6
+extra_basic_tests=7
. $(dirname $0)/basic-test.sh
$CMD_PREFIX ostree --version > version.yaml
@@ -112,3 +112,15 @@ $OSTREE checkout --force-copy perms out
$OSTREE checkout ${CHECKOUT_H_ARGS} --union-identical perms out
$OSTREE fsck
echo "ok checkout checksum with canonical perms"
+
+cd ${test_tmpdir}
+rm repo -rf
+ostree_repo_init repo init --mode=bare-user-only
+rm files -rf && mkdir files
+echo afile > files/afile
+$OSTREE commit ${COMMIT_ARGS} -b perms files
+rm out -rf
+$OSTREE checkout --force-copy perms out
+$OSTREE checkout ${CHECKOUT_H_ARGS} --union-identical perms out
+$OSTREE fsck
+echo "ok automatic canonical perms for bare-user-only"