From patchwork Sun Aug 4 17:28:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bogdan Harjoc X-Patchwork-Id: 33957 Received: (qmail 81325 invoked by alias); 4 Aug 2019 17:28:17 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 81317 invoked by uid 89); 4 Aug 2019 17:28:16 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.1 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=HX-Received:a81, H*RU:sk:mail-yw, Patch, HX-Spam-Relays-External:sk:mail-yw X-HELO: mail-yw1-f53.google.com Received: from mail-yw1-f53.google.com (HELO mail-yw1-f53.google.com) (209.85.161.53) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 04 Aug 2019 17:28:15 +0000 Received: by mail-yw1-f53.google.com with SMTP id z197so28787649ywd.13 for ; Sun, 04 Aug 2019 10:28:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=StYmz2G2f7uy8SgEYp7H4R+jxYOQqAbHkLyb0HS5wQg=; b=SeHpmsxV/0qsfOX4yE6GXnxN1DoSZXWa6h7X+BZMWJE80nwPQd4zYjiCK5rZh/Pokp WimQGbFc/3jDg02Wb7atLEecnhec4myldw5iBvrTLkv09HeEJdpOgZIWVFzZN5oyXbm0 QhZo69YqLkkhVllZ6KtG8yx2k4yDvln/1FlM4mwBlfLt1vYPgC4UcKVEAJCZgQ1EkbkN LhuAmYdq0rPqa84FuJq65zKp+TLLTfA+OvzA4BNqDTVRRno9tElIuWGJzuCCxCCp2Mly 0bZsGv2T4umY01g29QyE4hwzMW28UQY6iewrhuJpFl1GudpeTYQ8iuQRS3QsYbXv4sSr dj3g== MIME-Version: 1.0 From: Bogdan Harjoc Date: Sun, 4 Aug 2019 20:28:02 +0300 Message-ID: Subject: [PATCH] Fix double free in tui_source_element To: gdb-patches@sourceware.org X-IsSubscribed: yes To reproduce, cycle a few times between these layouts: no tui, tui one-window, tui two-windows (including some layout that shows disassembly). tui_set_source_content() expands win_info->content, and has to move tui_source_element items to the new vector storage, destroying the items in the old storage, and ~tui_source_element() calls xfree on 'line'. Due to a missing copy ctor, items in the new storage have the old 'line' pointer which eventually gets freed again. Patch is attached, I added DISABLE_COPY_AND_ASSIGN() in a few more tui classes to check for more similar issues. Valgrind output: ==27971== Invalid free() / delete / delete[] / realloc() void xfree(char*) (common-utils.h:60) tui_set_source_content(...) (tui-source.c:198) tui_update_source_window_as_is(...) (tui-winsource.c:95) tui_show_symtab_source(...) (tui-source.c:221) tui_update_source_windows_with_addr(...) (tui-winsource.c:152) tui_set_layout(tui_layout_type) (tui-layout.c:198) ==27971== Address 0x... is 0 bytes inside a block of size 63 free'd void xfree (common-utils.h:60) tui_source_element::~tui_source_element() (tui-data.h:184) void std::_Destroy::_M_default_append(...) std::vector::resize(...) (stl_vector.h:692) tui_alloc_source_buffer(...) (tui-winsource.c:693) tui_set_source_content(...) (tui-source.c:138) diff --git a/gdb/tui/tui-data.h b/gdb/tui/tui-data.h index 214f728bef..71c1854a8f 100644 --- a/gdb/tui/tui-data.h +++ b/gdb/tui/tui-data.h @@ -39,6 +39,8 @@ struct tui_point /* Generic window information. */ struct tui_gen_win_info { + DISABLE_COPY_AND_ASSIGN(tui_gen_win_info); + protected: explicit tui_gen_win_info (enum tui_win_type t) @@ -183,6 +185,19 @@ struct tui_source_element xfree (line); } + tui_source_element (tui_source_element && o): + line(o.line), + line_or_addr(o.line_or_addr), + is_exec_point(o.is_exec_point), + break_mode(o.break_mode) + { + o.line = nullptr; + } + + tui_source_element (const tui_source_element & o) = delete; + tui_source_element & operator=(tui_source_element && o) = delete; + tui_source_element & operator=(const tui_source_element & o) = delete; + char *line = nullptr; struct tui_line_or_address line_or_addr; bool is_exec_point = false; @@ -208,6 +223,8 @@ typedef char tui_exec_info_content[TUI_EXECINFO_SIZE]; struct tui_locator_window : public tui_gen_win_info { + DISABLE_COPY_AND_ASSIGN(tui_locator_window); + tui_locator_window () : tui_gen_win_info (LOCATOR_WIN) { diff --git a/gdb/tui/tui-file.h b/gdb/tui/tui-file.h index 44d66b56d8..2d86a8454c 100644 --- a/gdb/tui/tui-file.h +++ b/gdb/tui/tui-file.h @@ -25,6 +25,8 @@ class tui_file : public stdio_file { + DISABLE_COPY_AND_ASSIGN(tui_file); + public: explicit tui_file (FILE *stream); diff --git a/gdb/tui/tui-out.h b/gdb/tui/tui-out.h index 083094ba75..7f368c21d3 100644 --- a/gdb/tui/tui-out.h +++ b/gdb/tui/tui-out.h @@ -26,6 +26,8 @@ window instead of printing the line in the console window. */ class tui_ui_out : public cli_ui_out { + DISABLE_COPY_AND_ASSIGN(tui_ui_out); + public: explicit tui_ui_out (ui_file *stream); diff --git a/gdb/tui/tui-regs.h b/gdb/tui/tui-regs.h index 0646729917..89467affa2 100644 --- a/gdb/tui/tui-regs.h +++ b/gdb/tui/tui-regs.h @@ -28,6 +28,8 @@ struct tui_data_item_window : public tui_gen_win_info { + DISABLE_COPY_AND_ASSIGN(tui_data_item_window); + tui_data_item_window () : tui_gen_win_info (DATA_ITEM_WIN) { diff --git a/gdb/tui/tui-winsource.h b/gdb/tui/tui-winsource.h index ec44d1d2c0..b3a282a021 100644 --- a/gdb/tui/tui-winsource.h +++ b/gdb/tui/tui-winsource.h @@ -28,6 +28,8 @@ struct tui_exec_info_window : public tui_gen_win_info { + DISABLE_COPY_AND_ASSIGN(tui_exec_info_window); + tui_exec_info_window () : tui_gen_win_info (EXEC_INFO_WIN) {