From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3831 invoked by alias); 19 Mar 2015 06:01:26 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 3804 invoked by uid 89); 19 Mar 2015 06:01:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 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, 19 Mar 2015 06:01:23 +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 <0NLG00FSB3KYYE20@mailout3.w1.samsung.com> for gcc-patches@gcc.gnu.org; Thu, 19 Mar 2015 06:05:22 +0000 (GMT) Received: from eusync1.samsung.com ( [203.254.199.211]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id AE.D1.07834.D956A055; Thu, 19 Mar 2015 05:58:53 +0000 (GMT) Received: from [106.109.129.103] by eusync1.samsung.com (Oracle Communications Messaging Server 7u4-23.01(7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0NLG00F1E3E5AA00@eusync1.samsung.com>; Thu, 19 Mar 2015 06:01:18 +0000 (GMT) Message-id: <550A662E.3080308@samsung.com> Date: Thu, 19 Mar 2015 06:01:00 -0000 From: Marat Zakirov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-version: 1.0 To: Andrew Pinski Cc: "gcc-patches@gcc.gnu.org" , Kostya Serebryany , Dmitry Vyukov , Yury Gribov , Andrey Ryabinin Subject: [PINGv2][PATCH] ASan on unaligned accesses References: <54F6BBA0.2010302@samsung.com> In-reply-to: Content-type: multipart/mixed; boundary=------------080608010904080706040306 X-SW-Source: 2015-03/txt/msg00988.txt.bz2 This is a multi-part message in MIME format. --------------080608010904080706040306 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1027 On 03/04/2015 11:07 AM, Andrew Pinski wrote: > On Wed, Mar 4, 2015 at 12:00 AM, Marat Zakirov wrote: >> Hi all! >> >> Here is the patch which forces ASan to work on memory access without proper >> alignment. it's useful because some programs like linux kernel often cheat >> with alignment which may cause false negatives. This patch needs additional >> support for proper work on unaligned accesses in global data and heap. It >> will be implemented in libsanitizer by separate patch. >> >> >> --Marat >> >> gcc/ChangeLog: >> >> 2015-02-25 Marat Zakirov >> >> * asan.c (asan_emit_stack_protection): Support for misalign >> accesses. >> (asan_expand_check_ifn): Likewise. >> * params.def: New option asan-catch-misaligned. >> * params.h: New param ASAN_CATCH_MISALIGNED. > Since this parameter can only be true or false, I think it should be a > normal option. Also you did not add documentation of the param. > > Thanks, > Andrew Fixed. --------------080608010904080706040306 Content-Type: text/x-patch; name="mavdt-95_17.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mavdt-95_17.diff" Content-length: 8531 gcc/ChangeLog: 2015-03-12 Marat Zakirov * asan.c (asan_emit_stack_protection): Support for misalign accesses. (asan_expand_check_ifn): Likewise. * common.opt: New flag -fasan-catch-misaligned. * doc/invoke.texi: New flag description. * opts.c (finish_options): Add check for new flag. (common_handle_option): Switch on flag if SANITIZE_KERNEL_ADDRESS. gcc/testsuite/ChangeLog: 2015-03-12 Marat Zakirov * c-c++-common/asan/misalign-catch.c: New test. diff --git a/gcc/asan.c b/gcc/asan.c index 9e4a629..80bf2e8 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -1050,7 +1050,6 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, rtx_code_label *lab; rtx_insn *insns; char buf[30]; - unsigned char shadow_bytes[4]; HOST_WIDE_INT base_offset = offsets[length - 1]; HOST_WIDE_INT base_align_bias = 0, offset, prev_offset; HOST_WIDE_INT asan_frame_size = offsets[0] - base_offset; @@ -1193,11 +1192,37 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, if (STRICT_ALIGNMENT) set_mem_align (shadow_mem, (GET_MODE_ALIGNMENT (SImode))); prev_offset = base_offset; + + vec shadow_mems; + vec shadow_bytes; + + shadow_mems.create(0); + shadow_bytes.create(0); + for (l = length; l; l -= 2) { if (l == 2) cur_shadow_byte = ASAN_STACK_MAGIC_RIGHT; offset = offsets[l - 1]; + if (l != length && flag_asan_catch_misaligned) + { + HOST_WIDE_INT aoff + = base_offset + ((offset - base_offset) + & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1)) + - ASAN_RED_ZONE_SIZE; + if (aoff > prev_offset) + { + shadow_mem = adjust_address (shadow_mem, VOIDmode, + (aoff - prev_offset) + >> ASAN_SHADOW_SHIFT); + prev_offset = aoff; + shadow_bytes.safe_push (0); + shadow_bytes.safe_push (0); + shadow_bytes.safe_push (0); + shadow_bytes.safe_push (0); + shadow_mems.safe_push (shadow_mem); + } + } if ((offset - base_offset) & (ASAN_RED_ZONE_SIZE - 1)) { int i; @@ -1212,13 +1237,13 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, if (aoff < offset) { if (aoff < offset - (1 << ASAN_SHADOW_SHIFT) + 1) - shadow_bytes[i] = 0; + shadow_bytes.safe_push (0); else - shadow_bytes[i] = offset - aoff; + shadow_bytes.safe_push (offset - aoff); } else - shadow_bytes[i] = ASAN_STACK_MAGIC_PARTIAL; - emit_move_insn (shadow_mem, asan_shadow_cst (shadow_bytes)); + shadow_bytes.safe_push (ASAN_STACK_MAGIC_PARTIAL); + shadow_mems.safe_push(shadow_mem); offset = aoff; } while (offset <= offsets[l - 2] - ASAN_RED_ZONE_SIZE) @@ -1227,12 +1252,21 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, (offset - prev_offset) >> ASAN_SHADOW_SHIFT); prev_offset = offset; - memset (shadow_bytes, cur_shadow_byte, 4); - emit_move_insn (shadow_mem, asan_shadow_cst (shadow_bytes)); + shadow_bytes.safe_push (cur_shadow_byte); + shadow_bytes.safe_push (cur_shadow_byte); + shadow_bytes.safe_push (cur_shadow_byte); + shadow_bytes.safe_push (cur_shadow_byte); + shadow_mems.safe_push(shadow_mem); offset += ASAN_RED_ZONE_SIZE; } cur_shadow_byte = ASAN_STACK_MAGIC_MIDDLE; } + for (unsigned i = 0; flag_asan_catch_misaligned && i < shadow_bytes.length () - 1; i++) + if (shadow_bytes[i] == 0 && shadow_bytes[i + 1] > 0) + shadow_bytes[i] = 8 + (shadow_bytes[i + 1] > 7 ? 0 : shadow_bytes[i + 1]); + for (unsigned i = 0; i < shadow_mems.length (); i++) + emit_move_insn (shadow_mems[i], asan_shadow_cst (&shadow_bytes[i * 4])); + do_pending_stack_adjust (); /* Construct epilogue sequence. */ @@ -1285,34 +1319,8 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, if (STRICT_ALIGNMENT) set_mem_align (shadow_mem, (GET_MODE_ALIGNMENT (SImode))); - prev_offset = base_offset; - last_offset = base_offset; - last_size = 0; - for (l = length; l; l -= 2) - { - offset = base_offset + ((offsets[l - 1] - base_offset) - & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1)); - if (last_offset + last_size != offset) - { - shadow_mem = adjust_address (shadow_mem, VOIDmode, - (last_offset - prev_offset) - >> ASAN_SHADOW_SHIFT); - prev_offset = last_offset; - asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT); - last_offset = offset; - last_size = 0; - } - last_size += base_offset + ((offsets[l - 2] - base_offset) - & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1)) - - offset; - } - if (last_size) - { - shadow_mem = adjust_address (shadow_mem, VOIDmode, - (last_offset - prev_offset) - >> ASAN_SHADOW_SHIFT); - asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT); - } + for (unsigned i = 0; i < shadow_mems.length (); i++) + asan_clear_shadow (shadow_mems[i], 4); do_pending_stack_adjust (); if (lab) @@ -2643,7 +2651,7 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls) tree base_addr = gimple_assign_lhs (g); tree t = NULL_TREE; - if (real_size_in_bytes >= 8) + if (real_size_in_bytes >= 8 && !flag_asan_catch_misaligned) { tree shadow = build_shadow_mem_access (&gsi, loc, base_addr, shadow_ptr_type); @@ -2662,7 +2670,7 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls) /* Aligned (>= 8 bytes) can test just (real_size_in_bytes - 1 >= shadow), as base_addr & 7 is known to be 0. */ - if (align < 8) + if (align < 8 || flag_asan_catch_misaligned) { gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, base_addr, 7)); diff --git a/gcc/common.opt b/gcc/common.opt index b49ac46..a7af95e 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1161,6 +1161,12 @@ Common Driver Var(flag_report_bug) Collect and dump debug information into temporary file if ICE in C/C++ compiler occured. +fasan-catch-misaligned +Common Driver Var(flag_asan_catch_misaligned) +Catch invalid unaligned memory accesses. +This option is needed to prevent potential ASan false positives due to +unaligned to type size memory accesses in some apllication like Linux kernel. + fdump-passes Common Var(flag_dump_passes) Init(0) Dump optimization passes diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 1534ed9..c85aa38 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -6680,6 +6680,12 @@ text / bss / data / heap / stack / dso start locations. Collect and dump debug information into temporary file if ICE in C/C++ compiler occured. +@item -fasan-catch-misaligned +@opindex fasan-catch-misaligned +Catch invalid unaligned memory accesses. +This option is needed to prevent potential ASan false positives due to +unaligned to type size memory accesses in some apllication like Linux kernel. + @item -fdump-unnumbered @opindex fdump-unnumbered When doing debugging dumps, suppress instruction numbers and address output. diff --git a/gcc/opts.c b/gcc/opts.c index 39c190d..b238b90 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -925,6 +925,9 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, opts->x_flag_aggressive_loop_optimizations = 0; opts->x_flag_strict_overflow = 0; } + + if (flag_asan_catch_misaligned && !opts->x_flag_sanitize) + error_at (loc, "-fasan-catch-misaligned is valid only with -fsanitize option"); } #define LEFT_COLUMN 27 @@ -1662,6 +1665,7 @@ common_handle_option (struct gcc_options *opts, maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0, opts->x_param_values, opts_set->x_param_values); + flag_asan_catch_misaligned = true; } break; diff --git a/gcc/testsuite/c-c++-common/asan/misalign-catch.c b/gcc/testsuite/c-c++-common/asan/misalign-catch.c new file mode 100644 index 0000000..158efd4 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/misalign-catch.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-options "-fasan-catch-misaligned" } */ +/* { dg-shouldfail "asan" } */ + +long long *ptr; + +__attribute__((noinline)) +void foo () { + ptr = ((long long int *)(((char *)ptr) + 1)); + *ptr = 1; +} + +int main() +{ + long long int local[9]; + ptr = (long long *)&local[8]; + foo (); + return 0; +} + +/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow.*(\n|\r\n|\r)" } */ --------------080608010904080706040306--