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

utime disallowed by user set with force_owner when not given direct FD on file #609

Closed
charles-dyfis-net opened this issue Oct 7, 2021 · 3 comments

Comments

@charles-dyfis-net
Copy link
Contributor

charles-dyfis-net commented Oct 7, 2021

With a file stored on gocryptfs 2.1, when force_owner is used to present the mount point as owned by a different (non-root) user, a process running as that non-root user can successfully run the following Python code to copy a file while preserving its timestamp:

#!/usr/bin/env python3
import os, sys, shutil
source_name, dest_name = sys.argv[1:3]

src_stat = os.lstat(source_name)
with open(source_name, 'rb') as infile:
    with open(dest_name, 'wb') as outfile:
        shutil.copyfileobj(infile, outfile)
        outfile.flush()
        os.utime(outfile.fileno(), (src_stat.st_atime, src_stat.st_mtime))

...but cannot run the following, which differs only that it passes the utimensat syscall a path to the target file as opposed to an already-opened file handle:

#!/usr/bin/env python3
import os, sys, shutil
source_name, dest_name = sys.argv[1:3]

src_stat = os.lstat(source_name)
with open(source_name, 'rb') as infile:
    with open(dest_name, 'wb') as outfile:
        shutil.copyfileobj(infile, outfile)
    os.utime(source_name, (src_stat.st_atime, src_stat.st_mtime))

...which receives a PermissionError: [Errno 1] Operation not permitted

This issue did not exist in gocryptfs 1.7 -- and it impacts far more applications than just the reproducer above (for example, rsync passes utimensat a relative path to open and is subject to this bug).


In the environment where this is reproduced, the backing store for gocryptfs is owned by a special-purpose user that does nothing other than own this directory and run gocryptfs processes; the mount options include -force_owner with the uid and gid of the user running the above code (which is different from the account running gocryptfs itself), and -allow_other.

@charles-dyfis-net
Copy link
Contributor Author

charles-dyfis-net commented Oct 8, 2021

After inspecting with -fusedebug, it looks like force_owner behavior has changed between 1.7 and 2.1.

With gocryptfs 1.7, the response to a CREATE or a LOOKUP has the force_owner-specified UID.

With gocryptfs 2.1, the response to a CREATE or a LOOKUP has the underlying UID, ignoring the value specified for force_owner.

@charles-dyfis-net
Copy link
Contributor Author

#610 fixes this issue, confirming that it is in fact caused by force_owner not being honored for LOOKUP and CREATE.

@charles-dyfis-net charles-dyfis-net changed the title utime sometimes incorrectly disallowed when not given direct FD on file utime disallowed by user set with force_owner when not given direct FD on file Oct 9, 2021
rfjakob added a commit that referenced this issue Oct 15, 2021
@rfjakob
Copy link
Owner

rfjakob commented Oct 15, 2021

Test added ( 3b881b0 ) and patch merged ( 8ec872e ), thanks!

@rfjakob rfjakob closed this as completed Oct 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants