New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/snap-confine: handle CURRENT_TAGS on systems that support it #10540
Conversation
Try to determine whether the libudev/libsystemd supports CURRENT_TAGS which has been introduced in systemd v247: https://github.com/systemd/systemd/blob/f6278558da0304ec6b646bb172ce4688c7f162a5/NEWS#L1037-L1119 This comes in pair with TAGS becoming sticky, what means that our checks no longer behave correctly as the tags do not go away. If the library supports current tags, use the dynamically collected symbol to double check that the device is really currently tagged for a snap. The implementation introduced in v247 correctly checks whether the running systemd supports current tags and otherwise falls back to looking at TAGS property. Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
…sticky udev TAGS Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a security perspective, this looks fine - snap-confine is setuid root and dlopen
does not consult LD_LIBRARY_PATH
for setuid binaries so this should be safe from someone trying to supply their own udev_device_has_current_tag
in place of the real function from libudev.
Also the use of udev_device_has_current_tag
looks fine from what I can see too.
Instead of dlopen() and looking for the symbol ourselves, define a weak symbol and let the dynamic linker do the work. Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just comments about comments :-)
cmd/snap-confine/udev-support.c
Outdated
* and on slow devices we may indeed observe a device that no longer | ||
* exists. | ||
* | ||
* Similar debug + continue pattern repeats in all the udev calls in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comment! I was exactly wondering if all those debug()
calls in sc_udev_allow_assigned_device()
should be something more serious, but this clarifies it.
if [ "$SPREAD_REBOOT" = 0 ]; then | ||
echo "Given a snap is installed" | ||
"$TESTSTOOLS"/snaps-state install-local test-snapd-sh | ||
echo "Given a snap is installed" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that you didn't originally write this, but maybe it's a good occasion to fix this comment (I guess that it should be "given snap is installed").
if [ "$(systemctl --version | awk '/systemd [0-9]+/ { print $2 }')" -ge 247 ]; then | ||
REBOOT | ||
fi | ||
# Reboot needed just on systemd 247+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But now we are not rebooting anymore. Should this comment be removed?
if [ "$SPREAD_REBOOT" = 0 ]; then | ||
echo "Given a snap is installed" | ||
"$TESTSTOOLS"/snaps-state install-local test-snapd-sh | ||
echo "Given a snap is installed" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as for the other test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, one comment about how we can expand the comments in the code and also I agree with @mardy on the spread tests
cmd/snap-confine/udev-support.c
Outdated
debug("cannot find device from syspath %s", path); | ||
continue; | ||
} | ||
if (udev_device_has_current_tag != NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this deserves a comment too, something like
if (udev_device_has_current_tag != NULL) { | |
// If we are able to query if the device has a current tag, | |
// do so and if there are no current tags, continue to prevent | |
// allowing assigned devices to the cgroup - this has the net | |
// desired effect of not re-creating device cgroups that were | |
// previously created/setup but should no longer be setup due | |
// to interface disconnection, etc. | |
if (udev_device_has_current_tag != NULL) { |
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Add a blocked label again. The testing with a simple binary was showing that the 'weak' symbol is getting properly resolved. However, when I tried with the snap artifact from our github job, the symbol isn't even listed in readelf output:
while building locally:
|
Another data point. A binary built on 20.04 has the weak symbol correctly resolved on Arch, and correctly does not find the symbol on 16.04, although I can clearly see that ld.so tries to look it up:
Now a binary built on 16.04, has the weak symbol:
but it is not correctly resolved anywhere, neither on 20.04 or Arch, see:
So somehow, the Xenial toolchain breaks how symbols are resolved, and that's why I was not able to observe current tags being checked when I used the snapd snap artifact from our testing. |
This reverts commit 35d28c4.
Note that we could try to define udev_device_has_current_tag with a weak attribute, which should in the normal case be the filled by ld.so when loading snap-confined. However this was observed to work in practice only when the binary itself is build with recent enough toolchain (eg. gcc & binutils on Ubuntu 20.04). In case when the snapd snap needs to be built on 16.04, we have observed that the weak symbol was indeed produced, but when resolving libraries and symbols by ld.so on a recent host, the symbol would not be populated. The patch revers to the original proposed behavior. Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
I will restore the original proposed behavior to unblock this PR. |
Pushed an update restoring dlopen() and dropped the 'blocked' label. |
Codecov Report
@@ Coverage Diff @@
## master #10540 +/- ##
========================================
Coverage 78.34% 78.35%
========================================
Files 888 888
Lines 99871 100091 +220
========================================
+ Hits 78247 78425 +178
- Misses 16718 16748 +30
- Partials 4906 4918 +12
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
…n 14.04 Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one question about the check in the spread test, but still lgtm overall
Fwiw, looks good overall from a (not too deep) look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still lgtm
I removed the 2.52 milestone, I think we want this in 2.53 instead. |
Try to determine whether the libudev/libsystemd supports CURRENT_TAGS which has
been introduced in systemd v247:
https://github.com/systemd/systemd/blob/f6278558da0304ec6b646bb172ce4688c7f162a5/NEWS#L1037-L1119
This comes in pair with TAGS becoming sticky, what means that our checks no
longer behave correctly as the tags do not go away.
If the library supports current tags, use the dynamically collected symbol to
double check that the device is really currently tagged for a snap. The
implementation introduced in v247 correctly checks whether the running systemd
supports current tags and otherwise falls back to looking at TAGS property.