Re: [Xcb] [PATCH libX11] xcb_io: Fix Xlib 32-bit request number wrapping bug

2014-09-15 Thread Jonas Petersen

Hi Keith,

(2nd try)

I went back in time and found your last post regarding this topic. You 
did make some suggestions that got lost, probably due to my 
discontinuing. Sorry about that. So let me pick it up again from there, 
in order to hopefully get the case going.


I will post an updated patch including your suggestions. Please see my 
inline comments in this mail, particularly on your last point.


I tested the patch against a fresh Ubuntu Desktop 14.04.1 i386 
(libx11-1.6.2). I verified that your test (nop.c) will fail before and 
succeed after applying the patch.



Am 30.12.2013 um 21:04 schrieb Keith Packard:

Jonas Petersenjnsptr...@gmail.com  writes:


By design, on 32-bit systems, the Xlib internal 32-bit request sequence
numbers may wrap. There is two locations within xcb_io.c that are not
wrap-safe though. The value of last_flushed relies on request to be
sequential all the time. This is not given in the moment when the sequence
has just wrapped. Applications may then crash with a Fatal IO error 11
(Resource temporarily unavailable).

This patch fixes this by unwrapping the sequence number when needed to
retain the sequence relative to last_flushed.

Reviewed-by: Keith Packardkei...@keithp.com

There are some subtleties here which might be mentioned in comments:


+   unwrapped_request = dpy-request;
+   /* If there was a sequence number wrap since our last flush,
+* make sure the sequence number we use, stays in sequence
+* with dpy-xcb-last_flush. */
+   if (sizeof(uint64_t)  sizeof(unsigned long)  dpy-request  
dpy-xcb-last_flushed)
+   unwrapped_request += UINT64_C(1)  32;

The sizeof(uint64_t)  sizeof (unsigned long) test is an optimization;
dpy-request will *never* be less than last_flushed on a 64-bit system
(well, until we have to deal with 64-bit wrap). However, the check is
also useful to understand the append_pending_request call below.


Yes, it's an optimization. It will have an effect at compile time and it 
will make it end up only in 32-bit binaries. Actually there was some 
discussion about that at some other branch of this topic.





uint64_t sequence;
-   for(sequence = dpy-xcb-last_flushed + 1; sequence = 
dpy-request; ++sequence)
+   for(sequence = dpy-xcb-last_flushed + 1; sequence = 
unwrapped_request; ++sequence)
append_pending_request(dpy, sequence);

Here, we're passing a 64-bit sequence which may be 'unwrapped', in that
it can contain values above the maximum possible unsigned long sequence
number. However, that only happens (see check above) where unsigned long
is 32 bits. The 'sequence' formal in append_pending_request is an
unsigned long, and so any time the sequence passed might have a high
sequence value, it will get trimmed off by the type conversion.

Do we want an '(unsigned long)' cast in the actual here? It would be
strictly for documentation. Probably best to just mention what's
happening in a comment instead


Agreed, I will add a comment.


}
-   requests = dpy-request - dpy-xcb-last_flushed;
+   requests = unwrapped_request - dpy-xcb-last_flushed;
dpy-xcb-last_flushed = dpy-request;

I think last_flushed should be changed from uint64_t to unsigned long to
match all of the Xlib types.


By examining the usages of last_flushed, I'd say it makes a lot of sense 
changing it to unsigned long. Added it to the patch.



That would require a cast in the loop
above:

+   for(sequence = (uint64_t) dpy-xcb-last_flushed + 1; sequence = 
unwrapped_request; ++sequence)


Added that as well.


I think there's also a problem in require_socket -- it compares a 64-bit
value from xcb with a 32-bit local value. I think we need to change that
to:

 uint64_tsent64;
 unsigned long   sent;

 sent = sent64

 if ((long) (sent - dpy-last_request_read)  0)
 throw_thread_fail_assert(sequence wrapped)

This would only allow for 31-bit differences.


Here I'm not sure if I really get what you mean. So you would introduce 
another local variable instead of casting where appropriate? Please see 
my patch if I applied that right.


By the way, the line following next...

dpy-xcb-last_flushed = dpy-request = sent;

...now also is much more obvious. Because before it was a 64-32-64-bit 
assignment. Now it is 32-32-32. In my ealier patches I had added a 
comment to that line (which now would be obsolete):


/* Note: The following line will truncate the 64bit 'sent'
 * to 32bit for 'dpy-request'. This truncated value will
 * then be assigned to the 64-bit 'dpy-xcb-last_flushed'
 * (which is intended). */
dpy-xcb-last_flushed = dpy-request = sent;

Regards
Jonas
___
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

Re: [Xcb] [PATCH libX11] xcb_io: Fix Xlib 32-bit request number wrapping bug

2014-08-24 Thread Jonas Petersen

Hi Keith,

I went back in time and found your last post regarding this topic. You 
did make some suggestions that got lost, probably due to my 
discontinuing. Sorry about that. So let me pick it up again from there, 
in order to hopefully get the case going.


I will post an updated patch including your suggestions. Please see my 
inline comments in this mail, particularly on your last point.


I tested the patch against a fresh Ubuntu Desktop 14.04.1 i386 
(libx11-1.6.2). I verified that your test (nop.c) will fail before and 
succeed after applying the patch.



Am 30.12.2013 um 21:04 schrieb Keith Packard:

Jonas Petersenjnsptr...@gmail.com  writes:


By design, on 32-bit systems, the Xlib internal 32-bit request sequence
numbers may wrap. There is two locations within xcb_io.c that are not
wrap-safe though. The value of last_flushed relies on request to be
sequential all the time. This is not given in the moment when the sequence
has just wrapped. Applications may then crash with a Fatal IO error 11
(Resource temporarily unavailable).

This patch fixes this by unwrapping the sequence number when needed to
retain the sequence relative to last_flushed.

Reviewed-by: Keith Packardkei...@keithp.com

There are some subtleties here which might be mentioned in comments:


+   unwrapped_request = dpy-request;
+   /* If there was a sequence number wrap since our last flush,
+* make sure the sequence number we use, stays in sequence
+* with dpy-xcb-last_flush. */
+   if (sizeof(uint64_t)  sizeof(unsigned long)  dpy-request  
dpy-xcb-last_flushed)
+   unwrapped_request += UINT64_C(1)  32;

The sizeof(uint64_t)  sizeof (unsigned long) test is an optimization;
dpy-request will *never* be less than last_flushed on a 64-bit system
(well, until we have to deal with 64-bit wrap). However, the check is
also useful to understand the append_pending_request call below.


Yes, it's an optimization. It will have an effect at compile time and it 
will make it end up only in 32-bit binaries. Actually there was some 
discussion about that at some other branch of this topic.





uint64_t sequence;
-   for(sequence = dpy-xcb-last_flushed + 1; sequence = 
dpy-request; ++sequence)
+   for(sequence = dpy-xcb-last_flushed + 1; sequence = 
unwrapped_request; ++sequence)
append_pending_request(dpy, sequence);

Here, we're passing a 64-bit sequence which may be 'unwrapped', in that
it can contain values above the maximum possible unsigned long sequence
number. However, that only happens (see check above) where unsigned long
is 32 bits. The 'sequence' formal in append_pending_request is an
unsigned long, and so any time the sequence passed might have a high
sequence value, it will get trimmed off by the type conversion.

Do we want an '(unsigned long)' cast in the actual here? It would be
strictly for documentation. Probably best to just mention what's
happening in a comment instead


Agreed, I will add a comment.


}
-   requests = dpy-request - dpy-xcb-last_flushed;
+   requests = unwrapped_request - dpy-xcb-last_flushed;
dpy-xcb-last_flushed = dpy-request;

I think last_flushed should be changed from uint64_t to unsigned long to
match all of the Xlib types.


By examining the usages of last_flushed, I'd say it makes a lot of sense 
changing it to unsigned long. Added it to the patch.



That would require a cast in the loop
above:

+   for(sequence = (uint64_t) dpy-xcb-last_flushed + 1; sequence = 
unwrapped_request; ++sequence)


Added that as well.


I think there's also a problem in require_socket -- it compares a 64-bit
value from xcb with a 32-bit local value. I think we need to change that
to:

 uint64_tsent64;
 unsigned long   sent;

 sent = sent64

 if ((long) (sent - dpy-last_request_read)  0)
 throw_thread_fail_assert(sequence wrapped)

This would only allow for 31-bit differences.


Here I'm not sure if I really get what you mean. So you would introduce 
another local variable instead of casting where appropriate? Please see 
my patch if I applied that right.


By the way, the line following next...

dpy-xcb-last_flushed = dpy-request = sent;

...now also is much more obvious. Because before it was a 64-32-64-bit 
assignment. Now it is 32-32-32. In my ealier patches I had added a 
comment to that line (which now would be obsolete):


/* Note: The following line will truncate the 64bit 'sent'
 * to 32bit for 'dpy-request'. This truncated value will
 * then be assigned to the 64-bit 'dpy-xcb-last_flushed'
 * (which is intended). */
dpy-xcb-last_flushed = dpy-request = sent;

Regards
Jonas
___
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

Re: [Xcb] [PATCH libX11] xcb_io: Fix Xlib 32-bit request number wrapping bug

2014-08-20 Thread Jan Smout
Dear Keith,


thought I'd ping you again. Please fix your spam filter!


Regarding this patch:
http://patchwork.freedesktop.org/patch/16753/


my question is very simple: is this patch good enough to be put in a distro
release? Or are there things to be clarified?

I'm trying to get it into the upcoming Mageia 5 release (I assume it will
be released before Xorg releases it's next libX11 version)


I cannot stress enough the seriousness of this bug. An application that
gets killed by a library without any way to recover is not something to be
taken lightly. In a certain sense I got lucky that my app is so heavy on
graphics, so I was able to find a solution rather quickly (as did Jonas
btw).
I suspect most people just see (seemingly) random crashes, shrug and
restart whatever they were running and then blame the application
programmer for writing shitty software. I find that hard to accept...


best regards,
Jan

On 6 August 2014 17:14, Jan Smout smout@gmail.com wrote:

 Hello Keith,

 my previous mails probably got lost in the noise. Please see my question
 below:


 On 29 July 2014 18:56, Jan Smout smout@gmail.com wrote:

 Hi all,

 I recently stumbled into an application that crashed because of this:
 https://bugs.freedesktop.org/show_bug.cgi?id=71338

 and quickly found the following patch:
 http://patchwork.freedesktop.org/patch/16753/

 which seems to work fine (the application used to crash in less than 24
 hrs. Has been running for 5 days straight with the patch).


 Now my question: what is the status of this patch? Are there still
 details to be clarified before it can be put into the main tree?


 best regards,
 Jan
 --
 Life is complex, it has a real part and an imaginary part.




 --
 Life is complex, it has a real part and an imaginary part.




-- 
Life is complex, it has a real part and an imaginary part.
___
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

Re: [Xcb] [PATCH libX11] xcb_io: Fix Xlib 32-bit request number wrapping bug

2014-08-07 Thread Jan Smout
Hi Jonas,

the reason I am asking this is that I'm trying to push the patch into the
Mageia xlib package - mainly because it is the candidate for putting
realtime applications  the next coming 6/7 years. The requirements are
quite strong: it needs to run 24/7 and is heavy on graphics (one of them
would crash after less than 24 hrs).
Now, even though the application is entirely under my control, the compiler
is not, so I'm stuck with a deprecated 32-bit compiler for this iteration
(before migrating to another compiler).
Now, I had already traced it down to xlib and was traversing the library
code when I found that you had already went down that road. I reviewed your
patch and - provided there are no other hidden dragons - found that it
worked as advertised (using XNoOp as proof of concept and by running my
app). Thanks for the good work btw.

Regarding the seriousness I completely agree. It is an important bug. Other
applications might crash after weeks or months, in which case users will
have a hard time understanding why and might conclude the OS is not
stable or anything.

Anyway, for my apps I have no problem - we have custom installs anyways -
but other people might...

So, the only question I have for Keith is: is the patch good enough to be
put into an official linux distribution, while the next xlib release has
not yet been released?

best regards,
Jan
On Aug 6, 2014 10:49 PM, Jonas Petersen jnsptr...@gmail.com wrote:

  Hi Jan,

 thanks for pushing this.

 I spent really a lot of time (weeks) tracking this down and finding a
 solution. Digging down the depths of the operating system, while actually
 writting application software. The result is the mentioned patch. I then
 posted it here. I think there is approval that the fix actually does work.
 Then there was starting some discussion about implementation details,
 optimization and possible further problems at other locations.

 At some point I had to take a break, since this had cost me already so
 much time. Sorry about that. It's to bad this is still pending.

 If nothing happens I might be willing to spend another small amount of
 time to help completing this. But my time is limited. I can not promise
 anything.

 I think this bug is quite serious. It suddenly kills programs without
 asking out of nowhere. And it's patient.

 By the way, my software now runs on 64-bit, so luckily I'm not affected
 anymore (hopefully). But there's probably still plenty of 32-bit systems
 endangered by this.

 Have you seen? Keith posted a program to reproduce the bug (or confirm
 that the patch works) as fast as possible:

 /* cc -o nop nop.c `pkg-config --cflags --libs x11` */
 #includestdio.h
 #includestdint.h
 #includeX11/Xlib.h

 int
 main (int argc, char **argv)
 {
   uint64_ti = 0;
   Display *dpy = XOpenDisplay(NULL);

   for (;;) {
   ++i;
   if ((i  0xfff) == 0) {
   XFlush(dpy);
   printf (0x%llx\n, i);
   }
   XNoOp(dpy);
   }
 }


 Regards
 Jonas




 Am 29.07.2014 um 18:56 schrieb Jan Smout:

 Hi all,

 I recently stumbled into an application that crashed because of this:
 https://bugs.freedesktop.org/show_bug.cgi?id=71338

 and quickly found the following patch:
 http://patchwork.freedesktop.org/patch/16753/

  which seems to work fine (the application used to crash in less than 24
 hrs. Has been running for 5 days straight with the patch).


 Now my question: what is the status of this patch? Are there still details
 to be clarified before it can be put into the main tree?


  best regards,
  Jan
  --
 Life is complex, it has a real part and an imaginary part.



___
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

Re: xcb_io: Fix Xlib 32-bit request number wrapping bug

2014-08-06 Thread Jan Smout
Hello,

can somebody have a look at my question below please?


thanks,
On 31 July 2014 18:05, Jan Smout smout@gmail.com wrote:

 Hello again,

 just thought I should ask again. Probably the message got lost in the
 noise  ;-)


 On 29 July 2014 18:56, Jan Smout smout@gmail.com wrote:

 Hi all,

 I recently stumbled into an application that crashed because of this:
 https://bugs.freedesktop.org/show_bug.cgi?id=71338

 and quickly found the following patch:
 http://patchwork.freedesktop.org/patch/16753/

 which seems to work fine (the application used to crash in less than 24
 hrs. Has been running for 5 days straight with the patch).


 Now my question: what is the status of this patch? Are there still
 details to be clarified before it can be put into the main tree?


 best regards,
 Jan
 --
 Life is complex, it has a real part and an imaginary part.






-- 
Life is complex, it has a real part and an imaginary part.
___
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

Re: xcb_io: Fix Xlib 32-bit request number wrapping bug

2014-08-06 Thread Michel Dänzer
On 06.08.2014 20:13, Jan Smout wrote:
 
 can somebody have a look at my question below please?

Have you tried asking on the xcb mailing list?


-- 
Earthling Michel Dänzer|  http://www.amd.com
Libre software enthusiast  |Mesa and X developer
___
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


Re: [Xcb] [PATCH libX11] xcb_io: Fix Xlib 32-bit request number wrapping bug

2014-08-06 Thread Jan Smout
Hello Keith,

my previous mails probably got lost in the noise. Please see my question
below:


On 29 July 2014 18:56, Jan Smout smout@gmail.com wrote:

 Hi all,

 I recently stumbled into an application that crashed because of this:
 https://bugs.freedesktop.org/show_bug.cgi?id=71338

 and quickly found the following patch:
 http://patchwork.freedesktop.org/patch/16753/

 which seems to work fine (the application used to crash in less than 24
 hrs. Has been running for 5 days straight with the patch).


 Now my question: what is the status of this patch? Are there still details
 to be clarified before it can be put into the main tree?


 best regards,
 Jan
 --
 Life is complex, it has a real part and an imaginary part.




-- 
Life is complex, it has a real part and an imaginary part.
___
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

Re: [Xcb] [PATCH libX11] xcb_io: Fix Xlib 32-bit request number wrapping bug

2014-08-06 Thread Jonas Petersen

Hi Jan,

thanks for pushing this.

I spent really a lot of time (weeks) tracking this down and finding a 
solution. Digging down the depths of the operating system, while 
actually writting application software. The result is the mentioned 
patch. I then posted it here. I think there is approval that the fix 
actually does work. Then there was starting some discussion about 
implementation details, optimization and possible further problems at 
other locations.


At some point I had to take a break, since this had cost me already so 
much time. Sorry about that. It's to bad this is still pending.


If nothing happens I might be willing to spend another small amount of 
time to help completing this. But my time is limited. I can not promise 
anything.


I think this bug is quite serious. It suddenly kills programs without 
asking out of nowhere. And it's patient.


By the way, my software now runs on 64-bit, so luckily I'm not affected 
anymore (hopefully). But there's probably still plenty of 32-bit systems 
endangered by this.


Have you seen? Keith posted a program to reproduce the bug (or confirm 
that the patch works) as fast as possible:


/* cc -o nop nop.c `pkg-config --cflags --libs x11` */
#includestdio.h
#includestdint.h
#includeX11/Xlib.h

int
main (int argc, char **argv)
{
uint64_ti = 0;
Display *dpy = XOpenDisplay(NULL);

for (;;) {
++i;
if ((i  0xfff) == 0) {
XFlush(dpy);
printf (0x%llx\n, i);
}
XNoOp(dpy);
}
}


Regards
Jonas




Am 29.07.2014 um 18:56 schrieb Jan Smout:

Hi all,

I recently stumbled into an application that crashed because of this:
https://bugs.freedesktop.org/show_bug.cgi?id=71338

and quickly found the following patch:
http://patchwork.freedesktop.org/patch/16753/

which seems to work fine (the application used to crash in less than 
24 hrs. Has been running for 5 days straight with the patch).



Now my question: what is the status of this patch? Are there still 
details to be clarified before it can be put into the main tree?



best regards,
Jan
--
Life is complex, it has a real part and an imaginary part.


___
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

Re: xcb_io: Fix Xlib 32-bit request number wrapping bug

2014-07-31 Thread Jan Smout
Hello again,

just thought I should ask again. Probably the message got lost in the
noise  ;-)


On 29 July 2014 18:56, Jan Smout smout@gmail.com wrote:

 Hi all,

 I recently stumbled into an application that crashed because of this:
 https://bugs.freedesktop.org/show_bug.cgi?id=71338

 and quickly found the following patch:
 http://patchwork.freedesktop.org/patch/16753/

 which seems to work fine (the application used to crash in less than 24
 hrs. Has been running for 5 days straight with the patch).


 Now my question: what is the status of this patch? Are there still details
 to be clarified before it can be put into the main tree?


 best regards,
 Jan
 --
 Life is complex, it has a real part and an imaginary part.

___
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

Re: [Xcb] [PATCH libX11] xcb_io: Fix Xlib 32-bit request number wrapping bug

2014-07-29 Thread Jan Smout
Hi all,

I recently stumbled into an application that crashed because of this:
https://bugs.freedesktop.org/show_bug.cgi?id=71338

and quickly found the following patch:
http://patchwork.freedesktop.org/patch/16753/

which seems to work fine (the application used to crash in less than 24
hrs. Has been running for 5 days straight with the patch).


Now my question: what is the status of this patch? Are there still details
to be clarified before it can be put into the main tree?


best regards,
Jan
-- 
Life is complex, it has a real part and an imaginary part.
___
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

Re: [Xcb] [PATCH libX11] xcb_io: Fix Xlib 32-bit request number wrapping bug

2013-12-30 Thread Keith Packard
Jonas Petersen jnsptr...@gmail.com writes:

 By design, on 32-bit systems, the Xlib internal 32-bit request sequence
 numbers may wrap. There is two locations within xcb_io.c that are not
 wrap-safe though. The value of last_flushed relies on request to be
 sequential all the time. This is not given in the moment when the sequence
 has just wrapped. Applications may then crash with a Fatal IO error 11
 (Resource temporarily unavailable).

 This patch fixes this by unwrapping the sequence number when needed to
 retain the sequence relative to last_flushed.

Reviewed-by: Keith Packard kei...@keithp.com

There are some subtleties here which might be mentioned in comments:

 + unwrapped_request = dpy-request;
 + /* If there was a sequence number wrap since our last flush,
 +  * make sure the sequence number we use, stays in sequence
 +  * with dpy-xcb-last_flush. */
 + if (sizeof(uint64_t)  sizeof(unsigned long)  dpy-request  
 dpy-xcb-last_flushed)
 + unwrapped_request += UINT64_C(1)  32;

The sizeof(uint64_t)  sizeof (unsigned long) test is an optimization;
dpy-request will *never* be less than last_flushed on a 64-bit system
(well, until we have to deal with 64-bit wrap). However, the check is
also useful to understand the append_pending_request call below.

   uint64_t sequence;
 - for(sequence = dpy-xcb-last_flushed + 1; sequence = 
 dpy-request; ++sequence)
 + for(sequence = dpy-xcb-last_flushed + 1; sequence = 
 unwrapped_request; ++sequence)
   append_pending_request(dpy, sequence);

Here, we're passing a 64-bit sequence which may be 'unwrapped', in that
it can contain values above the maximum possible unsigned long sequence
number. However, that only happens (see check above) where unsigned long
is 32 bits. The 'sequence' formal in append_pending_request is an
unsigned long, and so any time the sequence passed might have a high
sequence value, it will get trimmed off by the type conversion.

Do we want an '(unsigned long)' cast in the actual here? It would be
strictly for documentation. Probably best to just mention what's
happening in a comment instead



   }
 - requests = dpy-request - dpy-xcb-last_flushed;
 + requests = unwrapped_request - dpy-xcb-last_flushed;
   dpy-xcb-last_flushed = dpy-request;

I think last_flushed should be changed from uint64_t to unsigned long to
match all of the Xlib types. That would require a cast in the loop
above:

+   for(sequence = (uint64_t) dpy-xcb-last_flushed + 1; sequence = 
unwrapped_request; ++sequence)

I think there's also a problem in require_socket -- it compares a 64-bit
value from xcb with a 32-bit local value. I think we need to change that
to:

uint64_tsent64;
unsigned long   sent;

sent = sent64

if ((long) (sent - dpy-last_request_read)  0)
throw_thread_fail_assert(sequence wrapped)

This would only allow for 31-bit differences.

-- 
keith.pack...@intel.com


pgp1rpCQKEoMJ.pgp
Description: PGP signature
___
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

[PATCH libX11] xcb_io: Fix Xlib 32-bit request number wrapping bug

2013-12-15 Thread Jonas Petersen
By design, on 32-bit systems, the Xlib internal 32-bit request sequence
numbers may wrap. There is two locations within xcb_io.c that are not
wrap-safe though. The value of last_flushed relies on request to be
sequential all the time. This is not given in the moment when the sequence
has just wrapped. Applications may then crash with a Fatal IO error 11
(Resource temporarily unavailable).

This patch fixes this by unwrapping the sequence number when needed to
retain the sequence relative to last_flushed.

Signed-off-by: Jonas Petersen jnsptr...@gmail.com
---
 src/xcb_io.c |   13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/xcb_io.c b/src/xcb_io.c
index 727c6c7..34ca46e 100644
--- a/src/xcb_io.c
+++ b/src/xcb_io.c
@@ -455,7 +455,7 @@ void _XSend(Display *dpy, const char *data, long size)
static const xReq dummy_request;
static char const pad[3];
struct iovec vec[3];
-   uint64_t requests;
+   uint64_t requests, unwrapped_request;
_XExtension *ext;
xcb_connection_t *c = dpy-xcb-connection;
if(dpy-flags  XlibDisplayIOError)
@@ -464,6 +464,13 @@ void _XSend(Display *dpy, const char *data, long size)
if(dpy-bufptr == dpy-buffer  !size)
return;
 
+   unwrapped_request = dpy-request;
+   /* If there was a sequence number wrap since our last flush,
+* make sure the sequence number we use, stays in sequence
+* with dpy-xcb-last_flush. */
+   if (sizeof(uint64_t)  sizeof(unsigned long)  dpy-request  
dpy-xcb-last_flushed)
+   unwrapped_request += UINT64_C(1)  32;
+
/* iff we asked XCB to set aside errors, we must pick those up
 * eventually. iff there are async handlers, we may have just
 * issued requests that will generate replies. in either case,
@@ -471,10 +478,10 @@ void _XSend(Display *dpy, const char *data, long size)
if(dpy-xcb-event_owner != XlibOwnsEventQueue || dpy-async_handlers)
{
uint64_t sequence;
-   for(sequence = dpy-xcb-last_flushed + 1; sequence = 
dpy-request; ++sequence)
+   for(sequence = dpy-xcb-last_flushed + 1; sequence = 
unwrapped_request; ++sequence)
append_pending_request(dpy, sequence);
}
-   requests = dpy-request - dpy-xcb-last_flushed;
+   requests = unwrapped_request - dpy-xcb-last_flushed;
dpy-xcb-last_flushed = dpy-request;
 
vec[0].iov_base = dpy-buffer;
-- 
1.7.10.4

___
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