tup only works with sudo ("setgroups: Permission denied")
So I just upgraded to ubuntu 24.04. Now, this is what I get :
$ tup
/proc/11285/setgroups: Permission denied
tup error: Unable to deny setgroups when setting up user namespace.
tup error: master_fork server did not start up correctly.
However, sudo tup works
GPT and I have been investigating on that. Turns out apparmor was making the trouble, and this solved the issue for me:
- delete
/etc/apparmor.d/tupor any file there named aftertup - create the file
/etc/apparmor.d/usr.local.bin.tup(adapt the filename and file content to yourtuppath):
#include <tunables/global>
"/usr/local/bin/tup" {
#include <abstractions/base>
capability sys_admin,
mount,umount,
/** rwk,
/** ix,
}
- run
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.tup
This basically allows everything tup might have requested for during my tests.
in case I missed anything and you have tup complain about missing rights, you can then run aa-notify -s 1 -v to see what was denied and tune the file above
I had to add flags=(attach_disconnected) to mine to make it work:
#include <tunables/global>
"/usr/local/bin/tup" flags=(attach_disconnected) {
#include <abstractions/base>
capability sys_admin,
mount,umount,
/** rwk,
/** ix,
}
I don't really know anything about AppArmor so I don't know why I needed it and why that worked, but in case other people are having trouble getting it to work, adding that worked for me.
This is what I saw in journalctl -xe before adding it:
Jul 23 10:16:26 mosi kernel: audit: type=1400 audit(1721726186.039:4133): apparmor="DENIED" operation="getattr" class="file" info="Failed name lookup - disconnected path" error=-13 profile="/usr/local/bin/tup" name="home/dan/foo/.tup/tmp/>```
Ubuntu 22.04 LTS "Jammy".
I have the exact same error message. Nothing tup-related in the journalctl log.
I followed the suggestion above and added the flag, but it didn't help.
My tup is in /usr/bin rather than /usr/local/bin, but I made that change to the AppArmor config above.
If it's any use, here is my aa-notify output:
Profile: /usr/bin/tup
Operation: capable
Name: dac_override
Logfile: /var/log/kern.log
Profile: /usr/bin/tup
Operation: capable
Name: dac_override
Logfile: /var/log/kern.log
Profile: /usr/bin/tup
Operation: capable
Name: dac_override
Logfile: /var/log/kern.log
I don't know how to progress this. Just to get some work done, I'll switch to make. (Ugh.)
This version worked for me (/etc/apparmor.d/tup):
abi <abi/4.0>,
include <tunables/global>
profile tup /usr/local/bin/tup flags=(complain) {
userns,
capability sys_admin, # Allow system administrator capabilities in user namespaces
# Site-specific additions and overrides. See local/README for details.
include if exists <local/tup>
}
I've no idea how good/bad that is, just a ChatGPT solution in my case 😬 .
Note, I needed to reload after making changes with sudo apparmor_parser -r /etc/apparmor.d/tup.
I encountered the same issue with an instance of tup installed via Nix on Ubuntu 24.04. In that case the issue was not the lack of additional capabilities in the apparmor configuration, but rather that the default file pattern (/usr/bin/tup) did not apply. I added a dedicated apparmor configuration for a Nix provided tup to /etc/apparmor.d/tup/tup-nix:
abi <abi/4.0>,
include <tunables/global>
profile tup /nix/store/*/bin/tup flags=(unconfined) {
userns,
include if exists <local/tup>
}
After reloading via sudo apparmor_parser -r /etc/apparmor.d/tup-nix tup worked again.
ah, maybe flags=(unconfined) already implies capability sys_admin?
I had to do something similar, but even during ./bootstrap.sh and with the file locations specified in the apparmor files as those in the directory I was building in.
I believe only userns is required, not capability sys_admin. The point of creating the user namespace is so that we get cap_sys_admin inside the namespace, but without requiring actual admin privileges, so you shouldn't need to list cap_sys_admin explicitly. Those of you who found success with this, can you try removing capability sys_admin and see if it still works? The default tup apparmor profile on Ubuntu does this correctly, though you have to make sure the path listed there corresponds to the path to tup on your system. (ie: if you're building tup from git, presumably the path won't match up). My whole file looks like this:
include <tunables/global>
profile tup /usr/bin/tup flags=(unconfined) {
userns,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/tup>
}
The local/tup file is empty for me. With this, if the executable is at /usr/bin/tup, it will setup the namespace properly. If tup is anywhere else, the setgroups permission denied thing shows up.
The problem here is that the creating the new user namespace (via unshare(CLONE_NEWUSER)) appears to succeed, but apparmor prevents it from acquiring any new capabilities, so it isn't able to setup the namespace properly. I'm not sure of a good way to detect that aside from seeing the open on the setgroups file fail. However, we can at least provide a sane fallback behavior, similar to cases where unshare(CLONE_NEWUSER) itself fails. I've added a commit to do this, though the code is ugly. It provides a warning message that it is proceeding without namespaces and tries to provide some direction on how to address it (which is, update the apparmor profile to allow namespacing, or run tup with TUP_NO_NAMESPACING=1 to keep the non-namespaced behavior but skip the warning messages).
Sorry it took so long for me to get to this. Life has been very busy for the last year :)