[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-xorg-devel
Subject:    [PATCH 1/3 xserver] xace: Add new hook to override Xtrans Read and Write invocations
From:       Andrew Eikum <aeikum () codeweavers ! com>
Date:       2012-12-21 20:32:51
Message-ID: 20121221203251.GB32255 () foghorn ! codeweavers ! com
[Download RAW message or body]

This hook is useful for environments where the security extension might
need to inject data into the stream or process out-of-band information
from clients. Between this and the following patch, I believe I have
added relevant hooks to all accept/read/write/close/disconnect calls in
the tree.

I only hook those five calls. I don't add hooks for other auxiliary
Xtrans calls such as XTransSetOption. The idea is that a security
extension would copy the existing Xtrans implementation and add
modifications. I didn't intend to allow security extensions to create an
entirely "hot-pluggable" Xtrans in a security extension.

Signed-off-by: Andrew Eikum <aeikum@codeweavers.com>
---

As always with a new project, it's hard to be sure if I'm following
all of the submission rules :)

Looking at the calendar, I think I missed the 1.13 merge window.
Hopefully we can get any problems worked out and target 1.14 with this
series, then.

I appreciate any feedback!

Thanks,
Andrew

 Xext/xace.c     | 17 ++++++++++++++++-
 Xext/xace.h     |  8 +++++++-
 Xext/xacestr.h  | 12 ++++++++++++
 os/connection.c | 12 +++++++++---
 os/io.c         | 30 +++++++++++++++++++++++++-----
 5 files changed, 69 insertions(+), 10 deletions(-)


["0001-xace-Add-new-hook-to-override-Xtrans-Read-and-Write-.patch" (text/x-patch)]

diff --git a/Xext/xace.c b/Xext/xace.c
index 026d3c5..d51a720 100644
--- a/Xext/xace.c
+++ b/Xext/xace.c
@@ -103,12 +103,16 @@ XaceHook(int hook, ...)
         XaceScreenAccessRec screen;
         XaceAuthAvailRec auth;
         XaceKeyAvailRec key;
+        XaceXtransRec xtrans;
     } u;
     int *prv = NULL;            /* points to return value from callback */
     va_list ap;                 /* argument list */
 
-    if (!XaceHooks[hook])
+    if (!XaceHooks[hook]) {
+        if (hook == XACE_XTRANS_DISPATCH)
+            return BadImplementation;
         return Success;
+    }
 
     va_start(ap, hook);
 
@@ -202,6 +206,17 @@ XaceHook(int hook, ...)
         u.key.count = va_arg(ap, int);
 
         break;
+    case XACE_XTRANS_DISPATCH:
+        u.xtrans.type = va_arg(ap, int);
+        u.xtrans.ciptr = va_arg(ap, XtransConnInfo);
+        u.xtrans.client = va_arg(ap, ClientPtr);
+        u.xtrans.result = va_arg(ap, int *);
+        u.xtrans.buf = va_arg(ap, char *);
+        u.xtrans.size = va_arg(ap, int);
+
+        u.xtrans.status = BadImplementation; /* signal no such hook */
+        prv = &u.xtrans.status;
+        break;
     default:
         va_end(ap);
         return 0;               /* unimplemented hook number */
diff --git a/Xext/xace.h b/Xext/xace.h
index 5e6cb04..14f30e0 100644
--- a/Xext/xace.h
+++ b/Xext/xace.h
@@ -54,7 +54,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define XACE_KEY_AVAIL			14
 #define XACE_AUDIT_BEGIN		15
 #define XACE_AUDIT_END			16
-#define XACE_NUM_HOOKS			17
+#define XACE_XTRANS_DISPATCH		17
+#define XACE_NUM_HOOKS			18
+
+#define XACE_XTRANS_READ 0
+#define XACE_XTRANS_WRITE 1
+#define XACE_XTRANS_READV 2
+#define XACE_XTRANS_WRITEV 3
 
 extern _X_EXPORT CallbackListPtr XaceHooks[XACE_NUM_HOOKS];
 
diff --git a/Xext/xacestr.h b/Xext/xacestr.h
index 989b033..144fead 100644
--- a/Xext/xacestr.h
+++ b/Xext/xacestr.h
@@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "property.h"
 #include "selection.h"
 #include "xace.h"
+#include <X11/Xtrans/Xtrans.h>
 
 /* XACE_CORE_DISPATCH */
 typedef struct {
@@ -144,4 +145,15 @@ typedef struct {
     int requestResult;
 } XaceAuditRec;
 
+/* XACE_XTRANS_DISPATCH */
+typedef struct {
+    int type; /* one of XACE_XTRANS_* */
+    XtransConnInfo ciptr;
+    ClientPtr client;
+    int *result;
+    char *buf;
+    int size;
+    int status;
+} XaceXtransRec;
+
 #endif                          /* _XACESTR_H */
diff --git a/os/connection.c b/os/connection.c
index 6cd8bcf..6ddb9aa 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -890,7 +890,7 @@ return TRUE;
 static void
 ErrorConnMax(XtransConnInfo trans_conn)
 {
-    int fd = _XSERVTransGetConnectionNumber(trans_conn);
+    int fd = _XSERVTransGetConnectionNumber(trans_conn), err, result;
     xConnSetupPrefix csp;
     char pad[3] = { 0, 0, 0 };
     struct iovec iov[3];
@@ -907,7 +907,10 @@ ErrorConnMax(XtransConnInfo trans_conn)
     FD_SET(fd, &mask);
     (void) Select(fd + 1, &mask, NULL, NULL, &waittime);
     /* try to read the byte-order of the connection */
-    (void) _XSERVTransRead(trans_conn, &order, 1);
+    err = XaceHook(XACE_XTRANS_DISPATCH, XACE_XTRANS_READ, trans_conn,
+            NULL, &result, &order, 1);
+    if (err == BadImplementation)
+        (void) _XSERVTransRead(trans_conn, &order, 1);
     if (order == 'l' || order == 'B' || order == 'r' || order == 'R') {
         csp.success = xFalse;
         csp.lengthReason = sizeof(NOROOM) - 1;
@@ -926,7 +929,10 @@ ErrorConnMax(XtransConnInfo trans_conn)
         iov[1].iov_base = NOROOM;
         iov[2].iov_len = (4 - (csp.lengthReason & 3)) & 3;
         iov[2].iov_base = pad;
-        (void) _XSERVTransWritev(trans_conn, iov, 3);
+        err = XaceHook(XACE_XTRANS_DISPATCH, XACE_XTRANS_WRITEV, trans_conn,
+                NULL, &result, iov, 3);
+        if (err == BadImplementation)
+            (void) _XSERVTransWritev(trans_conn, iov, 3);
     }
 }
 
diff --git a/os/io.c b/os/io.c
index 2f091c4..3128c7f 100644
--- a/os/io.c
+++ b/os/io.c
@@ -78,6 +78,7 @@ SOFTWARE.
 #include "opaque.h"
 #include "dixstruct.h"
 #include "misc.h"
+#include "xace.h"
 
 CallbackListPtr ReplyCallback;
 CallbackListPtr FlushCallback;
@@ -213,7 +214,7 @@ ReadRequestFromClient(ClientPtr client)
     ConnectionInputPtr oci = oc->input;
     int fd = oc->fd;
     unsigned int gotnow, needed;
-    int result;
+    int result, err;
     register xReq *request;
     Bool need_header;
     Bool move_header;
@@ -346,8 +347,15 @@ ReadRequestFromClient(ClientPtr client)
             YieldControlDeath();
             return -1;
         }
-        result = _XSERVTransRead(oc->trans_conn, oci->buffer + oci->bufcnt,
-                                 oci->size - oci->bufcnt);
+        err = XaceHook(XACE_XTRANS_DISPATCH, XACE_XTRANS_READ, oc->trans_conn,
+                client, &result, oci->buffer + oci->bufcnt, oci->size - oci->bufcnt);
+        if (err == BadImplementation)
+            result = _XSERVTransRead(oc->trans_conn, oci->buffer + oci->bufcnt,
+                                     oci->size - oci->bufcnt);
+        else if (err != Success) {
+            errno = EIO;
+            result = -1;
+        }
         if (result <= 0) {
             if ((result < 0) && ETEST(errno)) {
 #if defined(SVR4) && defined(__i386__) && !defined(sun)
@@ -852,7 +860,7 @@ int
 FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
 {
     ConnectionOutputPtr oco = oc->output;
-    int connection = oc->fd;
+    int connection = oc->fd, err;
     XtransConnInfo trans_conn = oc->trans_conn;
     struct iovec iov[3];
     static char padBuffer[3];
@@ -909,7 +917,19 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
             InsertIOV(padBuffer, padsize)
 
             errno = 0;
-        if (trans_conn && (len = _XSERVTransWritev(trans_conn, iov, i)) >= 0) {
+
+        if (trans_conn) {
+            err = XaceHook(XACE_XTRANS_DISPATCH, XACE_XTRANS_WRITEV, trans_conn,
+                    who, &len, iov, i);
+            if (err == BadImplementation)
+                len = _XSERVTransWritev(trans_conn, iov, i);
+            else if (err != Success) {
+                errno = EIO;
+                len = -1;
+            }
+        }
+
+        if (trans_conn && len >= 0) {
             written += len;
             notWritten -= len;
             todo = notWritten;


_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic