[apparmor] apparmor policy sha-1 behavior
John Johansen
john.johansen at canonical.com
Tue Nov 17 00:28:47 UTC 2015
So there is an open question on how the sha-1 of policy should be handled.
Currently, each cache file that is generated is a container file that
contains a header and one or more profiles. This results in a cache file
laid out like
[policy consistency hash header]
header
[shared data]
profile 1
[header]
[profile 2]
...
where subsequent headers are optional and if not present the last header
is used. The header contains namespace and version/abi information, and
new headers can not change namespaces etc. ie. a single cache file can not
contain policy for more than one policy namespace.
The profiles may be loaded as a unit or the may be loaded individually
dependent on whether the kernel module supports a set load. In the kernel
if the sha-1 config is selected, each loaded profile has a sha-1 sum
derived from the input data associated with it in the file
/sys/kernel/security/apparmor/policy/profiles/profile.name.###/sha1
this sha1 is computed from the header (so that abi and version info is
include) and all the input data from the beginning to the end of the
profile. This results in a unique sha-1 for each profile loaded from a
cache file, and for the sha-1 of a profile loaded from that cache whether
in set or individually being the same (that is to say if the loader
individually loads the profiles out of the cache the sha1 value for each
profile should be the same as when the whole cache is loaded in one go).
However this scheme results in a hash that can not be directly compared
to running sha1sum on the userspace cache file. Instead an aa-sha1
utility is needed.
sha1sum /etc/apparmor.d/cache/usr.bin.evince
4be48e881f31c7ae60305bfddaf000a8781ed95f /etc/apparmor.d/cache/usr.bin.evince
vs.
aa-sha1 /etc/apparmor.d/cache/usr.bin.evince
FILE: /etc/apparmor.d/cache/usr.bin.evince
7fff06a7c24c258a93eb61cf51fb6c3687c1f75e: /usr/bin/evince
773b1afb1e8282a797dd83abd2d7d74c5906dc57: /usr/bin/evince//sanitized_helper
06f28a7215ec6c861d7b4f8d185ff4b87e353f5c: /usr/bin/evince-previewer
53c35b21ff19045273ecfea7816576a032c616fe: /usr/bin/evince-previewer//sanitized_helper
0cbf1f9d4831e6362666e3b3ee7364825b76bb4c: /usr/bin/evince-thumbnailer
98cd45f364810cfff67a89590b9120a35fa88270: /usr/bin/evince-thumbnailer//sanitized_helper
There is an alternative strategy that could be used. Instead of having a
custom aa-sha1 tool we could, just take the sha1 sum in the kernel for the
whole input of the cache file, and have all profiles share the sha1 sum.
In the example case
4be48e881f31c7ae60305bfddaf000a8781ed95f: /usr/bin/evince
4be48e881f31c7ae60305bfddaf000a8781ed95f: /usr/bin/evince//sanitized_helper
4be48e881f31c7ae60305bfddaf000a8781ed95f: /usr/bin/evince-previewer
4be48e881f31c7ae60305bfddaf000a8781ed95f: /usr/bin/evince-previewer//sanitized_helper
4be48e881f31c7ae60305bfddaf000a8781ed95f: /usr/bin/evince-thumbnailer
4be48e881f31c7ae60305bfddaf000a8781ed95f: /usr/bin/evince-thumbnailer//sanitized_helper
the user could then just use a direct sha1sum on the cache file to compare
with what is loaded. However this scheme has its own issues.
- it breaks if incremental loading is used, so all cache files would have
to be updated automically
- it can break when a set of profiles is loaded, as part of a large cache
file, and then one of those profiles is replaced. Basically there is no
way to properly verify the hash associated with the other profiles from
the set, without requiring that be recompiled and reloaded too.
(currently there is another bug where the large cache file is not
invalidated by individual profiles are replaced which can result in
multiple cache files containing data for a single profile, but that
should not affect the design decisions here)
- the user has to know which cache file a given profile is in so a custom
tool to extract that information is needed anyway
I should note, that currently only profiles/hats defined in the same policy
file share the same cache file. But there are plans to allow for combining
of profiles from different files when compiled at the same time. This
would allow for greater sharing of data between compiled profiles reducing
the amount of memory used to stored compiled policy and also potentially
speeding up compiles.
So which solution should we pursue going forward. Currently I am of the
opinion we should stick to the current scheme, but I would like other
peoples input
More information about the AppArmor
mailing list