Interface for on device compilation (npm install, etc)

There are use cases when we need to compile code on device. This could be for various reasons.
Good example is homebridge project, where number of all plugins is prohibiting us simply precompile everything inside snap itself.
Same can be probably applied to many other npm projects with plugins.
I believe same could be applied on python projects and probably many others….

Way forward is to ship toolchain and allow npm to compile native code on device.
I have prepare snap doing this here https://github.com/kubiko/homebridge-snap
As proof of concept it’s using ‘docker-support’ interface. This should be ideally replaced by something more targeted.
For this particular case setgui and mknod were some of the blocked calls.
Any thoughts?

Without seeing the exact denials, I suspect that the mknod was for a regular file, but outside of the snap’s writable area (we only disallow the mknod syscall for character and block devices). The setuid is likely a seccomp denial and probably the snap doing a setuid/setgid to itself. This will be fixed in the future when we support privilege dropping/etc.

Today, I suspect you could use the snapcraft-preload plugin to workaround the setuid/setgid issue but there is a PR under review that turns seccomp denials from kill to EPERM that should land soon. When it does, I suspect your setuid/setgid calls may be non-fatal.

@jdstrand for reference this is shot for interface implementation which does satisfy compiler and npm installer.
Is it something we can consider as additional interface?
build-tools

It seems strange to have an interface for “build-tools”. There’s nothing special about build tools in snapd… they are just applications like anything else, and they need system access for doing certain things like anything else. So instead of thinking of it in terms of “build-tools”, we should be figuring what it is that they are trying to do and why.

Have you seen the comments from @jdstrand above?

The case at hand is even more concerning because it seems to want to change ownership of things and set the uid of processes. Unless that’s very well constrained into safe spaces (chown to current owner, setuid to current uid), we don’t want snaps playing with those.

In fact, npm gives some good background for why we don’t want that. :slight_smile:

https://github.com/npm/npm/issues/19883

@niemeyer name of the interface is just for testing, we can call it whatever we agree on…

As for comments from @jdstrand I was able to avoid mkdnod calls, or they would fails without affecting result. However for rest I can’t find other way to make it run without allowing chown and other calls.
While I agree with you that one should not need to call chown and other, this use case when we need to install npm plugin at run time just can’t be done without, or it seems like. Restricting to only own files and own gid/uid seems at the same time as sensible restriction…
Hacking npm or gcc would be overkill for the task, so we need to somehow make them happy enough to complete the task…
As discussed before, we can’t simply preinstall those npm components into the snap, so run time install is only option.

@ondra I will need a bit more information as you seem to be just restating the original message without much else in addition. I understand it wants to chown something, and that it wants to setuid something too. The comments above are precisely about that.

Thanks everybody for contribution here. I believe I have solve permission problem without need for new interface. Long story short, I have simply disabled all chown and fchown calls inside node binary, as those should not be needed anyway, files should already have correct owner. There does not seem to be any other offending calls.

@wmmihaa you might want to check homebridge-snap as this is fully solving problem you were having with npm install at runtime