[apparmor] [patch 20/21] Add the ability to specify ptrace rules

John Johansen john.johansen at canonical.com
Tue Mar 25 01:57:24 UTC 2014

On 03/24/2014 05:59 PM, Jamie Strandboge wrote:
> On 03/21/2014 08:34 PM, Seth Arnold wrote:
>> On Mon, Mar 17, 2014 at 04:29:30PM -0700, john.johansen at canonical.com wrote:
>>> ptrace rules currently take the form of
>>>   ptrace [<ptrace_perms>] [<peer_profile_name>],
>>>   ptrace_perm := read|trace|readby|tracedby
>>>   ptrace_perms := ptrace_perm | '(' ptrace_perm+ ')'
>>> After having used the cross check (permission needed in both profiles)
>>> I am not sure it is correct for ptrace.
>> Hrm, I'm liked the idea of the cross-check here for some time, but haven't
>> actually lived with it yet. What doesn't work so well?
> I started playing with these today and found that chromium-browser is not
> very selective on what it tries to ptrace. Ie, it seems to be walking /proc
> trying to ptrace everything-- I guess it is looking for its parent....
Its not actually trying to ptrace anything. But unfortunately the fs code
is doing a ptrace check against each processes file it touches.

There are 3 distinct possibilities here for behavior
keep cross check for both read and trace
keep cross check for trace but not read
get rid off cross check for ptrace entirely

> First off, the cross-check is pretty painful and doesn't honor deny rules
> the way I would expect. For example, chromium tries to 'ptrace read'
> everything, so I added rules like this:
>     ptrace (read) /usr/lib/chromium-browser/chromium-browser,
>     ptrace (read) /usr/lib/chromium-browser/chromium-browser//chromium_browser_sandbox,
>     ptrace (readby) /usr/lib/chromium-browser/chromium-browser//chromium_browser_sandbox,
>     deny ptrace (read) unconfined,
>     deny ptrace (read) /usr/bin/*,
>     deny ptrace (read) /usr/lib/firefox/*,
>     deny ptrace (read) /usr/lib/thunderbird/*,
>     deny ptrace (read) /usr/lib/telepathy/*,
>     # doesn't work
>     #deny ptrace (read) /usr/lib/[^c][^h][^r][^o][^m]*,
>     #deny ptrace (read) /usr/lib/[^c][^h][^r][^o][^m]**,
>     #deny ptrace (read) /usr/lib/[^c][^h][^r][^o][^m]*/*,
>     #deny ptrace (read) /usr/lib/[^c][^h][^r][^o][^m]*/**,
> But the deny rules don't silence the readby rule. Eg, I have this rule:
>     deny ptrace (read) /usr/bin/*,
> and expected since it silenced the denial that the corresponding readby
> rule would not be needed since the read was blocked. However, I get the
> following in the log still with the above rule:
>     apparmor="DENIED" operation="ptrace" profile="/usr/bin/rhythmbox"
>     pid=10522 comm="chrome-sandbox" requested_mask="readby"
>     denied_mask="readby"
>     target="/usr/lib/chromium-browser/chromium-browser//chromium_browser_sandbox"
Okay so the problem here is in the crosscheck there are always 2 profiles
involved, and you must have a deny in each profile to get a full quieting.

With the crosscheck you can get a denial from both profiles, just one, or
none. In the case above, you need the denial in the /usr/bin/rhythmbox

The crosscheck is pointing out an asymmetry in the policy between what is
expected between profiles. Ideally the tools would help by updating both
profiles involved at the same time.

> I'm on the fence about the utility of the *by rules. I guess I see the
> thinking if you have something that is confined and you want to say that
> only a specific profile can ptrace it. Would it make sense to leave the
> cross check in place, but don't trigger if trace/read was denied? I think
> that would make it less painful, at least in the case of chromium.
It it possible to bail on the first error instead of spitting out all
errors. Note however this is contrary to what several people asked me todo,
and would require multiple profile runs for the missing rejections to show up
so that valid policy could be generated.

> Note, I imagine with chromium-browser and oxide we are just going to allow:
>   ptrace read,

> since we have yama. Problem is, with doing that the cross check would
Ubuntu has, not all distros turn that on. The crosscheck behavior is an
upstream discussion as it affects all distros. Especially since policy
offers distros a way to disable the behavior by default. Where changing
the behavior upstream does not give distros the option of having the
cross check.

I'm not say the change shouldn't be done, just we need to be careful to
split out the upstream and ubuntu needs here.

> generate a ton of readby denials, which means all our profiles probably
> also need:
>   ptrace readby,

> or perhaps
>   deny ptrace (readby) /usr/lib/chromium-browser/chromium-browser//chromium_browser_sandbox,
>   deny ptrace (readby) /path/to/oxide/sandbox,
> Interestingly, once I set all the ptrace rules, chromium-browser doesn't run
> properly. I'm not sure why yet. Still trying to sort this out...
still possibly some other bugs in the kernel, steve reported some issue
around some of the changes to file handles, which are now being revalidated
at the exec boundary, and if the access fails getting duped to a null file.

However this is behavior similar to selinux so apps should cope with it well,
where just shutting down the file handle is not so good. The other option
would be to dup the open fd to a new special file that just denies everything.

Reverting to only doing revalidations at rw is not an option. There are good
reasons for doing it at the exec and SCM creds boundry

More information about the AppArmor mailing list