[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