Classic confinement request: devpack-for-rust

Note that I was not referring to linking of the stuff you build with your devpack once it is installed but about the binaries inside your snap.

Libs and binaries in a strictly confined snap only see libc and the ld.so linker from the base snap your app snap runs on top.

Under classic confinement the libs and binaries in your snap have access to the hosts linker and libc alongside and you need to absolutely prevent them from accidentally accessing these instead of the ones from the base snap.

For this you usually need to binary-patch all libs and executables inside your snap to remove all baked in rpath entries using patchelf.

If you don’t do this with a snap that was i.e. built on top of core26 and a user installs it on … say 22.04, it will try to use the hosts libc (or dynamic libs via the hosts linker), you get symbol errors and the whole thing explodes in your face with a segfault.

Alternatively to binary patching you could build everything statically, that way no linker will be used at runtime.

Hi @petrakat,

it still will eventually install programs that may arbitrary things to the user’s machine by design.

Since the functionality of the snap is to install the applications in the host system, it no longer falls under ā€œtools for local, non-root user drivenā€ category. Can you confirm devpack-for-rust is only dependent on rustup snap and everything else can be installed with cargo install?

However, given the functionality of devpack-for-rust snap is similar to rustup snap, which is already classic and the functionality of devpack-for-rust is to run arbitrary command, which falls under the consideration criteria as per Process for reviewing classic confinement snaps, I am inclined to grant classic confinement to devpack-for-rust. It still might need an override from an architect. What do other @reviewers think?

Who can approve this request? Petra has made changes as requested above.

We appreciate your help in getting this approved and want to make sure all of the policies are met.

That would be @jnsgruk , @niemeyer or @pedronis

Hello, I have since updated to the changes above (as Scott said). Specifically:

  • I am dropping permissions by setting uid instead of shelling out to sudo
  • Programs are installed with cargo install instead of apt

(Sorry for the late reply; I was on +1 maintenance last week.)

Did you try to run it on i.e. a 22.04 install yet (or a fedora or arch installation) to make sure the potential libc and rpath issues do not apply (like they usually do if you do not manually do a bunch of patchelf magic to all included binaries inside a classic snap) ?

I am getting this error when trying to run it on a Jammy instance:

/snap/devpack-for-rust/x1/bin/devpack-for-rust: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.39' not found (required by /snap/devpack-for-rust/x1/bin/devpack-for-rust)

This happens whether it is built with base: core26 or base: core22. I’m not sure if this is the issue you are talking about; the message shows before devpack-for-rust gets any control flow.

Yep, this exactly the symptom of what I described above, it will happen on any other distro that doesn’t have the correct libc version (and can be even worse if it has the same version built with completely different options)

This Blogpost (sorry I should have shared that earlier but had forgotten about it) explains the issue pretty well:

There is a patchelf option you can set in your snapcraft.yaml but this sometimes isn’t enough, the snapcraft linter is pretty helpful in these cases.

Here is a snapcraft.yaml for a classic snap I’m currently working on that has an example of how you can do it manually (it builds parts in a venv which snapcrafts built-in patchelf handler can’t manage)

1 Like

Hello, I have it kind of working on Jammy by borrowing these lines from the rustup snap:

build-environment:
  - RUSTFLAGS: >
      -Clink-arg=-Wl,-rpath=\$ORIGIN/lib:/snap/core26/current/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR
      -Clink-arg=-Wl,-dynamic-linker=$(find /snap/core26/current/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR -name 'ld*.so.*' -print | head -n1)

When using cargo build it is failing halfway through the compilation process with sig9 of all things, so I’m investigating that.

EDIT: the SIGKILL was due to OOMD. Allocating more ram to my multipass instance fixed it.

1 Like

Awesome !

Make sure to check the linter output at the end of the build (I’d always call snapcraft pack with the --verbose option during development, it has quite a lot of useful info) to make sure there are not any files missed with the wrong rpath/interpreter stuff …

I just had a nice meeting with @pedronis and @jslarraz where we discussed the installer; their two cents is that the classic confinement request should be approved as long as I document what happens regarding the snap lifecycle (ie, document that uninstalling the snap does not uninstall the tools and refreshing the snap does not update the tools.)

1 Like

HI @petrakat

Thanks for the info. Please ping me when the docs are sorted and I will go ahead and grant classic.

Hi @shishirsub10 , the docs as they are on Github are ready. Thank you!

+1 from me to grant classic to devpack-for-rust. Publisher being Canonical employee is already vetted. Granting classic to devpack-for-rust.

2 Likes