From a863107e78dee23e7c34cb9c46e1d9c061ca9bae Mon Sep 17 00:00:00 2001 From: Cagebreak Signing Key 3 Date: Sat, 10 Oct 2020 13:44:58 +0200 Subject: [PATCH] Release 1.4.3 - Fix Issue 17 - Fix Issue 18 - Fix Issue 19 - Fix Issue 20 --- Bugs.md | 34 ++++++++++++++++++++++++++++++++++ README.md | 5 +++++ man/cagebreak-config.5.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 2 +- output.c | 26 ++++++++++++++++---------- output.h | 1 + seat.c | 3 +-- signatures/1.4.2.sig | Bin 0 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes view.c | 37 ++++++++++++++++++++----------------- view.h | 5 +++-- xdg_shell.c | 21 +++++++++------------ xwayland.c | 23 +++++++++-------------- 14 files changed, 101 insertions(+), 60 deletions(-) create mode 100644 signatures/1.4.2.sig diff --git a/Bugs.md b/Bugs.md index 08e2d93..6080e81 100644 --- a/Bugs.md +++ b/Bugs.md @@ -224,3 +224,37 @@ Steps to reproduce: Cagebreak up to and including release 1.4.1 has a difficult-to-reproduce use-after-free bug, which can sometimes trigger crashes when popups are closed. +### Issue 17 + + * github issue number: N/A + * Fixed: 1.4.3 + +Cagebreak up to and including version 1.4.2 might have a use-after-free +on destroying unmapped views. view->workspace was set on view creation. +If the output containing this view was subsequently destroyed, the workspace +was freed, leading to a use-after-free when the view was destroyed. + +### Issue 18 + + * github issue number: N/A + * Fixed: 1.4.3 + +Cagebreak up to and including release 1.4.2 does not handle the position of +xwayland views adequately. + +### Issue 19 + + * github issue number: N/A + * Fixed: 1.4.3 + +Cagebreak up to and including release 1.4.2 does not handle unmanaged views +adequately. + +### Issue 20 + + * github issue number: N/A + * Fixed: 1.4.3 + +Cagebreak up to and including release 1.4.2 does not handle damaging adequately, +when scanning out views. + diff --git a/README.md b/README.md index 5046f2f..7a5b484 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,11 @@ ninja -C build For every release after 1.0.5, hashes will be provided. +1.4.3 + + * sha 256: 5e29cbaf7c0c5ca74f71a5605bb3d6e302e051798401fee9a79419720b8d8e95 + * sha 512: 8004865f8603648d9ac9bb700f3ee040e6516c222ad3d783b34219c8fa3a7bdbba6abb74fe92c4d0bd4dbbce0ec4d08be12297a8bad5032baeb589eec557e24e + 1.4.2 * sha 256: 27efb9328cf9cab1f81e66627696baf8c7cc2c372339a2890f955b40f3a7c396 diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index 5198daa..b6fbdbc 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -% CAGEBREAK-CONFIG(1) Version 1.4.2 | Cagebreak Manual +% CAGEBREAK-CONFIG(1) Version 1.4.3 | Cagebreak Manual # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index f140cc8..f00fe65 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -% CAGEBREAK(1) Version 1.4.2 | Cagebreak Manual +% CAGEBREAK(1) Version 1.4.3 | Cagebreak Manual # NAME diff --git a/meson.build b/meson.build index a87fae7..ea77b3a 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cagebreak', 'c', - version: '1.4.2', + version: '1.4.3', license: 'MIT', default_options: [ 'c_std=c11', diff --git a/output.c b/output.c index a330354..a38d65f 100644 --- a/output.c +++ b/output.c @@ -226,7 +226,8 @@ scan_out_primary_view(struct cg_output *output) { } } - struct cg_view *view = seat_get_focus(server->seat); + struct cg_view *view = + output->workspaces[output->curr_workspace]->focused_tile->view; if(view == NULL || view->wlr_surface == NULL) { return false; } @@ -312,20 +313,24 @@ handle_output_damage_frame(struct wl_listener *listener, void *data) { return; } - /* Check if we can scan-out the primary view. */ - static bool last_scanned_out = false; bool scanned_out = scan_out_primary_view(output); - if(scanned_out && !last_scanned_out) { + if(scanned_out && !output->last_scanned_out_view) { wlr_log(WLR_DEBUG, "Scanning out primary view"); } - if(last_scanned_out && !scanned_out) { + if(output->last_scanned_out_view && !scanned_out) { wlr_log(WLR_DEBUG, "Stopping primary view scan out"); - if(seat_get_focus(output->server->seat) != NULL) { - view_damage_whole(seat_get_focus(output->server->seat)); - } + wlr_output_damage_add_whole(output->damage); + output->last_scanned_out_view = NULL; + } + if(output->last_scanned_out_view && + output->last_scanned_out_view != seat_get_focus(output->server->seat)) { + wlr_output_damage_add_whole(output->damage); + } + if(scanned_out) { + output->last_scanned_out_view = + output->workspaces[output->curr_workspace]->focused_tile->view; } - last_scanned_out = scanned_out; if(scanned_out) { goto frame_done; @@ -436,7 +441,7 @@ output_destroy(struct cg_output *output) { wl_list_insert( &server->curr_output ->workspaces[server->curr_output->curr_workspace] - ->views, + ->unmanaged_views, &view->link); view->workspace = server->curr_output @@ -563,6 +568,7 @@ handle_new_output(struct wl_listener *listener, void *data) { output->wlr_output = wlr_output; output->server = server; output->damage = wlr_output_damage_create(wlr_output); + output->last_scanned_out_view = NULL; wl_list_insert(&server->outputs, &output->link); output->mode.notify = handle_output_mode; diff --git a/output.h b/output.h index bf9abb4..b114176 100644 --- a/output.h +++ b/output.h @@ -23,6 +23,7 @@ struct cg_output { struct cg_workspace **workspaces; struct wl_list messages; int curr_workspace; + struct cg_view *last_scanned_out_view; struct wl_list link; // cg_server::outputs }; diff --git a/seat.c b/seat.c index 9c7739a..13ef04e 100644 --- a/seat.c +++ b/seat.c @@ -53,8 +53,7 @@ static bool view_at(const struct cg_view *view, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { struct wlr_box *output_layout_box = wlr_output_layout_get_box( - view->workspace->output->server->output_layout, - view->workspace->output->wlr_output); + view->server->output_layout, view->workspace->output->wlr_output); double view_sx = lx - view->ox - output_layout_box->x; double view_sy = ly - view->oy - output_layout_box->y; diff --git a/signatures/1.4.2.sig b/signatures/1.4.2.sig new file mode 100644 index 0000000000000000000000000000000000000000..af4b2f1de0ed95389b364f13aa922b2757d09c9f GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+6HLHmt3S1SZD7Rm95KPD1rPrth0$*nq{{RXJ5Ofes z$K0jYsM-7v|5hnG4y+Bk9L`j8X3yMje8rWw?`oWm^A^aG&MSL{TYibi5 zaHL!>ui~gG%z76mOT_k70)0$HsG~eQ@KH`#a&QOP0Qilo@XndwS$#fg#%=}WHSHLu zzrzW$a(1YKY+5P&Y@+2fd?sKTmzF5Ecf9fHyMW7^_K2A6Ql8pnk!th{J12o@#8lqR zAvqk!!UC9!v?TI)oasx?wz(Tnt#y@?^Lx~k!x;WzpHe^3 zB&a>E(vYV~XCdpgn{^!NwS|>dAcs_pTygGQxS|2O<6?^J$gCa(7Q6K#y71rQ4U}sN zY)c8w!+SbC3ag2=qhDIY$+yNw#3ehVmZ^(iX$3DjTwAiyZl|M$+^KYy%gnZuBz=pn zvo|TBetgh?J|8NDJuB(etu9x_g-o85+Ax$U@A)B+Ue;20g8_=nz;W;j{_)aHvSSiq Eig{%a{Qv*} literal 0 HcmV?d00001 diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index af4b2f1de0ed95389b364f13aa922b2757d09c9f..e37900ae5112e1a847f09b2ebb0e6510976205e1 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY%OM1po>O5Ofes$K0jYsEa5M|4S<4>Nsp7chrSk^nD2_U@uRk zQNx1>=vLoe<9Zg}=*ENj-4!7Bz!paGe6(KE^paDYcA$QlsSD1re4S`Qjyk&4bY{dg z%XPEH&jD?y2|}H|vD69c8R66N)s1$!38gKvI29ExS(yx#hZ$t)<=<6xiB znD>7lzR`n!845o__I|0(jM^p9>@6{&@Z%YwP1x*7n>2a{YkmmZ)Bot2Un zy44@WV#BG00fuzq?WDKtU{q-cbG$loaZ7pfJulu@J26ME&xFPEeCF$9Q=)AFdfo%` z$$*NOMuA=~`G1V{3=)3;ZSzCqg;omRK6A^ zApJ7SDkc0 z-(j&u%c gPaDSy))yFO2F(j+Bk9L`j8X z3yMje8rWw?`oWm^A^aG&MSL{TYibi5aHL!>ui~gG%z76mOT_k70)0$HsG~eQ@KH`# za&QOP0Qilo@XndwS$#fg#%=}WHSHLuzrzW$a(1YKY+5P&Y=5HVG<+st8kd$Rw|Bhp z>bro;oA!v9?NXlFWsz$13p*!)X~b0C%^^7)$HD@bi?k&2c%11=&$hW6P~}j3MBaK6 z;`!$9VHSUkWho@tS2FN@E2Gwlr_surface == NULL) { + return; + } #if CG_HAS_XWAYLAND if((view->type != CG_XWAYLAND_VIEW || xwayland_view_should_manage(view))) #endif @@ -290,14 +294,13 @@ view_unmap(struct cg_view *view) { struct cg_view *prev = view_get_prev_view(view); wlr_output_damage_add_box(view_tile->workspace->output->damage, &view_tile->tile); - if(view == view->workspace->server->seat->focused_view) { - seat_set_focus(view->workspace->server->seat, prev); - } else if(view->workspace->server->seat->seat->keyboard_state + if(view == view->server->seat->focused_view) { + seat_set_focus(view->server->seat, prev); + } else if(view->server->seat->seat->keyboard_state .focused_surface == view->wlr_surface) { - wlr_seat_keyboard_clear_focus( - view->workspace->server->seat->seat); - seat_set_focus(view->workspace->server->seat, - view->workspace->server->seat->focused_view); + wlr_seat_keyboard_clear_focus(view->server->seat->seat); + seat_set_focus(view->server->seat, + view->server->seat->focused_view); } else { view_tile->view = prev; if(prev != NULL) { @@ -309,12 +312,11 @@ view_unmap(struct cg_view *view) { #if CG_HAS_XWAYLAND else { view_damage_whole(view); - if(view->workspace->server->seat->seat->keyboard_state - .focused_surface == NULL || - view->workspace->server->seat->seat->keyboard_state - .focused_surface == view->wlr_surface) { - seat_set_focus(view->workspace->server->seat, - view->workspace->server->seat->focused_view); + if(view->server->seat->seat->keyboard_state.focused_surface == NULL || + view->server->seat->seat->keyboard_state.focused_surface == + view->wlr_surface) { + seat_set_focus(view->server->seat, + view->server->seat->focused_view); } } #endif @@ -363,7 +365,7 @@ view_map(struct cg_view *view, struct wlr_surface *surface, void view_destroy(struct cg_view *view) { - struct cg_output *curr_output = view->workspace->server->curr_output; + struct cg_output *curr_output = view->server->curr_output; if(view->wlr_surface != NULL) { view_unmap(view); } @@ -375,9 +377,10 @@ view_destroy(struct cg_view *view) { } void -view_init(struct cg_view *view, struct cg_workspace *ws, enum cg_view_type type, - const struct cg_view_impl *impl) { - view->workspace = ws; +view_init(struct cg_view *view, enum cg_view_type type, + const struct cg_view_impl *impl, struct cg_server *server) { + view->workspace = NULL; + view->server = server; view->type = type; view->impl = impl; diff --git a/view.h b/view.h index 251c00f..65958b0 100644 --- a/view.h +++ b/view.h @@ -19,6 +19,7 @@ enum cg_view_type { struct cg_view { struct cg_workspace *workspace; + struct cg_server *server; struct wl_list link; // server::views struct wl_list children; // cg_view_child::link struct wlr_surface *wlr_surface; @@ -106,8 +107,8 @@ view_map(struct cg_view *view, struct wlr_surface *surface, void view_destroy(struct cg_view *view); void -view_init(struct cg_view *view, struct cg_workspace *ws, enum cg_view_type type, - const struct cg_view_impl *impl); +view_init(struct cg_view *view, enum cg_view_type type, + const struct cg_view_impl *impl, struct cg_server *server); struct wlr_surface * view_wlr_surface_at(const struct cg_view *view, double sx, double sy, diff --git a/xdg_shell.c b/xdg_shell.c index 6a65e01..35c170c 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -102,8 +102,7 @@ popup_unconstrain(struct cg_xdg_popup *popup) { struct cg_view *view = popup->view_child.view; struct wlr_box *popup_box = &popup->wlr_popup->geometry; - struct wlr_output_layout *output_layout = - view->workspace->output->server->output_layout; + struct wlr_output_layout *output_layout = view->server->output_layout; struct wlr_box *view_output_box = wlr_output_layout_get_box( output_layout, view->workspace->output->wlr_output); struct wlr_output *wlr_output = wlr_output_layout_output_at( @@ -297,11 +296,13 @@ handle_xdg_shell_surface_map(struct wl_listener *listener, void *_data) { xdg_shell_view->commit.notify = handle_xdg_shell_surface_commit; wl_signal_add(&xdg_shell_view->xdg_surface->surface->events.commit, &xdg_shell_view->commit); + xdg_shell_view->new_popup.notify = handle_new_xdg_popup; + wl_signal_add(&xdg_shell_view->xdg_surface->events.new_popup, + &xdg_shell_view->new_popup); - view_map( - view, xdg_shell_view->xdg_surface->surface, - view->workspace->server->curr_output - ->workspaces[view->workspace->server->curr_output->curr_workspace]); + view_map(view, xdg_shell_view->xdg_surface->surface, + view->server->curr_output + ->workspaces[view->server->curr_output->curr_workspace]); view_damage_whole(view); } @@ -350,10 +351,8 @@ handle_xdg_shell_surface_new(struct wl_listener *listener, void *data) { wlr_log(WLR_ERROR, "Failed to allocate XDG Shell view"); return; } - view_init( - &xdg_shell_view->view, - server->curr_output->workspaces[server->curr_output->curr_workspace], - CG_XDG_SHELL_VIEW, &xdg_shell_view_impl); + view_init(&xdg_shell_view->view, CG_XDG_SHELL_VIEW, &xdg_shell_view_impl, + server); xdg_shell_view->xdg_surface = xdg_surface; @@ -367,8 +366,6 @@ handle_xdg_shell_surface_new(struct wl_listener *listener, void *data) { handle_xdg_shell_surface_request_fullscreen; wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &xdg_shell_view->request_fullscreen); - xdg_shell_view->new_popup.notify = handle_new_xdg_popup; - wl_signal_add(&xdg_surface->events.new_popup, &xdg_shell_view->new_popup); } void diff --git a/xwayland.c b/xwayland.c index 4a19daf..e5f505b 100644 --- a/xwayland.c +++ b/xwayland.c @@ -82,9 +82,8 @@ maximize(struct cg_view *view, int width, int height) { struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view); struct cg_output *output = view->workspace->output; - struct wlr_box *box = - wlr_output_layout_get_box(view->workspace->server->output_layout, - view->workspace->output->wlr_output); + struct wlr_box *box = wlr_output_layout_get_box( + view->server->output_layout, view->workspace->output->wlr_output); struct wlr_xwayland_surface_size_hints *hints = xwayland_view->xwayland_surface->size_hints; @@ -108,9 +107,8 @@ maximize(struct cg_view *view, int width, int height) { } } - wlr_xwayland_surface_configure(xwayland_view->xwayland_surface, - view->ox + box->x, view->oy + box->y, width, - height); + wlr_xwayland_surface_configure(xwayland_view->xwayland_surface, view->ox, + view->oy, width, height); wlr_xwayland_surface_set_maximized(xwayland_view->xwayland_surface, true); } @@ -188,10 +186,9 @@ handle_xwayland_surface_map(struct wl_listener *listener, void *_data) { wl_signal_add(&xwayland_view->xwayland_surface->surface->events.commit, &xwayland_view->commit); - view_map( - view, xwayland_view->xwayland_surface->surface, - view->workspace->server->curr_output - ->workspaces[view->workspace->server->curr_output->curr_workspace]); + view_map(view, xwayland_view->xwayland_surface->surface, + view->server->curr_output + ->workspaces[view->server->curr_output->curr_workspace]); view_damage_whole(view); } @@ -238,10 +235,8 @@ handle_xwayland_surface_new(struct wl_listener *listener, void *data) { return; } - view_init( - &xwayland_view->view, - server->curr_output->workspaces[server->curr_output->curr_workspace], - CG_XWAYLAND_VIEW, &xwayland_view_impl); + view_init(&xwayland_view->view, CG_XWAYLAND_VIEW, &xwayland_view_impl, + server); xwayland_view->xwayland_surface = xwayland_surface; xwayland_view->map.notify = handle_xwayland_surface_map;