772 Commits

Author SHA1 Message Date
Sergio Costas
c59a5f6e87 i/apparmor: add snippets with priorities (#14061)
* Add snippets with priorities

AppArmor rules that forbid access to a resource have more
priority than rules that allow access to those same resources.
This means that if an interface restricts access to an specific
resource, it won't be possible to enable access to that same
resource from another, more privileged, interface.

An example of this is reading the .desktop files of all the
installed snaps in the system: the superprivileged interface
'desktop-launch' enables access to these files, so any snap
that has a connected plug for this interface should be able
to read them. Unfortunately, the 'desktop-legacy' interface
explicitly denies access to these files, and since it is
connected automatically if a snap uses the 'desktop' or the
'unity7' interfaces, this mean that no graphical application
will be able to read the .desktop files, even if the super-
privileged interface 'desktop-launch' interface is connected.

To allow this specific case, a temporary patch (
https://github.com/snapcore/snapd/pull/13933) was created and
merged, but it is clearly an ugly and not-generic solution.
For this reason, this new patch was created, following the
specification https://docs.google.com/document/d/1K-1MYhp1RKSW_jzuuyX7TSVCg2rYplKZFdJbZAupP4Y/edit

This patch allows to add "prioritized snippets". Each one has
an UID and a priority. If no prioritized snippet with the same
UID has been previously added, the new prioritized snippet will
be added like any other normal snippet. But if there is already
an added snippet with the same UID, then the priority of both
the old and the new snippets are compared. If the new priority
is lower than the old one, the new snippet is ignored; if the
new priority is bigger than the old one, the new snippet fully
replaces the old one. Finally, if both priorities are the same,
the new snippet will be appended to the old snippet.

This generic mechanism allows to give an interface priority
over others if needed, like in the previous case.

* Remove slices.Contains, since seems to be not supported

* Update interfaces/apparmor/spec.go

Co-authored-by: Zygmunt Bazyli Krynicki <me@zygoon.pl>

* Use testutils.Contains

* Replace "uid" with "key" for clarity and sanity

* Add specific type for priority keys and force registering them

* Remove unneeded return

* Use SnippetKey as type

* Don't use "slice" since MacOS seems to not support it

* Update interfaces/apparmor/spec.go

Co-authored-by: Zygmunt Bazyli Krynicki <me@zygoon.pl>

* Update interfaces/apparmor/spec.go

Co-authored-by: Zygmunt Bazyli Krynicki <me@zygoon.pl>

* Use String instead of GetValue

* Use SnippetKey as key instead of the inner string

* Update interfaces/connection.go

Co-authored-by: Zygmunt Bazyli Krynicki <me@zygoon.pl>

* Several changes requested

* Create the SnippetKeys inside Spec

* Move key registration outside Spec

This creates a centralized key registry inside apparmor module,
so keys can be registered using top variables, and any
duplicated key will produce a panic when snapd is launched,
thus just panicking in any test too.

* Added extra ways of working with SnippetKeys

* Add extra check

* Replace GetSnippetKey with GetSnippetKeys

* Update the priority code use case

A previous PR was merged with a Quick&Dirty(tm) solution to the
priority problem between unity7 and desktop-legacy interfaces
against desktop-launch interface.

Now that it has been merged, that code must be updated to the
new mechanism implemented in this PR. This is exactly what this
commit does.

* Add explanation and constants for prioritized snippets

* Fix prioritized snippet key and add test in all_test

* Several changes requested by Zygmunt Vazyli

---------

Co-authored-by: Zygmunt Bazyli Krynicki <me@zygoon.pl>
2024-07-08 22:27:44 +02:00
Jorge Sancho Larraz
265b7c44d1 sandbox/apparmor: aare exclusion rule generation (#13488)
* sandbox/apparmor: add GenerateAAREExclusionPatterns

This function is generic (and complex) enough to be able to handle all of the
overlapping and wildcard behavior we need in docker-support, and it could also
serve to replace numerous other places in the codebase where we need this sort
of complex behavior. It is a generalization of the existing
aareExclusionPatterns helper, though it's actually unclear if this exact
implementation will currently be able to serve the use case from that helper
directly or if more options/adjustments are needed to enable that use case as
well.

To keep the diff smaller, this patch does not actually change any of the
profiles/interfaces, just TODO's are left for where to use it.

Note that the generated rules are slightly more condensed in terms of number of
rules but significantly more verbose in terms of alternations, not sharing more
of repeated substrings between alternations inside the patterns. This was done
explicitly to keep the generating code simpler and easier to understand, but it
may prove to have performance effects, either detrimental or benevolent but
that should be measured before deciding to make the generation code even more
complex than it already is.

Signed-off-by: Ian Johnson <ian.johnson@canonical.com>

* interfaces/docker-support: generate AARE exclusion patterns with helper func

Signed-off-by: Ian Johnson <ian.johnson@canonical.com>

* sandbox/apparmor: unexport helper functions

These were not meant to be exported, only the fully generic one is meant to be
exported.

Signed-off-by: Ian Johnson <ian.johnson@canonical.com>

* sandbox/apparmor: fix bug mis-sorting capitalized letters in AARE exclude patt

Thanks to Alberto for spotting this :-)

Signed-off-by: Ian Johnson <ian.johnson@canonical.com>

* sandbox/apparmor: fix format issues introduced during rebase

* sandbox/apparmor: simplify generateAAREExclusionPatternsGenericImpl

* sandbox/apparmor: add checks for unsupported cases and improve documentation

* sandbox/apparmor: update tests to compare the apparmor binary instead of source

* interfaces/builtin/docker_support: check if userns is supported before adding it to the profile

* interfaces/builtin/docker_support: fix dependencies

* sandbox/apparmor: use placeholders

* i/b/docker_support_test: update TestGenerateAAREExclusionPatterns to use SnapAppSet

* testutil/apparmor: use go crypto/sha1 module instead of system sha1sum command

* {sandbox,testutil}/apparmor: minor format fixes

* move helper to find common prefix to strutil

* add copyright info

* use string builder

* i/b/docker_support_test.go: update accordingly to 277fbc266e (many: add components to interfaces.SnapAppSet (#13837))

* strutil/commonprefix.go: remove extra empty line

* sandbox/apparmor/apparmor.go: sort prefixes to ensure profile is always the same

* sandbox/apparmor/apparmor.go: remove extra empty line

* i/b/docker_support_test: skip TestGenerateAAREExclusionPatterns is apparmor_parser is not usable

---------

Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
Co-authored-by: Ian Johnson <ian.johnson@canonical.com>
2024-07-04 12:23:08 +02:00
Zygmunt Krynicki
dc21b817c2 interfaces/apparmor: replace references to ubuntu-core-launcher
Only comments are affected, the policy and sandbox is identical.

Jira: SNAPDENG-23247

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
2024-06-18 12:37:31 +02:00
Andrew Phelps
71d22420df many: add a *SnapAppSet to ConnectedPlug/Slot types and use it to build label expressions in interfaces (#13773)
Now that we have app sets in the interfaces repo, keep a pointer to them in ConnectedPlug/Slot types. Use this to build label expressions in the interfaces. 

* many: add a pointer to a SnapAppSet into Connected(Plug|Slot) to that interfaces can build a complete label expression, including component hooks

* interfaces: update doc comments on ConnectedPlug/Slot.AppSet

* interfaces: remove TODO that has been addressed

* interfaces: use app set pointer for instance name check

* snap: add Runnable type that represents the runnable parts of a snap

* interfaces, o/ifacestate: use snap.Runnable rather than interfaces.Runnable

* interfaces, i/builtin, o/ifacestate: panic on failed invariant check in NewConnectedPlug/Slot

* interfaces: add methods to app set for getting runnables that can connect to plug/slot

* interfaces: build label expressions using runnables

* interfaces: doc comment for SlotRunnables

* interfaces: implement Slot/PlugRunnables with shared helper

* interfaces: log and skip security tags that do not match expected pattern

* snap, interfaces: move runnable constructors to methods on AppInfo and HookInfo

* interfaces: refactor to allow labelExpr to operate directly on a ConnectedPlug/Slot

* snap: move around Runnable methods
2024-06-14 18:37:26 +02:00
Oliver Calder
0ff642e82e many: include prompt prefix in apparmor rules (#13822)
* features,i/{apparmor,builtin}: include prompt prefix in home interface

If prompting is supported and enabled, include the prompt prefix in
AppArmor rules for the home interface, which will cause AppArmor to send
a prompt when accessing any file in $HOME.

In the future, if other interfaces include the ###PROMPT### prefix in
their rule snippets, this will also be handled accordingly.

At the moment, the status of prompting support is checked whenever the
AppArmor backend prepares profiles. This is okay, since AppArmor support
for prompting depends on kernel and parser features, which are only
probed once after snapd starts. However, to ensure that the same
supported value is used even if that were not the case, and in case we
wish to only use the prompt prefix for some snaps or interfaces, we may
wish to embed whether to use the prompt prefix in the AppArmor
Specification instead.

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* features: adjust unsupported messages when checking apparmor features errors

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* interfaces: add prompting status to system key

Include whether prompting is supported and enabled as a single field in
the system key. This way, if `(supported && enabled)` changes, security
profiles will be regenerated when snapd starts up.

Currently, prompting support only changes when the AppArmor kernel or
parser features change, and profile regeneration is the only other place
where it is checked whether AppArmor prompting is supported and enabled.
Thus, including whether prompting is supported and enabled in the system
key ensures that security profiles are regenerated when necessary during
snapd startup, and only when necessary (e.g. not if support changed but
prompting flag remained disabled nor if flag changed but prompting
remained unsupported).

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* o/c/configcore: restart snapd when prompting value changes

When the prompting flag changes and the result entails that security
profiles should be regenerated, restart snapd to do so.

This is required iff prompting is supported and the experimental
apparmor-prompting flag changes -- if prompting is not supported,
prompting can't be used, so no need to regenerate profiles. Importantly,
prompting support is based entirely on the available AppArmor kernel and
parser features, and these are only probed once during snapd startup, so
prompting support cannot change (under the current implementation)
except when snapd restarts.

Since `(supported && enabled)` is part of the system key, and a restart
is only triggered if prompting is supported and the flag value changes
(which is equivalent to `(supported && enabled)`, since the supported
value cannot change while snapd is running), restarting after the flag
has changed causes the system key to be different, and thus to trigger a
security profile regeneration, as desired.

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* interfaces,o/ifacestate: set prompting in apparmor spec

Rather than checking whether AppArmor prompting is supported and enabled
whenever the AppArmor backend is processing a snippet, instead include
that precomputed value in the Specification itself, and place it there
via `buildConfinementOptions`. This way, any spec created with the same
`confinementOptions` will make the same decision as to whether to
include prompt prefixes on relevant rules.

Currently, `buildConfinementOptions` simply checks whether prompting is
supported and enabled via the methods on `features.AppArmorPrompting`,
but ideally, this value would be looked up from either the system key
or by checking whether the prompting listener is running. It remains to
be seen how the value computed as part of the system key can be
guaranteed to be the same as that used elsewhere, either in
`buildConfinementOptions` or when deciding whether to start the
listener.

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* o/c/configcore: request snapd restart whenever prompting flag changes

Previously, a snapd restart was only requested when the status of the
"apparmor-prompting" experimental feature flag changed and prompting was
supported. However, since prompting support is dependent on AppArmor
kernel and parser features which are probed only once during startup,
and systems which do not use vendored AppArmor may have had an update to
the system AppArmor package which newly supports AppArmor prompting, it
is safer to request a restart of snapd to re-check for prompting
support.

This way, if one is enabling prompting for the first time on a system
without prompting support, they can have snapd installed, update their
kernel or apparmor installation to support prompting, and then set the
prompting flag to enable prompting without needing to manually restart
snapd.

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* interfaces: support optional trailing space after ###PROMPT###

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

i/apparmor: move promptReplacer definition to before its use

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* tests: add test of restart behavior when setting experimental.apparmor-prompting

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* tests: refactor prompting test to reset failed count and safely check for restarts

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

tests: add shellcheck exception for apparmor prompting flag restart test

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* tests: check that snapd PID != 0 and use snap changes to wait for feature change to complete

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* tests: check for start-limit-hit before calling reset-failed

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* tests: add ubuntu core to apparmor prompting flag restart test

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* tests: check apparmor-prompting value after setting it unchanged

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* Revert "tests: check for start-limit-hit before calling reset-failed"

This reverts commit bea68516c3287fa44d6718f0794484746ae99ac5.

* tests: check systemd start-limit-hit when apparmor-prompting flag changed

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* o/configstate/configcore: add unit tests for doExperimentalApparmorPromptingDaemonRestart

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* i/builtin: add missing prompt prefix and adjust test

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* i/apparmor: add test for prompt prefix substitution

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* many: pass prompting value into system key functions

As such, we now precompute whether prompting is supported and enabled in
`InterfaceManager.StartUp()`, store it in the `InterfaceManager`
instance, and pass it into the call to `WriteSystemKey()`.

Additionally, we make `buildConfinementOptions` a method of
`InterfaceManager`, thus eliminating the need to check within the system
key functions whether prompting is supported and enabled.

However, there remains a problem that `snap run` calls
`SystemKeyMismatch()`, which previously invoked
`apparmor.ParserFeatures()` via `AppArmorPrompting.IsSupported()`, and
now calls `AppArmorPrompting.IsSupported()` directly and passes the
result into `SystemKeyMismatch()`. In either case, we really want this
to be avoided if at all possible, since `snap run` does not have access
to the cached value from the `InterfaceManager`, and thus must invoke
the `apparmor_parser` binary to check parser features whenever we want
to run any snap.

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* many: don't probe parser features when checking system key mismatch

Since `snap run` calls `SystemKeyMismatch()`, we want to avoid needing
to call `AppArmorPrompting.IsSupported()` if at all possible, since this
calls `apparmor.ParserFeatures()`, which executes the `apparmor_parser`
binary. We can and should call `AppArmorPrompting.IsSupported()` when
writing the system key, but not when checking for a mismatch.

The system key written to disk should correctly hold the list of kernel
and parser features, the parser mtime, and whether or not prompting was
previously supported and enabled. We can check whether apparmor parser
features have changed by checking the parser mtime, without needing to
probe parser features -- this optimization is already used by
`SystemKeyMismatch()`. If we knew whether prompting was previously
supported (regardless of whether it was enabled), then so long as the
parser and kernel features are unchanged, we know that prompting support
is also unchanged.

Thus, if we add a second prompting-related field to the system key, this
one storing whether prompting is supported (ignoring enabled), we can
check if prompting support is unchanged without needing to call
`AppArmorPrompting.IsSupported()`.

Furthermore, `SystemKeyMismatch()` is the function in question, and if
there is any mismatch detected, it should return such as soon as
possible, regardless of what the mismatch is. Therefore, if we know that
either kernel or parser features have changed, then we can immediately
return that there is a mismatch, and we don't need to check whether
those feature changes affect prompting support.

Therefore, the new cases which we must worry about when checking for a
system key mismatch are the following, when all other system key fields
are unchanged (note that prompting must be supported in order to be
supported&&enabled):

1. supported: F, supported&&enabled: F, newFlag: F, mismatch: F
2. supported: F, supported&&enabled: F, newFlag: T, mismatch: F
3. supported: T, supported&&enabled: F, newFlag: F, mismatch: F
4. supported: T, supported&&enabled: F, newFlag: T, mismatch: T
5. supported: T, supported&&enabled: T, newFlag: F, mismatch: T
6. supported: T, supported&&enabled: T, newFlag: T, mismatch: F

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* interfaces: fix test string formatting

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* o/configstate/configcore: adjust prompting-related comments

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* tests: increase prompting check_snapd_restarted timeout and add systemd show

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* tests: reset start limit when checking if snapd restarted after prompting change

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* many: add system key extra data to hold prompting enabled status

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* many: only store one apparmor prompting value in system key

When checking for a system key mismatch, use the stored AppArmor
parser features from the system key on disk (along with the kernel
features from the newly-generated key) to check whether prompting is
supported, and AND that with the `AppArmorPrompting` value passed in
with the `SystemKeyExtraData`. If the kernel or parser features have
changed, the system key will be a mismatch anyway, so it is perfectly
safe to use the existing parser features to check for prompting support.

As such, the functions to check for prompting support have been moved
from `features` to `sandbox/apparmor`, and the support check has been
separated from the call to get `ParserFeatures()` and
`KernelFeatures()`, so that the values from the system key can be passed
in instead of invoking those functions.

Using the system key's stored parser and kernel features, there is no
need to save whether prompting is supported as part of the system key,
simplifying the key and the logic used to set the prompting value.

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* tests: explicitly install jq in apparmor-prompting-flag-restart test

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* many: consolidate checks for apparmor prompting support

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* interfaces,s/apparmor: use features struct when checking prompting support

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* tests: improve logging in apparmor-prompting-flag-restart test

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

* tests: fix prompting flag restart test on core18

For some reason, when snapd fails due to start-limit-hit on core18, the
snapd.failure.service starts and acquires the state lock, thus
preventing snapd from successfully becoming "active" again and leaving
it retrying at "activating". It is unclear why this happens on core18
and not elsewhere.

As a fix, when resetting the start limit, stop snapd.failure.service
manually to ensure that snapd can successfully start.

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

---------

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>
2024-06-11 18:13:00 +01:00
Andrew Phelps
c1cf798549 many: generate security profiles from component hooks (#13686)
* interfaces: add method to SnapAppSet for getting list of runnable entities

* interfaces: replace references to hooks/apps in backends with usage of SnapAppSet.Runnables

* interfaces: rename SecurityTagGlob to SecurityTagGlobs and make it handle component hooks

* snap: add method for getting component hooks for a specific plug

* interfaces: add component hooks to output of SecurityTagsForConnectedPlug

* snapstate: add methods for getting components installed for the current and arbitrary revisions of a snap

* o/ifacestate: properly set up SnapAppSets with components prior to passing them off to security backends

* o/snapstate: create setup-profiles task when installing a component

* many: add side info param to snaptest.MockComponent

* many: fix failing tests caused by changes in rebase

* snap: add ComponentHookSecurityTag for getting a component hook's security tag

* interfaces: implement SecurityTagGlobs with snap.ComponentHookSecurityTag

* interfaces: move some helper functions to helpers.go

* o/snapstate: add functions that are useful when operating on component-related tasks

* o/ifacestate: use functions from snapstate rather than local functions

* i/apparmor: cleanup comment and whitespace

* o/snapstate: replace some speculative code with TODOs for now

* interfaces, o/ifacestate: remove Type from interfaces.Runnable and do not sort the result of SnapAppSet.Runnables()

* o/snapstate: remove unused variable
2024-05-08 11:30:03 -04:00
Andrew Phelps
277fbc266e many: add components to interfaces.SnapAppSet (#13837) 2024-05-07 09:53:59 -04:00
Maciej Borzecki
15b23e9d6c interfaces/apparmor: make the HomeIx unit test more realistic
The HOME_IX pattern is only included and expanded when processing snippets.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
2024-04-25 16:33:57 +02:00
Maciej Borzecki
52bd5eefd3 interfaces/apparmor: log a warning when pattern cannot be expanded
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
2024-04-25 16:33:57 +02:00
Maciej Borzecki
2498c77977 interfaces/apparmor: panic when template snippets cannot be expanded during testing
Try to catch all missing snippet expansions by invoking an explicit panic. Limit
this to scenarios when we are executing integration tests (when
SNAPPY_TESTING=1), or when running in a go test binary.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
2024-04-25 16:33:57 +02:00
Zygmunt Bazyli Krynicki
8edebfd988 i/apparmor: allow snap-update-ns to traverse to /var/lib/snapd (#13858)
I've noticed this denial in one of my test systems:

  kwi 19 10:54:52 ubuntu-2204-cryptfs kernel: audit: type=1400
  audit(1713516892.723:323): apparmor="DENIED" operation="open" class="file"
  profile="snap-update-ns.chromium" name="/var/lib/snapd /" pid=8425 comm="5"
  requested_mask="r" denied_mask="r" fsuid=0 ouid=0

Given that snap-update-ns must access mount profiles and contains code to
safely traverse a path without any symbolic links, I think the extra
permissions is acceptable.

I did not audit the code to pinpoint the exact cause.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
2024-04-20 09:29:13 +02:00
Zygmunt Bazyli Krynicki
5ca13c7dec i/apparmor: fix snap-update-ns with ecrypfs home (#13857)
Ever since snapd 2.62 was released, snap-update-ns requires opening the home
directory of the user for some validation and sanity checking. This is now
affected by a bug in base policy regarding ecryptfs. Add the similar workaround
we have in other templates.

Fixes: https://bugs.launchpad.net/ubuntu/+source/chromium-browser/+bug/2062330
Fixes: https://bugs.launchpad.net/ubuntu/+source/chromium-browser/+bug/2062173

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
2024-04-19 12:49:45 +02:00
Zygmunt Bazyli Krynicki
63a26ef1b7 i/apparmor: add missing expansion for s-u-n template (#13853)
This fixes access to /etc/apparmor.d/tunables when running from snapd snap.
When snapd snap re-executes, and uses apparmor_parser from snapd snap (those
are separate conditions), then it re-directs the parser away from host
/etc/apparmor.d and we have special code to load tunables from the host anyway.
Those tunables are themselves conditional on the conditional include syntax
that may or may not be supported by apparmor (otherwise the would be explicitly
spelled out in the template, and not dynamically expanded with custom logic).

The problem was introduced along with patch
b98e4af376 (i/apparmor: support for home.d
tunables from /etc/ (#13118)), as the case for snap-update-ns was missed, and
the default expansion is an empty string.

Regression-testing this requires that we re-package snapd snap, so the test
will come in with a separate patch as it requires somewhat more effort to
behave correctly.

This issue was identified by Maciej Borzecki.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
2024-04-18 14:47:34 +02:00
Zygmunt Bazyli Krynicki
d78bbedcb1 many: generalize wording of NFS workaround (#13758)
Ahead of introduction of CIFS workaround, generalize the names so that we use
more general language rather instead of focusing on NFS.

As a special exception the externally visible wording related to NFS is kept
intact in two places:

 - The apparmor "nfs-support" file name
 - The system key "nfs-home" key.

From points of view this is all an elaborate internal rename that should nto be
observable outside of snapd, apart from log messages that may no longer speak of
NFS but of remote file systems.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
2024-04-04 19:22:17 +02:00
Miguel Pires
79c5ac14b2 many: remove usages of deprecated io/ioutil package (#13768)
* many: remove usages of deprecated io/ioutil package

Signed-off-by: Miguel Pires <miguel.pires@canonical.com>

* .golangci.yml: remove errcheck ignore rule for io/ioutil

Signed-off-by: Miguel Pires <miguel.pires@canonical.com>

* run-checks: prevent new usages of io/ioutil

Signed-off-by: Miguel Pires <miguel.pires@canonical.com>

---------

Signed-off-by: Miguel Pires <miguel.pires@canonical.com>
2024-04-03 23:23:24 +02:00
Andrew Phelps
069b7f684e many: use interfaces.SnapAppSet in security backends (#13587) 2024-02-27 14:52:02 -05:00
Jorge Sancho Larraz
535f048bc4 interfaces/apparmor/template: add read access to /etc/default/keyboard 2024-02-23 08:34:24 +01:00
Andrew Phelps
d8a2e847e5 many: introduce SnapAppSet for use in security backends (#13574)
* interfaces: introduce SnapAppSet and forward one to the security backends

* snap: implement methods on snap.Info for getting apps and hooks for slots and plugs

This will enable us to remove the Hooks fields from the SlotInfo and
PlugInfo structs.

* interfaces: implement methods on SnapAppSet in terms of methods on snap.Info

* snap, interfaces: replace usage of {Plug,Slot}Info.SecurityTags with methods on SnapAppSet

* i/builtin: replace slotAppLabelExpr and plugAppLabelExpr with corresponding methods on SnapAppSet

* snap, o/snapstate, interfaces: remove Hooks field on snap.PlugInfo and snap.SlotInfo

* builtin, interfaces: fix tests that use Specification that now have a SnapAppSet

* snap: add tests for new methods on Info

* interfaces, i/builtin: port over some tests for SnapAppSet methods {Plug,Slot}LabelExpression

* interfaces: test PlugSecurityTags and SlotSecurityTags methods

* interfaces: add doc comments to SnapAppSet and methods

* i/builtin: remove ported over tests

* interfaces, many: require that SnapAppSet methods for getting security tags are called with plug/slot that comes from correct snap

Many tests did not properly adhere to this requirment, so they had to be
modifed to modify this rule.

Additionally, a hack was inroduced in the methods for getting label
expressions on the SnapAppSet. If a plug/slot did not originate from the
same snap that the SnapAppSet was created from, then we will use the
snap.Info that the plug/slot carries in the method instead. This will
fail to work once component hooks are introduced, so this will need to
be resolved by then.

* interfaces: test fallback for using LabelExpr methods with mismatch plug/slot

* snap: correct placement of TODOs to preserve doc comments

* snap: add doc comments for Plug/Slot.Unscoped

* interfaces: test for using SecurityTagsForPlug and SecurityTagsForSlot with wrong snap

* interfaces: tweak error messages in SnapAppSet SecurityTags methods

* i/builtin: fix missed conflict

* i/apparmor: add doc comment to Specification.appSet

* snap: fix doc coment on PlugInfo.Unscoped
2024-02-19 11:57:42 +01:00
Alex Murray
1ebfd19e87 interfaces: move lxd-support's use of AppArmor unconfined mode to an interface attribute (#13514)
* interfaces/apparmor: rework unconfined mode for dynamic enablement

For an interface to use unconfined mode, it must both declare support for it as
a static property and then enable it by an explicit call. This allows interfaces
to enable this dynamically via an plug/slot attribute or similar as needed (or
if not, it can be enabled the permanent plug/slot callback for the interface
instead).

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces/builtin/lxd-support: add an attr for unconfined mode

The use of AppArmor unconfined mode requires a small amount of support in lxd
itself, and so to ensure that we only use this when the lxd snap supports it,
add a new interface attribute which the snap can set to specify that it has the
required support and only enable this in the interface when that is present.

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces/apparmor: check for error in unconfined mode unit test

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces/apparmor: fixup comments documenting UnconfinedMode etc

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces/builtin: test validation of attr in lxd-support

Add a new unit test to check that the lxd-support interface validates the
enable-unconfined-mode attribute as a boolean correctly.

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces/builtin/lxd_support: clarify behaviour of unconfined mode

Add some comments to clarify the behaviour and use of unconfined mode.

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces/builtin/lxd_support: test unconfined mode enablement

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces/builtin/lxd_support: explicitly ignore error

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces/builtin/lxd_support: fixup gofmt in test

Signed-off-by: Alex Murray <alex.murray@canonical.com>

---------

Signed-off-by: Alex Murray <alex.murray@canonical.com>
2024-02-16 08:43:06 +01:00
Maciej Borzecki
921c574c8f interfaces/apparmor: limit s-u-n /proc/ access to entries owned by current process
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
2024-02-09 12:49:48 +01:00
Maciej Borzecki
97c061fab9 interfaces/apparmor: update apparmor template of s-u-n for changes in Go
Rebuilding snap-update-ns with Go 1.22.0 triggers a new denial with the process
trying to read /proc/self/maps.

The denial shows up as:

```
audit: type=1400 audit(1707404561.548:1563): apparmor="DENIED"
       operation="open" class="file"
       profile="snap-update-ns.test-snapd-sh-core22"
       name="/proc/2993630/maps" pid=2993630 comm="5"
       requested_mask="r" denied_mask="r" fsuid=0 ouid=0
```

Inspecting with strace, the attempt to open /proc/self/maps happens just a
handful of syscalls after execing into snap-update-ns.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
2024-02-09 12:49:48 +01:00
Zygmunt Bazyli Krynicki
27149948e9 many: assorted typos (#13510)
* snap-confine: fix typo in comment

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

* daemon: fix typo in comment

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

* i/apparmor: fix typo: panicking

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

* o/snapstate: fix typo: removable

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

---------

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
2024-01-24 08:42:23 +01:00
Maciej Borzecki
f716f2a23c intefaces/apparmor: do not combine unconfined and complain profile flags
d0023970be
added support for unconfined profile mode, however it is possible that in
certain scenarios snapd would produce a profile which contains both unconfined
and complain. This is rejected by the parser, as profile mode are exclusive.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
2024-01-18 14:43:05 +01:00
Alex Murray
d0023970be many: add support for AppArmor unconfined profile mode (#13333)
* sandbox/apparmor: read apparmor kernel sub-features

These are required to be able to detect whether the running kernel supports the
use of the unconfined profile mode amongst others.

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* sandbox/apparmor: add support for probing parser for unconfined flag

AppArmor 4.0 introduced a new flag named unconfined - since this is a profile
flag rather than part of the main profile syntax, also add support for probing
for flags within AppArmor profiles.

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces/apparmor: add support for unconfined profile flag

Add a new unconfined attribute to the AppArmor specification which is used to
denote that a profile should include the unconfined flag. Then refactor flag
handling within the AppArmor backend so that both this new flag and the complain
flag (used for classic and dev mode snaps) are handled together. Finally, only
emit this flag when we are sure both the AppArmor parser and kernel provide
appropriate support.

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces/builtin/lxd_support: add userns and unconfined permissions

LXD requires the use of unprivileged userns and the ability to run unconfined -
so support for both of these to the lxd-support interface.

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* tests/main/lxd: verify apparmor profile has expected perms on mantic

On Ubuntu 23.10 the LXD snap should run with the new unconfined profile flag and
with the userns AppArmor permission, so check for these via spread.

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces: rework AppArmor unconfined mode to be a static property

As suggested by @pedronis, refactor the implementation of AppArmor unconfined
profile mode to be a static property of an interface so that it is much more
tightly coupled to the interface itself. Add various tests as well to ensure
that only super-privileged interfaces can use this property too.

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* tests/main/lxd: add details to the spread test

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* sandbox/apparmor: test kernel sub-features

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces: clarify comment regarding AppArmorUnconfined{Plugs,Slots}

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* interfaces/policy: check for unconfined plug/slots outside type loop

Signed-off-by: Alex Murray <alex.murray@canonical.com>

* sandbox/apparmor: fix double space in profiles when probing parser

Thanks for the suggestion @MiguelPires

Signed-off-by: Alex Murray <alex.murray@canonical.com>

---------

Signed-off-by: Alex Murray <alex.murray@canonical.com>
2024-01-03 11:23:48 +00:00
Ernest Lotter
fdc90dfe41 many: ensure-dir mounts for personal-files missing dirs (#13260)
* many: ensure-dir mount entries from personal-files write attrs

* many: review improvements

* strutil: make pathiter current path slash trimming use existing method

* osutil, strutil: more review fixes

* i, i/apparmor, i/builtin, osutil: improve unit test coverage

* i, i/apparmor, i/builtin, i/mount: review improvements

* strutil: improve comment

* interfaces/apparmor: allow snap-update-ns to open home directory

* tests: revert interfaces-personal-files changes to simplify merge

* interfaces/builtin: improve plug connect error message

Co-authored-by: Miguel Pires <miguelpires94@gmail.com>

* interfaces/builtin: fixed ut

---------

Co-authored-by: Miguel Pires <miguelpires94@gmail.com>
2023-12-15 15:25:49 +02:00