diff options
| author | Isaac Freund <ifreund@ifreund.xyz> | 2021-08-12 22:38:08 +0200 |
|---|---|---|
| committer | Isaac Freund <ifreund@ifreund.xyz> | 2021-08-12 22:38:08 +0200 |
| commit | 6e51a8fcdda64fd1c2d34b969c0758c82895b9a5 (patch) | |
| tree | ee473db9d5feabe5b8066176a2198624fc6a0f61 | |
| parent | d4c249a5cb92dcb188b6c4ba806cc261b1705a80 (diff) | |
| download | river-6e51a8fcdda64fd1c2d34b969c0758c82895b9a5.tar.gz river-6e51a8fcdda64fd1c2d34b969c0758c82895b9a5.tar.xz | |
river-status: fix output status destruction
There was a use-after-free if the Output was destroyed first, and the
memory of the output status was leaked.
| -rw-r--r-- | river/OutputStatus.zig | 10 | ||||
| -rw-r--r-- | river/Root.zig | 2 |
2 files changed, 10 insertions, 2 deletions
diff --git a/river/OutputStatus.zig b/river/OutputStatus.zig index e6e6045..2000126 100644 --- a/river/OutputStatus.zig +++ b/river/OutputStatus.zig @@ -43,6 +43,13 @@ pub fn init(self: *Self, output: *Output, output_status: *zriver.OutputStatusV1) self.sendFocusedTags(output.current.tags); } +pub fn destroy(self: *Self) void { + const node = @fieldParentPtr(std.SinglyLinkedList(Self).Node, "data", self); + self.output.status_trackers.remove(node); + self.output_status.setHandler(*Self, handleRequest, null, self); + util.gpa.destroy(node); +} + fn handleRequest(output_status: *zriver.OutputStatusV1, request: zriver.OutputStatusV1.Request, self: *Self) void { switch (request) { .destroy => output_status.destroy(), @@ -50,8 +57,7 @@ fn handleRequest(output_status: *zriver.OutputStatusV1, request: zriver.OutputSt } fn handleDestroy(output_status: *zriver.OutputStatusV1, self: *Self) void { - const node = @fieldParentPtr(std.SinglyLinkedList(Self).Node, "data", self); - self.output.status_trackers.remove(node); + self.destroy(); } /// Send the current tags of each view on the output to the client. diff --git a/river/Root.zig b/river/Root.zig index 33792d8..3af4ec1 100644 --- a/river/Root.zig +++ b/river/Root.zig @@ -203,6 +203,8 @@ pub fn removeOutput(self: *Self, output: *Output) void { // Destroy all layouts of the output while (output.layouts.first) |layout_node| layout_node.data.destroy(); + while (output.status_trackers.first) |status_node| status_node.data.destroy(); + // Arrange the root in case evacuated views affect the layout fallback_output.arrangeViews(); self.startTransaction(); |
