[gamin] socket credentials: necessary?


I am continuing this discussion on the mailing list as you requested
in http://bugzilla.gnome.org/show_bug.cgi?id=306706 .

When a gamin client wants to talk to a gamin server, it open()s a well
known file system node which a gamin server is presumably listening
on.  Both the client and the server need to protect themselves from

A client will only use a server that it trusts according to the
following criteria: 1) the directory containing the socket node is
owned by the same user id that the client is running under; 2) the
directory's mode is 0700; 3) the owner of the socket node is the user
id that the client is running under; 4) the node is a socket; and 5)
none of the group or other permission bits are set on the node.  This
is done in gamin_check_secure_path() using stat().  (This final bit
exposes a small race: between the stat and the connect the socket
could have been replaced.  Slighly more secure would be to do the
connect and then verify that the socket's permissions using fstat.)
Once the connection is made, the client requests the server's
credentials in gamin_check_cred() using the LOCAL_CREDS socket option.

The server, when it creates the socket node, is careful to set
sufficiently restrictive permissions such that only clients which have
the authority of the user id which it is running under can connect().
Like the client, when a connection is established, it also sets the
LOCAL_CREDS option so as to obtain the client's credentials.

As far as the client and server should be concerned, the file system
enforces their respecitve security requirements: the server can be
sure that only clients which have the level of authority it is running
under can connect() to the socket; the client knows that only a
process with its level of authority can create a node which is owned
by its user id and has said permissions.  That is, the file system
provides sufficient mechanisms for both the client and the server to
articulate their security policy and both can trust the file system to
do that as it is part of each's trusted computing base (TCB).

The socket credential check is at best a double check and a poor one
at that in particular on systems with different access control
systems.  Moreover, the information provided by LOCAL_CRED violates
the principle of least information (i.e. it exposes information that
neither the client nor the server require to sufficiently implement
their security policy).

The Hurd is one such system: resources are accessed using kernel
protected capabilities.  On the Hurd, POSIX user ids are just
capabilities like most other capabilities but convey significantly
more authority.  As such, a process can hold one user id, many user
ids and even no user ids.  If we were to implement the LOCAL_CRED
semantics, we would have to determine which effective user id to
provide.  We think that programs never require the information that
LOCAL_CRED supplies to implement their security policy as such we
don't implement it.

I have provided a patch in the above bug report to correctly not use
LOCAL_CRED on systems which don't support it.  This patch DOES NOT
remove LOCAL_CRED checking on systems which support it.  Removing
LOCAL_CRED completely is something to consider but it is not something
my patch does.  Again, my patch only allows gamin to run on systems
which don't support LOCAL_CRED.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]