Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bare-user files are always executable (0755 perms) #907

Closed
gtristan opened this issue Jun 4, 2017 · 6 comments
Closed

bare-user files are always executable (0755 perms) #907

gtristan opened this issue Jun 4, 2017 · 6 comments

Comments

@gtristan
Copy link
Contributor

gtristan commented Jun 4, 2017

With bare repository this is not an issue, but with bare-user and user mode checkouts, my expectation is that permissions are not munged, only file ownership is left to the active user.

This test case exhibits some strange behavior:

#!/bin/bash

# Test case demonstrating files becoming executable out of thin air
#
# This seems to occur with bare-user repository and checking out in user mode
#
# Usage:
#
#  ./test.sh <work directory>
#
#
set -e
set -x

topdir=${1}
mkdir -p "${topdir}"
topdir="$(cd ${topdir} && pwd)"

repo="${topdir}/repo"
checkin="${topdir}/checkin"
checkout="${topdir}/checkout"

#
# Create test data with some permissions
#
mkdir -p "${checkin}/subdir"
echo "foo" > "${checkin}/foo"
echo "bar" > "${checkin}/bar"
chmod 0600 "${checkin}/foo"
chmod 0755 "${checkin}/bar"
echo "foo" > "${checkin}/subdir/foo"
echo "bar" > "${checkin}/subdir/bar"
chmod 0600 "${checkin}/subdir/foo"
chmod 0755 "${checkin}/subdir/bar"
touch "${checkin}/emptyfile"

#
# Init repo with bare-user
#
ostree init --repo "${repo}" --mode bare-user

#
# Create commit
#
ostree commit --repo "${repo}" --branch "test" -s "test commit" "${checkin}"

#
# Checkout commit, just pass in --disable-cache here because it's default
# when using the API (but should not make a difference, here we are not
# using a compressed repo anyway).
#
ostree checkout --repo "${repo}" --user-mode --disable-cache "test" "${checkout}"
@cgwalters cgwalters changed the title Permissions change in strange ways with bare-user repository bare-user files are always executable (0755 perms) Jun 5, 2017
@cgwalters
Copy link
Member

Some discussion on list about this https://mail.gnome.org/archives/ostree-list/2017-June/msg00011.html

Honestly, I don't know why we use 0755 always. Looking at a patch.

cgwalters added a commit to cgwalters/ostree that referenced this issue Jun 5, 2017
Having every object in a bare-user repo (and checkouts) be executable
is ugly.  I can't think of a good reason to do that.  So make
the committed mode semantics mirror that for user-mode checkouts; we
strip suid/sgid bits.

However, we also do ensure that the written files are read/writable by the
owning user, since otherwise we couldn't do anything to them. I'm not aware of
any real use cases for non-readable/non-writable by owner files in ostree.

Closes: ostreedev#907
@cgwalters
Copy link
Member

PR in #908 - does that make sense to you?

@gtristan
Copy link
Contributor Author

gtristan commented Jun 6, 2017

Well, sort of :)

First, yes now that I have understood a bit more the purpose of "bare-user" mode is for users to run software in these checkouts inside containers, it makes sense for this use case to strip the suid bits, and certainly this part was previously missing for hardlink user mode checkouts of "bare-user" repositories.

Second, I'm not sure it's necessary to force read-write for user onto the mode bits. Probably there are two opposing things to consider here:

  • Why would any commit originally have files without these bits ? Surely if they did, there is a reason, or it just never happens.
  • The rationale of forcing these bits may be that we are worried that this may cause a regression to containers which previously expected these bits to be forced, but can probably live with only forcing read-write for owning user ?

Anyway, seems to me that the chance of these bits not already being present at commit time are astronomically low, on my system for example:

# sudo find / ! -perm /u+wr
/dev/pts/ptmx
/run/crond.reboot
/run/systemd/inaccessible
/run/systemd/inaccessible/sock
/run/systemd/inaccessible/fifo
/run/systemd/inaccessible/blk
/run/systemd/inaccessible/chr
/run/systemd/inaccessible/dir
/run/systemd/inaccessible/reg

Not sure what these files are for, also not sure what it buys us to force them to be read-write.

@gtristan
Copy link
Contributor Author

gtristan commented Jun 6, 2017

Note: Another more appropriate invocation of find (find any files which either do not have S_IRUSR or do not have S_IWUSR) sudo find / ! -perm /u+w -o ! -perm /u+r yielded more interesting results.

On my system for instance, there is a huge amount of results from git repositories which store the objects as read-only even for the regular user, since those are never expected to change this seems like a reasonable mode.

@gtristan
Copy link
Contributor Author

gtristan commented Jun 7, 2017

As I am a bit worried about the SUID situation and how I will be able to create filesystem images which do contain setuid binaries, from inside bubblewrap sandboxes based on user mode checkouts that do not contain setuid binaries (which seems a problem I wont be able to escape without horrible hacks like yocto's pseudo or debian's fakeroot)...

I would like to ask that this line in #908:

const mode_t content_mode = (mode & ~(S_ISUID|S_ISGID)) | S_IRUSR | S_IWUSR;

At least be changed to simply be:

const mode_t content_mode = (mode & ~(S_ISUID|S_ISGID));

If the concern is only about setuid & setgid binaries being owned by the checking out user (which is a valid concern, but something I think a user might want to live with for some use cases), then I dont see why we should further be forcing read/write permissions on these files.

@cgwalters
Copy link
Member

Ignore /run - it's a dynamic tmpfs, so one wouldn't commit it to ostree.

I think the notion I had of requiring writablity came from directories; see this Red Hat bugzilla.

Oh wait, the rationale for user-writable is in the comment - we need it to write xattrs. However,
But you're clearly right, there's no reason to force writability. And I guess not readability either. We just need to special case the non-writable-by-user by doing the fchmod() twice. Updating the patch.

cgwalters added a commit to cgwalters/ostree that referenced this issue Jun 7, 2017
Having every object in a bare-user repo (and checkouts) be executable
is ugly.  I can't think of a good reason to do that; they should only
be executable if their input is.  This does
for `bare-user` what we did for `bare-user-only` in
ostreedev#909
It's also a stronger version of what we do with `checkout -U` in suppressing
suid - here we also strip world-writable files and the sticky bit (even though
that's meaningless today, it might not be in the future).

Closes: ostreedev#907
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants