[apparmor] IPC syntax - again

John Johansen john.johansen at canonical.com
Tue Jul 2 04:08:23 UTC 2013


On 07/01/2013 05:35 PM, Tyler Hicks wrote:
> On 2013-06-30 03:23:43, John Johansen wrote:
>> On 06/28/2013 11:55 PM, John Johansen wrote:
>>> 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
>>>   letters.
>>> and
>>> - 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
>>> simplified.
>>>
>>> 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,
>>>
>> Sigh so this was supposed to be send/receive and acquire permissions
>>   dbus send foo,
>>   dbus acquire bar,
>>
>> Now, that this is had a couple days I will criticize the none pairing solution.
>>
>> Basically the none pairing solution treats this type of communication as
>> a shared object. With everything happening through the same address. As
>> such it is fairly easy to get confused about what a rule means.
>>
>>   dbus (send, receive) foo,
>>
>> so is foo my target or is it my local address?  That is, is (send, receive)
>> (send from, receive on) or is it (send to, receive from)
>>
>> In this case it is both sort of, in pairing syntax.
>>
>>   dbus (send, receive) subject=(foo) peer=(foo),
>>   dbus (send, receive) subject=(foo),
>>   dbus (send, receive) peer=(foo),
>>
>> there are times I am okay with this and others I go ugh, I think I want
>> to be able to say only
>>
>>   dbus (send, receive) peer=(foo),
>>
>> I am not so concerned with local and peer addresses colliding/overlapping
>> but I think it can be confusing when thinking about things in a messaging
>> context to not to be able to specify whether you are talking about
>> a peers address or your local address.
>>
>> So I am still not convinced on the value of "pairing" but I do think
>> we need from a language syntax pov. Something more than
>>
>>   dbus (send, receive) address=foo,
> 
> What about only allowing a single permission per rule? That would ensure
> that the rule is clearly written in the context of that permission and
> there is no confusion.
> 
Does it?
  network bind unix address=\0foo,

well this is clear, as bind is a local address only operation

  network send unix address=\0foo,
is that send from, or send to? Like send to as well we care about who
we are sending to and not the port/address we are sending from.
Again this would be some of the argument against "pairing", as most
of the time I might just care about the type of communication and who
I am sending too.

  network receive unix address=\0foo,

This one is a little harder as the receive side is the case where I see
pairing as most useful. I may want to say I am only receive message on
my bound address \0foo from X

If we aren't pairing then send receive are really implicit on the local
address and you are just specifying permissions to communicate with the
peer.

In this case I think it makes sense to separate what are obviously
local (bind, create, ...) from permissions to deal with the message/peer
but I don't think splitting them any further is required.


  Is that the local address I am allow sending from and receiving on or
is it the remote address I am sending to, receiving from.





More information about the AppArmor mailing list