Bug 1118353

Summary: Reliably crashes on xrandr resize events
Product: [Fedora] Fedora Reporter: Will Thompson <will>
Component: x11vncAssignee: Pavel Alexeev <pahan>
Status: CLOSED ERRATA QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 22CC: pahan, ppisar, rdieter
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: x11vnc-0.9.14-1.fc23 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-01-04 18:52:54 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---
Attachments:
Description Flags
This patch seems to work. none

Description Will Thompson 2014-07-10 13:38:55 UTC
Description of problem:

On receiving an xrandr resize event, x11vnc reliably unlocks a mutex twice, and crashes.

Version-Release number of selected component (if applicable):

x11vnc-0.9.13-11.fc20.x86_64

How reproducible:

Always

Steps to Reproduce:
1. Run x11vnc, eg `x11vnc -rfbport 5901 -display :0 -localhost`. It doesn't make any difference whether you pass an '-xrandr' option or not. There is also no need to connect a client.
2. Resize your display, eg from GNOME Settings -> Displays

Actual results:
x11vnc crashes while unlocking a mutex.

Expected results:
x11vnc resizes its framebuffer to match the new display size, without crashing.

Additional info:

There is the following comment in the top frame of the backtrace:

24	__lll_unlock_elision(int *lock, int private)
25	{
26	  /* When the lock was free we're in a transaction.
27	     When you crash here you unlocked a free lock.  */
28	  if (*lock == 0)
29	    _xend();
30	  else
31	    lll_unlock ((*lock), private);
32	  return 0;
33	}

x11vnc has a big global lock around X11 calls. What seems to be happening is:

* check_xevents() takes the lock.

* check_xevents() calls check_xrandr_event().

* check_xrandr_event() begins:

	/* it is assumed that X_LOCK is on at this point. */

  which is true.

* check_xrandr_event() releases the lock:

		if (do_change) {
			/* under do_change caller normally returns before its X_UNLOCK */
			X_UNLOCK;
			handle_xrandr_change(rev->width, rev->height);
		}

  handle_xrandr_change() does assume that the lock is not taken, so perhaps this is legit.

* check_xrandr_event() returns to check_xevents(), which goes on to X_UNLOCK; again, at which point we crash.



Log from the point where I change my desktop size to the crash:

10/07/2014 14:07:04 check_xrandr_event():
10/07/2014 14:07:04 Detected XRANDR event at location 'check_xevents':
10/07/2014 14:07:04   serial:          154
10/07/2014 14:07:04   timestamp:       3482878
10/07/2014 14:07:04   cfg_timestamp:   3482878
10/07/2014 14:07:04   size_id:         65535
10/07/2014 14:07:04   sub_pixel:       0
10/07/2014 14:07:04   rotation:        1
10/07/2014 14:07:04   width:           1920
10/07/2014 14:07:04   height:          1200
10/07/2014 14:07:04   mwidth:          508 mm
10/07/2014 14:07:04   mheight:         318 mm
10/07/2014 14:07:04 
10/07/2014 14:07:04 check_xrandr_event: previous WxH: 1920x1200
10/07/2014 14:07:04 check_xrandr_event: no change detected.
10/07/2014 14:07:04 check_xrandr_event: updating config...
10/07/2014 14:07:04 check_xrandr_event: current  WxH: 1920x1200
10/07/2014 14:07:04 check_xrandr_event(): returning control to caller...
10/07/2014 14:07:04 check_xrandr_event():
10/07/2014 14:07:04 Detected XRANDR event at location 'check_xevents':
10/07/2014 14:07:04   serial:          154
10/07/2014 14:07:04   timestamp:       3482878
10/07/2014 14:07:04   cfg_timestamp:   3482878
10/07/2014 14:07:04   size_id:         65535
10/07/2014 14:07:04   sub_pixel:       0
10/07/2014 14:07:04   rotation:        1
10/07/2014 14:07:04   width:           1680
10/07/2014 14:07:04   height:          1050
10/07/2014 14:07:04   mwidth:          445 mm
10/07/2014 14:07:04   mheight:         278 mm
10/07/2014 14:07:04 
10/07/2014 14:07:04 check_xrandr_event: previous WxH: 1920x1200
10/07/2014 14:07:04 check_xrandr_event: updating config...
10/07/2014 14:07:04 xrandr_mode: resize
10/07/2014 14:07:04 check_xrandr_event: trying to create new framebuffer...
10/07/2014 14:07:04 deleted 60 tile_row polling images.
10/07/2014 14:07:04 Default visual ID: 0x21
10/07/2014 14:07:04 Read initial data from X display into framebuffer.
10/07/2014 14:07:04 initialize_screen: fb_depth/fb_bpp/fb_Bpl 24/32/6720
10/07/2014 14:07:04 rfbNewFramebuffer(0xa2e350, 0x0, 1680, 1050, 8, 1, 4)
10/07/2014 14:07:04 
10/07/2014 14:07:04 X display :0 is 32bpp depth=24 true color
10/07/2014 14:07:04 
10/07/2014 14:07:04 calling setTranslateFunction()...
10/07/2014 14:07:04   done.
10/07/2014 14:07:04 
10/07/2014 14:07:04 Xinerama is present and active (e.g. multi-head).
10/07/2014 14:07:04 Xinerama: number of sub-screens: 1
10/07/2014 14:07:04 Xinerama: no blackouts needed (only one sub-screen)
10/07/2014 14:07:04 
10/07/2014 14:07:04 check_xrandr_event: fb       WxH: 1680x1050
10/07/2014 14:07:04 check_xrandr_event: current  WxH: 1680x1050
10/07/2014 14:07:04 check_xrandr_event(): returning control to caller...


Backtrace:

#0  __lll_unlock_elision (lock=0x9c71a0 <x11Mutex>, private=0) at ../nptl/sysdeps/unix/sysv/linux/x86/elision-unlock.c:29
No locals.
#1  0x00007ffff5928221 in __pthread_mutex_unlock_usercnt (decr=1, mutex=<optimized out>) at pthread_mutex_unlock.c:66
        type = <optimized out>
#2  __GI___pthread_mutex_unlock (mutex=<optimized out>) at pthread_mutex_unlock.c:310
No locals.
#3  0x00000000004aac15 in check_xevents (reset=reset@entry=0) at xevents.c:1675
        xev = {type = 28, xany = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598}, xkey = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, root = 447, subwindow = 7229189, time = 0, x = 65535, y = 65537, x_root = 1920, y_root = 1200, state = 508, keycode = 318, same_screen = 65793}, xbutton = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, root = 447, subwindow = 7229189, time = 0, x = 65535, y = 65537, x_root = 1920, y_root = 1200, state = 508, button = 318, same_screen = 65793}, xmotion = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, root = 447, subwindow = 7229189, time = 0, x = 65535, y = 65537, x_root = 1920, y_root = 1200, state = 508, is_hint = 62 '>', same_screen = 65793}, xcrossing = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, root = 447, subwindow = 7229189, time = 0, x = 65535, y = 65537, x_root = 1920, y_root = 1200, mode = 508, detail = 318, same_screen = 65793, focus = 65377, state = 0}, xfocus = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, mode = 447, detail = 0}, xexpose = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, x = 447, y = 0, width = 7229189, height = 0, count = 0}, xgraphicsexpose = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, drawable = 598, x = 447, y = 0, width = 7229189, height = 0, count = 0, major_code = 0, minor_code = 65535}, xnoexpose = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, drawable = 598, major_code = 447, minor_code = 0}, xvisibility = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, state = 447}, xcreatewindow = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, parent = 598, window = 447, x = 7229189, y = 0, width = 0, height = 0, border_width = 65535, override_redirect = 65537}, xdestroywindow = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, event = 598, window = 447}, xunmap = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, event = 598, window = 447, from_configure = 7229189}, xmap = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, event = 598, window = 447, override_redirect = 7229189}, xmaprequest = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, parent = 598, window = 447}, xreparent = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, event = 598, window = 447, parent = 7229189, x = 0, y = 0, override_redirect = 65535}, xconfigure = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, event = 598, window = 447, x = 7229189, y = 0, width = 0, height = 0, border_width = 65535, above = 5153960757120, override_redirect = 508}, xgravity = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, event = 598, window = 447, x = 7229189, y = 0}, xresizerequest = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, width = 447, height = 0}, xconfigurerequest = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, parent = 598, window = 447, x = 7229189, y = 0, width = 0, height = 0, border_width = 65535, above = 5153960757120, detail = 508, value_mask = 280792076976385}, xcirculate = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, event = 598, window = 447, place = 7229189}, xcirculaterequest = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, parent = 598, window = 447, place = 7229189}, xproperty = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, atom = 447, time = 7229189, state = 0}, xselectionclear = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, selection = 447, time = 7229189}, xselectionrequest = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, owner = 598, requestor = 447, selection = 7229189, target = 0, property = 281479271743487, time = 5153960757120}, xselection = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, requestor = 598, selection = 447, target = 7229189, property = 0, time = 281479271743487}, xcolormap = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, colormap = 447, new = 7229189, state = 0}, xclient = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, message_type = 447, format = 7229189, data = {b = "\000\000\000\000\000\000\000\000\377\377\000\000\001\000\001\000\200\a\000", s = {0, 0, 0, 0, -1, 0, 1, 1, 1920, 0}, l = {0, 281479271743487, 5153960757120, 1365799600636, 280792076976385}}}, xmapping = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, request = 447, first_keycode = 0, count = 7229189}, xerror = {type = 28, display = 0x9e, resourceid = 282578783305728, serial = 10288544, error_code = 86 'V', request_code = 2 '\002', minor_code = 0 '\000'}, xkeymap = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, window = 598, key_vector = "\277\001\000\000\000\000\000\000\005On", '\000' <repeats 13 times>, "\377\377\000\000\001\000\001"}, xgeneric = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, extension = 598, evtype = 0}, xcookie = {type = 28, serial = 158, send_event = 0, display = 0x9cfda0, extension = 598, evtype = 0, cookie = 447, data = 0x6e4f05}, pad = {140733193388060, 158, 282578783305728, 10288544, 598, 447, 7229189, 0, 281479271743487, 5153960757120, 1365799600636, 280792076976385, 0, 282578783305728, 269025167, 0, 0, 1155453787259863297, 282578783305728, 269025166, 1155453795849797889, 282578783305728, 269025119, 1155453937583718657}}
        tmp = <optimized out>
        have_clients = <optimized out>
        sent_some_sel = 0
        last_call = 1404997624
        last_bell = 1404997624
        last_init_check = 1404997624
        last_sync = 1404997522
        last_time_sync = 1404997606
        now = <optimized out>
        last_request = 1404997624.1960969
        last_xrefresh = 0
        old_handler = <optimized out>
#4  0x00000000004646f2 in watch_loop () at screen.c:4611
        msg = "new client: %s taking unixpw client off hold.\n"
        cnt = 0
        tile_diffs = <optimized out>
        skip_pe = <optimized out>
        tm = 1404997624.4061949
        dtr = <optimized out>
        dt = <optimized out>
        start = <optimized out>
#5  0x0000000000410c5a in main (argc=<optimized out>, argv=<optimized out>) at x11vnc.c:5990
        i = <optimized out>
        len = <optimized out>
        tmpi = <optimized out>
        ev = 0
        er = 145
        maj = 1
        min = 13
        arg = <optimized out>
        remote_sync = <optimized out>
        remote_cmd = <optimized out>
        query_cmd = <optimized out>
        query_retries = <optimized out>
        query_delay = <optimized out>
        query_match = <optimized out>
        gui_str = <optimized out>
        got_gui_pw = <optimized out>
        pw_loc = <optimized out>
        got_passwd = <optimized out>
        got_rfbauth = 0
        nopw = <optimized out>
        got_viewpasswd = <optimized out>
        got_localhost = <optimized out>
        got_passwdfile = <optimized out>
        vpw_loc = <optimized out>
        dt = <optimized out>
        bg = 0
        got_rfbwait = <optimized out>
        got_httpdir = <optimized out>
        try_http = <optimized out>
        orig_use_xdamage = 1
        http_oneport_msg = <optimized out>
        fb0 = <optimized out>
        ncache_msg = <optimized out>
        got_rfbport_str = <optimized out>
        got_rfbport_pos = <optimized out>
        got_tls = <optimized out>
        got_inetd = <optimized out>
        got_noxrandr = <optimized out>
        argc_vnc = 1
        argv_vnc = {0x9cc080 "/usr/bin/x11vnc", 0x7891e0 <str> "-desktop", 0x8b3fc0 <title> "foo:0", 0x7891e0 <str> "-desktop", 0x8b3fc0 <title> "foo:0", 0x7891e0 <str> "-desktop", 0x8b3fc0 <title> "foo:0", 0x7891e0 <str> "-desktop", 0x8b3fc0 <title> "foo:0", 0x0 <repeats 2039 times>}

Comment 1 Will Thompson 2014-07-10 13:39:55 UTC
Created attachment 917080 [details]
This patch seems to work.

(though I haven't tested it much)

Comment 2 Will Thompson 2014-07-18 13:54:52 UTC
The patch was accepted upstream: https://github.com/LibVNC/libvncserver/pull/13#event-143080774

Comment 3 Fedora End Of Life 2015-05-29 12:20:31 UTC
This message is a reminder that Fedora 20 is nearing its end of life.
Approximately 4 (four) weeks from now Fedora will stop maintaining
and issuing updates for Fedora 20. It is Fedora's policy to close all
bug reports from releases that are no longer maintained. At that time
this bug will be closed as EOL if it remains open with a Fedora  'version'
of '20'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 20 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

Comment 4 Will Thompson 2015-05-29 13:36:42 UTC
I no longer use x11vnc, but I'm pretty sure this bug still exists in F21 and F22. The Fedora 21 (and 22, they are identical) x11vnc package still includes the offending code, without my patch which was accepted upstream:

		if (do_change) {
			/* under do_change caller normally returns before its X_UNLOCK */
			X_UNLOCK;
			handle_xrandr_change(rev->width, rev->height);
		}

Upstream, x11vnc has been split into its own repository. It doesn't seem to have been released, though. https://github.com/LibVNC/x11vnc/blob/master/src/xrandr.c#L267-L272

Comment 5 Fedora Update System 2015-11-30 10:23:02 UTC
x11vnc-0.9.14-1.fc23 has been submitted as an update to Fedora 23. https://bodhi.fedoraproject.org/updates/FEDORA-2015-6685346aaa

Comment 6 Pavel Alexeev 2015-11-30 12:43:11 UTC
Will thank you.

Comment 7 Fedora Update System 2015-12-01 02:22:37 UTC
x11vnc-0.9.14-1.fc23 has been pushed to the Fedora 23 testing repository. If problems still persist, please make note of it in this bug report.
If you want to test the update, you can install it with
$ su -c 'dnf --enablerepo=updates-testing update x11vnc'
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2015-6685346aaa

Comment 8 Fedora Update System 2016-01-04 18:52:51 UTC
x11vnc-0.9.14-1.fc23 has been pushed to the Fedora 23 stable repository. If problems still persist, please make note of it in this bug report.