Skip to content

libweston: fix crash when a client binds to a destroyed output

Paul Pu requested to merge puhui/weston:UAF-of-weston_head into main

Environment

  • weston version: 12.0.1
  • wayland version: 1.22.0
  • hardware: card2-LVDS-1 below is hot-pluggable.
lrwxrwxrwx    1 root     root             0 Dec 18 16:26 card0 -> ../../devices/platform/etnaviv/drm/card0
lrwxrwxrwx    1 root     root             0 Dec 18 12:07 card1 -> ../../devices/platform/soc@0/32c00000.bus/32fc6000.display-controller/drm/card1
lrwxrwxrwx    1 root     root             0 Dec 18 12:07 card1-HDMI-A-1 -> ../../devices/platform/soc@0/32c00000.bus/32fc6000.display-controller/drm/card1/card1-HDMI-A-1
lrwxrwxrwx    1 root     root             0 Dec 18 12:07 card2 -> ../../devices/platform/soc@0/32c00000.bus/32e80000.display-controller/drm/card2
lrwxrwxrwx    1 root     root             0 Dec 18 12:07 card2-DSI-1 -> ../../devices/platform/soc@0/32c00000.bus/32e80000.display-controller/drm/card2/card2-DSI-1
lrwxrwxrwx    1 root     root             0 Dec 18 16:27 card2-LVDS-1 -> ../../devices/platform/soc@0/32c00000.bus/32e80000.display-controller/drm/card2/card2-LVDS-1
lrwxrwxrwx    1 root     root             0 Dec 18 12:07 card3 -> ../../devices/platform/soc@0/32c00000.bus/32e90000.display-controller/drm/card3
lrwxrwxrwx    1 root     root             0 Dec 18 12:07 card3-LVDS-2 -> ../../devices/platform/soc@0/32c00000.bus/32e90000.display-controller/drm/card3/card3-LVDS-2
lrwxrwxrwx    1 root     root             0 Dec 18 16:26 renderD128 -> ../../devices/platform/etnaviv/drm/renderD128
-r--r--r--    1 root     root          4096 Dec 18 12:07 version

Debug information

call stack

#0  0x0000ffffa21faf74 in wl_list_insert (list=list@entry=0xaaab0d2bb148, elm=0xaaab0d2fe6e0) at ../../../../../../workspace/sources/wayland/src/wayland-util.c:50
#1  0x0000ffffa223bc64 in bind_output (client=0xaaab0d2fe970, data=0xaaab0d2bb100, version=2, id=<optimized out>) at ../../../../../../workspace/sources/weston/libweston/compositor.c:5388
#2  0x0000ffffa1ff65f0 in ffi_call_SYSV () at ../libffi-3.4.4/src/aarch64/sysv.S:127
#3  0x0000ffffa1ff5cfc in ffi_call_int (cif=cif@entry=0xffffd4922b08, fn=0xffffd4922c90, orig_rvalue=0xaaab0d2bb3c0, orig_rvalue@entry=0x0, avalue=avalue@entry=0xffffd4922bd8, closure=0x11434af1378f7400, closure@entry=0x0)    at ../libffi-3.4.4/src/aarch64/ffi.c:816
#4  0x0000ffffa1ff617c in ffi_call (cif=cif@entry=0xffffd4922b08, fn=<optimized out>, rvalue=rvalue@entry=0x0, avalue=avalue@entry=0xffffd4922bd8) at ../libffi-3.4.4/src/aarch64/ffi.c:825
#5  0x0000ffffa21cde50 in wl_closure_invoke (closure=closure@entry=0xaaab0d2bb3c0, flags=flags@entry=2, target=<optimized out>, opcode=0, data=<optimized out>, data@entry=0xaaab0d2fe970)    at ../../../../../../workspace/sources/wayland/src/connection.c:1025
#6  0x0000ffffa21c87f0 in wl_client_connection_data (fd=<optimized out>, mask=<optimized out>, data=0xaaab0d2fe970) at ../../../../../../workspace/sources/wayland/src/wayland-server.c:438
#7  0x0000ffffa21cbc40 in wl_event_loop_dispatch (loop=0xaaab0d2a98a0, timeout=timeout@entry=-1) at ../../../../../../workspace/sources/wayland/src/event-loop.c:1027
#8  0x0000ffffa21c90b4 in wl_display_run (display=display@entry=0xaaab0d2a97b0) at ../../../../../../workspace/sources/wayland/src/wayland-server.c:1501
#9  0x0000ffffa245d248 in wet_main (argc=<optimized out>, argv=0xffffd4923958, test_data=<optimized out>) at ../../../../../../workspace/sources/weston/compositor/main.c:4216
#10 0x0000ffffa22cb230 in __libc_start_call_main (main=main@entry=0xaaaae0a10740 <main>, argc=argc@entry=6, argv=argv@entry=0xffffd4923958) at ../sysdeps/nptl/libc_start_call_main.h:58
#11 0x0000ffffa22cb30c in __libc_start_main_impl (main=0xaaaae0a10740 <main>, argc=6, argv=0xffffd4923958, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=<optimized out>) at ../csu/libc-start.c:389#12 0x0000aaaae0a107b0 in _start () at ../sysdeps/aarch64/start.S:81 

How it occurs

  1. the head for that LVDS-1 has already created
  2. a client connected, so the corresponding output is notified to this client
  3. the client requests to bind to this output
  4. before the server starts to handle the bind request, this head gets destroyed along with the LVDS-1's disappear
  5. the server starts to handle the bind request, but the head has gone, the UAF occurs.

Note

I haven't done test with the latest version of wayland & weston, but from the codes it looks the latest version has the same problem.

Edited by Marius Vlad

Merge request reports

Loading