From patchwork Wed Jun 14 17:10:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 775881 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 3wntS86lDGz9s72 for ; Thu, 15 Jun 2017 03:10:32 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="S0hbaPBe"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=P61iO53NPckmtBKhFHco8ijP2uKmV mwIC1Izx1CZGhRY4AD4IPprpYACPOBU726XF2AxF3cALOKkyqIUQj+EZOLj0HDDJ 3e1NB7STIaYTj0gs53/rbRO4Uk0MMhwEWikNq64+O0zdTe+f529tKWZLipRQmGp1 RKSK7qiO4taRbo= 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:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=fAHiNducC3EcG3slulAw7FNnkz8=; b=S0h baPBe4vCo2NbD/YDAnU8NObOjlKDzviU1F4vNTUcfI6mjoE4UWpTQPM6W+eKmge4 HSOgsvqSFyiv+a7OhHD6f69xGPMVFkZAzzxkWQVxBa0rvEyDqL5Vjg2GopFlidgA fc/JTNvsQ6e3NyzZMKuct2G3CXWVGAHQ9kaW9lpk= Received: (qmail 94298 invoked by alias); 14 Jun 2017 17:10:18 -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 94279 invoked by uid 89); 14 Jun 2017 17:10:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-16.9 required=5.0 tests=BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=*note X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 14 Jun 2017 17:10:16 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D829FC0587CF; Wed, 14 Jun 2017 17:10:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com D829FC0587CF Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jakub@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com D829FC0587CF Received: from tucnak.zalov.cz (ovpn-117-215.ams2.redhat.com [10.36.117.215]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5C13417C16; Wed, 14 Jun 2017 17:10:19 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id v5EHAG5L004629; Wed, 14 Jun 2017 19:10:17 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id v5EHAEMG004628; Wed, 14 Jun 2017 19:10:14 +0200 Date: Wed, 14 Jun 2017 19:10:14 +0200 From: Jakub Jelinek To: Richard Biener Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Instrument aggregate call arguments even with -fsanitize=object-size (PR sanitizer/81094) Message-ID: <20170614171014.GC2123@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.7.1 (2016-10-04) X-IsSubscribed: yes Hi! -fsanitize=object-size is yet another sanitization that ignored aggregate function arguments. Fixed thusly (plus some small cleanup for instrument_null), bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-06-14 Jakub Jelinek PR sanitizer/81094 * ubsan.c (instrument_null): Add T argument, use it instead of computing it based on IS_LHS. (instrument_object_size): Likewise. (pass_ubsan::execute): Adjust instrument_null and instrument_object_size callers to pass gimple_get_lhs or gimple_assign_rhs1 result to it. Use instrument_null instead of calling get_base_address and instrument_mem_ref. Handle aggregate call arguments for object-size sanitization. * c-c++-common/ubsan/object-size-11.c: New test. Jakub --- gcc/ubsan.c.jj 2017-06-14 14:40:39.000000000 +0200 +++ gcc/ubsan.c 2017-06-14 14:49:17.702131958 +0200 @@ -1204,10 +1204,8 @@ instrument_mem_ref (tree mem, tree base, /* Perform the pointer instrumentation. */ static void -instrument_null (gimple_stmt_iterator gsi, bool is_lhs) +instrument_null (gimple_stmt_iterator gsi, tree t, bool is_lhs) { - gimple *stmt = gsi_stmt (gsi); - tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt); /* Handle also e.g. &s->i. */ if (TREE_CODE (t) == ADDR_EXPR) t = TREE_OPERAND (t, 0); @@ -1754,11 +1752,10 @@ instrument_nonnull_return (gimple_stmt_i points to an out-of-bounds location. */ static void -instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs) +instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs) { gimple *stmt = gsi_stmt (*gsi); location_t loc = gimple_location (stmt); - tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt); tree type; tree index = NULL_TREE; HOST_WIDE_INT size_in_bytes; @@ -1989,9 +1986,9 @@ pass_ubsan::execute (function *fun) if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT, fun->decl)) { if (gimple_store_p (stmt)) - instrument_null (gsi, true); + instrument_null (gsi, gimple_get_lhs (stmt), true); if (gimple_assign_single_p (stmt)) - instrument_null (gsi, false); + instrument_null (gsi, gimple_assign_rhs1 (stmt), false); if (is_gimple_call (stmt)) { unsigned args_num = gimple_call_num_args (stmt); @@ -2000,10 +1997,7 @@ pass_ubsan::execute (function *fun) tree arg = gimple_call_arg (stmt, i); if (is_gimple_reg (arg) || is_gimple_min_invariant (arg)) continue; - tree base = get_base_address (arg); - if (TREE_CODE (base) == MEM_REF - && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME) - instrument_mem_ref (arg, base, &gsi, false); + instrument_null (gsi, arg, false); } } } @@ -2033,9 +2027,21 @@ pass_ubsan::execute (function *fun) if (sanitize_flags_p (SANITIZE_OBJECT_SIZE, fun->decl)) { if (gimple_store_p (stmt)) - instrument_object_size (&gsi, true); + instrument_object_size (&gsi, gimple_get_lhs (stmt), true); if (gimple_assign_load_p (stmt)) - instrument_object_size (&gsi, false); + instrument_object_size (&gsi, gimple_assign_rhs1 (stmt), + false); + if (is_gimple_call (stmt)) + { + unsigned args_num = gimple_call_num_args (stmt); + for (unsigned i = 0; i < args_num; ++i) + { + tree arg = gimple_call_arg (stmt, i); + if (is_gimple_reg (arg) || is_gimple_min_invariant (arg)) + continue; + instrument_object_size (&gsi, arg, false); + } + } } gsi_next (&gsi); --- gcc/testsuite/c-c++-common/ubsan/object-size-11.c.jj 2017-06-14 16:16:43.192137010 +0200 +++ gcc/testsuite/c-c++-common/ubsan/object-size-11.c 2017-06-14 16:16:22.000000000 +0200 @@ -0,0 +1,53 @@ +/* PR sanitizer/81094 */ +/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */ +/* { dg-options "-fsanitize=object-size" } */ + +#define N 20 + +struct S { int i; }; + +__attribute__((noinline, noclone)) void +f0 (struct S s) +{ + asm volatile ("" : : "r" (s.i) : "memory"); +} + +__attribute__((noinline, noclone)) void +f1 (int i) +{ + char *orig; + struct S *p; + orig = (char *) __builtin_calloc (N, sizeof (struct S)); + p = (struct S *) orig; + f0 (*(p + i)); + f0 (p[i]); + p++; + f0 (p[i - 1]); + f0 (*(p + i - 1)); + __builtin_free (orig); +} + +/* { dg-output "load of address \[^\n\r]* with insufficient space for an object of type 'struct S'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'struct S'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'struct S'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'struct S'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\\^" } */ + +int +main () +{ + f1 (N); + return 0; +}