[apparmor] DBus rule syntax for subject and peer components

Steve Beattie steve at nxnw.org
Wed Jun 12 18:40:18 UTC 2013

On Tue, Jun 11, 2013 at 02:41:03PM -0700, Tyler Hicks wrote:
> > * Proposal 3 - Grouping of subject and peer address components
> > 
> > Based on Steve's suggestion[4] and refined by Jamie[5]. It groups the
> > connection attributes together based on whether it is the subject's connection
> > attributes or the peer's.
> > 
> > dbus [<bus>] [subj=(<subject>)] [acquire],
> > dbus [<bus>] [subj=(<subject>)] [peer=(<peer>)] [send | receive],
> > 
> > /usr/bin/gnome-screensaver {
> >   # Ignore file and accessibility bus access for this excercise
> >   file,
> >   dbus bus=accessibility,
> > 
> >   # Talks to system and session buses
> >   dbus bus={system,session} peer=(name=org.freedesktop.DBus) (send receive),
> > 
> >   # Sends messages on the system bus
> >   dbus bus=system peer=(name=org.freedesktop.ConsoleKit path=/org/freedesktop/ConsoleKit/Manager interface=org.freedesktop.ConsoleKit.Manager) send,
> >   dbus bus=system peer=(name=org.freedesktop.Accounts path=/org/freedesktop/Accounts interface=org.freedesktop.Accounts) send,
> >   dbus bus=system peer=(name=org.freedesktop.Accounts path=/org/freedesktop/Accounts/User* interface=org.freedesktop.DBus.Properties) send,
> > 
> >   # Receives messages on the session bus
> >   dbus bus=session subj=(name=org.gnome.ScreenSaver) acquire,
> >   dbus bus=session subj=(path=/org/gnome/ScreenSaver interface=org.freedesktop.DBus.Properties) receive,
> >   # Be selective because the Lock method is mediated by these rules
> >   dbus bus=session subj=(path=/org/gnome/ScreenSaver interface=org.gnome.ScreenSaver) peer=(label=/usr/bin/gnome-settings-daemon) receive,
> >   dbus bus=session subj=(path=/org/gnome/ScreenSaver interface=org.gnome.ScreenSaver) peer=(name=com.canonical.indicator.session) receive,
> > 
> >   # Sends messages on the session bus
> >   dbus bus=session peer=(name=org.gnome.SessionManager path=/org/gnome/SessionManager/Presence interface=org.freedesktop.DBus.Properties) send,
> >   dbus bus=session peer=(path=/org/gtk/vfs/mounttracker interface=org.gtk.vfs.MountTracker) send,
> >   dbus bus=session peer=(name=org.gnome.Shell path=/org/gnome/Shell interface=org.freedesktop.DBus.Properties) send,
> > }

A dumb question due to my insufficient dbus knowledge: what
is the difference between a path, an interface, and a dest? Because
in your examples, you had rules with all three.

> This one clicked for me. The syntax just made sense while writing this
> profile.
> Unfortunately, it is a bit ugly but I think clarity is more important
> and this syntax makes it very clear what components are related to the
> subject and which ones relate to the peer.
> I like Proposal 3 the best. I'd also be fine with dropping the '=' chars
> from "peer=()" and "subj=()".

Is there a reason to go all 1970s creat() or should we spell out
'subject' entirely? I mean, other than using 'subj' makes rules line
up in vertical columns nicely.

> Proposal 3 seems to be the clear leader at this point. Speak up soon if
> you're not a fan of Proposal 3.
> As a side note, one thing that I'm not real happy about is the asymmetry
> of send and receive rules.
> When writing a send rule, it doesn't make sense to have a path,
> interface, or member specified in the subject address grouping.
> When writing a receive rule, it doesn't make sense to have a path,
> interface, or member specified in the peer address grouping.
> This is because you simply send a message through your connection, which
> only consists of a connection name and a connection label. When you
> receive, you receive messages according to the path, interface, and
> member.
> So, a rule like this wouldn't really translate to anything that made
> sense:
>   dbus bus=session subj=(path=/org/gnome/ScreenSaver interface=org.gnome.ScreenSaver) peer=(path=/com/canonical/indicator/session/session interface=com.canonical.indicator.session) (send receive),
> But these two rules do makes sens:
>   dbus bus=session subj=(path=/org/gnome/ScreenSaver interface=org.gnome.ScreenSaver) receive,
>   dbus bus=session peer=(path=/com/canonical/indicator/session/session interface=com.canonical.indicator.session) send,
> If we distill that down a little bit, it means that the only subj
> conditionals that make sense with send are name and label and the only
> peer conditionals that make sense with receive are name and label.

> It seems like we should be able use that to come up with a syntax that
> is simpler, but I haven't been able to think of one.

Are there ever situations where one would write {send,receive} for
the same set of paths/interfaces/dests, that isn't merely a case of
being sloppy/lazy?

You *could* make the argument that, since you would only ever specify
a peer or a subj in a rule, you wouldn't need to specify either and
the context would let you distinguish. My fear is that the implicit
nature of whether you are referring to the subject's address or the
peer's would be confusing to rule writers.

Also, something to keep in mind is that, while dbus uses what you
might consider an anonymous endpoint for one end of each connection,
other forms of IPC won't necessarily do so, e.g. networking. We'd
ideally like to have a consistent language pattern across the IPC
mechanisms we mediate, such that there's not too much cognitive
dissonance when writing rules for multiple types of IPC.

So while I could kind of see reversing the permission and modifier
ordering to be something like:

  dbus bus=session acquire dest=org.gnome.ScreenSaver,
  dbus bus=session receive subj=(path=/org/gnome/ScreenSaver interface=org.gnome.ScreenSaver),
  dbus bus=session send peer=(path=/com/canonical/indicator/session/session interface=com.canonical.indicator.session),

or even:

  dbus acquire bus=session dest=org.gnome.ScreenSaver,
  dbus receive bus=session subj=(path=/org/gnome/ScreenSaver interface=org.gnome.ScreenSaver),
  dbus send    bus=session peer=(path=/com/canonical/indicator/session/session interface=com.canonical.indicator.session),

would it make it too confusing for e.g.:

  # in this profile, allow ssh portforwarding via port 7979 on a tun
  # device to the ssh port of a class rage of hosts
  tcp send subj=(iface=tun* port=7979) peer=(addr= port=22),

(I guess with this ordering I start to see why people have wanted
to have the file permissions first before file paths, as the
send/receive/acquire bits get lost visually, at least without syntax

Thanks for resurrecting the discussion with concrete examples.

Steve Beattie
<sbeattie at ubuntu.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20130612/adf34ef7/attachment.pgp>

More information about the AppArmor mailing list