[Xcb] new SELinux protocol reply problem
Xavier Toth
txtoth at gmail.com
Fri Feb 23 11:07:30 PST 2007
I've defined a new protocol GetPropertyContext which I modeled after
GetAtomName in xproto.xml but it isn't quite working. Using the code
I've include in this message the call to
xcb_se_linux_get_property_context_reply in my test client never
returns which implies that the client never received the reply or the
full reply. At one point I did try setting the reply length to zero
and got a reply but the 'context' string returned only contained 20 of
41 bytes sent. What was also curious about this was that as I was
debugging and rooting around I could see in the connection in that the
entire context string had been received from the server. Is this just
a matter of setting the reply length correctly, if so what should I be
setting to and why? Also as I look at examples in xproto.xml many
requests and replies have a lot of padding that I don't understand the
need for can you help me understand why this is necessary?
XCB Protocol
<xcb header="xselinux" extension-xname="SELinux" extension-name="SELinux"
major-version="1" minor-version="0">
<import>xproto</import>
<request name="ChangePropertyContext" opcode="0">
<field type="WINDOW" name="window" />
<field type="ATOM" name="property" />
<field type="CARD16" name="context_len" />
<list type="char" name="context">
<fieldref>context_len</fieldref>
</list>
</request>
<request name="GetPropertyContext" opcode="1">
<field type="WINDOW" name="window" />
<field type="ATOM" name="property" />
<reply>
<pad bytes="1" />
<field type="CARD16" name="context_len" />
<list type="CARD8" name="context">
<fieldref>context_len</fieldref>
</list>
</reply>
</request>
</xcb>
Server GetPropertyContext proc.
int
ProcGetPropertyContext(ClientPtr client)
{
PropertyPtr pProp, prevProp;
unsigned long len, rc;
WindowPtr pWin;
xcb_se_linux_get_property_context_reply_t reply;
Mask access_mode = DixReadAccess;
REQUEST(xcb_se_linux_get_property_context_request_t);
security_context_t ctx;
REQUEST_SIZE_MATCH(xcb_se_linux_get_property_context_request_t);
rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
if (rc != Success)
return rc;
if (!ValidAtom(stuff->property))
{
client->errorValue = stuff->property;
return(BadAtom);
}
/* Find the property */
pProp = wUserProps (pWin);
prevProp = (PropertyPtr)NULL;
while (pProp)
{
if (pProp->propertyName == stuff->property)
break;
prevProp = pProp;
pProp = pProp->next;
}
if (!pProp)
return NullPropertyContextReply(client, &reply);
switch (XaceHook(XACE_PROPERTY_ACCESS, client, pWin, stuff->property,
access_mode))
{
case XaceErrorOperation:
client->errorValue = stuff->property;
return BadAtom;;
case XaceIgnoreOperation:
return NullPropertyContextReply(client, &reply);
}
/*
* Return context value to client
*/
rc = avc_sid_to_context(PropertyGetSIDPriv(pProp), &ctx);
if (rc < 0) {
FatalError("XSELinux: Failed to get security context!\n");
}
len = strlen(ctx);
reply.response_type = X_Reply;
reply.length = (len + 3) >> 2;
reply.sequence = client->sequence;
reply.context_len = len;
WriteToClient(client,
sizeof(xcb_se_linux_get_property_context_reply_t), &reply);
if (len > 0)
{
WriteToClient(client, len, (char *)ctx);
}
freecon(ctx);
return(client->noClientException);
}
Test code.
#include <stdio.h>
#include <xcb/xcb.h>
#include <xcb/xcb_atom.h>
#include <xcb/xselinux.h>
int
main ()
{
xcb_connection_t *c;
xcb_screen_t *screen;
xcb_window_t win;
char *title = "Hello World !";
char *title_icon = "Hello World ! (iconified)";
xcb_generic_error_t *generic_error = NULL;
xcb_intern_atom_cookie_t atom_cookie;
xcb_intern_atom_reply_t *atom_reply;
xcb_atom_t atom;
xcb_get_atom_name_cookie_t atom_name_cookie;
xcb_get_atom_name_reply_t *atom_name_reply;
xcb_se_linux_get_property_context_cookie_t prop_cookie;
xcb_se_linux_get_property_context_reply_t *prop_reply;
/* Open the connection to the X server */
c = xcb_connect (NULL, NULL);
/* Get the first screen */
screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
/* Ask for our window's Id */
win = xcb_generate_id (c);
/* Create the window */
xcb_create_window (c, /* Connection */
0, /* depth */
win, /* window Id */
screen->root, /* parent window */
0, 0, /* x, y */
250, 150, /* width, height */
10, /* border_width */
XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
screen->root_visual, /* visual */
0, NULL); /* masks, not used */
/* Set the title of the window */
xcb_change_property (c, XCB_PROP_MODE_REPLACE, win,
WM_NAME, STRING, 8,
strlen (title), title);
/* Set the title of the window icon */
xcb_change_property (c, XCB_PROP_MODE_REPLACE, win,
WM_ICON_NAME, STRING, 8,
strlen(title_icon), title_icon);
/* Map the window on the screen */
xcb_map_window (c, win);
xcb_flush (c);
atom = xcb_intern_atom_reply (c,
xcb_intern_atom (c,
0,
strlen("WM_NAME"),
"WM_NAME"),
NULL)->atom;
atom_name_cookie = xcb_get_atom_name(c, atom);
atom_name_reply = xcb_get_atom_name_reply(c, atom_name_cookie,
&generic_error);
fprintf(stderr, "atom %d %s\n",
xcb_get_atom_name_name_length(atom_name_reply),
(char*)xcb_get_atom_name_name(atom_name_reply));
fprintf(stderr, "xcb_se_linux_get_property_context_reply_t %d\n",
sizeof(xcb_se_linux_get_property_context_reply_t));
prop_cookie = xcb_se_linux_get_property_context(c, win, WM_NAME);
prop_reply = xcb_se_linux_get_property_context_reply(c, prop_cookie,
&generic_error);
if ((generic_error != NULL) || (prop_reply == NULL)) {
free(generic_error);
return 0;
}
int num_ret = xcb_se_linux_get_property_context_context_length(prop_reply);
char *retval = xcb_se_linux_get_property_context_context(prop_reply);
fprintf(stderr, "Context %d %s %d\n", num_ret, retval, strlen(retval));
while (1) {}
return 0;
}
More information about the Xcb
mailing list