From patchwork Thu Mar 23 20:37:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 742883 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 3vpyz95Vsfz9s7K for ; Fri, 24 Mar 2017 07:37:25 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="DXRX5bsr"; 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=Ys2dl6i5cYs9vVx+4CYPxDIAnlBjn GIO0qjdXgiz4NNQLKknTDpPoACWBZJUaINtFakjVp9pg+k0vdtMAOy6FpD2EPGZO Gi+HSWbhCq7vzLKFZavSmzwWtnYyMsDxaF5tYe4Y3gj+NXSy1G1/VnkhvivEfoc4 RLNNTX09hMFerY= 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=7RoOSQdU3K5t0ytdujDVaWiQlfs=; b=DXR X5bsr4xiC1/efxJ+IviK5Z47pgH2QN40h4uQhFd/lWZEL0co/PccnNrHlsWUpn0g 945UVAnZC92CJTgR1AJgCqauN4tYgopoxnxJW6e3/r1u0y9XUNSvpX00sqcFTJkK LhzsDlh+0MJ6/IX7xvkiPgjUJAP7B0rKiugylqDo= Received: (qmail 14124 invoked by alias); 23 Mar 2017 20:37:12 -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 14109 invoked by uid 89); 23 Mar 2017 20:37:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= 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; Thu, 23 Mar 2017 20:37:10 +0000 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 45D4D7AEAD for ; Thu, 23 Mar 2017 20:37:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 45D4D7AEAD Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jakub@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 45D4D7AEAD Received: from tucnak.zalov.cz (ovpn-116-72.ams2.redhat.com [10.36.116.72]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C6EC653; Thu, 23 Mar 2017 20:37:10 +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 v2NKb6f2005604; Thu, 23 Mar 2017 21:37:07 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id v2NKb5iZ005603; Thu, 23 Mar 2017 21:37:05 +0100 Date: Thu, 23 Mar 2017 21:37:05 +0100 From: Jakub Jelinek To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [C++ PATCH] Fix -fsanitize={null, alignment} of references (PR c++/79572) Message-ID: <20170323203705.GX11094@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! Since late C++ folding has been committed, we don't sanitize some reference bindings to NULL. Earlier we had always NOP_EXPR to REFERENCE_TYPE say from INTEGER_CST or whatever else, but cp_fold can now turn that right into INTEGER_CST with REFERENCE_TYPE. The following patch sanitizes even those. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-03-23 Jakub Jelinek PR c++/79572 * c-ubsan.h (ubsan_maybe_instrument_reference): Change argument to tree *. * c-ubsan.c (ubsan_maybe_instrument_reference): Likewise. Handle not just NOP_EXPR to REFERENCE_TYPE, but also INTEGER_CST with REFERENCE_TYPE. * cp-gimplify.c (cp_genericize_r): Sanitize INTEGER_CSTs with REFERENCE_TYPE. Adjust ubsan_maybe_instrument_reference caller for NOP_EXPR to REFERENCE_TYPE. * g++.dg/ubsan/null-8.C: New test. Jakub --- gcc/c-family/c-ubsan.h.jj 2017-01-01 12:45:46.000000000 +0100 +++ gcc/c-family/c-ubsan.h 2017-03-23 09:13:16.287888726 +0100 @@ -28,7 +28,7 @@ extern tree ubsan_instrument_return (loc extern tree ubsan_instrument_bounds (location_t, tree, tree *, bool); extern bool ubsan_array_ref_instrumented_p (const_tree); extern void ubsan_maybe_instrument_array_ref (tree *, bool); -extern void ubsan_maybe_instrument_reference (tree); +extern void ubsan_maybe_instrument_reference (tree *); extern void ubsan_maybe_instrument_member_call (tree, bool); /* Declare this here as well as in ubsan.h. */ --- gcc/c-family/c-ubsan.c.jj 2017-01-01 12:45:46.000000000 +0100 +++ gcc/c-family/c-ubsan.c 2017-03-23 09:18:51.775486699 +0100 @@ -458,17 +458,26 @@ ubsan_maybe_instrument_reference_or_call return fold_build2 (COMPOUND_EXPR, TREE_TYPE (op), call, op); } -/* Instrument a NOP_EXPR to REFERENCE_TYPE if needed. */ +/* Instrument a NOP_EXPR to REFERENCE_TYPE or INTEGER_CST with REFERENCE_TYPE + type if needed. */ void -ubsan_maybe_instrument_reference (tree stmt) +ubsan_maybe_instrument_reference (tree *stmt_p) { - tree op = TREE_OPERAND (stmt, 0); + tree stmt = *stmt_p; + tree op = stmt; + if (TREE_CODE (stmt) == NOP_EXPR) + op = TREE_OPERAND (stmt, 0); op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op, TREE_TYPE (stmt), UBSAN_REF_BINDING); if (op) - TREE_OPERAND (stmt, 0) = op; + { + if (TREE_CODE (stmt) == NOP_EXPR) + TREE_OPERAND (stmt, 0) = op; + else + *stmt_p = op; + } } /* Instrument a CALL_EXPR to a method if needed. */ --- gcc/cp/cp-gimplify.c.jj 2017-03-03 13:23:58.000000000 +0100 +++ gcc/cp/cp-gimplify.c 2017-03-23 09:21:26.693460888 +0100 @@ -1130,6 +1130,19 @@ cp_genericize_r (tree *stmt_p, int *walk } } + if (TREE_CODE (stmt) == INTEGER_CST + && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE + && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) + && !wtd->no_sanitize_p) + { + ubsan_maybe_instrument_reference (stmt_p); + if (*stmt_p != stmt) + { + *walk_subtrees = 0; + return NULL_TREE; + } + } + /* Other than invisiref parms, don't walk the same tree twice. */ if (p_set->contains (stmt)) { @@ -1477,7 +1490,7 @@ cp_genericize_r (tree *stmt_p, int *walk if ((flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) && TREE_CODE (stmt) == NOP_EXPR && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE) - ubsan_maybe_instrument_reference (stmt); + ubsan_maybe_instrument_reference (stmt_p); else if (TREE_CODE (stmt) == CALL_EXPR) { tree fn = CALL_EXPR_FN (stmt); --- gcc/testsuite/g++.dg/ubsan/null-8.C.jj 2017-03-23 09:42:31.664696676 +0100 +++ gcc/testsuite/g++.dg/ubsan/null-8.C 2017-03-23 09:43:31.501908802 +0100 @@ -0,0 +1,19 @@ +// PR c++/79572 +// { dg-do run } +// { dg-options "-fsanitize=null -std=c++14" } +// { dg-output "reference binding to null pointer of type 'const int'" } + +void +foo (const int &iref) +{ + if (&iref) + __builtin_printf ("iref %d\n", iref); + else + __builtin_printf ("iref is NULL\n"); +} + +int +main () +{ + foo (*((int*) __null)); +}