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

Permission denied: container can't write to /dangerzone #157

Closed
raffaem opened this issue Apr 17, 2022 · 27 comments · Fixed by #336
Closed

Permission denied: container can't write to /dangerzone #157

raffaem opened this issue Apr 17, 2022 · 27 comments · Fixed by #336
Labels
bug Something isn't working container
Milestone

Comments

@raffaem
Copy link

raffaem commented Apr 17, 2022

I have Fedora Workstation 35 and I have compiled dangerzone from source.

It all goes well until I try to sanitize a document, when this error is thrown:

image

@yveszoundi
Copy link

As you're building from source, I think that adding --userns keep-id in container.py "should" fix it.
I had to deal with something similar recently with my own "dangerzone rust-based fork" today (Debian + Podman).

If that still doesn't work, I've seen podman bugs/questions apparently related to SELinux leading to "permission denied" issues. I don't know if those type of problems still happen on redhat like-systems. => TL;DR add :z at the end (for each volume).

@odub
Copy link

odub commented Jun 5, 2022

I created a branch implementing @yveszoundi's recommendations.

It resolves the issue for input_file access but still seems to have trouble writing to the /dangerzone volume that's used for output.

Branch

CLI output:

QSocketNotifier: Can only be used with threads started with QThread
QObject::connect: No such signal QPlatformNativeInterface::systemTrayWindowChanged(QScreen*)
load glyph failed err=6 face=0x55769096f250, glyph=65535
> /usr/bin/podman run --network none --userns keep-id -v '/home/odub/Downloads/test.pdf:/tmp/input_file:z' -v /home/odub/.config/dangerzone/tmp/tmpwqn3j8ll/pixels:/dangerzone:z dangerzone.rocks/dangerzone /usr/bin/python3 /usr/local/bin/dangerzone.py document-to-pixels
3% Separating document into pages
5% Converting page 1/1 to pixels
50% Converted document to pixels
Invalid JSON returned from container: Traceback (most recent call last):

Invalid JSON returned from container:   File "/usr/lib/python3.10/shutil.py", line 813, in move

Invalid JSON returned from container:     os.rename(src, real_dst)

Invalid JSON returned from container: OSError: [Errno 18] Cross-device link: '/tmp/page-1.rgb' -> '/dangerzone/page-1.rgb'

Invalid JSON returned from container:

Invalid JSON returned from container: During handling of the above exception, another exception occurred:

Invalid JSON returned from container:

Invalid JSON returned from container: Traceback (most recent call last):

Invalid JSON returned from container:   File "/usr/local/bin/dangerzone.py", line 541, in <module>

Invalid JSON returned from container:     sys.exit(main())

Invalid JSON returned from container:   File "/usr/local/bin/dangerzone.py", line 532, in main

Invalid JSON returned from container:     return converter.document_to_pixels()

Invalid JSON returned from container:   File "/usr/local/bin/dangerzone.py", line 311, in document_to_pixels

Invalid JSON returned from container:     shutil.move(filename, "/dangerzone")

Invalid JSON returned from container:   File "/usr/lib/python3.10/shutil.py", line 833, in move

Invalid JSON returned from container:     copy_function(src, real_dst)

Invalid JSON returned from container:   File "/usr/lib/python3.10/shutil.py", line 435, in copy2

Invalid JSON returned from container:     copystat(src, dst, follow_symlinks=follow_symlinks)

Invalid JSON returned from container:   File "/usr/lib/python3.10/shutil.py", line 378, in copystat

Invalid JSON returned from container:     _copyxattr(src, dst, follow_symlinks=follow)

Invalid JSON returned from container:   File "/usr/lib/python3.10/shutil.py", line 328, in _copyxattr

Invalid JSON returned from container:     os.setxattr(dst, name, value, follow_symlinks=follow_symlinks)

Invalid JSON returned from container: PermissionError: [Errno 13] Permission denied: '/dangerzone/page-1.rgb'

documents-to-pixels failed

Feels like it'd be helpful to take on some more advice at this point

@yveszoundi
Copy link

yveszoundi commented Jun 5, 2022

It's looking good @odub , despite the remaining errors:

  • This is due to operations between different underlying filesystems: overlays vs regular file system.
  • It's been a while since I used Docker, but all the overall code changes are Docker compatible (I think)

Solution final touches

Replace the shutil.move and/or os.rename => shutil.copy/shutil.copy2 + os.remove
or
Just run a shell command if "shutil" does funny stuff behind the scenes: mv source destination

References

Working equivalent Rust solution (sorry for Rust)

https://github.com/rimerosolutions/dangerzone-rust/blob/main/dangerzone_container/src/main.rs#L144

Related problem in the past (I think), in this repo

Use shutil.move instead of os.rename in the final step - Issue 134

Similar problems with explanations

@deeplow deeplow added the bug Something isn't working label Aug 17, 2022
@deeplow
Copy link
Contributor

deeplow commented Aug 17, 2022

@odub I've recently fixed a similar problem. If you have a chance, can you check that it's working on this branch #183.

I don't know if those type of problems still happen on redhat like-systems. => TL;DR add :z at the end (for each volume).

If it doesn't work we'll need to add this.

@deeplow deeplow changed the title Permission denied Permission denied: container can't write to /dangerzone Aug 17, 2022
@deeplow deeplow added this to the 0.3.2 milestone Aug 17, 2022
@deeplow
Copy link
Contributor

deeplow commented Aug 25, 2022

Closing this as it is probably solved in the 0.3.2 release. Feel free to open this in case it wasn't.

@deeplow deeplow closed this as completed Aug 25, 2022
@Roxiun
Copy link

Roxiun commented Sep 6, 2022

@deeplow

Closing this as it is probably solved in the 0.3.2 release. Feel free to open this in case it wasn't.

I'm getting this issue.

I followed this:
#118 (comment)

I tried both with this project and for fork on the 118-podman-machine branch (with the apparmor removed).

Invalid JSON returned from container: Traceback (most recent call last):

Invalid JSON returned from container:   File "/usr/lib/python3.10/shutil.py", line 815, in move

Invalid JSON returned from container:     os.rename(src, real_dst)

Invalid JSON returned from container: OSError: [Errno 18] Cross-device link: '/tmp/page-1.rgb' -> '/dangerzone/page-1.rgb'

Invalid JSON returned from container:

Invalid JSON returned from container: During handling of the above exception, another exception occurred:

Invalid JSON returned from container:

Invalid JSON returned from container: Traceback (most recent call last):

Invalid JSON returned from container:   File "/usr/local/bin/dangerzone.py", line 542, in <module>

Invalid JSON returned from container:     sys.exit(main())

Invalid JSON returned from container:   File "/usr/local/bin/dangerzone.py", line 533, in main

Invalid JSON returned from container:     return converter.document_to_pixels()

Invalid JSON returned from container:   File "/usr/local/bin/dangerzone.py", line 312, in document_to_pixels

Invalid JSON returned from container:     shutil.move(filename, "/dangerzone")

Invalid JSON returned from container:   File "/usr/lib/python3.10/shutil.py", line 835, in move

Invalid JSON returned from container:     copy_function(src, real_dst)

Invalid JSON returned from container:   File "/usr/lib/python3.10/shutil.py", line 434, in copy2

Invalid JSON returned from container:     copyfile(src, dst, follow_symlinks=follow_symlinks)

Invalid JSON returned from container:   File "/usr/lib/python3.10/shutil.py", line 256, in copyfile

Invalid JSON returned from container:     with open(dst, 'wb') as fdst:

Invalid JSON returned from container: PermissionError: [Errno 13] Permission denied: '/dangerzone/page-1.rgb'

documents-to-pixels failed

@toms-place
Copy link

As you can see here:

user_args = ["-u", "dangerzone"]

The container always gets startet with user dangerzone.

If you want to map directories from the current user on the host you would need to set --user $(id -u):$(id -g)

@deeplow
Copy link
Contributor

deeplow commented Sep 14, 2022

Just to be double sure, @Roxiun did you rebuild the image? i.e. run `./install/linux/build-image.sh (or whatever OS you're on). If you haven't done so yet, this could be the source of the issue.

If you want to map directories from the current user on the host you would need to set --user $(id -u):$(id -g)

So you're arguing is that in order to use volumes in containers you need to run the container as the current user? From my testing this wasn't the case.

And I just tested getting a shell on the document-to-pixels container and confirmed files touched in /dangerzone within the container (with user dangerzone):

/ $ cd dangerzone/
/dangerzone $ ls
/dangerzone $ touch some_file
/dangerzone $ ls -lah some_file 
-rw-r--r--    1 dangerzo dangerzo       0 Sep 14 11:59 some_file

did in fact show up in the mapped directory on the host:

[user@dz-dev dangerzone]$ ls -lah /home/user/.config/dangerzone/tmp/tmp6ndq6e07/pixels
total 8.0K
drwxr-xr-x 2 user user 4.0K Sep 14 12:59 .
drwx------ 4 user user 4.0K Sep 14 12:58 ..
-rw-r--r-- 1 user user    0 Sep 14 12:59 some_file

@toms-place
Copy link

@deeplow can you please show me the ids of the user inside the container and the id of the user on the host?

in my case I had user 1001 on the host and user 1000 inside the container, so I couldn't write inside the /dangerzone directory. (I am on debian btw.)

@Roxiun
Copy link

Roxiun commented Sep 16, 2022

@deeplow

Just to be double sure, @Roxiun did you rebuild the image? i.e. run `./install/linux/build-image.sh (or whatever OS you're on). If you haven't done so yet, this could be the source of the issue.

Yep i used ./install/macos/build-image.sh to build after modifying the file to use podman (see below)

#!/bin/sh

echo "Building container image"
podman build container --tag dangerzone.rocks/dangerzone

echo "Saving container image"
podman save dangerzone.rocks/dangerzone -o share/container.tar

echo "Compressing container image"
gzip -f share/container.tar

echo "Looking up the image id"
podman image ls dangerzone.rocks/dangerzone | grep "dangerzone.rocks/dangerzone" | tr -s ' ' | cut -d' ' -f3 > share/image-id.txt

@deeplow
Copy link
Contributor

deeplow commented Sep 19, 2022

In the container it was running as user 1000:

/ $ whoami
dangerzone
/ $ id
uid=1000(dangerzone) gid=1000(dangerzone)
/ $ ps -ef
PID   USER     TIME  COMMAND
    1 dangerzo  0:00 /usr/bin/python3 /usr/local/bin/dangerzone.py document-to-pixels

And in the host it was also running as user 1000:

$ ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
[...]
user        8074    7968 86 11:35 ?        00:00:07 pdftocairo /tmp/page-3.pdf -png -singlefile /tmp/page-3
$ id
uid=1000(user) gid=1000(user) groups=1000(user),98(qubes)

@deeplow deeplow reopened this Sep 19, 2022
@rtfmkiesel
Copy link

+1

I'm on Debian 11 and also get the error PermissionError: [Errno 13] Permission denied: '/tmp/input_file'.

It happens with the version installed by 'apt' as well as when building from the v0.3.2 master branch. I tried running 'dangerzone-cli' or the builds as uid 1000 or 0. The error stays the same.

@websi96 Where would I need to add --user $(id -u):$(id -g)?

@toms-place
Copy link

As you can see here:

user_args = ["-u", "dangerzone"]

The container always gets startet with user dangerzone.

If you want to map directories from the current user on the host you would need to set --user $(id -u):$(id -g)

I thought about changing it like this in container.py:

user_args = ["-u", "dangerzone"] to user_args = ["-u", "$(id -u):$(id -g)"]

@rtfmkiesel
Copy link

This results in Error: unable to find user $(id -u): no matching entries in passwd file

However if I set the ID to either 0:0 or 1000:1000 it works if I execute dangerzone with the matching user.

@toms-place
Copy link

I see.. Then there must be some other way to resolve the current ID of the user via this Python script I guess..

It doesn't interpolate the environment variables as I guessed it would..

@rtfmkiesel
Copy link

rtfmkiesel commented Oct 6, 2022

I was able to resolve this issue for me. (dangerzone v0.3.2 on Debian 11 inside a VirtualBox)

So when a user wants to access a VirtualBox shared folder, the user needs to be inside the vboxsf group. This will cause permission issues in dangerzone if the input file is located inside a VirtualBox shared folder. If I copy the files from the VirtualBox shared folder to /tmp or /home/myuser it runs without any problems.

edit: works on the "apt install" version as well as a self built version

@apyrgio
Copy link
Contributor

apyrgio commented Oct 6, 2022

@Lu-Ka: Thanks for digging more into this, and posting your workaround. If possible, could you clarify something?

In the Dangerzone container you are not part of the vboxsf group, since the container is in a different user namespace (which is good!). As a result, the file which will be mounted in the Dangerzone container will have an unknown user and group, most probably nobody. This is actually the case for every file that will get mounted into the Dangerzone container, even the ones you move at /home or /tmp. The reason you can read those is because their permissions are usually -rw-r--r-- (0644). That is, even other users (besides owner/group) can read the file.

So, what is different with the file in the Virtualbox shared folder? Can you share its permissions here? Also, what's the guest OS?

@apyrgio
Copy link
Contributor

apyrgio commented Oct 6, 2022

@websi96: Did you manage to make Dangerzone work, or do you still need to use a custom switch?

@rtfmkiesel
Copy link

Host OS: Fedora 36

Here is the output for the Virtualbox shared folder from inside the Debian 11 VM:

me@debian:~$ ls -la /IN
total 8
drwxrwx---  1 root vboxsf   14 Oct  6 16:39 .
drwxr-xr-x 20 root root   4096 Oct  5 13:52 ..
-rwxrwx---  1 root vboxsf 1057 Jan 22  2020 img.png

@toms-place
Copy link

I did not look into it further.. I just started it as user 1000 on my host.

@apyrgio
Copy link
Contributor

apyrgio commented Oct 6, 2022

Thanks for the output @Lu-Ka . So, this is why the container couldn't read img.png, because it's not readable by other users. I wonder, are these permissions the same in your Fedora 36 host, or does vboxsf somehow intervene here?

In any case, your workaround makes sense. What Dangerzone could do here, both for your case and @websi96's, is to copy the file into a temporary directory, before any container starts, and set its permissions accordingly so that the first container can read it. This requires some thinking, but I think it would be feasible.

@rtfmkiesel
Copy link

That would work. It would just make the process a bit slower for larger files. (Don't think that this matters in the context of using dangerzone)

The vboxsf group does not exist on my host OS since its only needed for users inside of a VirtualBox VM (where the VirtualBox Guest Additions are installed). On my host OS img.png has:

$ ls -la /somepath/IN
total 4
drwxr-xr-x. 1 luka luka   14  6. Okt 16:39 .
drwxr-xr-x. 1 luka luka  422  6. Okt 16:39 ..
-rw-r--r--. 1 luka luka 1057 22. Jan 2020  img.png

VirtualBox on my host runs as the same user:

luka        5296  5.6  2.8 2611940 223348 ?      Sl   23:07   0:00 /usr/lib64/virtualbox/VirtualBox

@apyrgio
Copy link
Contributor

apyrgio commented Oct 10, 2022

Yeah, the processing pipeline of Dangerzone ends up reading and writing a single file multiple times, so an extra copy wouldn't hurt. The pros outweigh the cons in this case.

Thanks a lot for sharing the permissions in your host OS btw. So, we can see that the file in the host Fedora OS has the typical permissions (644):

-rw-r--r--. 1 luka luka 1057 22. Jan 2020  img.png

whereas the same file within the Debian 11 VM has different permissions (770):

-rwxrwx---  1 root vboxsf 1057 Jan 22  2020 img.png

So, Virtualbox Shared Folders do not take into account the file permissions in the host system, by default. Users can alter this behavior though, and mount the shared folder under their own UID/GID in the guest VM. See here for more info: https://forums.virtualbox.org/viewtopic.php?f=3&t=15868.

@apyrgio
Copy link
Contributor

apyrgio commented Oct 10, 2022

All in all, we have a workaround for this issue for now. I propose keeping this issue open until we fix the underlying cause, which is ensuring that the Dangerzone container can access the files reliably.

@rtfmkiesel
Copy link

rtfmkiesel commented Oct 10, 2022

Thanks for the link. I did not know that you can mount VirtualBox shares manually. I can confirm mounting it manually via sudo mount -t vboxsf -o rw,uid=1000,gid=1000 IN /IN works as intended and thus also is a valid workaround. When you add a share just disable Auto-Mount under Settings/Shared Folders.

before

For auto mount add IN /IN vboxsf defaults,uid=1000,gid=1000,umask=0022 0 0 to /etc/fstab and add vboxsf to /etc/modules. The VirtualBox guest utils need to be installed.

Non the less I think a temporary file copy made by dangerzone would be a good idea.

@henryreed
Copy link

henryreed commented Feb 4, 2023

I have this error as well on Fedora 37 with SELinux on. Running sudo setenforce 0 fixes the issue, but it's not advisable to turn off SELinux.

If that still doesn't work, I've seen podman bugs/questions apparently related to SELinux leading to "permission denied" issues. I don't know if those type of problems still happen on redhat like-systems. => TL;DR add :z at the end (for each volume).

This is the reason why under Fedora 37, the Permission Denied issue occurs. I suspect this is also what occurs in #260. The :z argument needs to be amended to all mount commands in order for Dangerzone to work under systems with SELinux and podman. That argument is ignored and does not break compatibility with systems that do not use SELinux. I have not tested this on systems using docker.

@deeplow
Copy link
Contributor

deeplow commented Feb 6, 2023

We have work-in-progress code that redoes the day documents are mounted and their permissions. It's not SELinux-related but it might fix this issue for some #248.

@apyrgio apyrgio modified the milestones: 0.5.0, 0.4.1 Feb 8, 2023
apyrgio added a commit that referenced this issue Feb 8, 2023
Copy input files in a temporary dir before mounting them, thereby
changing their permissions, without affecting the original files. This
way, we can avoid cases where a file is accessible to the user only due
to a supplemental user group, which does not work for containers.

Fixes #157
Fixes #260
Fixes #335
apyrgio added a commit that referenced this issue Feb 8, 2023
Copy input files in a temporary dir before mounting them, thereby
changing their permissions, without affecting the original files. This
way, we can avoid cases where a file is accessible to the user only due
to a supplemental user group, which does not work for containers.

Fixes #157
Fixes #260
Fixes #335
apyrgio added a commit that referenced this issue Feb 15, 2023
Copy input files in a temporary dir before mounting them, thereby
changing their permissions, without affecting the original files. This
way, we can avoid cases where a file is accessible to the user only due
to a supplemental user group, which does not work for containers.

Fixes #157
Fixes #260
Fixes #335
apyrgio added a commit that referenced this issue Feb 15, 2023
Copy input files in a temporary dir before mounting them, thereby
changing their permissions, without affecting the original files. This
way, we can avoid cases where a file is accessible to the user only due
to a supplemental user group, which does not work for containers.

Fixes #157
Fixes #260
Fixes #335
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working container
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants