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

Some AppImages break, "Permission denied" #2690

Open
probonopd opened this issue May 11, 2019 · 29 comments
Open

Some AppImages break, "Permission denied" #2690

probonopd opened this issue May 11, 2019 · 29 comments
Labels
bug Something isn't working

Comments

@probonopd
Copy link
Contributor

probonopd commented May 11, 2019

Some AppImages break with Permission denied:

For example:

me@host:~$ firejail --version
firejail version 0.9.49

me@host:~$ wget -c -q "https://github.com/AppImage/AppImageHub/releases/download/deps/firejail.tar.gz" ; sudo tar xf firejail.tar.gz -C /
me@host:~$ sudo chown root:root /usr/bin/firejail ; sudo chmod u+s /usr/bin/firejail # suid
me@host:~$ firejail --quiet --noprofile --net=none --appimage Downloads/tectonic-continuous-x86_64.AppImage 

/bin/bash: /run/firejail/appimage/.appimage-10595/AppRun: Permission denied ### ERROR <------

# Without Firejail it works:

me@host:~$ Downloads/tectonic-continuous-x86_64.AppImage 
error: The following required arguments were not provided:
    <INPUT>

USAGE:
    tectonic-continuous-x86_64.AppImage <INPUT> --chatter <LEVEL> --format <PATH> --outfmt <FORMAT> --pass <PASS>

For more information try --help

References:

@rusty-snake
Copy link
Collaborator

May related to #2671.

@rusty-snake
Copy link
Collaborator

@probonopd firejail 0.9.49 is old, have you try it with the lastest firejail version?

@probonopd
Copy link
Contributor Author

Yes:

me@host:~$ firejail --quiet --noprofile --net=none --appimage Downloads/tectonic-continuous-x86_64.AppImage 
/bin/bash: /run/firejail/appimage/.appimage-14495/AppRun: Permission denied
me@host:~$ firejail --version
firejail version 0.9.60

@probonopd
Copy link
Contributor Author

Why is this? We also have the same issue with PhotoGIMP now.

@rusty-snake
Copy link
Collaborator

rusty-snake commented Jun 7, 2019

$ firejail --noprofile --shell=/bin/bash --appimage Downloads/PhotoGIMP-x86_64.AppImage
/bin/bash: /run/firejail/appimage/.appimage-24531/AppRun: Permission denied
$ cat myshell
#!/bin/bash
ls -AlR /run/firejail/appimage
$ ls -l myshell
rwxr-xr-x myshell
$ firejail --noprofile --shell=~/myshell --appimage Downloads/PhotoGIMP-x86_64.AppImage
/run/firejail/appimage:
total 0
drwx------.  root root … .appimage-24773
ls: cannot open directory '/run/firejail/appimage/.appimage-24773': Permission denied

=> /run/firejail/appimage/.appimage-XXXXX is owned by root and has 700.

@rusty-snake rusty-snake added the bug Something isn't working label Jun 7, 2019
@probonopd
Copy link
Contributor Author

probonopd commented Jun 8, 2019

Apparently the permissions for non-root users are missing in the squashfs image. What is interesting, though, is that the native AppImage implementation (using squashfuse) can still use those, but Firejail cannot. Is this because Firejail uses the kernel to mount the squashfs image?

@sudo-give-me-coffee
Copy link

How to make permissions in the right way?

Currently:

chmod 755

Defined in:

https://github.com/sudo-give-me-coffee/PhotoGIMP/blob/bd4964162378347639fff0af751b00893b5f85e3/makePhotoGIMP.sh#L86

This produces the following permissions:

-rwxrwxr-x 1 root root  2451 jun 15 22:24 AppRun
-rw-r--r-- 1 root root  6134 jun 15 22:24 apprun-helper.sh
-rw-rw-r-- 1 root root  8403 jun 15 22:24 gimp.desktop
drwxrwxr-x 5 root root     0 jun 15 22:24 PATCH
-rw-rw-r-- 1 root root 30077 jun 15 22:24 photogimp.png
drwxrwxr-x 2 root root     0 jun 15 22:24 startup_scripts
drwx------ 9 root root     0 jun 15 22:24 usr

Teorically at least AppRun should be run:

rwx  -> Owner  ->  read, write, execute
rwx  -> Group  ->  read, write, execute
r-x  -> Others ->  read, execute

But not occurs:

/bin/bash: /run/firejail/appimage/.appimage-4148/AppRun: Permission denied

@rusty-snake
Copy link
Collaborator

@sudo-give-me-coffee (nice name 😉)
/run/firejail/appimage/.appimage-4148/AppRun may have the right permissions, but
/run/firejail/appimage/.appimage-4148 has the wrong.

@sudo-give-me-coffee
Copy link

I understood, so for now, the ideal is to mount the AppImage outside the sandbox?

@probonopd
Copy link
Contributor Author

I wonder why some AppImages have the wrong permissions there (most AppImages are correct).

In any case, it looks like Firejail is behaving correctly.

@crass
Copy link
Collaborator

crass commented Jul 8, 2019

Actually, I would say that firejail does the wrong thing here.

First a surprising (at least to me) example. I took the tutanota appimage which also has this issue (#2831), and exctracted the squashfs image from the appimage. Then I mounted it with squashfuse:

$ squashfuse tutanota-desktop-linux.AppImage.sqfs tmpmnt/
$ mount|tail -n 1
squashfuse on /tmp/tmpmnt type fuse.squashfuse (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)
$ ls -ld tmpmnt/
drwxr-x--- 6 root root 0 Jul  5 10:47 tmpmnt/
$ ls -l tmpmnt/AppRun
-rwxr-xr-x 1 root root 6921 Jul  5 10:47 tmpmnt/AppRun

So, mounting with squashfuse as a normal user, I can access the contents of the root of the squashfs directory, even though the permissions on the directory clearly indicate it shouldn't be allowed!

$ sudo squashfuse tutanota-desktop-linux.AppImage.sqfs tmpmnt/
$ ls -l tmpmnt/AppRun
ls: cannot access 'tmpmnt/AppRun': Permission denied
$ ls -ld tmpmnt
ls: cannot access 'tmpmnt': Permission denied

If I mount via fuse but as root, a normal user cannot access the contents of the root of the squashfs directory, and strangely can not even get information on the directory itself!

$ sudo mount -o loop -t squashfs tutanota-desktop-linux.AppImage.sqfs tmpmnt/
[sudo] password for crass: 
$ ls -l tmpmnt/AppRun
ls: cannot access 'tmpmnt/AppRun': Permission denied
$ ls -ld tmpmnt
drwxr-x--- 6 root root 509 Jul  5 10:47 tmpmnt

When mounting via loopback using the squashfs kernel fs module, things work as expected.

Ok, this is important because appimage will use fuse to mount the embedded squashfs as the invoking user (in this case a regular user). However, firejail will mount the squashfs using the squashfs kernel module. While it might seem like a security issue for the permissions to be ignored when using fuse and accessing the squashfs root directory, I don't believe there's a problem because the files are all read only.

So I'm thinking that firejail should instead use the appimage binary to fuse mount itself. Using strace on the appimage shows that first mount("tutanota-desktop-linux.AppImage", "/tmp/.mount_tutanobofSI7", "fuse.tutanota-desktop-linux.AppImage", MS_RDONLY|MS_NOSUID|MS_NODEV, "fd=<fuse dev fd>,rootmode= 40000,user_id=<uid>,group_id=<gid>") is tried, but for fails a regular user with EPERM. Then it tries to use the help: execve("/bin/fusermount", ["fusermount", "-o", "ro,nosuid,nodev,subtype=tutanota-desktop-linux.AppImage", "--", "/tmp/.mount_tutanobofSI7"], <env>). I suggest we use this method instead. Any objects? better ideas? thoughts?

@crass crass reopened this Jul 8, 2019
@probonopd
Copy link
Contributor Author

So, mounting with squashfuse as a normal user, I can access the contents of the root of the squashfs directory, even though the permissions on the directory clearly indicate it shouldn't be allowed!

So I would say the FUSE-based AppImage runtime is actually doing the wrong thing.

@crass
Copy link
Collaborator

crass commented Jul 9, 2019

@probonopd, so if I understand you correctly, you're saying that the permissions should not be ignored by the fuse fs. Correct me if I'm wrong. If that's what you want then the AppImage runtime should be changed to add default_permissions to the fuse mount options here.

You can test that default_permissions will deny access if non-root and allow access with root with the tutanota appimage by using this command: squashfuse -o ro,offset=$(./tutanota-desktop-linux.AppImage --appimage-offset),default_permissions ./tutanota-desktop-linux.AppImage /mnt

From mount.fuse man page:

       default_permissions
              By  default  FUSE  doesn't  check  file  access permissions, the
              filesystem is free to implement it's access policy or  leave  it
              to the underlying file access mechanism (e.g. in case of network
              filesystems). This option enables permission checking, restrict‐
              ing access based on file mode.  This is option is usually useful
              together with the allow_other mount option.

The annoying thing is that we'll have to get offending appimage builders to build a fixed appimage, which may or may not even be feasible (in the case of abandoned appimages with this issue). And I don't see this as actually adding any extra security. On the brightside, it seems that not a lot of appimages have this issue.

Relatedly, we may still want to make the modifications I suggested because I think it would be a way to future proof our appimage mounting code. We should be letting appimage figure out how to mount itself, rather than us emulating appimage code. So when AppImage Type 3 comes out with the next best compressed filesystem, we won't have to make any code modifications.

@probonopd
Copy link
Contributor Author

@crass thanks for your detailed analysis.

@probonopd, so if I understand you correctly, you're saying that the permissions should not be ignored by the fuse fs.

Yes, I think that would produce the same errors that we see with Firejail now in non-Firejail setups as well, hopefully leading to application developers seeing and fixing those permissions errors, resulting in less issues when using AppImages with Firejail. At least that was my line of thinking.

Relatedly, we may still want to make the modifications I suggested because I think it would be a way to future proof our appimage mounting code. We should be letting appimage figure out how to mount itself, rather than us emulating appimage code. So when AppImage Type 3 comes out with the next best compressed filesystem, we won't have to make any code modifications.

You have a point there, but doesn't it mean it would reduce performance?

@crass
Copy link
Collaborator

crass commented Jul 9, 2019

Yes, I think that would produce the same errors that we see with Firejail now in non-Firejail setups as well, hopefully leading to application developers seeing and fixing those permissions errors, resulting in less issues when using AppImages with Firejail. At least that was my line of thinking.

I think moving forward it would be great for AppImage to more strictly enforce perms. But I'm not sure how long it'll take all the offending appimage builders to incorporate the change. In the meantime, we can make it less painful for users wanting to use these appimages (and less issues for us!). If there was a security issue, then I'd be much less accommodating.

Relatedly, we may still want to make the modifications I suggested because I think it would be a way to future proof our appimage mounting code. We should be letting appimage figure out how to mount itself, rather than us emulating appimage code. So when AppImage Type 3 comes out with the next best compressed filesystem, we won't have to make any code modifications.

You have a point there, but doesn't it mean it would reduce performance?

What's your thinking on where the performance reduction would be coming from? As I see it, there will be a negligible hit to performance. The place I see for the most performance degradation would be from all file access needing to go through FUSE. But that's what native appimage currently does. Both appimage and firejail have some impact on performance (both seem unnoticeable in my experience). So what I'm proposing would performance-wise look like the performance impact of appimage + impact of firejail, which I suspect will be negligible. Maybe I'm missing something though.

@crass
Copy link
Collaborator

crass commented Jul 10, 2019

After looking at fuse a bit more, its not possible to use the appimage to mount itself using the mount system call (ie without executing the appimage). This is obvious now, the binary has the user-space code that emulates the filesystem (squashfs in this case), so of course some of its code will need to be executed.

So I see two roads forward here:

  1. In firejail spawn appimage --appimage-mount (as normal user of course) to fuse mount the appimage. This is ideal, except that we can not specify a mount directory, a temporary one is automatically generated using mkdtemp. We could then move the mount to where we like it in /run/firejail. Then before firejail exits, it would send SIGINT to the appimage process, which means we'd need to keep track of the pid. The other problem with this approach is that type 1 appimages don't have the --appimage-mount option. So the change would need to keep the existing code that handles type 1 appimages.
  2. Use squashfuse and appimage --appimage-offset to fuse mount the appimage. This method is nice because we don't need to keep track of squashfuse pid. We just spawn fusermount -u /mntdir to clean up. However, it creates a dependency on squashfuse and we'd need fuseiso9660 for appimage type1. That makes this option a non-starter.

Ok, I think I've convinced myself that its not worth the trouble to change firejail for the moment. Perhaps it'll be worth using the appimage to mount itself if there become a lot of appimage types in the future.

@kakasync
Copy link

I have this problem with onlyoffice, may I know, how to fix it? thanks.

@probonopd
Copy link
Contributor Author

@bdantas offers new insights into this in AppImage/appimage.github.io#1909 (comment):

the problem is the default firejail profile. /etc/firejail/default.profile contains this:
include /etc/firejail/disable-common.inc /etc/firejail/disable-common.inc contains this: blacklist ${PATH}/fusermount

If I comment-out the offending line in /etc/firejail/disable-common.inc, then the AppImage works as expected.

Can you confirm? Is this something that could be fixed in Firejail?

@glitsj16
Copy link
Collaborator

glitsj16 commented Feb 28, 2020

Is this something that could be fixed in Firejail?

@probonopd Yes, we can fix this by conditionally blacklisting ${PATH}/fusermount via ?HASAPPIMAGE: trickery in disable-common.inc:

...
blacklist ${PATH}/fusermount
?HAS_APPIMAGE: noblacklist ${PATH}/fusermount
...

#3249 also mentions needing to noblacklist ${PATH}/nc.
I propose to wait a bit on confirmation by affected users that this indeed fixes things. We'll merge this in as soon as that arrives. Support for '?HASAPPIMAGE:' is available from firejail 0.9.62 onwards, so this shouldn't pose any problems IMHO.

@bdantas
Copy link

bdantas commented Feb 28, 2020

@probonopd Just unblacklisting fusermount is not enough. I've done much more extensive testing since that post, and things are much more clear now. Please see here: #3249

EDIT: Sorry, it seems that after even more testing I Ianded right back here on this permissions issue.

@bdantas
Copy link

bdantas commented Feb 28, 2020

Is there a workaround for this? How do we get the appropriate permissions? I don't mind taking an even more manual approach (e.g., creating the squashfs archive in one step, ensuring appropriate permissions, then adding the runtime as a separate step).

@bdantas
Copy link

bdantas commented Feb 29, 2020

It seems appimagetool may be to blame.
If AppImage is created manually with mksquashfs and cat (instead of using appimagetool), then this "Permission denied" problem goes away.
See AppImage/AppImageKit#1032 (comment)

@Vincent43
Copy link
Collaborator

Thx for digging into it. Fixing it in appimagetool would be appreciated as fixing it in firejail as shown in #2690 (comment) is quite complicated.

@probonopd
Copy link
Contributor Author

probonopd commented Mar 7, 2020

@shoogle found out that when used with Firejail, the mount point for the AppImage is rwx for root and nobody else. Do you know why this is, and could it be changed? All files inside AppImages produced by appimagetool (and apparently also the directory that gets mounted to the mountpoint) are owned by root, and we would prefer to keep it that way.

// creates appimage mount point perms 0700
if (asprintf(&mntdir, "%s/.appimage-%u", RUN_FIREJAIL_APPIMAGE_DIR, getpid()) == -1)
errExit("asprintf");
EUID_ROOT();
mkdir_attr(mntdir, 0700, getuid(), getgid());

may be the culprit? What would happen if we would use 0755 instead of 0700 there?

@rusty-snake
Copy link
Collaborator

@probonopd see #2690 (comment), the irrational think is that some AppImages work with firejail and other not. @netblue30 any reason why this is owned by root and 7000?

Maybe also here:

if (asprintf(&mode, "mode=700,uid=%d,gid=%d", getuid(), getgid()) == -1)

@probonopd
Copy link
Contributor Author

probonopd commented Mar 7, 2020

@rusty-snake

the irrational think is that some AppImages work with firejail and other not.

Maybe we found out why: Some AppImages have all files inside the squashfs owned by root and some don't. @bdantas showed in AppImage/AppImageKit#1032 that it works when the files are not owned by root, and it fails when the files are owned by root.

@Vincent43
Copy link
Collaborator

Vincent43 commented Mar 8, 2020

It seem two conditions make same appimages broken:

  1. root ownership of files (done by appimagetool), other tools make files unrpiv user owned and that's why they work.
  2. mounting filesystem with 700 permissions, aka only owner has access (done by firejail)

It's interesting that initial appimage support used 755 permissions and was changed later to 700 without much explanation. Maybe restoring initial mode will fix this?

EDIT: here are some explanations for above change, although not explicitly about 700 vs 755.

@smitsohu
Copy link
Collaborator

smitsohu commented Mar 8, 2020

Maybe restoring initial mode will fix this?

I just tried, unfortunately it doesn't help.

Also since 3740f37 we don't pass these options any more to the squashfs mount, to work around a regression in the kernel.

@Flashwalker
Copy link

So what's the fix?

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

No branches or pull requests

10 participants