view: Fix null dereference

There seems to be a null pointer access that can happen. I was able to
reproduce this by running the cemu emulator[1] with the new collabora
wine wayland driver[2] and opening and closing some sub menus.

Adding a trival null check seems to do the trick to stop sway from
crashing and returning to tty and everything else works normally.

[1]: http://cemu.info/
[2]: https://www.winehq.org/pipermail/wine-devel/2021-December/203035.html

Stack trace from lldb:

* thread #1, name = 'sway', stop reason = signal SIGSEGV: invalid address (fault address: 0xf8)
    frame #0: 0x00005555555c3fc3 sway`view_child_init(child=0x0000555555f67940, impl=0x00005555555ee030, view=0x00005555565bc590, surface=0x00005555565b6940) at view.c:1117:25
   1114		wl_signal_add(&view->events.unmap, &child->view_unmap);
   1115		child->view_unmap.notify = view_child_handle_view_unmap;
   1116	
-> 1117		struct sway_workspace *workspace = child->view->container->pending.workspace;
   1118		if (workspace) {
   1119			wlr_surface_send_enter(child->surface, workspace->output->wlr_output);
   1120		}
(lldb) up
error: sway {0x000342ab}: DIE has DW_AT_ranges(DW_FORM_sec_offset 0x67) attribute, but range extraction failed (invalid range list offset 0x67), please file a bug and attach the file at the start of this error message
frame #1: 0x00005555555c39f8 sway`view_child_subsurface_create(child=0x00005555564a10d0, wlr_subsurface=0x0000555556586910) at view.c:985:2
   982 		}
   983 		subsurface->child.parent = child;
   984 		wl_list_insert(&child->children, &subsurface->child.link);
-> 985 		view_child_init(&subsurface->child, &subsurface_impl, child->view,
   986 			wlr_subsurface->surface);
   987 	
   988 		wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
(lldb) up
frame #2: 0x00005555555c3c2a sway`view_child_handle_surface_new_subsurface(listener=0x00005555564a1130, data=0x0000555556586910) at view.c:1031:2
   1028		struct sway_view_child *child =
   1029			wl_container_of(listener, child, surface_new_subsurface);
   1030		struct wlr_subsurface *subsurface = data;
-> 1031		view_child_subsurface_create(child, subsurface);
   1032	}
   1033	
   1034	static void view_child_handle_surface_destroy(struct wl_listener *listener,
(lldb) up
frame #3: 0x00007ffff78f4bfe libwlroots.so.10`wlr_signal_emit_safe(signal=0x00005555565b2470, data=0x0000555556586910) at signal.c:29:3
   26  			wl_list_remove(&cursor.link);
   27  			wl_list_insert(pos, &cursor.link);
   28  	
-> 29  			l->notify(l, data);
   30  		}
   31  	
   32  		wl_list_remove(&cursor.link);
(lldb) up
frame #4: 0x00007ffff78e5a41 libwlroots.so.10`subsurface_parent_commit(subsurface=0x0000555556586910) at wlr_surface.c:517:3
   514 	
   515 		if (!subsurface->added) {
   516 			subsurface->added = true;
-> 517 			wlr_signal_emit_safe(&subsurface->parent->events.new_subsurface,
   518 				subsurface);
   519 		}
   520 	}
(lldb) up
frame #5: 0x00007ffff78e56fa libwlroots.so.10`surface_commit_state(surface=0x00005555565b21b0, next=0x00005555565b2338) at wlr_surface.c:439:3
   436 			wl_list_insert(&surface->current.subsurfaces_above,
   437 				&subsurface->current.link);
   438 	
-> 439 			subsurface_parent_commit(subsurface);
   440 		}
   441 		wl_list_for_each_reverse(subsurface, &surface->pending.subsurfaces_below,
   442 				pending.link) {
(lldb) up
frame #6: 0x00007ffff78e5b88 libwlroots.so.10`surface_handle_commit(client=0x0000555556564c80, resource=0x0000555556599a20) at wlr_surface.c:555:3
   552 		if (surface->pending.cached_state_locks > 0 || !wl_list_empty(&surface->cached)) {
   553 			surface_cache_pending(surface);
   554 		} else {
-> 555 			surface_commit_state(surface, &surface->pending);
   556 		}
   557 	}
   558 	
(lldb) up
frame #7: 0x00007ffff7000d4a libffi.so.8`___lldb_unnamed_symbol118 + 82
libffi.so.8`___lldb_unnamed_symbol118:
->  0x7ffff7000d4a <+82>: leaq   0x18(%rbp), %rsp
    0x7ffff7000d4e <+86>: movq   (%rbp), %rcx
    0x7ffff7000d52 <+90>: movq   0x8(%rbp), %rdi
    0x7ffff7000d56 <+94>: movq   0x10(%rbp), %rbp
(lldb) up
frame #8: 0x00007ffff7000267 libffi.so.8`___lldb_unnamed_symbol115 + 439
libffi.so.8`___lldb_unnamed_symbol115:
->  0x7ffff7000267 <+439>: movq   -0x38(%rbp), %rax
    0x7ffff700026b <+443>: subq   %fs:0x28, %rax
    0x7ffff7000274 <+452>: jne    0x7ffff70004e7            ; <+1079>
    0x7ffff700027a <+458>: leaq   -0x28(%rbp), %rsp
(lldb) up
frame #9: 0x00007ffff795a173 libwayland-server.so.0`___lldb_unnamed_symbol271 + 371
libwayland-server.so.0`___lldb_unnamed_symbol271:
->  0x7ffff795a173 <+371>: movq   0x8(%r12), %rax
    0x7ffff795a178 <+376>: movq   0x8(%rax), %rdi
    0x7ffff795a17c <+380>: movl   (%r12), %eax
    0x7ffff795a180 <+384>: testl  %eax, %eax
(lldb) up
frame #10: 0x00007ffff795555c libwayland-server.so.0`___lldb_unnamed_symbol210 + 588
libwayland-server.so.0`___lldb_unnamed_symbol210:
->  0x7ffff795555c <+588>: jmp    0x7ffff7955435            ; <+293>
    0x7ffff7955561 <+593>: nopl   (%rax)
    0x7ffff7955568 <+600>: callq  *0xd76a(%rip)
    0x7ffff795556e <+606>: cmpl   $0xb, (%rax)
(lldb) up
frame #11: 0x00007ffff795804a libwayland-server.so.0`wl_event_loop_dispatch + 202
libwayland-server.so.0`wl_event_loop_dispatch:
->  0x7ffff795804a <+202>: addq   $0xc, %r15
    0x7ffff795804e <+206>: cmpq   %r15, %rbp
    0x7ffff7958051 <+209>: jne    0x7ffff7958038            ; <+184>
    0x7ffff7958053 <+211>: movq   0x8(%rsp), %rcx1
(lldb) up
frame #12: 0x00007ffff7955bc7 libwayland-server.so.0`wl_display_run + 39
libwayland-server.so.0`wl_display_run:
->  0x7ffff7955bc7 <+39>: movl   0x8(%rbx), %eax
    0x7ffff7955bca <+42>: testl  %eax, %eax
    0x7ffff7955bcc <+44>: jne    0x7ffff7955bb0            ; <+16>
    0x7ffff7955bce <+46>: popq   %rbx
(lldb) up
frame #13: 0x00005555555756eb sway`server_run(server=0x00005555555f0640) at server.c:296:2
   293 	void server_run(struct sway_server *server) {
   294 		sway_log(SWAY_INFO, "Running compositor on wayland display '%s'",
   295 				server->socket);
-> 296 		wl_display_run(server->wl_display);
   297 	}
(lldb) up
frame #14: 0x0000555555574947 sway`main(argc=1, argv=0x00007fffffffe8d8) at main.c:428:2
   425 			swaynag_show(&config->swaynag_config_errors);
   426 		}
   427 	
-> 428 		server_run(&server);
   429 	
   430 	shutdown:
   431 		sway_log(SWAY_INFO, "Shutting down sway");
(lldb) up
frame #15: 0x00007ffff761db25 libc.so.6`__libc_start_main + 213
libc.so.6`__libc_start_main:
->  0x7ffff761db25 <+213>: movl   %eax, %edi
    0x7ffff761db27 <+215>: callq  0x7ffff7635630            ; exit
    0x7ffff761db2c <+220>: movq   (%rsp), %rax
    0x7ffff761db30 <+224>: leaq   0x163929(%rip), %rdi
(lldb) up
frame #16: 0x00005555555656be sway`_start + 46
sway`_start:
->  0x5555555656be <+46>: hlt    
    0x5555555656bf:       nop    
sway`deregister_tm_clones:
    0x5555555656c0 <+0>:  leaq   0x8aeb9(%rip), %rdi       ; optind@GLIBC_2.2.5
    0x5555555656c7 <+7>:  leaq   0x8aeb2(%rip), %rax       ; optind@GLIBC_2.2.5

Signed-off-by: Alexander Orzechowski <orzechowski.alexander@gmail.com>
This commit is contained in:
Alexander Orzechowski 2021-12-13 03:02:00 -05:00 committed by Simon Ser
parent f7725011ef
commit 8a3026337f

View file

@ -1114,9 +1114,12 @@ void view_child_init(struct sway_view_child *child,
wl_signal_add(&view->events.unmap, &child->view_unmap);
child->view_unmap.notify = view_child_handle_view_unmap;
struct sway_workspace *workspace = child->view->container->pending.workspace;
if (workspace) {
wlr_surface_send_enter(child->surface, workspace->output->wlr_output);
struct sway_container *container = child->view->container;
if (container != NULL) {
struct sway_workspace *workspace = container->pending.workspace;
if (workspace) {
wlr_surface_send_enter(child->surface, workspace->output->wlr_output);
}
}
view_child_init_subsurfaces(child, surface);