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

OS.File.write functions fail when user has no write permission for directory #70

Open
verbosemode opened this issue Jul 16, 2017 · 4 comments

Comments

@verbosemode
Copy link

OS.File.write functions use with_oc, which creates temporary files in the directory of the target file. This however fails if the user has just permissions to write to the file, but not for the directory itself.

Maybe this could be fixed by making the directory for the temp files configurable for these functions. But in this case special caution might be required by the user to not use a world-readable directory if the files contain sensitive information.

Here are two examples where the write functions fail.

Example 1: Writing to files in /sys on GNU/Linux

utop # OS.File.write (Fpath.v "/sys/class/backlight/intel_backlight/brightness") "500";;

  • : (unit, _[> Rresult.R.msg ]) result = Result.Error (`Msg
    "create temporary file /sys/class/backlight/intel_backlight/bos-bf1c94.tmp: Permission denied")

Example 2: Writing to a file in a root-owned directory in /tmp, where the user has only write permission to this single file

$ whoami
lobo
$ mkdir /tmp/foo
$ touch /tmo/foo/bar
$ sudo chown root:root /tmp/foo
$ sudo chmod 755 /tmp/foo
$ ls -ld /tmp/foo
drwxr-xr-x 2 root root 4096 Jul 16 15:02 /tmp/foo
$ ls -ld /tmp/foo/bar
-rw------- 1 lobo lobo 0 Jul 16 15:02 /tmp/foo/bar

utop # OS.File.write (Fpath.v "/tmp/foo/bar") "500";;

  • : (unit, _[> Rresult.R.msg ]) result = Result.Error (`Msg "create temporary file /tmp/foo/bos-b33494.tmp: Permission denied")
@dbuenzli
Copy link
Owner

Yes this is documented here.

I'm afraid there's no good solution to this problem but not use these functions and handle this yourself in these cases, using for example bos' support for temporary files and Bos.OS.File.move.

The problem is that bos wants to guarantee you atomicity which only rename(2) gives you. However many Linux setup have the default temporary directory on another file system which leads to EXDEV errors when you rename(2).

@dbuenzli
Copy link
Owner

Or maybe an atomic optional argument could be added which defaults to true.

@verbosemode
Copy link
Author

Thank you very much for the clarification. Having an atomic argument sounds like a good solution, if it doesn't clutter the code too much. Since this is really just a corner case. Actually, example 2 was just made up and I would have only needed it for writing to /sys recently.

@dbuenzli
Copy link
Owner

dbuenzli commented Oct 8, 2018

Actually, example 2 was just made up and I would have only needed it for writing to /sys recently.

Note that I guess example1 could be solved by stating the file and avoid doing this on non-regular files. This could also solve the problem for writing to /dev/stdout and /dev/stderr.

/cc @rizo

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