[Xcb] Re: new SELinux protocol reply problem
Ted X Toth
txtoth at gmail.com
Sat Feb 24 08:17:15 PST 2007
The problem was that xcb in its' read_packet function expects replies to
be at least 32 bytes long. When I padded the reply the protocol worked.
Admittedly I'm no xcb expert but this seems a bit broken and at the
least should be documented. Maybe the xslt could flag when replies
aren't long enough?
Xavier Toth wrote:
> 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