diff options
author | Dominique Martinet <asmadeus@codewreck.org> | 2018-07-04 14:45:35 +0900 |
---|---|---|
committer | Dominique Martinet <asmadeus@codewreck.org> | 2018-07-04 18:47:11 +0900 |
commit | b0918b1058a704675fc2590ee9ff3bef6324f734 (patch) | |
tree | fdd2c89fe953f6414bbcf289eb0e39b7289cd030 /sway/ipc-server.c | |
parent | Merge pull request #2202 from RyanDwyer/fix-focus-damage (diff) | |
download | sway-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.c | 34 |
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; | |||
31 | static struct wl_event_source *ipc_event_source = NULL; | 31 | static struct wl_event_source *ipc_event_source = NULL; |
32 | static struct sockaddr_un *ipc_sockaddr = NULL; | 32 | static struct sockaddr_un *ipc_sockaddr = NULL; |
33 | static list_t *ipc_client_list = NULL; | 33 | static list_t *ipc_client_list = NULL; |
34 | static struct wl_listener ipc_display_destroy; | ||
34 | 35 | ||
35 | static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'}; | 36 | static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'}; |
36 | 37 | ||
@@ -56,6 +57,22 @@ void ipc_client_disconnect(struct ipc_client *client); | |||
56 | void ipc_client_handle_command(struct ipc_client *client); | 57 | void ipc_client_handle_command(struct ipc_client *client); |
57 | bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length); | 58 | bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length); |
58 | 59 | ||
60 | static 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 | |||
59 | void ipc_init(struct sway_server *server) { | 76 | void 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 | ||
92 | void 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 | |||
106 | struct sockaddr_un *ipc_user_sockaddr(void) { | 112 | struct 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) { |