Socket: permission denied

I would like to run a program as a non-root user.

I added a new user and put the user to inet group. From what I know, if a user is in this particular group, the user gets internet access and the user can be create sockets too (?). This is defined in /system/etc/permissions/platform.xml file (<permission name="android.permission.INTERNET" />).

However the program fails to connect as “socket: permission denied” message is written to log.
Any ideas how to resolve this?

I’m not sure if this will help, but have you looked into capabilities at all? You can define this at a binary level (using the setcap command), or can define it within a systemd service unit as an ambient capability. (Actually, it seems as if the AmbientCapabilities directive within systemd is not currently supported on Sailfish OS, which is at version as of this writing.)

For instance, I utilized capabilities to get Nebula working on Sailfish as an unprivileged user.

In your case, I would look into the CAP_NET_RAW capability, possibly coupled with the CAP_NET_ADMIN capability. In my case, I needed those two, plus my user needed to be in the vpn group. In order to access /dev/net/tun at all, I needed to be in the vpn group. In order to do anything with the tun device, I needed CAP_NET_ADMIN. In order to set up a UDP listener (even on a high-numbered port), I needed CAP_NET_RAW.

I would start off trying commands like the following as root to see if you can get it working (obviously replace my fake paths, arguments (if needed), and username below)…

setcap cap_net_admin,cap_net_raw+ep /path/to/your/binary
su -s /bin/bash -c '/path/to/your/binary arg1 arg2' unprivilegeduser

If that works, I would try removing cap_net_admin and see if it still works. You may very well have to keep your user in the inet group as well, but you can experiment with and without that.

In the end, in my case, I ended up using systemd to run things, but since ambient capabilities are not supported within systemd on Sailfish OS (as of the time of this post, anyway), I set the capabilities manually on the binary itself like I illustrated above.

Thank you for the reply. It led me on the right path.

I am aware of capabilities. I was not sure if they were needed in this context. And they were.
And yes, it became clear that systemd in SFOS does not support AmbientCapabilities= directive (error: “Unknown lvalue ‘AmbientCapabilities’ in section ‘Service’”). So I had to give needed capability directly for the binary with setcap command.

It turned out that the unprivileged user running the program did not need to be in inet group. It is enough that the binary has cap_net_raw+ep capability. Now it works just fine.

I’m glad you got it resolved, and thanks for sharing what you did to get it resolved.

I admit at first when I replied (before an edit) I thought everything was working fine with AmbientCapabilities in systemd, but while double checking what I had done as part of writing my reply, I noticed with getcap that I still had capabilities set directly on the binary. I then removed them and my systemd startup started failing, and after looking closer, I noticed that Unknown lvalue error you shared.

Thanks for asking this question, as I would have spent a lot of time trying to figure out what went wrong the next time I went to upgrade Nebula, since I would have assumed the binary didn’t need the capabilities set, whereas it actually did on Sailfish.