From c6b72f527bd836d810890dfc6c8efd0229157fc3 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Thu, 19 Aug 2021 13:50:21 +0000 Subject: [PATCH 1/2] lib/core/checksum: add flag to use canonical permissions This adds a new `OSTREE_CHECKSUM_FLAGS_CANONICAL_PERMISSIONS` checksumming flag, which is needed in bare-user-only mode to ignore local IDs. --- src/libostree/ostree-core.c | 8 ++++++++ src/libostree/ostree-core.h | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c index 6a7c2afa..aecaf31a 100644 --- a/src/libostree/ostree-core.c +++ b/src/libostree/ostree-core.c @@ -984,6 +984,9 @@ ostree_checksum_file_at (int dfd, g_autoptr(GFileInfo) file_info = _ostree_stbuf_to_gfileinfo (stbuf); + const gboolean canonicalize_perms = + ((flags & OSTREE_CHECKSUM_FLAGS_CANONICAL_PERMISSIONS) != 0); + g_autoptr(GInputStream) in = NULL; if (S_ISREG (stbuf->st_mode)) { @@ -991,6 +994,11 @@ ostree_checksum_file_at (int dfd, if (!glnx_openat_rdonly (dfd, path, FALSE, &fd, error)) return FALSE; in = g_unix_input_stream_new (glnx_steal_fd (&fd), TRUE); + if (canonicalize_perms) + { + g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0); + g_file_info_set_attribute_uint32 (file_info, "unix::gid", 0); + } } else if (S_ISLNK (stbuf->st_mode)) { diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h index 3b903d5c..7dc1ffb7 100644 --- a/src/libostree/ostree-core.h +++ b/src/libostree/ostree-core.h @@ -460,12 +460,21 @@ gboolean ostree_break_hardlink (int dfd, /** * OstreeChecksumFlags: + * @OSTREE_CHECKSUM_FLAGS_NONE: Default checksumming without tweaks. + * (Since: 2017.13.) + * @OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS: Ignore xattrs when checksumming. + * (Since: 2017.13.) + * @OSTREE_CHECKSUM_FLAGS_CANONICAL_PERMISSIONS: Use canonical uid/gid/mode + * values, for bare-user-only mode. (Since: 2021.4.) + * + * Flags influencing checksumming logic. * * Since: 2017.13 */ typedef enum { OSTREE_CHECKSUM_FLAGS_NONE = 0, OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS = (1 << 0), + OSTREE_CHECKSUM_FLAGS_CANONICAL_PERMISSIONS = (1 << 1), } OstreeChecksumFlags; _OSTREE_PUBLIC From d41fcd17a7956fd96831a8fed35309d194c69f9d Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Thu, 19 Aug 2021 14:07:19 +0000 Subject: [PATCH 2/2] lib/repo/checkout: use canonical perms in bare-user-only mode This automatically enables canonical permissions for checkouts in bare-user-only mode. --- src/libostree/ostree-repo-checkout.c | 8 +++++++- tests/basic-test.sh | 8 ++++---- tests/test-basic-user-only.sh | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/libostree/ostree-repo-checkout.c b/src/libostree/ostree-repo-checkout.c index 00c6a773..eaa33a28 100644 --- a/src/libostree/ostree-repo-checkout.c +++ b/src/libostree/ostree-repo-checkout.c @@ -375,6 +375,9 @@ create_file_copy_from_input_at (OstreeRepo *repo, if (repo->disable_xattrs) flags |= OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS; + if (repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY) + flags |= OSTREE_CHECKSUM_FLAGS_CANONICAL_PERMISSIONS; + g_autofree char *actual_checksum = NULL; if (!ostree_checksum_file_at (destination_dfd, destination_name, &dest_stbuf, OSTREE_OBJECT_TYPE_FILE, @@ -526,7 +529,10 @@ checkout_file_hardlink (OstreeRepo *self, * */ OstreeChecksumFlags flags = 0; if (self->disable_xattrs) - flags |= OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS; + flags |= OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS; + + if (self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY) + flags |= OSTREE_CHECKSUM_FLAGS_CANONICAL_PERMISSIONS; g_autofree char *actual_checksum = NULL; if (!ostree_checksum_file_at (destination_dfd, destination_name, diff --git a/tests/basic-test.sh b/tests/basic-test.sh index 4d1356eb..89d35273 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" + COMMIT_ARGS="--canonical-permissions --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" @@ -706,7 +706,7 @@ for x in $(seq 3); do # But they share the GPL echo 'this is the GPL' > pkg${x}/usr/share/licenses/COPYING ln -s COPYING pkg${x}/usr/share/licenses/LICENSE - $OSTREE commit -b union-identical-pkg${x} --tree=dir=pkg${x} + $OSTREE commit ${COMMIT_ARGS} -b union-identical-pkg${x} --tree=dir=pkg${x} done rm union-identical-test -rf for x in $(seq 3); do @@ -756,7 +756,7 @@ cd ${test_tmpdir} rm files -rf && mkdir files touch files/anemptyfile touch files/anotheremptyfile -$CMD_PREFIX ostree --repo=repo commit --consume -b tree-with-empty-files --tree=dir=files +$CMD_PREFIX ostree --repo=repo commit ${COMMIT_ARGS} --consume -b tree-with-empty-files --tree=dir=files $CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} tree-with-empty-files tree-with-empty-files if files_are_hardlinked tree-with-empty-files/an{,other}emptyfile; then fatal "--force-copy-zerosized failed" @@ -773,7 +773,7 @@ echo "ok checkout zero sized files are not hardlinked" $CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files $CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files echo notempty > tree-with-empty-files/anemptyfile.new && mv tree-with-empty-files/anemptyfile{.new,} -$CMD_PREFIX ostree --repo=repo commit --consume -b tree-with-conflicting-empty-files --tree=dir=tree-with-empty-files +$CMD_PREFIX ostree --repo=repo commit ${COMMIT_ARGS} --consume -b tree-with-conflicting-empty-files --tree=dir=tree-with-empty-files # Reset back to base rm tree-with-empty-files -rf $CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files diff --git a/tests/test-basic-user-only.sh b/tests/test-basic-user-only.sh index f65094fd..02129b28 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=5 +extra_basic_tests=6 . $(dirname $0)/basic-test.sh $CMD_PREFIX ostree --version > version.yaml @@ -41,6 +41,7 @@ ostree_repo_init repo init --mode=bare-user-only cd ${test_tmpdir} rm repo-input -rf ostree_repo_init repo-input init --mode=archive + cd ${test_tmpdir} cat > statoverride.txt < 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 checkout checksum with canonical perms"