From patchwork Thu Oct 16 08:39:56 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Gribov X-Patchwork-Id: 400215 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 80CB51400A3 for ; Thu, 16 Oct 2014 19:40:02 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; q=dns; s=default; b=f+k2K/qDzfhc4aj0K Ex3UYo8+4TNbURJ8FmUayA15lww/wYVoYCNQz2LylpE8JLdG6m4Smk9T9G+2tRd5 uOjHFYx8w/2pP3Q/q6LmP4/DQ+C472InC/fDaTQywDSBSuAthwvL0ocR3TVLzxh7 qXQ21Qp9N4HtXZh1rP5Cu4hJIM= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; s=default; bh=HfUBFST/BkCe5A8ez8cZljE cwY0=; b=Qu9m2K7VEIGMR0n4XdPxSBZW1R8AIltBE55UO22LpzCKyQVnQrvHqGj KKG43XOzPk+3T6XU5GnIAw1vI3XpM3kno4r6E2kaOlZrh4Zc7x2T6WOrBw6LEu2H 4O56AUFHT+t2ZVpl0N/JUawV2nhlNA0ph9ixkRSw8T+z1ZRyL2xA= Received: (qmail 4728 invoked by alias); 16 Oct 2014 08:39:55 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 4717 invoked by uid 89); 16 Oct 2014 08:39:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mailout3.w1.samsung.com Received: from mailout3.w1.samsung.com (HELO mailout3.w1.samsung.com) (210.118.77.13) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (DES-CBC3-SHA encrypted) ESMTPS; Thu, 16 Oct 2014 08:39:52 +0000 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NDJ00BWG4743X40@mailout3.w1.samsung.com> for gcc-patches@gcc.gnu.org; Thu, 16 Oct 2014 09:42:40 +0100 (BST) Received: from eusync4.samsung.com ( [203.254.199.214]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id E2.34.25543.4548F345; Thu, 16 Oct 2014 09:39:48 +0100 (BST) Received: from [106.109.9.145] by eusync4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0NDJ00I6H42CO890@eusync4.samsung.com>; Thu, 16 Oct 2014 09:39:48 +0100 (BST) Message-id: <543F845C.2090908@samsung.com> Date: Thu, 16 Oct 2014 12:39:56 +0400 From: Yury Gribov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.2 MIME-version: 1.0 To: GCC Patches Cc: Jakub Jelinek , Dmitry Vyukov , Konstantin Khlebnikov , Andrey Ryabinin , Viacheslav Garbuzov Subject: [PATCH 9/17] Initial KAsan support References: <543F831B.4090502@samsung.com> In-reply-to: <543F831B.4090502@samsung.com> Content-type: multipart/mixed; boundary=------------000202010700090500040509 X-IsSubscribed: yes The patch was slightly updated to take care of missing UBSan work (SANITIZE_FLOAT_DIVIDE, SANITIZE_FLOAT_CAST, SANITIZE_BOUNDS). 2014-10-15 Yury Gribov Backport from mainline 2014-07-31 Yury Gribov * doc/cpp.texi (__SANITIZE_ADDRESS__): Updated description. * doc/invoke.texi (-fsanitize=kernel-address): Describe new option. * flag-types.h (SANITIZE_USER_ADDRESS, SANITIZE_KERNEL_ADDRESS): New enums. * gcc.c (sanitize_spec_function): Support new option. (SANITIZER_SPEC): Remove now redundant check. * opts.c (common_handle_option): Support new option. (finish_options): Check for incompatibilities. * toplev.c (process_options): Split userspace-specific checks. diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index aaed739..0a6e50c 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -2354,8 +2354,8 @@ This macro is defined, with value 3, when @option{-fstack-protector-strong} is in use. @item __SANITIZE_ADDRESS__ -This macro is defined, with value 1, when @option{-fsanitize=address} is -in use. +This macro is defined, with value 1, when @option{-fsanitize=address} +or @option{-fsanitize=kernel-address} are in use. @item __TIMESTAMP__ This macro expands to a string constant that describes the date and time diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 4012f08..179f273 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -5286,6 +5286,11 @@ more details. The run-time behavior can be influenced using the @url{https://code.google.com/p/address-sanitizer/wiki/Flags#Run-time_flags} for a list of supported options. +@item -fsanitize=kernel-address +@opindex fsanitize=kernel-address +Enable AddressSanitizer for Linux kernel. +See @uref{http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel} for more details. + @item -fsanitize=thread @opindex fsanitize=thread Enable ThreadSanitizer, a fast data race detector. diff --git a/gcc/flag-types.h b/gcc/flag-types.h index ec16faa..1dd1b3e 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -204,20 +204,22 @@ enum vect_cost_model { enum sanitize_code { /* AddressSanitizer. */ SANITIZE_ADDRESS = 1 << 0, + SANITIZE_USER_ADDRESS = 1 << 1, + SANITIZE_KERNEL_ADDRESS = 1 << 2, /* ThreadSanitizer. */ - SANITIZE_THREAD = 1 << 1, + SANITIZE_THREAD = 1 << 3, /* LeakSanitizer. */ - SANITIZE_LEAK = 1 << 2, + SANITIZE_LEAK = 1 << 4, /* UndefinedBehaviorSanitizer. */ - SANITIZE_SHIFT = 1 << 3, - SANITIZE_DIVIDE = 1 << 4, - SANITIZE_UNREACHABLE = 1 << 5, - SANITIZE_VLA = 1 << 6, - SANITIZE_NULL = 1 << 7, - SANITIZE_RETURN = 1 << 8, - SANITIZE_SI_OVERFLOW = 1 << 9, - SANITIZE_BOOL = 1 << 10, - SANITIZE_ENUM = 1 << 11, + SANITIZE_SHIFT = 1 << 5, + SANITIZE_DIVIDE = 1 << 6, + SANITIZE_UNREACHABLE = 1 << 7, + SANITIZE_VLA = 1 << 8, + SANITIZE_NULL = 1 << 9, + SANITIZE_RETURN = 1 << 10, + SANITIZE_SI_OVERFLOW = 1 << 11, + SANITIZE_BOOL = 1 << 12, + SANITIZE_ENUM = 1 << 13, SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE | SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN | SANITIZE_SI_OVERFLOW | SANITIZE_BOOL | SANITIZE_ENUM diff --git a/gcc/gcc.c b/gcc/gcc.c index 9c4c40c..1034de8 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -734,8 +734,7 @@ proper position among the other output files. */ #ifndef SANITIZER_SPEC #define SANITIZER_SPEC "\ %{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\ - %{static:%ecannot specify -static with -fsanitize=address}\ - %{%:sanitize(thread):%e-fsanitize=address is incompatible with -fsanitize=thread}}\ + %{static:%ecannot specify -static with -fsanitize=address}}\ %{%:sanitize(thread):" LIBTSAN_SPEC "\ %{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}\ %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\ @@ -8173,7 +8172,9 @@ sanitize_spec_function (int argc, const char **argv) return NULL; if (strcmp (argv[0], "address") == 0) - return (flag_sanitize & SANITIZE_ADDRESS) ? "" : NULL; + return (flag_sanitize & SANITIZE_USER_ADDRESS) ? "" : NULL; + if (strcmp (argv[0], "kernel-address") == 0) + return (flag_sanitize & SANITIZE_KERNEL_ADDRESS) ? "" : NULL; if (strcmp (argv[0], "thread") == 0) return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL; if (strcmp (argv[0], "undefined") == 0) diff --git a/gcc/opts.c b/gcc/opts.c index bbd6b9c..fbdebd7 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -868,6 +868,20 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, /* The -gsplit-dwarf option requires -gpubnames. */ if (opts->x_dwarf_split_debug_info) opts->x_debug_generate_pub_sections = 1; + + /* Userspace and kernel ASan conflict with each other and with TSan. */ + + if ((flag_sanitize & SANITIZE_USER_ADDRESS) + && (flag_sanitize & SANITIZE_KERNEL_ADDRESS)) + error_at (loc, + "-fsanitize=address is incompatible with " + "-fsanitize=kernel-address"); + + if ((flag_sanitize & SANITIZE_ADDRESS) + && (flag_sanitize & SANITIZE_THREAD)) + error_at (loc, + "-fsanitize=address and -fsanitize=kernel-address " + "are incompatible with -fsanitize=thread"); } #define LEFT_COLUMN 27 @@ -1453,7 +1467,10 @@ common_handle_option (struct gcc_options *opts, size_t len; } spec[] = { - { "address", SANITIZE_ADDRESS, sizeof "address" - 1 }, + { "address", SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS, + sizeof "address" - 1 }, + { "kernel-address", SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS, + sizeof "kernel-address" - 1 }, { "thread", SANITIZE_THREAD, sizeof "thread" - 1 }, { "leak", SANITIZE_LEAK, sizeof "leak" - 1 }, { "shift", SANITIZE_SHIFT, sizeof "shift" - 1 }, @@ -1514,6 +1531,25 @@ common_handle_option (struct gcc_options *opts, the null pointer checks. */ if (flag_sanitize & SANITIZE_NULL) opts->x_flag_delete_null_pointer_checks = 0; + + /* Kernel ASan implies normal ASan but does not yet support + all features. */ + if (flag_sanitize & SANITIZE_KERNEL_ADDRESS) + { + maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD, 0, + opts->x_param_values, + opts_set->x_param_values); + maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, + opts->x_param_values, + opts_set->x_param_values); + maybe_set_param_value (PARAM_ASAN_STACK, 0, + opts->x_param_values, + opts_set->x_param_values); + maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0, + opts->x_param_values, + opts_set->x_param_values); + } + break; } diff --git a/gcc/toplev.c b/gcc/toplev.c index d646faf..588fa2b 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1555,9 +1555,18 @@ process_options (void) warn_stack_protect = 0; /* Address Sanitizer needs porting to each target architecture. */ + if ((flag_sanitize & SANITIZE_ADDRESS) - && (targetm.asan_shadow_offset == NULL - || !FRAME_GROWS_DOWNWARD)) + && !FRAME_GROWS_DOWNWARD) + { + warning (0, + "-fsanitize=address and -fsanitize=kernel-address " + "are not supported for this target"); + flag_sanitize &= ~SANITIZE_ADDRESS; + } + + if ((flag_sanitize & SANITIZE_USER_ADDRESS) + && targetm.asan_shadow_offset == NULL) { warning (0, "-fsanitize=address not supported for this target"); flag_sanitize &= ~SANITIZE_ADDRESS;