Well this is a doozy. Made public a while back was a security vulnerability in many Snap Packages and the Snapcraft tool used to create them. Specifically, this is the vulnerability identified as CVE-2020-27348. It unfortunately affects many many snap packages…
What is it?
The issue at the heart of this vulnerability is the prolific way that we in the Snapcraft community are overriding the Dynamic Linker search path. The Dynamic Linker is the library that searches for and loads libraries into memory when an application needs them. By default the Dynamic Linker searches a set of predefined paths for the libraries. These paths aren’t suitable for Snap Packages because all our shipped libraries will be accessible under the non-standard prefix of /snap/$SNAP_NAME/$SNAP_REVISION
.
To alleviate the problem of relocating libraries the Dynamic Linker supports an environment variable to list additional paths to search when looking for libraries. This environment variable, LD_LIBRARY_PATH
, is a colon-delimited list of filesystem paths to search.
What’s the problem?
The problem arises when the LD_LIBRARY_PATH
includes an empty element in its list. When the Dynamic Linker sees an empty element it will look in the current working directory of the process. So if we construct our search paths with an accidental empty element the application inside our Snap Package could be caused to load a shared library from outside the Snap Package’s shipped files. This can lead to an arbitrary code execution.
It has been common to put a definition of the LD_LIBRARY_PATH
variable into a Snap Package’s snapcraft.yaml
that references a predefined $LD_LIBRARY_PATH
as if to extend it. Unfortunately, despite this being common, it was poorly understood that SnapD ensures that the $LD_LIBRARY_PATH
is unset when starting a Snap Package’s applications. What that means is that where the author tried to extend the variable they have inadvertently inserted the bad empty element. The empty element appears because $LD_LIBRARY_PATH
is unset so the shell will expand it to an empty string.
Example
One such example is where we want to reference the path $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib
in our search paths. We could do this like so (don’t do this!):
|
|
When the shell expands the variable above we get the variable set as:
|
|
Note the colon at the end - that is telling the Dynamic Linker to expect another element, but the element itself is empty because we expected to append a pre-existing $LD_LIBRARY_PATH
, but it is unset resulting in “nothing”.
The example is better done like this (yes, do this instead!):
|
|
It’s widespread
I, personally, have dozens of Snap Packages that I maintain, many of which are all vulnerable to this issue. I’ve been working my way through them to get them all updated, but it’s a big job. When you consider that I’m only one publisher with many packages that have been impacted, and extrapolate that out to the whole ecosystem of 6300 Snap Packages you can appreciate that this problem might be very widespread indeed!