[apparmor] dbus/pair address rule encoding
Jamie Strandboge
jamie at canonical.com
Fri May 10 14:45:07 UTC 2013
On 05/10/2013 02:27 AM, John Johansen wrote:
> On 05/09/2013 05:06 PM, Steve Beattie wrote:
>> On Thu, May 09, 2013 at 02:41:19PM -0700, John Johansen wrote:
>> I don't mind Jamie's proposed syntax above, I don't really care for
>> "(send, receive)" first, because having the dbus or network identifier
>> first is a useful context granting mechanism.
>>
> So context granting for the parser or the human? I actually find the
> permission first easier for some things, but I think that is just me
>
I think human parsing is vitally important. We need to have a clear and
understandable syntax for policy writers so they get expected behavior
and we need the same for policy auditing.
> I find I don't particularly like the permission embedded in the middle
> of the rule, it makes it harder to find and associates it with the
> local address, which isn't really true. It is for the pair.
>
> so what about
>
> dbus (send, receive) name= ....,
>
> is that a better placement?
>
This is actually what I thought you meant when you said access first. I
am ok with this personally (but prefer my original to this).
>> I had a thought that perhaps we should be explicit about which addresses
>> are local to the subject and which are specific to a peer subject,
>> rather than rely on contextual information of whether it's before or
>> after a specific token. It could be something as simple as prefixing all
>> the peer address identifiers with peer (or 'peer.' or 'peer_' or ...),
>> so e.g. something like the following:
>>
>> profile SubjectA {
>>
>> dbus bus=session name=this.subjects.service acquire,
>> dbus bus=session name=this.subjects.service receive,
>> dbus bus=session peername=a.peer.address send,
>> dbus bus=accessibility name=this.subjects.other.service acquire,
>> dbus bus=accessibility name=this.subjects.other.service peername=another.peer.address receive,
>> net tcp addr=192.168.0.1 peeraddr=10.1.0.0/24 peerport=443 send
>> net tcp addr=192.168.0.1 peerport=80 send
>> }
>>
> so I don't care for prefixing peer
>
Yeah, me either cause we end up with peername, peerpath, peermethod,
and peerinterface which seems a bit verbose.
>> This way, the peer element doesn't get lost, like the bare peer keyword
>> does.
>>
>> Alternatively, you could use some grouping, a la:
>>
>> profile SubjectA {
>>
>> dbus bus=session name=SubjectA.service acquire,
>> dbus bus=session name=SubjectA.service method=service.method receive,
>> dbus bus=session peer(name=a.peer.address) send,
>> dbus bus=accessibility name=this.subjects.other.service acquire,
>> dbus bus=accessibility name=this.subjects.other.service peer(name=another.peer.address) receive,
>> net tcp addr=192.168.0.1 peer(addr=10.1.0.0/24 port=443) send
>> net tcp addr=192.168.0.1 peer(port=80) send
>> }
>>
> I am okay with grouping, though I need to ponder the syntax more. What you
> have is a little different than we have traditionally used for ( )
>
From a writer/auditer POV, I think I prefer grouping over everything
else so far. The context isn't lost within the rule like 'peer' is, the
grouping is very clear in what it applies to and there is no symbol with
extra connotational (/me likes to make up words) baggage. It also still
conveys to me the 'over there' sentiment that jj was looking for since
it is so separate from the subject.
> basically we have { } which denote a rule grouping, or are used for
> alternation in globbing syntax. Grouping could work but I think would not
> be the best choice (seeing it typed out makes me dislike it even more
>
> ie, dbus bus=session peer { name=a.peer.address } send,
>
> ( ) - used for a multi-valued set, but traditionally its been bare
>
> profile (complain, attach_disconnected) { }
> dbus name=subjectA.service (send,receive),
>
> or prefixed with the value being set
> profile flags=(complain, attach_disconnected) { }
>
> mount flags=(...),
>
>
> would you be opposed to
>
> dbus bus=session peer=(name=a.peer.address) send,
> net tcp addr=192.168.0.1 peer(addr=10.1.0.0/24 port=443) send,
>
The 'dbus' rule uses 'peer=()' and the 'net' rule uses 'peer()'. I'm
assuming this is not intentional?
Regardless, mount also has:
mount options=ro /dev/foo -> /mnt/,
mount options=(ro,atime),
mount options in (ro,atime),
I realize mount rule syntax is necessarily crazy and only point it out
because while 'options=(ro,atime)' and 'options in (ro,atime)' are
multi-valued sets, they convey quite different things.
To exhaust all options, I'll mention we could do something with more in
line with 'mount options in' and do:
dbus bus=session peer is (name=a.peer.address) send,
net tcp addr=192.168.0.1 peer is (addr=10.1.0.0/24 port=443) send,
but this seems like a feeble attempt at language consistency, is
cluttered and offers no benefit as a policy writer or auditer.
Another option that retains the spirit of the multi-valued set (note the
commas within peer()) is:
dbus peer (name=a.peer.address, interface=a.peer.interface) send,
net tcp addr=192.168.0.1 peer (addr=10.1.0.0/24, port=443) send,
but this is horribly inconsistent within the rule itself when the
subject is specified (and no, I don't want commas for the subject). Eg:
dbus name=... path=... peer (name=..., interface=...) send,
Furthermore, I don't think we can achieve perfect language consistency
with the obvious grouping options: [], {}, and (). They are all used in
our policy syntax and we already have some inconsistency with {}. It is
used to group policy rules in a profile, for aare and for vars. Policy
rules are grouped, but separated by commas which as noted above, doesn't
work well. aare uses commas with {} and vars can be space-separated (eg,
@{HOME}=@{HOMEDIRS}/*/ /root/). Perhaps since {} is already
inconsistent, that is a case for it:
dbus bus=session peer{name=a.peer.address} send,
net tcp addr=192.168.0.1 peer{addr=10.1.0.0/24 port=443} send,
or:
dbus bus=session peer={name=a.peer.address} send,
net tcp addr=192.168.0.1 peer={addr=10.1.0.0/24 port=443} send,
This doesn't look as clean and when reading it makes me start thinking
about aare. I might point out we see '()' used in different ways in
other languages. For example, C-based languages with loops and functions
so I don't think people will despair if '()' isn't a multi-valued set in
our policy language. To me, Steve's original '()' is still the best:
dbus bus=session peer(name=a.peer.address) send,
net tcp addr=192.168.0.1 peer(addr=10.1.0.0/24 port=443) send,
(though I'm open to other grouping ideas).
--
Jamie Strandboge http://www.ubuntu.com/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 899 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20130510/6682301d/attachment.pgp>
More information about the AppArmor
mailing list