if (objtype == OSTREE_OBJECT_TYPE_FILE &&
self->mode == OSTREE_REPO_MODE_BARE_USER)
{
+ if (!write_file_metadata_to_xattr (fd, uid, gid, mode, xattrs, error))
+ return FALSE;
+
if (!object_is_symlink)
{
- /* We need to apply at least some mode bits, because the repo file was created
- with mode 644, and we need e.g. exec bits to be right when we do a user-mode
- checkout. To make this work we apply all user bits and the read bits for
- group/other. Furthermore, setting user xattrs requires write access, so
- this makes sure it's at least writable by us. (O_TMPFILE uses mode 0 by default) */
- if (fchmod (fd, mode | 0744) < 0)
- return glnx_throw_errno (error);
+ /* Note that previously this path added `| 0755` which made every
+ * file executable, see
+ * https://github.com/ostreedev/ostree/issues/907
+ */
+ const mode_t content_mode = (mode & (S_IFREG | 0775));
+ if (fchmod (fd, content_mode) < 0)
+ return glnx_throw_errno_prefix (error, "fchmod");
}
-
- if (!write_file_metadata_to_xattr (fd, uid, gid, mode, xattrs, error))
- return FALSE;
}
else if (objtype == OSTREE_OBJECT_TYPE_FILE &&
self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY
set -euo pipefail
-echo "1..66"
+echo "1..$((66 + ${extra_basic_tests:-0}))"
$CMD_PREFIX ostree --version > version.yaml
python -c 'import yaml; yaml.safe_load(open("version.yaml"))'
is_bare_user_only_repo () {
grep -q 'mode=bare-user-only' $1/config
}
+
+# Given a path to a file in a repo for a ref, print its checksum
+ostree_file_path_to_checksum() {
+ repo=$1
+ ref=$2
+ path=$3
+ $CMD_PREFIX ostree --repo=$repo ls -C $ref $path | awk '{ print $5 }'
+}
+
+# Given a path to a file in a repo for a ref, print the path to its object
+ostree_file_path_to_object_path() {
+ repo=$1
+ ref=$2
+ path=$3
+ checksum=$(ostree_file_path_to_checksum $repo $ref $path)
+ test -n "${checksum}"
+ echo ${repo}/objects/${checksum:0:2}/${checksum:2}.file
+}
setup_test_repository "bare-user"
+extra_basic_tests=3
. $(dirname $0)/basic-test.sh
+
+# Reset things so we don't inherit a lot of state from earlier tests
+rm repo files -rf
+setup_test_repository "bare-user"
+
+cd ${test_tmpdir}
+objpath_nonexec=$(ostree_file_path_to_object_path repo test2 baz/cow)
+# Sigh, umask
+touch testfile
+default_mode=$(stat -c '%a' testfile)
+rm testfile
+assert_file_has_mode ${objpath_nonexec} ${default_mode}
+objpath_ro=$(ostree_file_path_to_object_path repo test2 baz/cowro)
+assert_file_has_mode ${objpath_ro} 600
+objpath_exec=$(ostree_file_path_to_object_path repo test2 baz/deeper/ohyeahx)
+assert_file_has_mode ${objpath_exec} 755
+echo "ok bare-user committed modes"
+
+rm test2-checkout -rf
+$OSTREE checkout -U -H test2 test2-checkout
+cd test2-checkout
+assert_file_has_mode baz/cow ${default_mode}
+assert_file_has_mode baz/cowro 600
+assert_file_has_mode baz/deeper/ohyeahx 755
+echo "ok bare-user checkout modes"
+
+rm test2-checkout -rf
+$OSTREE checkout -U -H test2 test2-checkout
+touch test2-checkout/unwritable
+chmod 0400 test2-checkout/unwritable
+$OSTREE commit -b test2-unwritable --tree=dir=test2-checkout
+chmod 0600 test2-checkout/unwritable
+rm test2-checkout -rf
+$OSTREE checkout -U -H test2-unwritable test2-checkout
+cd test2-checkout
+assert_file_has_mode unwritable 400
+echo "ok bare-user unwritable"