aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2020-05-13 21:12:53 -0400
committerLibravatar Tudor Brindus <me@tbrindus.ca>2020-05-14 23:51:17 -0400
commit975b8a90ad9a35b5c4a874ff1e83927b09ffd3fa (patch)
treec91fece3ec16a7056875eafc79c74db705d3f7db
parentsecurity.d: remove directory (diff)
downloadsway-975b8a90ad9a35b5c4a874ff1e83927b09ffd3fa.tar.gz
sway-975b8a90ad9a35b5c4a874ff1e83927b09ffd3fa.tar.zst
sway-975b8a90ad9a35b5c4a874ff1e83927b09ffd3fa.zip
input: reset keyboard groups keyboard on reset all
If the keyboard that triggers the reload binding is using the default keymap, default repeat delay, and default repeat rate, the associated keyboard group is never being destroyed on reload. This was causing the keyboard group's keyboard not to get disarmed and result in a use-after-free in handle_keyboard_repeat. If the keyboard was not using the defaults for all three settings, then it's associated keyboard would get destroyed during the reset - which did disarm the keyboard group's keyboard. In this case, the use-after-free would not occur. This adds a block to input_manager_reset_all_inputs that resets the keyboard for all keyboard groups in all seats, which will disarm them. Since the inputs are all being reset anyway, which will reset all individual keyboards, it is not necessary to be selective on which ones get reset.
-rw-r--r--sway/input/input-manager.c18
-rw-r--r--sway/input/seat.c15
2 files changed, 30 insertions, 3 deletions
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index dc07cbf0..c576a593 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -4,15 +4,17 @@
4#include <string.h> 4#include <string.h>
5#include <math.h> 5#include <math.h>
6#include <wlr/backend/libinput.h> 6#include <wlr/backend/libinput.h>
7#include <wlr/types/wlr_cursor.h>
8#include <wlr/types/wlr_keyboard_group.h>
7#include <wlr/types/wlr_input_inhibitor.h> 9#include <wlr/types/wlr_input_inhibitor.h>
8#include <wlr/types/wlr_virtual_keyboard_v1.h> 10#include <wlr/types/wlr_virtual_keyboard_v1.h>
9#include <wlr/types/wlr_virtual_pointer_v1.h> 11#include <wlr/types/wlr_virtual_pointer_v1.h>
10#include <wlr/types/wlr_cursor.h>
11#include "sway/config.h" 12#include "sway/config.h"
13#include "sway/input/cursor.h"
12#include "sway/input/input-manager.h" 14#include "sway/input/input-manager.h"
15#include "sway/input/keyboard.h"
13#include "sway/input/libinput.h" 16#include "sway/input/libinput.h"
14#include "sway/input/seat.h" 17#include "sway/input/seat.h"
15#include "sway/input/cursor.h"
16#include "sway/ipc-server.h" 18#include "sway/ipc-server.h"
17#include "sway/server.h" 19#include "sway/server.h"
18#include "sway/tree/view.h" 20#include "sway/tree/view.h"
@@ -553,6 +555,18 @@ void input_manager_reset_all_inputs() {
553 wl_list_for_each(input_device, &server.input->devices, link) { 555 wl_list_for_each(input_device, &server.input->devices, link) {
554 input_manager_reset_input(input_device); 556 input_manager_reset_input(input_device);
555 } 557 }
558
559 // If there is at least one keyboard using the default keymap, repeat delay,
560 // and repeat rate, then it is possible that there is a keyboard group that
561 // needs to be reset. This will disarm the keyboards as well as exit and
562 // re-enter any focus views.
563 struct sway_seat *seat;
564 wl_list_for_each(seat, &server.input->seats, link) {
565 struct sway_keyboard_group *group;
566 wl_list_for_each(group, &seat->keyboard_groups, link) {
567 seat_reset_device(seat, group->seat_device->input_device);
568 }
569 }
556} 570}
557 571
558 572
diff --git a/sway/input/seat.c b/sway/input/seat.c
index a4e06c57..1d45b256 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -7,6 +7,7 @@
7#include <wlr/types/wlr_cursor.h> 7#include <wlr/types/wlr_cursor.h>
8#include <wlr/types/wlr_data_device.h> 8#include <wlr/types/wlr_data_device.h>
9#include <wlr/types/wlr_idle.h> 9#include <wlr/types/wlr_idle.h>
10#include <wlr/types/wlr_keyboard_group.h>
10#include <wlr/types/wlr_output_layout.h> 11#include <wlr/types/wlr_output_layout.h>
11#include <wlr/types/wlr_primary_selection.h> 12#include <wlr/types/wlr_primary_selection.h>
12#include <wlr/types/wlr_tablet_v2.h> 13#include <wlr/types/wlr_tablet_v2.h>
@@ -691,7 +692,12 @@ static void seat_configure_keyboard(struct sway_seat *seat,
691 if (!seat_device->keyboard) { 692 if (!seat_device->keyboard) {
692 sway_keyboard_create(seat, seat_device); 693 sway_keyboard_create(seat, seat_device);
693 } 694 }
694 sway_keyboard_configure(seat_device->keyboard); 695 if (!wlr_keyboard_group_from_wlr_keyboard(
696 seat_device->input_device->wlr_device->keyboard)) {
697 // Do not configure keyboard group keyboards. They will be configured
698 // based on the keyboards in the group.
699 sway_keyboard_configure(seat_device->keyboard);
700 }
695 wlr_seat_set_keyboard(seat->wlr_seat, 701 wlr_seat_set_keyboard(seat->wlr_seat,
696 seat_device->input_device->wlr_device); 702 seat_device->input_device->wlr_device);
697 struct sway_node *focus = seat_get_focus(seat); 703 struct sway_node *focus = seat_get_focus(seat);
@@ -746,6 +752,13 @@ static struct sway_seat_device *seat_get_device(struct sway_seat *seat,
746 } 752 }
747 } 753 }
748 754
755 struct sway_keyboard_group *group = NULL;
756 wl_list_for_each(group, &seat->keyboard_groups, link) {
757 if (group->seat_device->input_device == input_device) {
758 return group->seat_device;
759 }
760 }
761
749 return NULL; 762 return NULL;
750} 763}
751 764