The AppArmor user space development project.
Find a file
Zygmunt Krynicki cc04181578 Allow running tests with spread
Spread is a full-system, or integration test suite runner initially developed
to test snapd. Over time it has spread to other projects where it provides a
structured way to organize, run and debug complex full-system interactions.
Spread is documented on https://github.com/canonical/spread and is used in
production since late 2016.

Spread has a notion of backends which are responsible for allocating and
discarding test machines. For the purpose of running AppArmor regression tests,
I've combined spread with my own tool, image garden. The tool provides
off-the-shelf images, constructed on-the-fly from freely available images, and
makes them easily available to spread.

The reason for doing it this way is so that using non-free cloud systems is not
required and anyone can repeat the test process locally, on their own computer.
Vanilla spread is somewhat limited to x86-64 systems but the way I've used it
here makes it equally possible to test x86_64 *and* aarch64 systems. I've done
most of the development on an ARM single-board-computer running on my desk.

Spread requires a top-level spread.yaml file and a collection of task.yaml
files that describe individual tasks (for us, those are just tests). Tasks have
no implied dependency except that to reach a given task, spread will run all
the _prepare_ statements leading to that task, starting from the project, test
suite and then task. With proper care one can then run a specific individual
test with a one-line command, for example:

```
spread -v garden:ubuntu-cloud-24.04:tests/regression/apparmor:at_secure
```

This will prepare a fresh ubuntu-cloud-24.04 system (matching the CPU
architecture of the host), copy the project tree into the test machine, install
all the build dependencies, build all the parts of apparmor and then run one
specific variant of the regression test, namely the at_secure program.
Importantly the same test can also run on, say debian-cloud-13 (Debian Trixie),
but also, if you have a Google cloud account, on Google Compute Engine or in
one of the other backends either built into spread or available as a fork of
spread or as a helper for ad-hoc backend. Spread can also create more than one
worker per system and distribute the tests to all of the available instances.
In no way are we locking ourselves out of the ability to run our test suite on
our target of choice.

Spread has other useful switches, such as:
- `-reuse` for keeping machines around until discarded with -discard
- `-resend` for re-sending updated copy of the project (useful for -reuse)
- `-debug` for starting an interactive shell on any failure
- `-shell` for starting an interactive shell instead of the `execute` phase

This first patch contains just the spread elements, assuming that both spread
and image-garden are externally installed. A GitLab continuous integration
installing everything required and running a subset of tests will follow
shortly.

I've expanded the initial selection of systems to allow running all the tests
on several versions of Ubuntu, Debian and openSUSE, mainly as a sanity check
but also to showcase how practical spread is at covering real-world systems.

A number of systems and tests are currently failing:

- garden:debian-cloud-12:tests/regression/apparmor:attach_disconnected
- garden:debian-cloud-12:tests/regression/apparmor:deleted
- garden:debian-cloud-12:tests/regression/apparmor:unix_fd_server
- garden:debian-cloud-12:tests/regression/apparmor:unix_socket_pathname
- garden:debian-cloud-13:tests/regression/apparmor:attach_disconnected
- garden:debian-cloud-13:tests/regression/apparmor:deleted
- garden:debian-cloud-13:tests/regression/apparmor:unix_fd_server
- garden:debian-cloud-13:tests/regression/apparmor:unix_socket_pathname
- garden:opensuse-cloud-15.6:tests/regression/apparmor:attach_disconnected
- garden:opensuse-cloud-15.6:tests/regression/apparmor:deleted
- garden:opensuse-cloud-15.6:tests/regression/apparmor:e2e
- garden:opensuse-cloud-15.6:tests/regression/apparmor:unix_fd_server
- garden:opensuse-cloud-15.6:tests/regression/apparmor:unix_socket_pathname
- garden:opensuse-cloud-15.6:tests/regression/apparmor:xattrs_profile
- garden:opensuse-cloud-tumbleweed:tests/regression/apparmor:attach_disconnected
- garden:opensuse-cloud-tumbleweed:tests/regression/apparmor:deleted
- garden:opensuse-cloud-tumbleweed:tests/regression/apparmor:unix_fd_server
- garden:opensuse-cloud-tumbleweed:tests/regression/apparmor:unix_socket_pathname
- garden:ubuntu-cloud-22.04:tests/regression/apparmor:attach_disconnected

In addition, only on openSUSE, I've skipped the entire test suite of the utils
directory, as it requires python3 ttk themes, which I cannot find in packaged
form.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
2024-12-05 02:17:07 +01:00
binutils binutils: add translation support to aa_status and initial pot file 2024-09-03 03:39:16 -07:00
changehat Update mailinglist and homepage in changehat READMEs 2024-03-03 18:12:06 +01:00
common On openSUSE 15.6 make fails to find awk 2024-11-25 15:05:23 +01:00
documentation documentation: update policy layout document 2023-02-07 10:45:46 -08:00
kernel-patches kernel-patches: add v4.17-out-of-tree net compatibility patches 2018-07-10 22:18:48 -07:00
libraries/libapparmor test-multi: no longer expect testcase01, 12 and 13 to fail 2024-10-23 19:25:35 +02:00
parser parser: equality tests: add the ability have tests that are a known problem 2024-12-03 13:44:53 -08:00
presentations opensuse 2018 conference presentation 2018-05-31 11:03:01 -07:00
profiles profiles: update bwrap profile 2024-11-26 09:52:17 -08:00
tests Allow running tests with spread 2024-12-05 02:17:07 +01:00
utils Allow running exactly one test in utils/test 2024-12-05 02:17:07 +01:00
.gitignore Allow running tests with spread 2024-12-05 02:17:07 +01:00
.gitlab-ci.yml Build regression tests in GitLab CI 2024-11-07 11:47:55 -08:00
.shellcheckrc CI: prepare for enabling shellcheck warnings and info 2022-02-13 19:43:48 +00:00
LICENSE Add a top-level "catch-all" GPLv2 license to cover any files that are 2007-03-30 15:47:14 +00:00
Makefile Pass -j flag for cov-build as well 2024-10-18 13:15:18 -07:00
README.md Apply 1 suggestion(s) to 1 file(s) 2024-11-26 16:49:57 +00:00
spread.yaml Allow running tests with spread 2024-12-05 02:17:07 +01:00

AppArmor

Build status Overall test coverage Core Infrastructure Initiative Best Practices


Introduction

AppArmor protects systems from insecure or untrusted processes by running them in restricted confinement, while still allowing processes to share files, exercise privilege and communicate with other processes. AppArmor is a Mandatory Access Control (MAC) mechanism which uses the Linux Security Module (LSM) framework. The confinement's restrictions are mandatory and are not bound to identity, group membership, or object ownership. The protections provided are in addition to the kernel's regular access control mechanisms (including DAC) and can be used to restrict the superuser.

The AppArmor kernel module and accompanying user-space tools are available under the GPL license (the exception is the libapparmor library, available under the LGPL license, which allows change_hat(2) and change_profile(2) to be used by non-GPL binaries).

For more information, you can read the techdoc.pdf (available after building the parser) and by visiting the https://apparmor.net/ web site.


Getting in Touch

Please send all complaints, feature requests, rants about the software, and questions to the AppArmor mailing list.

Bug reports can be filed against the AppArmor project on GitLab or reported to the mailing list directly for those who wish not to register for an account on GitLab. See the wiki page for more information.

Security issues can be filed in GitLab by opening up a new issue and selecting the tick box This issue is confidential and should only be visible to team members with at least Reporter access. or directed to security@apparmor.net. Additional details can be found in the wiki.


Privacy Policy

The AppArmor security project respects users privacy and data and does not collect data from or on its users beyond what is required for a given component to function.

The AppArmor kernel security module will log violations to the audit subsystem, and those will be logged/forwarded/recorded on the user's system(s) according to how the administrator has logging configured. Again this is not forwarded to or collected by the AppArmor project.

The AppArmor userspace tools do not collect information on the system user beyond the logs and information needed to interact with the user. This is not forwarded to, nor collected by the AppArmor project.

Users may submit information as part of an email, bug report or merge request, etc. and that will be recorded as part of the mailing list, bug/issue tracker, or code repository but only as part of a user initiated action.

The AppArmor project does not collect information from contributors beyond their interactions with the AppArmor project, code, and community. However contributors are subject to the terms and conditions and privacy policy of the individual platforms (currently GitLab) should they choose to contribute through those platforms. And those platforms may collect data on the user that the AppArmor project does not.

Currently GitLab requires a user account to submit patches or report bugs and issues. If a contributor does not wish to create an account for these platforms the mailing list is available. Membership in the list is not required. Content from non-list members will be sent to moderation, to ensure that it is on topic, so there may be a delay in choosing to interact in this way.


Source Layout

AppArmor consists of several different parts:

binutils/	source for basic utilities written in compiled languages
changehat/	source for using changehat with Apache, PAM and Tomcat
common/		common makefile rules
desktop/	empty
kernel-patches/	compatibility patches for various kernel versions
libraries/	libapparmor source and language bindings
parser/		source for parser/loader and corresponding documentation
profiles/	configuration files, reference profiles and abstractions
tests/		regression and stress testsuites
utils/		high-level utilities for working with AppArmor

Important note on AppArmor kernel code

While most of the kernel AppArmor code has been accepted in the upstream Linux kernel, a few important pieces were not included. These missing pieces unfortunately are important bits for AppArmor userspace and kernel interaction; therefore we have included compatibility patches in the kernel-patches/ subdirectory, versioned by upstream kernel (2.6.37 patches should apply cleanly to 2.6.38 source).

Without these patches applied to the kernel, the AppArmor userspace will not function correctly.


Building and Installing AppArmor Userspace

To build and install AppArmor userspace on your system, build and install in the following order. Some systems may need to export various python-related environment variables to complete the build. For example, before building anything on these systems, use something along the lines of:

$ export PYTHONPATH=$(realpath libraries/libapparmor/swig/python)
$ export PYTHON=/usr/bin/python3
$ export PYTHON_VERSION=3
$ export PYTHON_VERSIONS=python3

Note that, in general, the build steps can be run in parallel, while the test steps do not gain much speedup from being run in parallel. This is because the test steps spawn a handful of long-lived test runner processes that mostly run their tests sequentially and do not use make's jobserver. Moreover, process spawning overhead constitutes a significant part of test runtime, so reworking the test harnesses to add parallelism (which would be a major undertaking for the harnesses that do not have it already) would not produce much of a speedup.

libapparmor:

$ cd ./libraries/libapparmor
$ sh ./autogen.sh
$ sh ./configure --prefix=/usr --with-perl --with-python # see below
$ make -j $(nproc)
$ make check
$ make install

[an additional optional argument to libapparmor's configure is --with-ruby, to generate Ruby bindings to libapparmor.]

Binary Utilities:

$ cd binutils
$ make -j $(nproc)
$ make check
$ make install

Parser:

$ cd parser
$ make -j $(nproc)		# depends on libapparmor having been built first
$ make -j $(nproc) tst_binaries		# a build step of make check that can be parallelized
$ make check
$ make install

Utilities:

$ cd utils
$ make -j $(nproc)
$ make check PYFLAKES=/usr/bin/pyflakes3
$ make install

Apache mod_apparmor:

$ cd changehat/mod_apparmor
$ make -j $(nproc)		# depends on libapparmor having been built first
$ make install

PAM AppArmor:

$ cd changehat/pam_apparmor
$ make -j $(nproc)		# depends on libapparmor having been built first
$ make install

Profiles:

$ cd profiles
$ make
$ make check	# depends on the parser having been built first
$ make install

Note that the empty local/* profile sniplets no longer get created by default. If you want them, run make local before running make check.

[Note that for the parser, binutils, and utils, if you only wish to build/use some of the locale languages, you can override the default by passing the LANGS arguments to make; e.g. make all install "LANGS=en_US fr".]


AppArmor Testsuites

A number of testsuites are in the AppArmor sources. Most have documentation on usage and how to update and add tests. Below is a quick overview of their location and how to run them.

Regression tests

For details on structure and adding tests, see tests/regression/apparmor/README.

To run:

Regression tests - using apparmor userspace installed on host

$ cd tests/regression/apparmor (requires root)
$ make -j $(nproc) USE_SYSTEM=1
$ sudo make tests USE_SYSTEM=1
$ sudo bash open.sh -r	 # runs and saves the last testcase from open.sh

Regression tests - using apparmor userspace from the tree.

$ cd tests/regression/apparmor (requires root)
$ make -j $(nproc)
$ sudo make tests
$ sudo bash open.sh -r	 # runs and saves the last testcase from open.sh

Parser tests

For details on structure and adding tests, see parser/tst/README.

To run:

$ cd parser/tst
$ make
$ make tests

Libapparmor

For details on structure and adding tests, see libraries/libapparmor/README.

$ cd libraries/libapparmor
$ make check

Utils

Tests for the Python utilities exist in the test/ subdirectory.

$ cd utils
$ make check

The aa-decode utility to be tested can be overridden by setting up environment variable APPARMOR_DECODE; e.g.:

$ APPARMOR_DECODE=/usr/bin/aa-decode make check

Profile checks

A basic consistency check to ensure that the parser and aa-logprof parse successfully the current set of shipped profiles. The system or other parser and logprof can be passed in by overriding the PARSER and LOGPROF variables.

$ cd profiles
$ make && make check

Stress Tests

To run AppArmor stress tests:

$ make all

Use these:

$ ./change_hat
$ ./child
$ ./kill.sh
$ ./open
$ ./s.sh

Or run all at once:

$ ./stress.sh

Please note that the above will stress the system so much it may end up invoking the OOM killer.

To run parser stress tests (requires /usr/bin/ruby):

$ ./stress.sh

(see stress.sh -h for options)

Coverity Support

Coverity scans are available to AppArmor developers at https://scan.coverity.com/projects/apparmor.

In order to submit a Coverity build for analysis, the cov-build binary must be discoverable from your PATH. See the "To Setup" section of https://scan.coverity.com/download?tab=cxx to obtain a pre-built copy of cov-build.

To generate a compressed tarball of an intermediate Coverity directory:

$ make coverity

The compressed tarball is written to apparmor-<SNAPSHOT_VERSION>-cov-int.tar.gz, where <SNAPSHOT_VERSION> is something like 2.10.90~3328, and must be uploaded to https://scan.coverity.com/projects/apparmor/builds/new for analysis. You must include the snapshot version in Coverity's project build submission form, in the "Project Version" field, so that it is quickly obvious to all AppArmor developers what snapshot of the AppArmor repository was used for the analysis.


Building and Installing AppArmor Kernel Patches

TODO


Required versions

The AppArmor userspace utilities are written with some assumptions about installed and available versions of other tools. This is a (possibly incomplete) list of known version dependencies:

The Python utilities require a minimum of Python 3.3.

The aa-notify tool's Python dependencies can be satisfied by installing the following packages (Debian package names, other distros may vary):

  • python3-notify2
  • python3-psutil
  • python3-tk
  • python3-ttkthemes
  • python3-gi

Perl is no longer needed since none of the utilities shipped to end users depend on it anymore.

Most shell scripts are written for POSIX-compatible sh. aa-decode expects bash, probably version 3.2 and higher.