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 ubuntu-core-launcher around apparmor.
Snappy creates apparmor profiles for each application (for each snap) present in the system. Upon each execution of ubuntu-core-launcher 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 LoadedProfiles() ([]string, error)
- func MockIsHomeUsingNFS(new func() (bool, error)) (restore func())
- 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() interfaces.Specification
- func (b *Backend) Remove(snapName string) error
- func (b *Backend) SandboxFeatures() []string
- func (b *Backend) Setup(snapInfo *snap.Info, opts interfaces.ConfinementOptions, ...) error
- func (b *Backend) SetupMany(snaps []*snap.Info, ...) []error
- 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) AddLayout(si *snap.Info)
- 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) 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) SetUsesPtraceTrace()
- 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) UpdateNS() []string
- func (spec *Specification) UpdateNSIndexOf(snippet string) (idx int, ok bool)
- func (spec *Specification) UsesPtraceTrace() bool
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 LoadedProfiles ¶
LoadedProfiles interrogates the kernel and returns a list of loaded apparmor profiles.
Snappy manages apparmor profiles named "snap.*". Other profiles might exist on the system (via snappy dimension) and those are filtered-out.
func MockIsHomeUsingNFS ¶
MockIsHomeUsingNFS mocks the real implementation of osutil.IsHomeUsingNFS. This is exported so that other packages that indirectly interact with AppArmor backend can mock isHomeUsingNFS.
func ValidateNoAppArmorRegexp ¶
ValidateNoAppArmorRegexp will check that the given string does not contain AppArmor regular expressions (AARE), double quotes or \0.
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() interfaces.Specification
NewSpecification returns a new, empty apparmor specification.
func (*Backend) SandboxFeatures ¶
SandboxFeatures returns the list of apparmor features supported by the kernel.
func (*Backend) Setup ¶
func (b *Backend) Setup(snapInfo *snap.Info, 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(snaps []*snap.Info, 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 Specification ¶
type Specification struct {
// contains filtered or unexported fields
}
Specification assists in collecting apparmor entries associated with an interface.
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 mount-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) AddLayout ¶
func (spec *Specification) AddLayout(si *snap.Info)
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 require exponential memory when compiled with apparmor_parser -O no-expr-simplify.
func (*Specification) AddPermanentPlug ¶
func (spec *Specification) AddPermanentPlug(iface interfaces.Interface, plug *snap.PlugInfo) error
AddPermanentPlug records mount-specific side-effects of having a plug.
func (*Specification) AddPermanentSlot ¶
func (spec *Specification) AddPermanentSlot(iface interfaces.Interface, slot *snap.SlotInfo) error
AddPermanentSlot records mount-specific side-effects of having a slot.
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) SetUsesPtraceTrace ¶
func (spec *Specification) SetUsesPtraceTrace()
SetUsesPtraceTrace records when to omit explicit ptrace deny rules.
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) 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) UsesPtraceTrace ¶
func (spec *Specification) UsesPtraceTrace() bool
UsesPtraceTrace returns whether ptrace is being used by any of the interfaces in the spec.