Glynn,
We ended up patching the source as you recommended.
We were a little surprised to discover that tightening the umask or mode
prior to socket creation did not prevent others from connecting to Xvfb.
So our second approach was to compare the EUID of the Xvfb process with
the EUID of the client attempting to connect, and only allow connections
when they match, effectively limiting users only to the Xvfb instances
that they started themselves. This doesn't fix the issue of two users
wanting to use the same DISPLAY number, but telling users to "export
DISPLAY=:$$" seemed to generally take care of that problem for us. This
code isn't enough to be included in X right now, but if there is enough
interest in this feature that it might be included, maybe I can make it
a configuration option.
I've attached our patch, applied to Xtranssock.c in the xtrans-1.2.7
source code (don't mind my bad indentation). From what we've tested, it
appears to work for us. I thought I'd post our solution anyway, in case
I've overlooked something.
Thanks,
Billy Wilson
On 01/16/2015 08:22 PM, Glynn Clements wrote:
Billy Wilson wrote:
Is there a way to secure Xvfb during an installation from source, such
as during ./configure?
I don't think that you're going to get the behaviour you desire
without patching the source.
--- Xtranssock.c.orig 2015-01-23 16:13:06.288288000 -0700
+++ Xtranssock.c 2015-01-23 16:16:46.543003000 -0700
@@ -1249,6 +1249,8 @@
XtransConnInfo newciptr;
struct sockaddr_in sockname;
SOCKLEN_T namelen = sizeof(sockname);
+ struct ucred cr;
+ int cl=sizeof(cr);
prmsg (2, "SocketINETAccept(%p,%d)\n", ciptr, ciptr->fd);
@@ -1271,6 +1273,24 @@
return NULL;
}
+ if (getsockopt(newciptr->fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) != 0) {
+ prmsg (1, "SocketINETAccept: failed to get uid\n");
+ close (newciptr->fd);
+ free (newciptr);
+ *status = TRANS_ACCEPT_FAILED;
+ return NULL;
+
+ }
+
+ if (cr.uid != geteuid())
+ {
+ prmsg (1, "SocketINETAccept: euid mismatch, permission denied\n");
+ close (newciptr->fd);
+ free (newciptr);
+ *status = TRANS_ACCEPT_FAILED;
+ return NULL;
+ }
+
#ifdef TCP_NODELAY
{
/*
@@ -1325,6 +1345,8 @@
XtransConnInfo newciptr;
struct sockaddr_un sockname;
SOCKLEN_T namelen = sizeof sockname;
+ struct ucred cr;
+ int cl=sizeof(cr);
prmsg (2, "SocketUNIXAccept(%p,%d)\n", ciptr, ciptr->fd);
@@ -1344,6 +1366,24 @@
return NULL;
}
+ if (getsockopt(newciptr->fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) != 0) {
+ prmsg (1, "SocketUNIXAccept: failed to get uid\n");
+ close (newciptr->fd);
+ free (newciptr);
+ *status = TRANS_ACCEPT_FAILED;
+ return NULL;
+
+ }
+
+ if (cr.uid != geteuid())
+ {
+ prmsg (1, "SocketUNIXAccept: euid mismatch, permission denied\n");
+ close (newciptr->fd);
+ free (newciptr);
+ *status = TRANS_ACCEPT_FAILED;
+ return NULL;
+ }
+
ciptr->addrlen = namelen;
/*
* Get the socket name and the peer name from the listener socket,
_______________________________________________
xorg@lists.x.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.x.org/mailman/listinfo/xorg
Your subscription address: %(user_address)s