Snaps interfere with mount namespaces

I have a tool (https://github.com/ausbin/nsdo) that uses network namespaces and mount namespaces to isolate particular applications in VPNs. It’s useful if you want to run some applications through a VPN and others not.

This tool handles the networking part of this with network namespaces. But to handle /etc/resolv.conf, it uses overlayfs with mount namespaces. However, when I run a snap like Firefox, snap mangles the mount namespace I have set up, and the browser ends up in the original mount namespace (with the wrong /etc/resolv.conf) instead of the one it was exec()'d in. This was very confusing to debug, since I didn’t expect a non-privileged program to setns() itself — I only figured it out when I navigated snap Firefox to file:///etc/resolv.conf and saw the wrong configuration.

Is there a way around this? Currently I just stopped using the Firefox snap and things work great, but it would be nice to find a resolution for users who use snaps (e.g., Ubuntu 22.04 users for whom snap Firefox is the default)

edit: Forgot to say, this is snap 2.56 on Ubuntu 22.04

Been looking into this a bit, and it seems like mount namespaces are set up in a particular way, and this mount namespace is shared by invocations of a particular snap: 1, 2.

This raises an interesting question of how to make this work with the little nsdo tool mentioned above. Normally, nsdo will setns() to the mount namespace and network namespace and exec() the program. The mount namespace to setns() into could be different if I want to run my application in different VPNs. So I don’t think custom hooks for snap mount namespace setup would help, since I may want to run Firefox in no VPN or different VPNs later on. Somehow nsdo would have to mess with the snap mount namespace at runtime (sus) or create new mount namespaces for every VPN for every snap (oh my).

Oh man… I don’t think this is an unfair use case, though