[RFC] Input design

David Zeuthen david at fubar.dk
Fri Apr 20 13:16:58 PDT 2007

(apologies if this breaks threading for folks, I wasn't subscribed to
the list until I was pointed to this thread)

On Thu, 2007-04-19 at 16:16 +0000, an Daniel Stone wrote:
> Hi,
> So, one of the reasons I've been very hesitant to put out is my
> dissatisfaction with the current design of the input hotplugging.  I
> think I know how to fix it, however, and would appreciate comments from
> the other people bored enough to hack on input.
>  * Too much onus on the client
>    Right now, we rely on an intelligent config client to get things
>    done: you cannot simply have the server add all devices, or do
>    something otherwise sensible.  This, IMO, is a big mark against us.

I can see why some people object to this. Still, I think an intelligent
client is what most of the desktop projects (e.g. GNOME, KDE) wants to
do - your thoughts on that?

(Just because I have this point of view doesn't mean I object to it
being easy to use dumb clients or have the server do _some_
autoconfiguration if that's what the user wants.)

>  * Why D-Bus is not our ideal IPC system
>    D-Bus is a very good idea, and there's not much wrong with the spec
>    per se[0], but the client library is, well, abhorrent.  Its worst
>    transgression is to repeatedly call assert() from a library, which is
>    a design decision and will not be changed.  Its API is also quite
>    horrible and awkward to use (see config.c and respeclaration).  The
>    excuse for this is that no-one ever uses plain C anymore, so we
>    should use the GLib/Qt bindings.  IOW, someone needs to write
>    libdbus-desuckified.

Well, Daniel, that's your opinion which both I and other D-Bus authors
disagree with; suffice to say; the point, I think, is that as long as
you write non-buggy code and don't pass garbage to libdbus you'll be
fine (I'm sure I can find lots of functions in the X server that will
crash if I pass a NULL pointer or garbage). It's no different from most
other API's out there. For the record, this have already been
extensively discussed on the dbus list... for reference to other
readers, see


for rebuttal and also surrounding messages. Anyway, I don't think it's
useful to rehash that discussion, at least not right now. It's more an
implementation detail at this point I think...

>  * Security issues not even solved properly
>    Right now, we need someone to write a D-Bus authentication plugin to
>    map X servers to users, in order to come up with a sensible security
>    policy.  Plus, MPX kind of blows this out of the water.

There's things like ConsoleKit that is already shipped with Fedora 7;
I've copied some docs here for consideration


> To recap, the reason I went with D-Bus is because adding input devices
> is a security concern.  Either you can steal someone's keystrokes, or
> overwrite your partition table with the PS/2 init sequence.  The way
> we've dealt with this previously has been to have security policy
> out-of-band (i.e. config file), and keeping that way seemed an appealing
> method of skirting the security issues that came with doing it over the
> wire.  Also, D-Bus's security policies are fundamentally aimed at 'who's
> sitting at the machine?', rather than 'who can access /tmp?', and this
> is a good thing.
> Here's the proposed new approach:
>   * More server-centric configuration
>     The server should at least be aware of which input devices are
>     around it.  We can do this by adding HAL support to the server, and
>     having it enumerate input devices via HAL.  This way, it always
>     keeps a list of active input devices, and enabling them is just one
>     step away from enumerating.  This provides for an xcompmgr -a type
>     situation where the server can just DTRT for us.

Adding HAL support to the server means it needs to talk to HAL - this
can only be done via D-Bus (the system bus specifically) so your
complaints about libdbus may apply here. It's true, however, that
there's a C library, libhal, that does this for you (via libdbus) and it
checks everything (or tries to) to make sure it doesn't send garbage to
libdbus. And this works fine.

(As the maintainer of HAL, I usually tell people _not_ to use libhal; I
tell them to use native bindings (glib, Qt, Mono, Java, Python,
whatever) for D-Bus instead. For the X server, I don't know; I guess if
using libhal makes your life easier (and you don't mind blocking calls),
then why not. But if it was me, I'd use libdbus directly and just make
sure my code isn't buggy.)

>   * Leverage synergies for the benefit of all market segments
>     Just making sure you're still paying attention.
>   * Move from D-Bus back to wire protocol

For the record, whether you use D-Bus or X protocol to do this both
works as long as you can get the information you need about the client
(e.g. uid, pid whatever) to make a security decision. It's not like I'm
religiously attached to D-Bus; I just don't think your complaints about
libdbus are valid.

>     So, if we have a list of devices (optionally filtered by the admin;
>     we'll have to provide some mechanism of filtering the list), our
>     interaction with the client moves from 'add/remove this device' to
>     'enable/disable' this device.  This is a relatively safe operation:
>     HAL won't let us trash someone's partition table by writing the PS/2
>     init sequence to /dev/hda.  Multi-user issues will require a
>     security policy; this should probably be dealt with via the
>     server-side security framework.  Right now, we already allow random
>     users to steal other peoples' pointers with MPX, so that issue needs
>     to be solved through the security framework anyway.

Btw, I don't see why it's useful to let the server keep this list; I'd
just stick it in a library and let the client use it; I mean, what
really is the big win between

 1) client using X protocol to enumerate devices AND select device; vs.

 2) client using some library to enumerate devices AND then use X
    protocol to select device

Maybe there's something I don't get?

> I think we can do this reasonably quickly, and once that's settled down,
> we can start shoving the 1.3.99.x releases out.
> Questions? Opinions?

The ideas Jon (ConsoleKit author) and myself have for multi-user (e.g.
fast-user-switching and multi-seat) might be interesting to review in
this context. Allow me to list them

 1. HAL will know about what devices are attached to what seats

 2. ConsoleKit knows about what sessions belongs to what seats and
    whether they are active or inactive; what /dev/tty device, what
    X server and so on.

 3. HAL maintains ACL's on devices; whether a user get an ACL depends
    on security policy; one such security policy is to grant access
    to a device only if a user is in an active session that is local to
    the seat that the session goes on at.

    So if you fast-user-switch away from a session, the user owning that
    session will get his ACL removed from one or more device files.

    (In the future when Linux gains revoke() we will also revoke access
    to devices; e.g. do more than just remove user from the ACL)

In Fedora 7 we have 2. and 3. already implemented with the caveat that
we give an ACL to a user only if he's at a local console nonwithstanding
whether his session is active or now. In the future this will change; as
soon as revoke() is available it makes sense to revoke access to devices
for inactive session.

(context/justification: For example, for webcams and audio devices it's
useful to revoke access to a devices for users in sessions that become
inactive.. Think campus setting and shared workstations; you don't want
to enable bored grad students to use the webcam/soundcard to spy on
other users (the attacker has an inactive session on the host))

Anyway, why am I writing all this? Because I see it apply to X.org and
input devices as well. 

My point really is that, security policy wise, when a user is requesting
an X input device to be added to the server, then 

 1. X.org checks it's really an input device - you need to do this
    check anyway and it's probably sufficient just checking major/minor

 2. Check that the user that requests a device have access to it; e.g
    access(2) etc.

 3. Keep in mind that access to the device may be revoked at any point
    in the future for the user that added the device; Since the server
    (currently) runs as root, perhaps that means you want to run your X
    input driver in a child process with  the uid of the user that added
    the device... and then handle ENXIO or SIGBUS [1]. 

So I guess I'm saying that it would be appropriate if the X server,
instead of X inventing it's own security access scheme, just uses access
checks on device nodes as the security check whether a user should be
allowed to add/remove a device.

Note that distros already manage ACL on some devices already (sound
cards, cdrom, cameras etc.), using custom distro-specific stuff (e.g.
pam-console, group membership on Debian etc. etc.) so they need little
changes if you just make X respect the ACL on the device node.

For embedded; my guess is that these folks can add their own simple
custom code (e.g. udev rules or whatever) for managing ACL's.

For the record, ConsoleKit/HAL is just a way to do this in a way that is
not distro-specific; it's pretty new stuff but it looks like a number of
distros are going to pick it up. Of course, I'm a bit biased here so
people should make up their own mind on this :-)

Anyway, hope this is useful input in untangling the input device mess. I
hope I haven't started a flamewar here. Thoughts?


[1] : http://lwn.net/Articles/225619/

More information about the xorg mailing list