Documentation ¶
Overview ¶
Package apparmor contains primitives for working with apparmor.
References:
- http://wiki.apparmor.net/index.php/Kernel_interfaces
- http://apparmor.wiki.kernel.org/
- http://manpages.ubuntu.com/manpages/xenial/en/man7/apparmor.7.html
Package apparmor implements integration between snappy and snap-confine around apparmor.
Snappy creates apparmor profiles for each application (for each snap) present in the system. Upon each execution of snap-confine application process is launched under the profile. Prior to that the profile must be parsed, compiled and loaded into the kernel using the support tool "apparmor_parser".
Each apparmor profile contains a simple <header><content><footer> structure. The header specifies the profile name that the launcher will use to launch a process under this profile. Snappy uses "abstract identifiers" as profile names.
The actual profiles are stored in /var/lib/snappy/apparmor/profiles.
NOTE: A systemd job (apparmor.service) loads all snappy-specific apparmor profiles into the kernel during the boot process.
Index ¶
- func GenWritableFileProfile(emit func(f string, args ...interface{}), path string, assumedPrefixDepth int)
- func GenWritableMimicProfile(emit func(f string, args ...interface{}), path string, assumedPrefixDepth int)
- func GenWritableProfile(emit func(f string, args ...interface{}), path string, assumedPrefixDepth int)
- func RegisteredSnippetKeys() []string
- func RemoveAllSnapAppArmorProfiles() error
- func ValidateNoAppArmorRegexp(s string) error
- type Backend
- func (b *Backend) Initialize(opts *interfaces.SecurityBackendOptions) error
- func (b *Backend) Name() interfaces.SecuritySystem
- func (b *Backend) NewSpecification(appSet *interfaces.SnapAppSet, opts interfaces.ConfinementOptions) interfaces.Specification
- func (b *Backend) Remove(snapName string) error
- func (b *Backend) RemoveLate(snapName string, rev snap.Revision, typ snap.Type) error
- func (b *Backend) SandboxFeatures() []string
- func (b *Backend) Setup(appSet *interfaces.SnapAppSet, opts interfaces.ConfinementOptions, ...) error
- func (b *Backend) SetupMany(appSets []*interfaces.SnapAppSet, ...) []error
- type SnippetKey
- type Specification
- func (spec *Specification) AddConnectedPlug(iface interfaces.Interface, plug *interfaces.ConnectedPlug, ...) error
- func (spec *Specification) AddConnectedSlot(iface interfaces.Interface, plug *interfaces.ConnectedPlug, ...) error
- func (spec *Specification) AddDeduplicatedSnippet(snippet string)
- func (spec *Specification) AddEnsureDirMounts(ifaceName string, ensureDirSpecs []*interfaces.EnsureDirSpec)
- func (spec *Specification) AddExtraLayouts(si *snap.Info, layouts []snap.Layout)
- func (spec *Specification) AddLayout(appSet *interfaces.SnapAppSet)
- func (spec *Specification) AddOvername(si *snap.Info)
- func (spec *Specification) AddParametricSnippet(templateFragment []string, value string)
- func (spec *Specification) AddPermanentPlug(iface interfaces.Interface, plug *snap.PlugInfo) error
- func (spec *Specification) AddPermanentSlot(iface interfaces.Interface, slot *snap.SlotInfo) error
- func (spec *Specification) AddPrioritizedSnippet(snippet string, key SnippetKey, priority uint)
- func (spec *Specification) AddSnippet(snippet string)
- func (spec *Specification) AddUpdateNS(snippet string)
- func (spec *Specification) AddUpdateNSf(f string, args ...interface{})
- func (spec *Specification) SecurityTags() []string
- func (spec *Specification) SetSuppressHomeIx()
- func (spec *Specification) SetSuppressPtraceTrace()
- func (spec *Specification) SetSuppressPycacheDeny()
- func (spec *Specification) SetSuppressSysModuleCapability()
- func (spec *Specification) SetUnconfinedEnabled() error
- func (spec *Specification) SetUsesPtraceTrace()
- func (spec *Specification) SetUsesSysModuleCapability()
- func (spec *Specification) SnapAppSet() *interfaces.SnapAppSet
- func (spec *Specification) SnippetForTag(tag string) string
- func (spec *Specification) Snippets() map[string][]string
- func (spec *Specification) SuppressHomeIx() bool
- func (spec *Specification) SuppressPtraceTrace() bool
- func (spec *Specification) SuppressPycacheDeny() bool
- func (spec *Specification) SuppressSysModuleCapability() bool
- func (spec *Specification) Unconfined() UnconfinedMode
- func (spec *Specification) UpdateNS() []string
- func (spec *Specification) UpdateNSIndexOf(snippet string) (idx int, ok bool)
- func (spec *Specification) UsePromptPrefix() bool
- func (spec *Specification) UsesPtraceTrace() bool
- func (spec *Specification) UsesSysModuleCapability() bool
- type UnconfinedMode
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GenWritableFileProfile ¶
func GenWritableFileProfile(emit func(f string, args ...interface{}), path string, assumedPrefixDepth int)
GenWritableFileProfile writes a profile for snap-update-ns for making given file writable.
func GenWritableMimicProfile ¶
func GenWritableMimicProfile(emit func(f string, args ...interface{}), path string, assumedPrefixDepth int)
GenWritableMimicProfile generates apparmor rules for a writable mimic at the given path.
func GenWritableProfile ¶
func GenWritableProfile(emit func(f string, args ...interface{}), path string, assumedPrefixDepth int)
GenWritableProfile generates a profile for snap-update-ns for making given directory writable.
func RegisteredSnippetKeys ¶
func RegisteredSnippetKeys() []string
GetSnippetKey retrieves all the current valid keys
func RemoveAllSnapAppArmorProfiles ¶
func RemoveAllSnapAppArmorProfiles() error
Removes all AppArmor profiles from disk but does not unload them from the kernel - currently it is not possible to ensure that all services of a snap are stopped and so it is not possible to safely unload the profile for a snap from the kernel and so we only remove it from the cache on disk
func ValidateNoAppArmorRegexp ¶
ValidateNoAppArmorRegexp will check that the given string does not contain AppArmor regular expressions (AARE), double quotes or \0. Note that to check the inverse of this, that is that a string has valid AARE, one should use interfaces/utils.NewPathPattern().
Types ¶
type Backend ¶
type Backend struct {
// contains filtered or unexported fields
}
Backend is responsible for maintaining apparmor profiles for snaps and parts of snapd.
func (*Backend) Initialize ¶
func (b *Backend) Initialize(opts *interfaces.SecurityBackendOptions) error
Initialize prepares customized apparmor policy for snap-confine.
func (*Backend) Name ¶
func (b *Backend) Name() interfaces.SecuritySystem
Name returns the name of the backend.
func (*Backend) NewSpecification ¶
func (b *Backend) NewSpecification(appSet *interfaces.SnapAppSet, opts interfaces.ConfinementOptions) interfaces.Specification
NewSpecification returns a new, empty apparmor specification.
func (*Backend) Remove ¶
Remove removes the apparmor profiles of a given snap from disk and the cache.
func (*Backend) RemoveLate ¶
func (*Backend) SandboxFeatures ¶
SandboxFeatures returns the list of apparmor features supported by the kernel.
func (*Backend) Setup ¶
func (b *Backend) Setup(appSet *interfaces.SnapAppSet, opts interfaces.ConfinementOptions, repo *interfaces.Repository, tm timings.Measurer) error
Setup creates and loads apparmor profiles specific to a given snap. The snap can be in developer mode to make security violations non-fatal to the offending application process.
This method should be called after changing plug, slots, connections between them or application present in the snap.
func (*Backend) SetupMany ¶
func (b *Backend) SetupMany(appSets []*interfaces.SnapAppSet, confinement func(snapName string) interfaces.ConfinementOptions, repo *interfaces.Repository, tm timings.Measurer) []error
SetupMany creates and loads apparmor profiles for multiple snaps. The snaps can be in developer mode to make security violations non-fatal to the offending application process. SetupMany tries to recreate all profiles without interrupting on errors, but collects and returns them all.
This method is useful mainly for regenerating profiles.
type SnippetKey ¶
type SnippetKey struct {
// contains filtered or unexported fields
}
SnippetKey is an opaque string identifying a class of snippets.
Some APIs require the use of snippet keys to allow adding many different snippets with the same key but possibly different priority.
func RegisterSnippetKey ¶
func RegisterSnippetKey(key string) SnippetKey
RegisterSnippetKey adds a key to the list of valid keys
func (*SnippetKey) String ¶
func (pk *SnippetKey) String() string
type Specification ¶
type Specification struct {
// contains filtered or unexported fields
}
Specification assists in collecting apparmor entries associated with an interface.
func NewSpecification ¶
func NewSpecification(appSet *interfaces.SnapAppSet) *Specification
func (*Specification) AddConnectedPlug ¶
func (spec *Specification) AddConnectedPlug(iface interfaces.Interface, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error
AddConnectedPlug records apparmor-specific side-effects of having a connected plug.
func (*Specification) AddConnectedSlot ¶
func (spec *Specification) AddConnectedSlot(iface interfaces.Interface, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error
AddConnectedSlot records apparmor-specific side-effects of having a connected slot.
func (*Specification) AddDeduplicatedSnippet ¶
func (spec *Specification) AddDeduplicatedSnippet(snippet string)
AddDeduplicatedSnippet adds a new apparmor snippet to all applications and hooks using the interface.
Certain combinations of snippets may be computationally expensive for apparmor_parser in its de-duplication step. This function lets snapd perform de-duplication of identical rules at the potential cost of a somewhat more complex auditing process of the text of generated apparmor profile. Identical mount rules should typically use this, but this function can also be used to avoid repeated rules that inhibit auditability.
func (*Specification) AddEnsureDirMounts ¶
func (spec *Specification) AddEnsureDirMounts(ifaceName string, ensureDirSpecs []*interfaces.EnsureDirSpec)
AddEnsureDirMounts adds snap-update-ns snippets that permit snap-update-ns to create missing directories according to the provided ensure directory mount specs.
func (*Specification) AddExtraLayouts ¶
func (spec *Specification) AddExtraLayouts(si *snap.Info, layouts []snap.Layout)
AddExtraLayouts adds additional apparmor snippets based on the provided layouts. The function is in part identical to AddLayout, except that it considers only the layouts passed as parameters instead of those declared in the snap.Info structure. XXX: Should we just combine this into AddLayout instead of this separate function?
func (*Specification) AddLayout ¶
func (spec *Specification) AddLayout(appSet *interfaces.SnapAppSet)
AddLayout adds apparmor snippets based on the layout of the snap.
The per-snap snap-update-ns profiles are composed via a template and snippets for the snap. The snippets may allow (depending on the snippet):
- mount profiles via the content interface
- creating missing mount point directories under $SNAP* (the 'tree' of permissions is needed for SecureMkDirAll that uses open(..., O_NOFOLLOW) and mkdirat() using the resulting file descriptor)
- creating a placeholder directory in /tmp/.snap/ in the per-snap mount namespace to support writable mimic which uses tmpfs and bind mount to poke holes in arbitrary read-only locations
- mounting/unmounting any part of $SNAP into placeholder directory
- mounting/unmounting tmpfs over the original $SNAP/** location
- mounting/unmounting from placeholder back to $SNAP/** (for reconstructing the data)
Importantly, the above mount operations are happening within the per-snap mount namespace.
func (*Specification) AddOvername ¶
func (spec *Specification) AddOvername(si *snap.Info)
AddOvername adds AppArmor snippets allowing remapping of snap directories for parallel installed snaps
Specifically snap-update-ns will apply the following bind mounts - /snap/foo_bar -> /snap/foo - /var/snap/foo_bar -> /var/snap/foo - /home/joe/snap/foo_bar -> /home/joe/snap/foo
func (*Specification) AddParametricSnippet ¶
func (spec *Specification) AddParametricSnippet(templateFragment []string, value string)
AddParametricSnippet adds a new apparmor snippet both de-duplicated and optimized for the parser.
Conceptually the function takes a parametric template and a single value to remember. The resulting snippet text is a single entry resulting from the expanding the template and all the unique values observed, in the order they were observed.
The template is expressed as a slice of strings, with the parameter automatically injected between any two of them, or in the special case of only one fragment, after that fragment.
The resulting expansion depends on the number of values seen. If only one value is seen the resulting snippet is just the plain string one would expect if no parametric optimization had taken place. If more than one distinct value was seen then the resulting apparmor rule uses alternation syntax {param1,param2,...,paramN} which has better compilation time and memory complexity as compared to a set of naive expansions of the full snippet one after another.
For example the code:
AddParametricSnippet([]string{"/dev/", "rw,"}, "sda1") AddParametricSnippet([]string{"/dev/", "rw,"}, "sda3") AddParametricSnippet([]string{"/dev/", "rw,"}, "sdb2")
Results in a single apparmor rule:
"/dev/{sda1,sda3,sdb2} rw,"
This function should be used whenever the apparmor template features more than one use of "**" syntax (which represent arbitrary many directories or files) and a variable component, like a device name or similar. Repeated instances of this pattern slow down the apparmor parser in the default "expr-simplify" mode (see PR#12943 for measurements).
func (*Specification) AddPermanentPlug ¶
func (spec *Specification) AddPermanentPlug(iface interfaces.Interface, plug *snap.PlugInfo) error
AddPermanentPlug records apparmor-specific side-effects of having a plug.
func (*Specification) AddPermanentSlot ¶
func (spec *Specification) AddPermanentSlot(iface interfaces.Interface, slot *snap.SlotInfo) error
AddPermanentSlot records apparmor-specific side-effects of having a slot.
func (*Specification) AddPrioritizedSnippet ¶
func (spec *Specification) AddPrioritizedSnippet(snippet string, key SnippetKey, priority uint)
AddPrioritizedSnippet adds a new apparmor snippet to all applications and hooks using the interface, but identified with a key and a priority. If no other snippet exists with that key, the snippet is added like with AddSnippet, but if there is already another snippet with that key, the priority of both will be taken into account to decide whether the new snippet replaces the old one, is appended to it, or is just ignored. The key must have been previously registered using RegisterSnippetKey().
func (*Specification) AddSnippet ¶
func (spec *Specification) AddSnippet(snippet string)
AddSnippet adds a new apparmor snippet to all applications and hooks using the interface.
func (*Specification) AddUpdateNS ¶
func (spec *Specification) AddUpdateNS(snippet string)
AddUpdateNS adds a new apparmor snippet for the snap-update-ns program.
func (*Specification) AddUpdateNSf ¶
func (spec *Specification) AddUpdateNSf(f string, args ...interface{})
AddUpdateNSf formats and adds a new apparmor snippet for the snap-update-ns program.
func (*Specification) SecurityTags ¶
func (spec *Specification) SecurityTags() []string
SecurityTags returns a list of security tags which have a snippet.
func (*Specification) SetSuppressHomeIx ¶
func (spec *Specification) SetSuppressHomeIx()
SetSuppressHomeIx records suppression of the ix rules for the home interface.
func (*Specification) SetSuppressPtraceTrace ¶
func (spec *Specification) SetSuppressPtraceTrace()
SetSuppressPtraceTrace to request explicit ptrace deny rules
func (*Specification) SetSuppressPycacheDeny ¶
func (spec *Specification) SetSuppressPycacheDeny()
SetSuppressPycacheDeny records suppression of the ix rules for the home interface.
func (*Specification) SetSuppressSysModuleCapability ¶
func (spec *Specification) SetSuppressSysModuleCapability()
SetSuppressSysModuleCapability to request explicit denial of the sys_module capability
func (*Specification) SetUnconfinedEnabled ¶
func (spec *Specification) SetUnconfinedEnabled() error
SetUnconfinedEnabled records whether a profile should be applied without any real confinement - the spec must already support unconfined profiles via a previous call to setUnconfinedSupported()
func (*Specification) SetUsesPtraceTrace ¶
func (spec *Specification) SetUsesPtraceTrace()
SetUsesPtraceTrace records when to omit explicit ptrace deny rules.
func (*Specification) SetUsesSysModuleCapability ¶
func (spec *Specification) SetUsesSysModuleCapability()
SetUsesSysModuleCapability records that some interface has granted the sys_module capability
func (*Specification) SnapAppSet ¶
func (spec *Specification) SnapAppSet() *interfaces.SnapAppSet
func (*Specification) SnippetForTag ¶
func (spec *Specification) SnippetForTag(tag string) string
SnippetForTag returns a combined snippet for given security tag with individual snippets joined with the newline character. Empty string is returned for non-existing security tag.
func (*Specification) Snippets ¶
func (spec *Specification) Snippets() map[string][]string
Snippets returns a deep copy of all the added application snippets.
func (*Specification) SuppressHomeIx ¶
func (spec *Specification) SuppressHomeIx() bool
SuppressHomeIx returns whether the ix rules of the home interface should be suppressed.
func (*Specification) SuppressPtraceTrace ¶
func (spec *Specification) SuppressPtraceTrace() bool
SuppressPtraceTrace returns whether ptrace should be suppressed as dictated by any of the interfaces in the spec.
func (*Specification) SuppressPycacheDeny ¶
func (spec *Specification) SuppressPycacheDeny() bool
SuppressPycacheDeny returns whether the ix rules of the home interface should be suppressed.
func (*Specification) SuppressSysModuleCapability ¶
func (spec *Specification) SuppressSysModuleCapability() bool
SuppressSysModuleCapability returns whether any interface has asked the sys_module capability to be explicitly denied
func (*Specification) Unconfined ¶
func (spec *Specification) Unconfined() UnconfinedMode
Unconfined returns whether a profile should be applied without any real confinement
func (*Specification) UpdateNS ¶
func (spec *Specification) UpdateNS() []string
UpdateNS returns a deep copy of all the added snap-update-ns snippets.
func (*Specification) UpdateNSIndexOf ¶
func (spec *Specification) UpdateNSIndexOf(snippet string) (idx int, ok bool)
UpdateNSIndexOf returns the index of a previously added snippet.
func (*Specification) UsePromptPrefix ¶
func (spec *Specification) UsePromptPrefix() bool
UsePromptPrefix returns whether the prompt prefix should be included for relevant rules when generating security profiles.
func (*Specification) UsesPtraceTrace ¶
func (spec *Specification) UsesPtraceTrace() bool
UsesPtraceTrace returns whether ptrace is being used by any of the interfaces in the spec.
func (*Specification) UsesSysModuleCapability ¶
func (spec *Specification) UsesSysModuleCapability() bool
UsesSysModuleCapability returns whether the sys_module capability is being used by any of the interfaces in the spec.
type UnconfinedMode ¶
type UnconfinedMode int
UnconfinedMode describes the states of support for the AppArmor unconfined profile mode - this is only enabled when the interface supports it as a static property and it is then enabled via SetUnconfinedEnabled() method
const ( UnconfinedIgnored UnconfinedMode = iota UnconfinedSupported UnconfinedEnabled )