AppImage

`nosuid` fuse mount option deactivates `capabilities`

Hi all,

Assume that we want to make an AppImage from a binary which needs some Linux capabilities to run. For example ping needs cap_net_raw capability to be able to get run by a non-root user. Otherwise it will not run, saying: ping: socket: Operation not permitted!

Now if we make an AppImage of such a binary, even though you set capabilities for it beforehand, the AppImage would not run because it is mounted with nosuid fuse mount option and nosuid deactivates capabilities.

How can we make AppImages which mount without nosuid?

Any idea would be appreciated :wink:

@probono would you please give a hint on this problem?

One option is to run the AppImage like this:

sudo ./some.AppImage

then it will be mounted by the root user and be executed with root permissions.

Another option would be for the application inside the AppImage to copy some helper script or binary out of the AppImage to a temporary location, and ask the user for permission (e.g., using polkit) to execute that with elevated rights.

Check out https://github.com/AppImage/AppImageUpdate/issues/1 for more information on this subject, particularly https://github.com/AppImage/AppImageUpdate/issues/1#issuecomment-319678560 for how I solved this pragmatically in one of my AppImages.

Thanks for choosing AppImage. May I ask which app you are working on?

First, please let me thank you for your message :wink:

Running an app with root opens some probable security holes. Thus as I mentioned, it is preferable to give an app, just the capabilities it needs, not all capabilities by becoming root or by running by sudo. And we have used capabilities intentionally to avoid running as root.

That is a proprietary app of my employer which is going to be distributed this way. We should assume that not all users may use sudo, so the best way is to remove nosuid from the mount options. I am curious to know whether nosuid is governed by AppImage code or it is a requirement of Squashfs or something like it?

Again, thanks for your answer, I appreciate your further suggestions.

it is preferable to give an app, just the capabilities it needs, not all capabilities by becoming root or by running by sudo . And we have used capabilities intentionally to avoid running as root .

Looks like I am not familiar with the concept of capabilities. How does an application get capabilities? Certainly the user must give permission? Is this what polkit does?

In this case, you could copy out a helper app from the AppImage, and have polkit ask the user for the capabilities it needs, then run the helper.

It think it is a restriction coming from FUSE or even the layers below it and removing it from FUSE might cause mounting the AppImage require root rights.

No, that is a different story than polkit. I quote the next lines from this man page:

   For the purpose of performing permission checks, traditional UNIX
   implementations distinguish two categories of processes: privileged
   processes (whose effective user ID is 0, referred to as superuser or
   root), and unprivileged processes (whose effective UID is nonzero).
   Privileged processes bypass all kernel permission checks, while
   unprivileged processes are subject to full permission checking based
   on the process's credentials (usually: effective UID, effective GID,
   and supplementary group list).

   Starting with kernel 2.2, Linux divides the privileges traditionally
   associated with superuser into distinct units, known as capabilities,
   which can be independently enabled and disabled.  Capabilities are a
   per-thread attribute.

You can give desired capabilities to a file by setcap command. For example ping needs to create raw sockets for sending a packet. Creating raw sockets is one of the numerous root capabilities. If we run ping with sudo or su, it will inherit all of the root’s capabilities. It may be harmful in the case the intruder can use a vulnerability in ping and get full root access.
Thus we only give ping what it needs, not more:
setcap cap_net_raw=+eip /home/me/ping
Then, I as a non-root user will be able to run ping. If an intruder uses the vulnerability, he/she will be only able to create raw sockets of root’s capabilities, NOT MORE :smiley:

Can we investigate more and try it?