aboutsummaryrefslogtreecommitdiffstats
path: root/sway/ipc-server.c
diff options
context:
space:
mode:
authorLibravatar Dominique Martinet <asmadeus@codewreck.org>2018-07-04 14:45:35 +0900
committerLibravatar Dominique Martinet <asmadeus@codewreck.org>2018-07-04 18:47:11 +0900
commitb0918b1058a704675fc2590ee9ff3bef6324f734 (patch)
treefdd2c89fe953f6414bbcf289eb0e39b7289cd030 /sway/ipc-server.c
parentMerge pull request #2202 from RyanDwyer/fix-focus-damage (diff)
downloadsway-b0918b1058a704675fc2590ee9ff3bef6324f734.tar.gz
sway-b0918b1058a704675fc2590ee9ff3bef6324f734.tar.zst
sway-b0918b1058a704675fc2590ee9ff3bef6324f734.zip
ipc-server: add display destroy listener and remove ipc_terminate
wl_event_source_remove() is illegal after display has been destroyed, so just destroy everything when we still can. ==20392==ERROR: AddressSanitizer: heap-use-after-free on address 0x607000001240 at pc 0x00000048e86e bp 0x7ffe4b557e00 sp 0x7ffe4b557df0 READ of size 8 at 0x607000001240 thread T0 #0 0x48e86d in wl_list_insert ../common/list.c:149 #1 0x7fdf673d4d7d in wl_event_source_remove src/event-loop.c:487 #2 0x41b742 in ipc_terminate ../sway/ipc-server.c:94 #3 0x40b1ad in main ../sway/main.c:440 #4 0x7fdf6664c18a in __libc_start_main ../csu/libc-start.c:308 #5 0x409359 in _start (/opt/wayland/bin/sway+0x409359) 0x607000001240 is located 48 bytes inside of 72-byte region [0x607000001210,0x607000001258) freed by thread T0 here: #0 0x7fdf692c4880 in __interceptor_free (/lib64/libasan.so.5+0xee880) #1 0x7fdf673d371a in wl_display_destroy src/wayland-server.c:1097 previously allocated by thread T0 here: #0 0x7fdf692c4c48 in malloc (/lib64/libasan.so.5+0xeec48) #1 0x7fdf673d4d9e in wl_event_loop_create src/event-loop.c:522 #2 0x40acb2 in main ../sway/main.c:363 #3 0x7fdf6664c18a in __libc_start_main ../csu/libc-start.c:308
Diffstat (limited to 'sway/ipc-server.c')
-rw-r--r--sway/ipc-server.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index 3e510c2e..abc2d7cb 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -31,6 +31,7 @@ static int ipc_socket = -1;
31static struct wl_event_source *ipc_event_source = NULL; 31static struct wl_event_source *ipc_event_source = NULL;
32static struct sockaddr_un *ipc_sockaddr = NULL; 32static struct sockaddr_un *ipc_sockaddr = NULL;
33static list_t *ipc_client_list = NULL; 33static list_t *ipc_client_list = NULL;
34static struct wl_listener ipc_display_destroy;
34 35
35static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'}; 36static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'};
36 37
@@ -56,6 +57,22 @@ void ipc_client_disconnect(struct ipc_client *client);
56void ipc_client_handle_command(struct ipc_client *client); 57void ipc_client_handle_command(struct ipc_client *client);
57bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length); 58bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length);
58 59
60static void handle_display_destroy(struct wl_listener *listener, void *data) {
61 if (ipc_event_source) {
62 wl_event_source_remove(ipc_event_source);
63 }
64 close(ipc_socket);
65 unlink(ipc_sockaddr->sun_path);
66
67 list_free(ipc_client_list);
68
69 if (ipc_sockaddr) {
70 free(ipc_sockaddr);
71 }
72
73 wl_list_remove(&ipc_display_destroy.link);
74}
75
59void ipc_init(struct sway_server *server) { 76void ipc_init(struct sway_server *server) {
60 ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); 77 ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
61 if (ipc_socket == -1) { 78 if (ipc_socket == -1) {
@@ -85,24 +102,13 @@ void ipc_init(struct sway_server *server) {
85 102
86 ipc_client_list = create_list(); 103 ipc_client_list = create_list();
87 104
105 ipc_display_destroy.notify = handle_display_destroy;
106 wl_display_add_destroy_listener(server->wl_display, &ipc_display_destroy);
107
88 ipc_event_source = wl_event_loop_add_fd(server->wl_event_loop, ipc_socket, 108 ipc_event_source = wl_event_loop_add_fd(server->wl_event_loop, ipc_socket,
89 WL_EVENT_READABLE, ipc_handle_connection, server); 109 WL_EVENT_READABLE, ipc_handle_connection, server);
90} 110}
91 111
92void ipc_terminate(void) {
93 if (ipc_event_source) {
94 wl_event_source_remove(ipc_event_source);
95 }
96 close(ipc_socket);
97 unlink(ipc_sockaddr->sun_path);
98
99 list_free(ipc_client_list);
100
101 if (ipc_sockaddr) {
102 free(ipc_sockaddr);
103 }
104}
105
106struct sockaddr_un *ipc_user_sockaddr(void) { 112struct sockaddr_un *ipc_user_sockaddr(void) {
107 struct sockaddr_un *ipc_sockaddr = malloc(sizeof(struct sockaddr_un)); 113 struct sockaddr_un *ipc_sockaddr = malloc(sizeof(struct sockaddr_un));
108 if (ipc_sockaddr == NULL) { 114 if (ipc_sockaddr == NULL) {