Skip to content

Commit

Permalink
river-status: fix output status destruction
Browse files Browse the repository at this point in the history
There was a use-after-free if the Output was destroyed first, and the
memory of the output status was leaked.
  • Loading branch information
ifreund committed Aug 12, 2021
1 parent d4c249a commit 6e51a8f
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
10 changes: 8 additions & 2 deletions river/OutputStatus.zig
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,21 @@ 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(),
}
}

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.
Expand Down
2 changes: 2 additions & 0 deletions river/Root.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit 6e51a8f

Please sign in to comment.