From patchwork Wed Jun 24 12:33:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Popov X-Patchwork-Id: 11623065 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B940B90 for ; Wed, 24 Jun 2020 12:34:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A99AC214DB for ; Wed, 24 Jun 2020 12:34:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2403935AbgFXMez (ORCPT ); Wed, 24 Jun 2020 08:34:55 -0400 Received: from mail-qk1-f196.google.com ([209.85.222.196]:45492 "EHLO mail-qk1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2403929AbgFXMet (ORCPT ); Wed, 24 Jun 2020 08:34:49 -0400 Received: by mail-qk1-f196.google.com with SMTP id c139so1558910qkg.12; Wed, 24 Jun 2020 05:34:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=U/neUUCsqT0PlemfvVIM6cUhi6vcMD7QDpY9m0/55MY=; b=Ddcm39iTqbQU20VXksWlsXo7MLbZ08RTWRB3WjwMepD42pXxm/X58rglUB3kOgeuFz x1TA7b37ivk2Hr/dKliFsBj3qPCnE4RPaYuhQIQcFEjAPKxj7ABxARbfQCrZ+TG1JHaV 0bW+8D6kelPisJd7K+P6icuvzhi+7TxlnG1TvjVkuF3BcoamO/VKtXOPJYp7wjjwP8ft fnmD77fN0R03paT/trp5gxFpFCwETI3mGwiHhztsFZSkF+y34dQI2q4Jb+NqrDme+nFr 8puH4aG/JBGSM7PXvAWNAhXt0qLzhqFxBEsPkmnlkb1fo3LXBwutUX/s48SiIOXA5d+w /5iQ== X-Gm-Message-State: AOAM531aD+ucjD8ze+6B5YrcsYqYwB4YZh3kCgIE69WWk9WkEggULIq7 kWsblDEHaL/yjPSVlFBci6IeTQ/fkBo= X-Google-Smtp-Source: ABdhPJz9JvvyfA9b1/190kREHa6PK+V5IrA3vD+WvU3Zfs4N16fAWbTWXRT7gUAU+aWUjakQ5UQxCQ== X-Received: by 2002:a05:620a:10a4:: with SMTP id h4mr24496106qkk.320.1593002088433; Wed, 24 Jun 2020 05:34:48 -0700 (PDT) Received: from localhost.localdomain ([185.248.161.177]) by smtp.gmail.com with ESMTPSA id x26sm3354512qtr.4.2020.06.24.05.34.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Jun 2020 05:34:47 -0700 (PDT) From: Alexander Popov To: Kees Cook , Jann Horn , Emese Revfy , Miguel Ojeda , Masahiro Yamada , Michal Marek , Andrew Morton , Masahiro Yamada , Thiago Jung Bauermann , Luis Chamberlain , Jessica Yu , Sven Schnelle , Iurii Zaikin , Catalin Marinas , Will Deacon , Vincenzo Frascino , Thomas Gleixner , Peter Collingbourne , Naohiro Aota , Alexander Monakov , Mathias Krause , PaX Team , Brad Spengler , Laura Abbott , Florian Weimer , Alexander Popov , kernel-hardening@lists.openwall.com, linux-kbuild@vger.kernel.org, x86@kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, gcc@gcc.gnu.org Cc: notify@kernel.org Subject: [PATCH v2 5/5] gcc-plugins/stackleak: Add 'verbose' plugin parameter Date: Wed, 24 Jun 2020 15:33:30 +0300 Message-Id: <20200624123330.83226-6-alex.popov@linux.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20200624123330.83226-1-alex.popov@linux.com> References: <20200624123330.83226-1-alex.popov@linux.com> MIME-Version: 1.0 Sender: linux-kbuild-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org Add 'verbose' plugin parameter for stackleak gcc plugin. It can be used for printing additional info about the kernel code instrumentation. For using it add the following to scripts/Makefile.gcc-plugins: gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ += -fplugin-arg-stackleak_plugin-verbose Signed-off-by: Alexander Popov --- scripts/gcc-plugins/stackleak_plugin.c | 47 +++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c index a18b0d4af456..48e141e07956 100644 --- a/scripts/gcc-plugins/stackleak_plugin.c +++ b/scripts/gcc-plugins/stackleak_plugin.c @@ -34,6 +34,8 @@ __visible int plugin_is_GPL_compatible; static int track_frame_size = -1; static bool build_for_x86 = false; static const char track_function[] = "stackleak_track_stack"; +static bool disable = false; +static bool verbose = false; /* * Mark these global variables (roots) for gcc garbage collector since @@ -46,6 +48,7 @@ static struct plugin_info stackleak_plugin_info = { .help = "track-min-size=nn\ttrack stack for functions with a stack frame size >= nn bytes\n" "arch=target_arch\tspecify target build arch\n" "disable\t\tdo not activate the plugin\n" + "verbose\t\tprint info about the instrumentation\n" }; static void add_stack_tracking_gcall(gimple_stmt_iterator *gsi, bool after) @@ -102,6 +105,10 @@ static tree get_current_stack_pointer_decl(void) return var; } + if (verbose) { + fprintf(stderr, "stackleak: missing current_stack_pointer in %s()\n", + DECL_NAME_POINTER(current_function_decl)); + } return NULL_TREE; } @@ -195,6 +202,11 @@ static unsigned int stackleak_instrument_execute(void) if (!is_alloca(stmt)) continue; + if (verbose) { + fprintf(stderr, "stackleak: be careful, alloca() in %s()\n", + DECL_NAME_POINTER(current_function_decl)); + } + /* Insert stackleak_track_stack() call after alloca() */ add_stack_tracking(&gsi, true); if (bb == entry_bb) @@ -384,13 +396,31 @@ static bool remove_stack_tracking_gasm(void) */ static unsigned int stackleak_cleanup_execute(void) { + const char *fn = DECL_NAME_POINTER(current_function_decl); bool removed = false; - if (cfun->calls_alloca) + /* + * Leave stack tracking in functions that call alloca(). + * Additional case: + * gcc before version 7 called allocate_dynamic_stack_space() from + * expand_stack_vars() for runtime alignment of constant-sized stack + * variables. That caused cfun->calls_alloca to be set for functions + * that in fact don't use alloca(). + * For more info see gcc commit 7072df0aae0c59ae437e. + * Let's leave such functions instrumented as well. + */ + if (cfun->calls_alloca) { + if (verbose) + fprintf(stderr, "stackleak: instrument %s(): calls_alloca\n", fn); return 0; + } - if (large_stack_frame()) + /* Leave stack tracking in functions with large stack frame */ + if (large_stack_frame()) { + if (verbose) + fprintf(stderr, "stackleak: instrument %s()\n", fn); return 0; + } if (lookup_attribute_spec(get_identifier("no_caller_saved_registers"))) removed = remove_stack_tracking_gasm(); @@ -516,9 +546,6 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, /* Parse the plugin arguments */ for (i = 0; i < argc; i++) { - if (!strcmp(argv[i].key, "disable")) - return 0; - if (!strcmp(argv[i].key, "track-min-size")) { if (!argv[i].value) { error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), @@ -541,6 +568,10 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, if (!strcmp(argv[i].value, "x86")) build_for_x86 = true; + } else if (!strcmp(argv[i].key, "disable")) { + disable = true; + } else if (!strcmp(argv[i].key, "verbose")) { + verbose = true; } else { error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); @@ -548,6 +579,12 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, } } + if (disable) { + if (verbose) + fprintf(stderr, "stackleak: disabled for this translation unit\n"); + return 0; + } + /* Give the information about the plugin */ register_callback(plugin_name, PLUGIN_INFO, NULL, &stackleak_plugin_info);