Bug#234556: xlibs: many clients get BadLength error from X_ChangeProperty request
Hi,
I was pretty busy last two weeks...
In order to get rid of all these problem of "ghost bugs" caused by
optimizations, I recompiled a version of the X server without any "-Ox"
and with "-g". As expected the "out of range" error vanished in the air,
but not the bug.
After few tries, I think I know now the real cause of the error
(but I might be wrong once again!).
It seems that the server X is sending a packet through the socket and
getting something different when receiving it afterward.
In what I have experimented, the X server is sending a packet of size
864 and getting something of size 32 on the other side.
The funny thing is that this fact was previously hidden by the ghost bug
caused by the misinterpretation of the code by gdb.
(Remark: I should have tried to see if the same ghost bug appears on
plain x86 architecture, but I've been too lazy to try it).
Here is the gdb trace of it:
====
GNU gdb 6.0
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for
details.
This GDB was configured as "i386-linux"...
(gdb) break Color.c:99
Breakpoint 1 at 0x809f4cd: file Color.c, line 99.
(gdb) run :6
Starting program:
/home/fleury/devel/xfree_bug/src/xfree86-4.3.0/xc-no_opt-debug/programs/Xserver/Xnest :6
Breakpoint 1, xnestCreateColormap (pCmap=0x84b61e8) at Color.c:99
99 XQueryColors(xnestDisplay, xnestColormap(pCmap), colors,
ncolors);
(gdb) break _XFlushInt
Breakpoint 2 at 0x400c0609: file XlibInt.c, line 589.
(gdb) c
Continuing.
Breakpoint 2, _XFlushInt (dpy=0x84af750, cv=0x0) at XlibInt.c:589
589 if (dpy->flags & XlibDisplayIOError)
(gdb) disp size
1: size = 140421635
(gdb) s
597 while (dpy->flags & XlibDisplayWriting) {
1: size = 140421635
(gdb)
605 size = todo = dpy->bufptr - dpy->buffer;
1: size = 140421635
(gdb)
606 if (!size) return;
1: size = 864
(gdb)
608 dpy->flags |= XlibDisplayWriting;
1: size = 864
(gdb)
610 dpy->bufptr = dpy->bufmax;
1: size = 864
(gdb)
612 for (ext = dpy->flushes; ext; ext = ext->next_flush)
1: size = 864
(gdb)
614 bufindex = dpy->buffer;
1: size = 864
(gdb)
620 while (size) {
1: size = 864
(gdb)
621 ESET(0);
1: size = 864
(gdb)
622 write_stat = _X11TransWrite(dpy->trans_conn,
1: size = 864
(gdb)
_X11TransWrite (ciptr=0x84afcf0, buf=0x84afdb0 "<\001\002", size=864)
at Xtrans.c:843
843 return ciptr->transptr->Write (ciptr, buf, size);
(gdb) disp size
2: size = 864
(gdb) s
_X11TransSocketWrite (ciptr=0x84afcf0, buf=0x84afdb0 "<\001\002",
size=864)
at Xtranssock.c:1750
1750 return write (ciptr->fd, buf, size);
(gdb) disp size
3: size = 864
(gdb) s
1752 }
3: size = 864
(gdb)
_X11TransWrite (ciptr=0x84afcf0, buf=0x84afdb0 "<\001\002", size=864)
at Xtrans.c:844
844 }
2: size = 864
(gdb)
_XFlushInt (dpy=0x84af750, cv=0x0) at XlibInt.c:624
624 if (write_stat >= 0) {
1: size = 864
(gdb)
625 size -= write_stat;
1: size = 864
(gdb)
626 todo = size;
1: size = 0
(gdb)
627 bufindex += write_stat;
1: size = 0
(gdb)
620 while (size) {
1: size = 0
(gdb)
660 dpy->last_req = (char *)&_dummy_request;
1: size = 0
(gdb)
661 if ((dpy->request - dpy->last_request_read) >= SEQLIMIT
&&
1: size = 0
(gdb)
667 dpy->bufptr = dpy->buffer;
1: size = 0
(gdb)
669 dpy->flags &= ~XlibDisplayWriting;
1: size = 0
(gdb)
671 }
1: size = 0
(gdb)
_XReply (dpy=0x84af750, rep=0xbffff420, extra=0, discard=0) at
XlibInt.c:1670
1670 if(dpy->lock &&
(gdb) s
1674 dpy->flags |= XlibDisplayReply;
(gdb) s
1682 if (!dpy->lock || !dpy->lock->reply_was_read)
(gdb) s
1684 (void) _XRead(dpy, (char *)rep,
(long)SIZEOF(xReply));
(gdb) s
_XRead (dpy=0x84af750, data=0xbffff420 "\035I!@<D8>IH\bJ\001", size=32)
at XlibInt.c:1035
1035 int original_size = size;
(gdb) disp size
4: size = 32
(gdb) s
1038 if ((dpy->flags & XlibDisplayIOError) || size == 0)
4: size = 32
(gdb)
1040 ESET(0);
4: size = 32
(gdb)
1041 while ((bytes_read = _X11TransRead(dpy->trans_conn,
data, (int)size))
4: size = 32
(gdb)
_X11TransRead (ciptr=0x84afcf0, buf=0xbffff420 "\035I!@<D8>IH\bJ\001",
size=32)
at Xtrans.c:836
836 return ciptr->transptr->Read (ciptr, buf, size);
(gdb)
_X11TransSocketRead (ciptr=0x84afcf0, buf=0xbffff420
"\035I!@<D8>IH\bJ\001",
size=32) at Xtranssock.c:1736
1736 return read (ciptr->fd, buf, size);
(gdb)
1738 }
(gdb)
_X11TransRead (ciptr=0x84afcf0, buf=0xbffff420 "", size=32) at
Xtrans.c:837
837 }
(gdb)
_XRead (dpy=0x84af750, data=0xbffff420 "", size=32) at XlibInt.c:1072
1072 if (dpy->lock && dpy->lock->reply_bytes_left > 0)
4: size = 32
(gdb)
1081 return 0;
4: size = 32
(gdb)
1082 }
4: size = 32
(gdb)
_XReply (dpy=0x84af750, rep=0xbffff420, extra=0, discard=0) at
XlibInt.c:1686
1686 if (dpy->lock)
(gdb)
1690 switch ((int)rep->generic.type) { ===> Go to X_Error!!
====
So, my guess is that *something* is happening in _XReply (or around this
function) that cause the problem...
======
_XReply (dpy=0x84af750, rep=0xbffff420, extra=0, discard=0) at
XlibInt.c:1670
1670 if(dpy->lock &&
(gdb)
1674 dpy->flags |= XlibDisplayReply;
(gdb)
1682 if (!dpy->lock || !dpy->lock->reply_was_read)
(gdb)
1684 (void) _XRead(dpy, (char *)rep,
(long)SIZEOF(xReply));
======
Here:
(long)SIZEOF(xReply) = 32 (and not 864 as it should be)
Any idea to allow me to go further ???
How are managed the network transferts in X ?
What should I compile with the debug option to get some informations
about this problem of information leak ?
Regards
--
Emmanuel Fleury
Computer Science Department, | Office: B1-201
Aalborg University, | Phone: +45 96 35 72 23
Fredriks Bajersvej 7E, | Fax: +45 98 15 98 89
9220 Aalborg East, Denmark | Email: fleury@cs.auc.dk
Reply to: