[apparmor] Some apparmor profile statements are not honored for an application

John Johansen john.johansen at canonical.com
Wed Sep 2 07:47:38 UTC 2020


On 8/31/20 7:54 AM, John Ernberg wrote:
> Hi,
> 
> I seem to have a bit of an odd problem in that some of the profile 
> statements do not appear honored and the library loads they statements 
> allow are thus denied. There is the only program in the system so far 
> that is running confined. The program in question only handles files and 
> library loads.
> 
> I double checked the syntax of the failing rules, they are aligned with 
> functional rules. I re-did them by copy-pasting the file name in the 
> audit message and then copy-pasted the flags from a functional rule, 
> just to be sure. No change.
> 
example rules and profiles would help. If you don't want them on the
public list you can send them to me directly

> I have checked the statemachine produced with apparmor_parse -D 
> dfa-states and it looks correct, however, when I dump the statemachine 
> transitions in the kernel they are a little off compared to the 
> statemachine generated by apparmor_parse -D dfa-states command when 
> logging in aa_dfa_match on the kernel side, it really looks like the 
> machine makes incorrect lookups.
> 
this is weird. What are you using to dump the kernel state machine?

you can compare the binary in userspace and the equivalent kernel
blobs to make sure they are the same.

Eg. for the ping profile on my system

  $ cat /sys/kernel/security/apparmor/policy/profiles/ping.3/raw_sha1 
  704b8eafff4dc11ede6b1843384fb7379f13028b
  $ sudo sha1sum /etc/apparmor.d/cache/bin.ping
  704b8eafff4dc11ede6b1843384fb7379f13028b  /etc/apparmor.d/cache/bin.ping

and diff of binaries

  $ sudo diff -q /sys/kernel/security/apparmor/policy/profiles/ping.3/raw_data /etc/apparmor.d/cache/bin.ping 
  $

You need to be aware that the sha1 and raw_sha1 are different, you want
the raw_sha1 and raw_data when comparing to the userspace file.

Those two will correspond to the compiled blob in the file that is loaded
into the kernel. If that blob contains multiple profiles each profile
in the blob will point to the same raw_data, raw_sha1, but their
individual sha1 file will differ (its taken from a subsection).

The raw_data and raw_sha1 files reported by the profiles are the same
that can be found in /sys/kernel/security/apparmor/policy/raw_data
going through the profile just makes it easier to correlate with the
policy on disk.

Doing this check does not guarantee that what the kernel is using is
the same as what you see in userspace, but it does show what the
kernel should be using. This check will help us determine where we
should be focusing the search

The kernel unpacks the loaded blob into a native format so there
is some data shuffling of what is actually used by the kernel. So what
the kernel is using could be off for 3 reasons
- the unpack is broken
- there is kernel memory corrupts
- there was a previous version of the profile loaded into the kernel
  and it is in use. Profile replacement is not atomic, when a mediation
  hook is entered the current policy what ever it may be at that
  point will be used, even if profile replacement happens while the
  hook is running. The new profile should be used in the next call to
  a mediation hook but there have in the past been bugs, causing the
  old profile to be used long past when it should.


> I have noticed transitions to IDs other than those expected when 
> comparing to the dfa-states, and it seems to start skipping characters 
> in the paths or going beyond the end of the path string for some paths.
> These paths are the paths for which statements are not honored.
> 
how are you checking this? This should not be possible as it is the path
that drives the state machine. That is the path is walked linearly one
character at a time and we step to the next state in the state machine.

The only time we walk a path more than once per character is when doing
profile matching, and the overlapping express match allows for a limited
nfa stack of N states for backing up. iirc in 5.4 it is limited to 8
states worth of backup.

> Trying to add debug to the match_char macro on the kernel side seems to 
> break the statemachine completely, so I wasn't able to debug this route 
> further.
> 
you can add stuff to the macro but you do need to be careful it is 
easy to break it

> I'm running version 2.13.3 of the userspace tools, and kernel 5.4.24 
> (vendor kernel, can't upgrade, can't try mainline due to missing support 
> for the SoC I'm using), with the latest 5.4 stable patches for apparmor 
> applied on top.
> 
can you run a debug kernel with custom patches if needed?

> The rules is compiled on my machine (x86_64) and embedded in my target 
> (aarch64) readonly rootfs. Target has a readonly filesystem.
> 
this should be fine the compiled policy tries to arch independent but it
is always possible we have an bug in the native mappings. It is something
to keep in mind, while trying to figure out what is going on

> The rule is loaded on target with the following command:
>      /sbin/apparmor_parser -K -B /etc/apparmor.d/myprogram
> Where myprogram is the profile for my program
> 
what audit message/messages are logged when you do this

> So far I have not been able to create a shareable reproducer which, 
> unfortunately, makes this all the more harder.
> 
> I would appreciate any suggestions in how to proceed or what kind of 
> info I should be looking at in order to find out what is going wrong.
> 
First verify that the user space binary file and what the kernel expects
are the same.

Second, are you pinning the policy feature abi or using the kernel feature
abi, and if you are using the kernel feature abi, what is the feature
abi of the machine you are compiling on vs. the kernel you are loading
policy on.

Extracting the feature abi in apparmor 2.13 is a bit of a pita. For the
machine you are compiling on look for the .features file in the cache
directory. If you are not writing the cache, make a temporary cache
in tmp
  mkdir /tmp/cache

and add

  --cache-loc=/tmp/cache --write-cache

to your compile.

On the machine you are loading the policy on do the same thing. Make
a temporary cache and compile a simple profile

  profile test { }

will do.

Compare the two feature abi files.

Also can you be more specific about the rules that are having problems?
File rules, signal, and even which components. The more detail the
better, feel free to substitue example values instead of real ones if
you need to.


> Thank you in advance.
> 
> Best regards // John Ernberg
> 
> (not subscribed to the mailing list)
> 
thats fine just expect some moderation delay



More information about the AppArmor mailing list