From patchwork Wed Jan 24 00:29:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qing Zhao X-Patchwork-Id: 84639 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 678F53861846 for ; Wed, 24 Jan 2024 00:32:42 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by sourceware.org (Postfix) with ESMTPS id B8503385E02A for ; Wed, 24 Jan 2024 00:30:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B8503385E02A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=oracle.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=oracle.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B8503385E02A Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=205.220.165.32 ARC-Seal: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1706056237; cv=pass; b=HrrabnyE8vbkIvAQUJlggLvONPMrxik8uUb2RuOJCAoiyXwC8wlKN47eu13YXfPB0oUp/lEcdwfO+7yhN2ScssM86h32n4CPRupUC2rk7Da+PCmCl1oMWGM7gm+y3ycufLCoZ29LNLZef90kDz8SSuuNhmLd/Iy8JYlXQAcl/cU= ARC-Message-Signature: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1706056237; c=relaxed/simple; bh=+BFs7d9iztmRV+L0vetnfVUop4c7Y4pWqalgpa67NrE=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-Id: MIME-Version; b=GKcBW+bRYgdR222bot3qmkkaaYZ17JanmZQgMBhBlsWM2cWJrrU9ueaKfcWHo3HqocAH5yz/LEoEPAkhOBBnIYkgSnOKtbZEADxZQF3/6REFSUWl4zlbZPwYq15S41i4rCaj9t0GbuJW1hrS/UNnq5aQUY2Le6qvVLnBH2T0zow= ARC-Authentication-Results: i=2; server2.sourceware.org Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 40NMv0st014414; Wed, 24 Jan 2024 00:30:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-transfer-encoding : content-type : mime-version; s=corp-2023-11-20; bh=K88RStHMpvPAztc3mwpnGPHPq7BSeiP+vi3+4FdpGoY=; b=fO5z3VBz4g/dZGRNgYBoyjyNh3Mv5Un/aBRofTDrlYRidoeFUTpot1+VbIribrUsdp7t n+3VZS399xCCKwJd8g/q2PDqnj/oO018TIQU07fWCZj+jxcvCdcexHmnURmcpyYQNdOf E2nb4V8VJlDgHPJEWEDM4CqbjLv9N7Pd9LAwUShpz2nE7gMng9KRpqzBxxZ9gSs/f3fu GG6AbBhVLH7ueBfoQoDKXsVKBJJnBA4jyZqVJhC5sYoLR9sqzjCBozL9mKjwYGbLnx1J U25TVTdoGungiu68Dtk/mxQx0NkDDeTYm7nTS65ierH/UZY4M5M88hZ+ya6MRODkTqxC zQ== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3vr79nfux2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 24 Jan 2024 00:30:29 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 40NMkOOq001150; Wed, 24 Jan 2024 00:30:28 GMT Received: from nam10-bn7-obe.outbound.protection.outlook.com (mail-bn7nam10lp2101.outbound.protection.outlook.com [104.47.70.101]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3vs3235bdg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 24 Jan 2024 00:30:28 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TljV4iL0IUsGCl0wSDIKkdd7ukUPEZe1PO5+g+XFHZtdnCi3xa0EAI/39TxzMoaz0rRZBWRlrC/W1dfGGsJuUd/Say6CbVWnoE3GNJkkJ134MJMzPGjM/Ui1nPypIITH15pyzhxqLbyywKcHa7TNz+XESY9J55uC289yXCsvUGsv388j2JLisoESU9bNNHHD4autkIPfzjuQVJSw2PyWiN8gnV1axm6618CHZkZPqPPBbDlZqdsuaZ9iTO3SuAzpmg71TPj4AATuJUUfQW0xZIyCtFm1hJeMaLVfMPIO1kx/m2dhqIq8FlKlz4lpp38E9QbOJr3VLwASOu9ljwwXsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=K88RStHMpvPAztc3mwpnGPHPq7BSeiP+vi3+4FdpGoY=; b=EOlpBaLEIiAEcgzoejHFtMb2WUf0im0qzPIFPET0cFU4eWlsadA5tmNuLFB6LhYYJ0nsbYs80BRBvSGxKcVK16kkyDAnVjETsa6rIoyqNL3tfrCB9LGABBHtczbZMw0hcJPNVN24+eYk/ycTwEffFPuaHNGpXj4TgvbNN7ex4NBNDeAtVDVdAHgmH7XEuEggcIPVW8YrKUtzHTAeQhM0GMjuq8eOfJL5hMFivTvpPGC8+owGkbVwsZF4v+Rz7AKv9lQXwuPbeG24PmVISwfsFCaDRD7QM356oDjaacj8CkInnBT1q3lbEzqzr4Mmw/DxrjY2yPdTY6gAdLcnDkS9Xg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=K88RStHMpvPAztc3mwpnGPHPq7BSeiP+vi3+4FdpGoY=; b=ahg5VA6YvMS7aO6xFaX7SYJ2a5legyKuksWu9wCusUrQGbgzafrn6j8aiautlN+tIt30LiJzvmqDitx/WqvdaK8RWexyfOmuBAWKaSRZRPn/xi+d8RgdyIHIlIY4p0kCIpYsMSpkISQSUUw/t/tzBP1U7IhtoFT9hVU8jZJMqZU= Received: from CH3PR10MB7957.namprd10.prod.outlook.com (2603:10b6:610:1bf::19) by IA1PR10MB5994.namprd10.prod.outlook.com (2603:10b6:208:3ee::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.22; Wed, 24 Jan 2024 00:30:26 +0000 Received: from CH3PR10MB7957.namprd10.prod.outlook.com ([fe80::6234:e7a1:b517:c44]) by CH3PR10MB7957.namprd10.prod.outlook.com ([fe80::6234:e7a1:b517:c44%6]) with mapi id 15.20.7202.035; Wed, 24 Jan 2024 00:30:26 +0000 From: Qing Zhao To: joseph@codesourcery.com, richard.guenther@gmail.com, jakub@redhat.com, siddhesh@gotplt.org, uecker@tugraz.at Cc: keescook@chromium.org, isanbard@gmail.com, gcc-patches@gcc.gnu.org, Qing Zhao Subject: [PATCH v4 4/4] Use the .ACCESS_WITH_SIZE in bound sanitizer. Date: Wed, 24 Jan 2024 00:29:55 +0000 Message-Id: <20240124002955.3387096-5-qing.zhao@oracle.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20240124002955.3387096-1-qing.zhao@oracle.com> References: <20240124002955.3387096-1-qing.zhao@oracle.com> X-ClientProxiedBy: BL0PR0102CA0005.prod.exchangelabs.com (2603:10b6:207:18::18) To CH3PR10MB7957.namprd10.prod.outlook.com (2603:10b6:610:1bf::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH3PR10MB7957:EE_|IA1PR10MB5994:EE_ X-MS-Office365-Filtering-Correlation-Id: b9e5ceb0-aef8-4914-c790-08dc1c73a8e6 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 7jXYlq7GJ58F8Ee5pQNj4/WuzOtqUpRAk031VkdX0PhyORSwVGg3beVTC3rn2ft0SlZ3rTyeIZ+wskkqsaOucnl95CzroXE2tocYSVUGVClHc248xxYVRxAaETldKRVJqjGLfMVaVyX2SWscG2G0JecpBtmIWg1o3ObN4lv5ZDxlGBEl9KJeHQKV7Yg94X8pDYjRUVRTd2Uz794qMdhbaQf/ulJ0K+fGgLxMm9K4FmRiNyubYG6KmuPJQxrReOHdYPdjjkhWqlgT+SrplUW6+YXuOvVagctKLFJRiIbQTimOmb0/0dWBG2VcFu3xrIfDHD3s12yA2gXW9iZcL2Ad+T2SAsF5hEseBT2FWA/aJeIkVLMe0n/See8sXnxpU5E28lb3rS4oZFNt3/UrR5PtUmFWCu0V9YZxOZ0RFzVIeIJwDSBw86dNbYOehMDKdi0cef/ynBAOLV1U2tyMrWKifz3sKVPwo6OFkJbpR7iEn3CRdBkJM7bKl193Qw8texF4oiRVsXcG2nROPwUQrgaOAmX84KY43uoeau8K9t5Blo6g8rEh1laZPpCC75/FbfTq+wTdlGfDfWsUYLwazBUNJdaV4o5qPHatBH4+QQgpV44= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CH3PR10MB7957.namprd10.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(376002)(136003)(346002)(39860400002)(366004)(396003)(230922051799003)(451199024)(186009)(64100799003)(1800799012)(84970400001)(6666004)(6486002)(478600001)(38100700002)(26005)(2616005)(83380400001)(6512007)(6506007)(316002)(44832011)(5660300002)(30864003)(2906002)(8936002)(8676002)(4326008)(36756003)(86362001)(66556008)(66476007)(66946007)(1076003)(107886003)(41300700001)(142923001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: qhQPMG3aKfjzlq5eoLhzSFufzDJq9uAKzkVPhiHVmFqZR4d921wicqpEAjpJfvfDsrxn6NhzcpdnlPRxggFbzQQ8CwItRrZXrU+Sw0AiaQF8QYxdMJK/3GXMAXc3hc/om0pAd3ekyND65svySpQpAw6ZR9qfyB5tTEXILoFDUmgIRb1aAPkUHr01Ahr8Kz+exMDqalJsuTq3GoVd0YPNL6ts6Dg6Anm7ixSH3K32MKEMcCxYpRNI9tuhe1Qucxuw6JARkC0L0yqAbxHhYvQwUxuSIZE4KIoi/0d3kPQ5HEiYnC1XtgGHv+Z1s0hd6GXADaExcDZzhZHNF2wxUaWbqb+2JngAJWZFlRY7BPkRSph4llVNrc0kl0T3xRUTKh7PjFLBqSGJDzXgAcTqE89AlNHe/xrypJKQjS7T1MnNa+WvVx6emyw8ou+EpTV9Lsj3i9VFt0AYvE+DAEoc5ikZ3i4nIh5od9Z2GO4sn5LzXQy54s9BNtoCu8Jo3Ljims0DhVXujbRDE17kUwDHVDF9FYBgcVUuC2ubU/EDDOfxlNGTyPHM4Tu+xzEcKobpkw/wTdqKvyZBMjNKr2gs0r7zf/Kp4jUfknYRrwOWScoIKpcuPiT+rMe2/L/PYIG4no5Qp0MjjzWCARu9umDseTLJItD1GPH0ovXhyofWrinnmSlrLvkTd1YYKXTnd3guo1j6VxyA9P2UToplKyhmPNpYiPtzakKoHptocfGMgXaPl4AZemqDI9i4+l07wLhB+qXMYSvUTX8+NjRuo7h9PZ9Lb3oCq5oycZHoNhtVl9T4m1oSbhYlBG0m01RNu5Zd9k3eUAlQg546oUgMREZ00TMdkFQ37KKe6uzPzPW6riRuEluOyNu3Rb77g0SFqZSNBQZp59DwmVEYkps4MGcqV1D+jhZdnnXZKphzZc72S4ChK2jTSDREy1WtniSjjzupEpJPDpjCaZ6NN94GZ46QdjJnrtb1YVOzryWejQqnG5uNVFdz7P1b5xMmO/hjGgoGIBoocDx1kM0E9Q6GYzSB5uamepkcnPEoW4kVfsQTuXRoTtRx5e8frMs7F+jz0HGl601jPZGW/YpDsLwE2L/bwG/7yfskAvyA7pR/IuoR3Sk76Gj3g2Zhl3jJmAOznVMb7IUaANf1C/T/edt8TGPlTrcvwMBQf+/oMOMZvTLIDhMVJRTQAvGK4efdh7TpvG9Q8fwKxDMZ4NbHkTNyGID5lgT7WtS4/0lOnTljZ/+QWcX5SzDL6xZX9wGJ5CsB7BDYqR85zEF7f1TreRCoBDouDKPnSahwglFfkJ7JWk8//jmguXiF/rF1uMMFybxHBW4QHGxyHJqRHlst6qXeRdYcDUR/Bo1uvTrRyrYFI6KuTrEKTUJpmpixEa1OSQfhCrSvcn8DGWiR5IOwEifRzcZT7iuV12HPIDmV5w8bq4Ptc0vB+ibYcibB1An5FdhMm8VxixaAOetKJcBKKlXQHF1ZbLNjWWUoMxoftwXs0DO2yGYwh/5ia94TX29EdmnHdGzEfe7G0Kmx2oN8F0WsJLxZqQyJt6lULMkwuOvXHjGZ4eEdQeymsUdDBgwDypTdLMXPkeeL X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: I3mroFNvaes48Vawk/J3gg1t9QMYq6KHZnyUFMUxxbpF4RhMRJ5ELgZWccvt4mqhEhQJhjpUzGCzyGvkJ4u+qeyyv7kxVhw4DdbQvQ4IWArYNyJ1zOgWqogBlHsGgXr4Z+9L01v0j5ThPpHl85uqNawlxkxAdaP8Tiw/RsQx2o1uQ5EPLQ83vPRj619gA2Bt3m7qu9XhDjE8tMdtd9kot1lfK3WjWLruSiYbdMqCnoOX7Lt39T5rgoacZWTrwssXx5jvEDjRzK4/lXcHSTHLU+YaXcRr5czLfxxggdp1iHki+dat2BF8htoIOYIcmoEsBpsxxxlwlpR1jwmsgRL8MW1PNA8hfQ7q7bLE1jMnCiwj1P7JBRw7hCEjkHrfIgmBxvpwAuHkHtBgQ/S9rlhasaE4Er+p/V9o7uRTHLwC8XbsH/oESbhLDNkYlv1VGAzoOerjjJ0GxDT0AOdUIvIJqHWWQZBaWR1V/G2Pmua96InIHytAnbn6OpUiM7LGm6E23FliO5fda5ZcFRWbKe62bAWarZXrYGfN22w9EYcgFlmP2V485wglUumbLCPpaCousHxchzUwsPWqHnWD7ykN/AcKJlvQtxNkctUyLzt/HtY= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: b9e5ceb0-aef8-4914-c790-08dc1c73a8e6 X-MS-Exchange-CrossTenant-AuthSource: CH3PR10MB7957.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Jan 2024 00:30:26.1257 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: qsoz8nh7fgn0j/hAmYl6sxZ2CfRVUnOdnaKIPtMGYVO6thdN3qg7WOKSmItWrqKxVzDSF8YeBb8UEmFsh9Eo3Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR10MB5994 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-01-23_14,2024-01-23_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 adultscore=0 suspectscore=0 phishscore=0 malwarescore=0 mlxscore=0 mlxlogscore=999 spamscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311290000 definitions=main-2401240001 X-Proofpoint-GUID: 9UWOkYGWNFC9ib2b64P50QUAm7-AkT9c X-Proofpoint-ORIG-GUID: 9UWOkYGWNFC9ib2b64P50QUAm7-AkT9c X-Spam-Status: No, score=-10.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Since the result type of the call to .ACCESS_WITH_SIZE is a pointer to the element type. The original array_ref is converted to an indirect_ref, which introduced two issues for the instrumenation of bound sanitizer: A. The index for the original array_ref was mixed into the offset expression for the new indirect_ref. In order to make the instrumentation for the bound sanitizer easier, one more argument for the function .ACCESS_WITH_SIZE is added to record this original index for the array_ref. then later during bound instrumentation, get the index from the additional argument from the call to the function .ACCESS_WITH_SIZE. B. In the current bound sanitizer, no instrumentation will be inserted for an indirect_ref. In order to add instrumentation for an indirect_ref with a call to .ACCESS_WITH_SIZE, we should specially handle the indirect_ref with a call to .ACCESS_WITH_SIZE, and get the index and bound info from the arguments of the call. gcc/c-family/ChangeLog: * c-gimplify.cc (ubsan_walk_array_refs_r): Instrument indirect_ref. * c-ubsan.cc (get_bound_from_access_with_size): New function. (ubsan_instrument_bounds_indirect_ref): New function. (ubsan_indirect_ref_instrumented_p): New function. (ubsan_maybe_instrument_indirect_ref): New function. * c-ubsan.h (ubsan_maybe_instrument_indirect_ref): New prototype. gcc/c/ChangeLog: * c-typeck.cc (build_counted_by_ref): Minor style fix. (build_access_with_size_for_counted_by): Add one more argument. (build_array_ref): Set the 5th argument of a call to .ACCESS_WITH_SIZE to the index. gcc/testsuite/ChangeLog: * gcc.dg/ubsan/flex-array-counted-by-bounds-2.c: New test. * gcc.dg/ubsan/flex-array-counted-by-bounds.c: New test. --- gcc/c-family/c-gimplify.cc | 2 + gcc/c-family/c-ubsan.cc | 130 ++++++++++++++++++ gcc/c-family/c-ubsan.h | 1 + gcc/c/c-typeck.cc | 14 +- .../ubsan/flex-array-counted-by-bounds-2.c | 45 ++++++ .../ubsan/flex-array-counted-by-bounds.c | 46 +++++++ 6 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ubsan/flex-array-counted-by-bounds-2.c create mode 100644 gcc/testsuite/gcc.dg/ubsan/flex-array-counted-by-bounds.c diff --git a/gcc/c-family/c-gimplify.cc b/gcc/c-family/c-gimplify.cc index 494da49791d5..25a3ca1a9a99 100644 --- a/gcc/c-family/c-gimplify.cc +++ b/gcc/c-family/c-gimplify.cc @@ -108,6 +108,8 @@ ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data) } else if (TREE_CODE (*tp) == ARRAY_REF) ubsan_maybe_instrument_array_ref (tp, false); + else if (TREE_CODE (*tp) == INDIRECT_REF) + ubsan_maybe_instrument_indirect_ref (tp); else if (TREE_CODE (*tp) == MODIFY_EXPR) { /* Since r7-1900, we gimplify RHS before LHS. Consider diff --git a/gcc/c-family/c-ubsan.cc b/gcc/c-family/c-ubsan.cc index 940982819ddf..7bb6464eb5b5 100644 --- a/gcc/c-family/c-ubsan.cc +++ b/gcc/c-family/c-ubsan.cc @@ -376,6 +376,7 @@ ubsan_instrument_return (location_t loc) return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data)); } + /* Instrument array bounds for ARRAY_REFs. We create special builtin, that gets expanded in the sanopt pass, and make an array dimension of it. ARRAY is the array, *INDEX is an index to the array. @@ -501,6 +502,68 @@ ubsan_instrument_bounds (location_t loc, tree array, tree *index, *index, bound); } +/* Get the tree that represented the number of counted_by, i.e, the maximum + number of the elements of the object that the call to .ACCESS_WITH_SIZE + points to, this number will be the bound of the corresponding array. */ +static tree +get_bound_from_access_with_size (tree call) +{ + if (!is_access_with_size_p (call)) + return NULL_TREE; + + tree ref_to_size = CALL_EXPR_ARG (call, 1); + unsigned int type_of_size = TREE_INT_CST_LOW (CALL_EXPR_ARG (call, 2)); + unsigned int prec_of_size = TREE_INT_CST_LOW (CALL_EXPR_ARG (call, 3)); + tree type = build_nonstandard_integer_type (prec_of_size, 1); + tree size = fold_build2 (MEM_REF, type, unshare_expr (ref_to_size), + build_int_cst (ptr_type_node, 0)); + /* Only when type_of_size is 1,i.e, the number of the elements of + the object type, return the size. */ + if (type_of_size != 1) + return NULL_TREE; + else + size = fold_convert (sizetype, size); + + return size; +} + +/* Instrument array bounds for INDIRECT_REFs whose pointers are + POINTER_PLUS_EXPRs of calls to .ACCESS_WITH_SIZE. We create special + builtins that gets expanded in the sanopt pass, and make an array + dimension of it. ARRAY is the pointer to the base of the array, + which is a call to .ACCESS_WITH_SIZE. + We get the INDEX from the 6th argument of the call to .ACCESS_WITH_SIZE + Return NULL_TREE if no instrumentation is emitted. */ + +tree +ubsan_instrument_bounds_indirect_ref (location_t loc, tree array) +{ + if (!is_access_with_size_p (array)) + return NULL_TREE; + tree bound = get_bound_from_access_with_size (array); + tree index = CALL_EXPR_ARG (array, 5); + /* When the index is a constant -1, it's an invalid index. */ + if ((TREE_CODE (index) == INTEGER_CST) + && TREE_INT_CST_LOW (index) == (long unsigned int) -1) + return NULL_TREE; + gcc_assert (bound); + + /* Create a "(T *) 0" tree node to describe the original array type. + We get the original array type from the first argument of the call to + .ACCESS_WITH_SIZE (REF, COUNTED_BY_REF, 1, num_bytes, -1). + + Originally, REF is a COMPONENT_REF with the original array type, + it was converted to a pointer to an ADDR_EXPR, and the ADDR_EXPR's + first operand is the original COMPONENT_REF. */ + tree ref = CALL_EXPR_ARG (array, 0); + tree array_type + = unshare_expr (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (ref, 0), 0))); + tree zero_with_type = build_int_cst (build_pointer_type (array_type), 0); + return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS, + void_type_node, 3, zero_with_type, + unshare_expr (index), bound); +} + /* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS. */ bool @@ -536,6 +599,73 @@ ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one) } } +/* Return true iff T is an INDIRECT_REF that was instrumented + by SANITIZE_BOUNDS. */ + +bool +ubsan_indirect_ref_instrumented_p (const_tree t) +{ + if (TREE_CODE (t) != INDIRECT_REF) + return false; + + tree pointer = TREE_OPERAND (t, 0); + if (TREE_CODE (pointer) != POINTER_PLUS_EXPR) + return false; + tree offset = NULL_TREE; + if (is_access_with_size_p (TREE_OPERAND (pointer, 0))) + offset = TREE_OPERAND (pointer, 1); + else if (is_access_with_size_p (TREE_OPERAND (pointer, 1))) + offset = TREE_OPERAND (pointer, 0); + else + return false; + return TREE_CODE (offset) == COMPOUND_EXPR + && TREE_CODE (TREE_OPERAND (offset, 0)) == CALL_EXPR + && CALL_EXPR_FN (TREE_OPERAND (offset, 0)) == NULL_TREE + && CALL_EXPR_IFN (TREE_OPERAND (offset, 0)) == IFN_UBSAN_BOUNDS; +} + +/* Instrument an INDIRECT_REF, if it hasn't already been instrumented. + Right now, we only instrument an INDIRECT_REF when its pointer is a + POINTER_PLUS_EXPR, with one operand is a call to .ACCESS_WITH_SIZE, + and the other operand is an offset to the array. We will compute the + array index based on the offset and the size of each element, and use + the computed index for the instrumentation. */ + +void +ubsan_maybe_instrument_indirect_ref (tree *expr_p) +{ + if (!ubsan_indirect_ref_instrumented_p (*expr_p) + && sanitize_flags_p (SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT) + && current_function_decl != NULL_TREE) + { + tree pointer = TREE_OPERAND (*expr_p, 0); + if (TREE_CODE (pointer) != POINTER_PLUS_EXPR) + return; + tree array = NULL_TREE; + tree offset = NULL_TREE; + int nth_op = 0; + if (is_access_with_size_p (TREE_OPERAND (pointer, 0))) + { + array = TREE_OPERAND (pointer, 0); + offset = TREE_OPERAND (pointer, 1); + nth_op = 1; + } + else if (is_access_with_size_p (TREE_OPERAND (pointer, 1))) + { + array = TREE_OPERAND (pointer, 1); + offset = TREE_OPERAND (pointer, 0); + } + else + return; + + tree e = ubsan_instrument_bounds_indirect_ref (EXPR_LOCATION (*expr_p), + array); + if (e != NULL_TREE) + TREE_OPERAND (pointer, nth_op) + = build2 (COMPOUND_EXPR, TREE_TYPE (offset), e, offset); + } +} + static tree ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype, enum ubsan_null_ckind ckind) diff --git a/gcc/c-family/c-ubsan.h b/gcc/c-family/c-ubsan.h index 9df03445a2ba..ed495266e82d 100644 --- a/gcc/c-family/c-ubsan.h +++ b/gcc/c-family/c-ubsan.h @@ -28,6 +28,7 @@ extern tree ubsan_instrument_return (location_t); 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_indirect_ref (tree *); extern void ubsan_maybe_instrument_reference (tree *); extern void ubsan_maybe_instrument_member_call (tree, bool); diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 4020bafc8e36..4fcb99fa0a5d 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -2576,7 +2576,8 @@ build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type) { tree field_id = TREE_VALUE (TREE_VALUE (attr_counted_by)); counted_by_ref - = build_component_ref (UNKNOWN_LOCATION, datum, field_id, + = build_component_ref (UNKNOWN_LOCATION, + datum, field_id, UNKNOWN_LOCATION, UNKNOWN_LOCATION); counted_by_ref = build_fold_addr_expr (counted_by_ref); @@ -2602,11 +2603,15 @@ build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type) to: - .ACCESS_WITH_SIZE (REF, COUNTED_BY_REF, 1, num_bytes, -1) + .ACCESS_WITH_SIZE (REF, COUNTED_BY_REF, 1, num_bytes, -1, INDEX) NOTE: Both the return type and the type of the first argument of this function have been converted from the incomplete array type to the corresponding pointer type. + + INDEX is -1 when we build the call to .ACCESS_WITH_SIZE. and + will be set to the corresponding tree node when we parse the + index at build_array_ref. */ static tree build_access_with_size_for_counted_by (location_t loc, tree ref, @@ -2619,12 +2624,13 @@ build_access_with_size_for_counted_by (location_t loc, tree ref, tree call = build_call_expr_internal_loc (loc, IFN_ACCESS_WITH_SIZE, - result_type, 5, + result_type, 6, array_to_pointer_conversion (loc, ref), counted_by_ref, build_int_cst (integer_type_node, 1), build_int_cst (integer_type_node, counted_by_precision), + build_int_cst (integer_type_node, -1), build_int_cst (integer_type_node, -1)); SET_EXPR_LOCATION (call, loc); return call; @@ -3006,6 +3012,8 @@ build_array_ref (location_t loc, tree array, tree index) gcc_assert (TREE_CODE (TREE_TYPE (ar)) == POINTER_TYPE); gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE); + if (is_access_with_size_p (ar)) + CALL_EXPR_ARG (ar, 5) = index; ret = build_indirect_ref (loc, build_binary_op (loc, PLUS_EXPR, ar, index, false), RO_ARRAY_INDEXING); diff --git a/gcc/testsuite/gcc.dg/ubsan/flex-array-counted-by-bounds-2.c b/gcc/testsuite/gcc.dg/ubsan/flex-array-counted-by-bounds-2.c new file mode 100644 index 000000000000..148934975ee5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/flex-array-counted-by-bounds-2.c @@ -0,0 +1,45 @@ +/* test the attribute counted_by and its usage in + bounds sanitizer combined with VLA. */ +/* { dg-do run } */ +/* { dg-options "-fsanitize=bounds" } */ +/* { dg-output "index 11 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*index 20 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*index 11 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*index 10 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */ + + +#include + +void __attribute__((__noinline__)) setup_and_test_vla (int n, int m) +{ + struct foo { + int n; + int p[][n] __attribute__((counted_by(n))); + } *f; + + f = (struct foo *) malloc (sizeof(struct foo) + m*sizeof(int[n])); + f->n = m; + f->p[m][n-1]=1; + return; +} + +void __attribute__((__noinline__)) setup_and_test_vla_1 (int n1, int n2, int m) +{ + struct foo { + int n; + int p[][n2][n1] __attribute__((counted_by(n))); + } *f; + + f = (struct foo *) malloc (sizeof(struct foo) + m*sizeof(int[n2][n1])); + f->n = m; + f->p[m][n2][n1]=1; + return; +} + +int main(int argc, char *argv[]) +{ + setup_and_test_vla (10, 11); + setup_and_test_vla_1 (10, 11, 20); + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/ubsan/flex-array-counted-by-bounds.c b/gcc/testsuite/gcc.dg/ubsan/flex-array-counted-by-bounds.c new file mode 100644 index 000000000000..81eaeb3f2681 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/flex-array-counted-by-bounds.c @@ -0,0 +1,46 @@ +/* test the attribute counted_by and its usage in + bounds sanitizer. */ +/* { dg-do run } */ +/* { dg-options "-fsanitize=bounds" } */ + +#include + +struct flex { + int b; + int c[]; +} *array_flex; + +struct annotated { + int b; + int c[] __attribute__ ((counted_by (b))); +} *array_annotated; + +void __attribute__((__noinline__)) setup (int normal_count, int annotated_count) +{ + array_flex + = (struct flex *)malloc (sizeof (struct flex) + + normal_count * sizeof (int)); + array_flex->b = normal_count; + + array_annotated + = (struct annotated *)malloc (sizeof (struct annotated) + + annotated_count * sizeof (int)); + array_annotated->b = annotated_count; + + return; +} + +void __attribute__((__noinline__)) test (int normal_index, int annotated_index) +{ + array_flex->c[normal_index] = 1; + array_annotated->c[annotated_index] = 2; +} + +int main(int argc, char *argv[]) +{ + setup (10, 10); + test (10, 10); + return 0; +} + +/* { dg-output "36:21: runtime error: index 10 out of bounds for type" } */