[apparmor] IPC syntax - again

John Johansen john.johansen at canonical.com
Sat Jun 29 06:55:12 UTC 2013

On 06/28/2013 01:57 PM, Tyler Hicks wrote:
> I had to trim this down and focus on one section that has been bothering
> me. It is based upon the idea that we can do away with pairing. While I
> mostly agree, DBus intricacies were making it difficult for me to
> understand what exactly we would be doing away with.
> On 2013-06-26 11:00:52, John Johansen wrote:
> <snip>
>> It is confusing to specify these local permissions in a rule that also
>> specifies a peer address. That is to say it does not make a lot of sense
>> to specify bind/acquire et al in rules with a peer address.
>> So a profile will require ipc rules without peer addresses. In this
>> case specifying the subject is redundant.  Though it may be worth doing
>> for consistancy, if we have rules that specify both subject and peer at
>> the same time.
>> For rules that specify a peer address the major permissions involved are
>> read/write/send/receive. In this case the permission means that the
>> subject can read FROM the peer, write TO the peer.
>> If we also throw in a subject address the meaning of the permission
>>   r subject=(addres=foo) peer=(address=bar),
>> means read on subject address=foo from peer address=bar.
>> This pairs the local address/handle to a specific peer address handle.
>> The question is how useful is this compared to not allowing pairing in
>> rules. That is the rule address subject/peer is infered from the
>> permissions on the rule.
>> eg. which is easier to understand
>>   aquire subject=(address=foo),
>>   rw subject=(address=foo) peer=(address=bar),
>> or
>>   aquire address=foo,
>>   rw address=bar,
>> the second case can simplify the syntax because it doesn't care about
>> tying the comminication with the peer to a specific address on the subject.
>> Admittedly we can simplify the rules from the pair syntax example to
>> have the same semantics as the 2nd example.
>>   aquire subject=(address=foo),
>>   rw peer=(address=bar),
>> and it is not a lot more complicated. The question is, is this small
>> increase in syntax complexity worth it for that extra restrictions it
>> can give us.
>> So where is pairing possible?
>> - It is not reasonable possible for dbus rules
> After speaking with John in IRC, the bullet point above is too strongly
> worded. Pairing is possible for DBus rules, we're just trying to determine if
> it is worth the complexity.
> IIUC, taking away pairing would affect two types of rules:
>  1. send/receive rules where you want to specify the subject's connection name
>     - You would only do this if a process ownls multiple DBus connection names
>       and you want to allow certain operations on one, but not the other
>  2. receive rules where you want to specify the local address attributes (path,
>     interface, or member)
>     - You would only do this if you want to divvy up access to DBus objects
>       exported by a single process
>       + Maybe you don't want to grant one peer access to a certain method
>       + Maybe the subject has multiple, somewhat unrelated interfaces that
>         shouldn't all be accessible by a peer
>       + Maybe the subject creates a new path for each logged in user and you
>         want to leverage AppArmor user conditionals (future work)
> I think #1 has little importance and we won't miss that level of mediation. I
> think #2 has the potential to be very important and we'll need to determine if
> we can do without it.
> What clouds all of this is in my mind is that it really depends on one's
> definition of the term "pairing". From talking with you in IRC
> yesterday, your definition is "the tying of subject attributes to peer
> attributes, so that both set of conditions must be true before the
> permissions in the rule are granted." This is a fair definition and
> aligns with what I understood it to be after reading this email.
> However, I think our definition of pairing needs a little tweak.
> Lets shift to signal rules and think about a hypothetical screen locker.
> A session manager starts the screen locker and the screen locker *must*
> stay alive even if the user accidentally runs an untrusted, unconfined
> application that tries to kill it. Only the session manager should be
> able to kill it. So, the screen locker's profile may look like this:
> /usr/bin/screenlocker {
>   signal receive kill label=/usr/bin/sessionmanager,
> }
> That seems sane. Pairing isn't needed. Or is it? Is the signal type
> SIGKILL an attribute of the subject or the object? It doesn't really
> feel like it since there are a set of well defined signals and their
> names don't differ from application to application. But what exactly is
> the signal type an attribute of??
it can be viewed as an attribute/type of the message, but more below.

> Now, lets imagine that the screen locker has a DBus interface, with a
> Kill method, that some other session manager uses to kill the screen
> locker instead of a SIGKILL signal:
> /usr/bin/screenlocker {
>   signal receive kill label=/usr/bin/sessionmanager,
>   dbus receive member=Kill label=/usr/bin/othersessionmanager,
> }
> The dbus rule feels like it is using pairing. The Kill DBus method is an
It is sort of, its a matter of how tightly coupled things are

> attribute that is specific to the subject and we're tying it to an
> attribute of the peer (the peer's label).
Well its can be viewed as a property/type of the message. And yes so can
addresses. Addresses are really two distinct things,
 - the address bound to that a transport can send to/or receive on
 - a well defined property of a message that a transport uses to
   determine where to deliver a message.
   The address on the message really isn't a property of sender
   (subject) unless its the return address, in which case its again
   both a property of the subject and a property of the letter.

So we can mediate on well defined properties of a message, or addresses.
The problem with addresses is whether the address is something that
is reliable and can be trusted for mediation.

> So lets add another twist to the profile. The screen locker only locks.
> It launches a screen saver application that displays mesmerizing 3D
> pipes that rapidly grow in every direction. The screen locker must kill
> the screen saver when a user presses a button or moves the mouse. It
> does this over DBus by calling the screen saver's Kill method.
> /usr/bin/screenlocker {
>   signal receive kill label=/usr/bin/sessionmanager,
>   dbus receive member=Kill label=/usr/bin/othersessionmanager,
>   dbus send member=Kill label=/usr/bin/screensaver,
> }
> member=Kill is an attribute of the peer in the third rule, despite member=Kill
> being an attribute of the subject in the second rule. Confusing, but
> manageable. DBus path, interface, and member shift between being a subject or
> peer attribute depending on the access (send or receive). But maybe we
> shouldn't think of those attributes as being attributes of the subject
> or peer. Maybe we should think of them as being attributes of the DBus
> message being passed, just like the specific signal type SIGKILL is an
> attribute of the signal and not an attribute of the subject sending the
> signal or the peer receiving the signal. 
Hehe yes,
Your right that it can be viewed as a property of the subject and a
property of the peer, or as a property of the message. I prefer to think
of it like this.

Its a property of the message (like the address on a letter) that
the transport (the post office) matches to the address (property) of the
receiver. The receiver can then choose to accept/reject the message based
off of the well defined data (address, message type, ..). And if it accepts
the message (letter) it can open it and look at its contents.

There is a pairing to a degree in this. I am not arguing against that.
The question I am raising rephrased in terms of the post office, is this.

I have 2 doors in my house, a front, and a back door. I will accept
messages that the postman or ups deliver at the front door. At my back door
I will accept messages from the postman (I am not sure what he is doing
at the backdoor but what ever he is a good guy, buy that ups guy though is
shady so I yell at him to stop trespassing) or voice message from my
neighbour behind me (they like to yell across the yard).

So far all of this fits into the either model.

Now for the finer grained pairing, I will only accept letters from Joe
at address X, in my letter box at my front door. If Joe sends a letter
from a different address (he is touring europe) or if the postman tries
to deliver his message to the backdoor (even if its one I would accept
in my letter box at the front), I won't accept it.

So is it worth the complexity to distinguish between
- I can receive letters from Joe at address X at any location I accept
- I will only receive letters from Joe at address X, in my front letter
  box.  This is the explicit pairing I question whether we want to
  deal with the complexity of.

> Long story short, I think we can do away with pairing if we adjust our
> thinking a little. Certain attributes aren't subject attributes or peer
> attributes, they're just attributes of the signal, message, buffer,
> shared memory, etc., that is being shared over the given IPC mechanism.
I think you are right :) But I'd like to see Steve or Seth come up with
an example that changes my mind. I also think it is possible to extend
the simplified syntax to support pairing in the future but the rules
that used it would be a little uglier than the pairing syntax we where
working towards.

But if these rules are not commonly used, I would be willing to accept
them being a little uglier so that the more common rule could be

I also think that generally it makes sense when you think of things in
terms of messages instead of shared objects that it makes sense to
split the rule based on the send and receive permission, that is
  dbus send foo,
  dbus receive bar,

More information about the AppArmor mailing list