-
Notifications
You must be signed in to change notification settings - Fork 594
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
s/apparmor: expand apparmor prompting support checks #14448
s/apparmor: expand apparmor prompting support checks #14448
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #14448 +/- ##
==========================================
- Coverage 78.77% 78.75% -0.02%
==========================================
Files 1073 1074 +1
Lines 143693 144511 +818
==========================================
+ Hits 113191 113807 +616
- Misses 23401 23561 +160
- Partials 7101 7143 +42
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
eaa08a2
to
279771f
Compare
This now covers the debian sid TODO from #14458 |
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
@@ -106,9 +106,8 @@ execute: | | |||
fi | |||
|
|||
echo "Enable prompting via snap client where possible" | |||
if os.query is-core || os.query is-ubuntu-lt 22.04; then | |||
if os.query is-core || os.query is-ubuntu-lt 24.04; then |
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.
seems like 22.04 GCP kernel has the right bits already and this is failing?
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.
Well that sure is "interesting"..... and there's no debug log with kernel versions :( guess I'll have to add some debugging and see what's going on.
In general, we don't expect Jammy to have prompting. One could install a new Ubuntu kernel(/apparmor?) on Jammy (or potentially older) and get prompting to work, but I don't love the idea of testing this.
I think a more robust solution than os.query is-ubuntu-lt 24.04
would be to check is-ubuntu
and then check the kernel version itself. It's possible prompting could be backported to older kernels, but I hope not.
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.
hm debug output should contain this:
Lines 587 to 588 in e9b6640
echo '# Kernel information' | |
uname -a |
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.
FWIW, I think it's ok to count 22.04 as supported, since there's a hwe kernel which may have the right patches, and given that 22.04 isn't the most recent distro around I would expect the hwe kernel to be quite popular.
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.
hm debug output should contain this:
Lines 587 to 588 in e9b6640
echo '# Kernel information' uname -a
Yeah, for some reason the debug output is not showing at all on failure?? I'm trying some things.
FWIW, I think it's ok to count 22.04 as supported, since there's a hwe kernel which may have the right patches, and given that 22.04 isn't the most recent distro around I would expect the hwe kernel to be quite popular.
I agree, I think ideally we should change the spread checks to actually check kernel version/features for support. So instead of just asserting things about Ubuntu versions, we check whether it is Ubuntu and the kernel is [some constraints]. This might look a bit like the actual checks within snapd though, which I don't love. Ideally there's a very clear versioning scheme where prompting is only backported to kernels >= 6.x, but I'll have to check with JJ.
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.
This all looks good to me. Thank you for making easy-to-review patches!
I missed reverting the 22.04 changes to |
279771f
to
58e8da3
Compare
sandbox/apparmor/apparmor.go
Outdated
if strutil.ListContains(apparmorFeatures.KernelFeatures, "policy:notify") { | ||
if !strutil.ListContains(apparmorFeatures.KernelFeatures, "policy:notify:user:file") { | ||
return false, "the kernel does not support prompting for file access" | ||
// XXX: should this error message be "apparmor kernel features do not support prompting" as well? |
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.
Any thoughts on this? The error message if the other apparmor kernel features lack prompting support is "apparmor kernel features do not support prompting".
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 it is useful to distinguish each separate case to aid in debugging but perhaps each could share a common prefix to make it easy to know this relates to prompting?
For some reason the spread debug hooks don't seem to be running when the tests fail? Afaik these should run even if spread is not run with |
I ran prompting client integration tests on jammy and they did pass: #14387 (comment) So it looks like we need a more robust check for kernel version on pre-noble releases. Prompting should still never work on non-ubuntu systems, at least until the prompting patches are upstreamed. |
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 but I think an additional test case is needed on the kernel features.
sandbox/apparmor/apparmor.go
Outdated
if strutil.ListContains(apparmorFeatures.KernelFeatures, "policy:notify") { | ||
if !strutil.ListContains(apparmorFeatures.KernelFeatures, "policy:notify:user:file") { | ||
return false, "the kernel does not support prompting for file access" | ||
// XXX: should this error message be "apparmor kernel features do not support prompting" as well? |
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 it is useful to distinguish each separate case to aid in debugging but perhaps each could share a common prefix to make it easy to know this relates to prompting?
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!
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.
did a pass, some comments/questions
sandbox/apparmor/apparmor.go
Outdated
} | ||
} | ||
if !notify.SupportAvailable() { | ||
return false, "kernel notification socket required by listener is not present" |
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.
this message doesn't make clear that this issue related to prompting, in general I agree with Alex that some kind of common starting prefix/prefix would be good
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.
How does this sound?
--- a/sandbox/apparmor/apparmor.go
+++ b/sandbox/apparmor/apparmor.go
@@ -460,12 +460,11 @@ func PromptingSupportedByFeatures(apparmorFeatures *FeaturesSupported) (bool, st
// for its presence among the kernel features.
if strutil.ListContains(apparmorFeatures.KernelFeatures, "policy:notify") {
if !strutil.ListContains(apparmorFeatures.KernelFeatures, "policy:notify:user:file") {
- return false, "the kernel does not support prompting for file access"
- // XXX: should this error message be "apparmor kernel features do not support prompting" as well?
+ return false, "apparmor kernel features do not support prompting for file access"
}
}
if !notify.SupportAvailable() {
- return false, "kernel notification socket required by listener is not present"
+ return false, "apparmor kernel notification socket required by prompting listener is not present"
}
return true, ""
}
Since these are "unsupported reason" strings returned by the apparmor.PromptingSupported
function, I don't think a full-on prefix like apparmor prompting: ...
is necessary, but I do think having the common apparmor kernel ...
and including the word prompting
later could at least make things a bit clearer?
sandbox/apparmor/apparmor.go
Outdated
@@ -481,6 +509,7 @@ var ( | |||
|
|||
// Filesystem root defined locally to avoid dependency on the | |||
// 'dirs' package | |||
// XXX: is this still useful/relevant? The 'dirs' package is used here already. |
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.
until the code stops using it is relevant
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 meant whether "avoid dependency on the 'dirs' package" is still relevant. Could we move to just use dirs.GlobalRootDir
? I worked around it already so it's not that important for the time being, but it means tests have to be careful not to dig around the host filesystem.
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.
TODO: fix this eventually in follow-up PR
if err != nil { | ||
return []string{}, err | ||
} | ||
if data, err := os.ReadFile(filepath.Join(rootPath, featuresSysPath, "policy", "permstable32")); err == nil { |
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.
given we are revisiting this, what's the relation between permstable32 and permstable32_version, do we need to worry about the latter?
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.
JJ says the minimum version is 2. Technically 1 can work, but it has problems. I think we can add a check for version 2+, but the question is whether to include it in the apparmor kernel features probing, or to do a one-off check here (like we do for the socket presence).
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.
Per sync with Samuele, do this in the prompting support checks, rather than in the general apparmor kernel feature probing
d4aa4ac
to
094a2c7
Compare
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.
comments about the new error messages
sandbox/apparmor/apparmor.go
Outdated
@@ -466,6 +467,13 @@ func PromptingSupportedByFeatures(apparmorFeatures *FeaturesSupported) (bool, st | |||
if !notify.SupportAvailable() { | |||
return false, "apparmor kernel notification socket required by prompting listener is not present" | |||
} | |||
version, err := probeKernelFeaturesPermstable32Version() | |||
if err != nil { | |||
return false, "apparmor kernel permissions table version must be at least 2, but version could not be read" |
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.
this message doesn't mention prompting
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.
How does this sound?
return false, "apparmor kernel permissions table version must be at least 2, but version could not be read" | |
return false, "apparmor kernel permissions table version must be at least 2 to support prompting, but version could not be read" |
sandbox/apparmor/apparmor.go
Outdated
return false, "apparmor kernel permissions table version must be at least 2, but version could not be read" | ||
} | ||
if version < 2 { | ||
return false, fmt.Sprintf("apparmor kernel permissions table version must be at least 2, but version is %d", version) |
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
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.
Alternatively,
return false, fmt.Sprintf("apparmor kernel permissions table version must be at least 2, but version is %d", version) | |
return false, fmt.Sprintf("apparmor kernel permissions table version must be at least 2 for prompting to be supported, but version is %d", version) |
Prompting cannot be supported if the kernel notification socket does not exist. Thus, add a check for its presence to PromptingSupportedByFeatures. However, this alone is not sufficient. The notification socket may be used for other purposes as well. When this becomes the case, a directory will be added at `/sys/kernel/security/apparmor/features/policy/notify`. If that directory exists, and it contains a file called `user`, which contains the list of prompting mediation classes, then prompting is supported on the system. If no file called `user` exists in that directory, but the directory itself exists, then we know prompting is not supported. Signed-off-by: Oliver Calder <[email protected]>
…support test Signed-off-by: Oliver Calder <[email protected]>
…itu test Signed-off-by: Oliver Calder <[email protected]>
…le on debian-sid" This reverts commit 66eb862. Debian Sid reports prompting support in its AppArmor kernel and parser features, the former because the upstream kernel has extended permissions merged (but non-functional), and the latter because we use vendored AppArmor with snapd. But the kernel does not actually support AppArmor prompting, as this requires patches from the Ubuntu kernel which have not yet been upstreamed. Now that we check for the presence of the kernel notification socket as well as the AppArmor kernel and parser features, we can correctly identify that prompting is not supported on Debian Sid. Signed-off-by: Oliver Calder <[email protected]>
…ored apparmor on 22.04" This reverts commit 1ec4132. Signed-off-by: Oliver Calder <[email protected]>
…nal apparmor" This reverts commit a4e46bb. On Ubuntu LTS releases < 24.04, prompting is still not supported by the standard (non-hwe) kernels. This is reflected in tests, now that AppArmor prompting support checks test for the presence of the kernel notification socket. Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
Ubuntu systems older than 24.04 are capable of supporting AppArmor prompting if they are running a new enough Ubuntu kernel. In particular, the Ubuntu 22.04 image on GCP runs a 6.5 kernel which supports prompting. Thus, if run on GCP, Jammy supports prompting, but if run on lxd, it does not. Therefore, checks for Ubuntu version are insufficient for spread to identify whether prompting should be supported. Instead, check for the presence of the `prompt` directive in the permissions listed in `/sys/kernel/security/apparmor/features/policy/permstable32`. Any Ubuntu system which has `prompt` in that file should support prompting. This can't be the entirety of the check, because those permissions have been upstreamed to the Linux kernel, but other pieces which are required for prompting to function have not yet been upstreamed. Thus, Debian Sid reports supporting the prompt directive, even though prompting is not supported. Therefore, we must check that the system is Ubuntu, that it's not core, and that the `prompt` directive is supported. Signed-off-by: Oliver Calder <[email protected]>
…s't include file Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
Signed-off-by: Oliver Calder <[email protected]>
…erence prompting Signed-off-by: Oliver Calder <[email protected]>
5e27752
to
93c6a23
Compare
Adjusted error messages as suggested, and rebased to pull in test fixes from master. |
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.
thank you
* s/apparmor: expand apparmor prompting support checks Prompting cannot be supported if the kernel notification socket does not exist. Thus, add a check for its presence to PromptingSupportedByFeatures. However, this alone is not sufficient. The notification socket may be used for other purposes as well. When this becomes the case, a directory will be added at `/sys/kernel/security/apparmor/features/policy/notify`. If that directory exists, and it contains a file called `user`, which contains the list of prompting mediation classes, then prompting is supported on the system. If no file called `user` exists in that directory, but the directory itself exists, then we know prompting is not supported. Signed-off-by: Oliver Calder <[email protected]> * s/apparmor: add missing feature to mocked features list in prompting support test Signed-off-by: Oliver Calder <[email protected]> * features: remove superfluous test of apparmor function which has in-situ test Signed-off-by: Oliver Calder <[email protected]> * Revert "tests/main/interfaces-snap-interfaces-requests-control: disable on debian-sid" This reverts commit 66eb862. Debian Sid reports prompting support in its AppArmor kernel and parser features, the former because the upstream kernel has extended permissions merged (but non-functional), and the latter because we use vendored AppArmor with snapd. But the kernel does not actually support AppArmor prompting, as this requires patches from the Ubuntu kernel which have not yet been upstreamed. Now that we check for the presence of the kernel notification socket as well as the AppArmor kernel and parser features, we can correctly identify that prompting is not supported on Debian Sid. Signed-off-by: Oliver Calder <[email protected]> * Revert "tests/main/apparmor-prompting-snapd-startup: account for vendored apparmor on 22.04" This reverts commit 1ec4132. Signed-off-by: Oliver Calder <[email protected]> * Revert "tests: account for prompting supported on >= 22.04 with internal apparmor" This reverts commit a4e46bb. On Ubuntu LTS releases < 24.04, prompting is still not supported by the standard (non-hwe) kernels. This is reflected in tests, now that AppArmor prompting support checks test for the presence of the kernel notification socket. Signed-off-by: Oliver Calder <[email protected]> * s/apparmor,tests: improve comments around apparmor prompting Signed-off-by: Oliver Calder <[email protected]> * tests: add debug checks for prompting support Signed-off-by: Oliver Calder <[email protected]> * tests: make prompting-related tests work on any supported ubuntu system Ubuntu systems older than 24.04 are capable of supporting AppArmor prompting if they are running a new enough Ubuntu kernel. In particular, the Ubuntu 22.04 image on GCP runs a 6.5 kernel which supports prompting. Thus, if run on GCP, Jammy supports prompting, but if run on lxd, it does not. Therefore, checks for Ubuntu version are insufficient for spread to identify whether prompting should be supported. Instead, check for the presence of the `prompt` directive in the permissions listed in `/sys/kernel/security/apparmor/features/policy/permstable32`. Any Ubuntu system which has `prompt` in that file should support prompting. This can't be the entirety of the check, because those permissions have been upstreamed to the Linux kernel, but other pieces which are required for prompting to function have not yet been upstreamed. Thus, Debian Sid reports supporting the prompt directive, even though prompting is not supported. Therefore, we must check that the system is Ubuntu, that it's not core, and that the `prompt` directive is supported. Signed-off-by: Oliver Calder <[email protected]> * s/apparmor: add test case when policy/notify/user file exists but does't include file Signed-off-by: Oliver Calder <[email protected]> * s/apparmor: adjust prompting unsupported reason error messages Signed-off-by: Oliver Calder <[email protected]> * s/apparmor: prompting support checks for permstable32_version >= 2 Signed-off-by: Oliver Calder <[email protected]> * s/apparmor: add TODO about using dirs instead of rootPath Signed-off-by: Oliver Calder <[email protected]> * o/c/configcore,s/apparmor: mock aa root path in prompting tests Signed-off-by: Oliver Calder <[email protected]> * s/apparmor: trim whitespace from permstable32_version before parsing Signed-off-by: Oliver Calder <[email protected]> * s/apparmor: adjust prompting unsupported reason error messages to reference prompting Signed-off-by: Oliver Calder <[email protected]> --------- Signed-off-by: Oliver Calder <[email protected]>
This PR is based on #14294, only the final few commits are relevant to this PR. Should rebase this PR on master once that PR lands.
Prompting cannot be supported if the kernel notification socket does not exist. Thus, add a check for its presence to PromptingSupportedByFeatures.
However, this alone is not sufficient. The notification socket may be used for other purposes as well. When this becomes the case, a directory will be added at
/sys/kernel/security/apparmor/features/policy/notify
. If that directory exists, and it contains a file calleduser
, which contains the list of prompting mediation classes, then prompting is supported on the system. If no file calleduser
exists in that directory, but the directory itself exists, then we know prompting is not supported.This work is tracked internally by https://warthogs.atlassian.net/browse/SNAPDENG-31642