From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by sourceware.org (Postfix) with ESMTPS id 4B55E384AB59 for ; Fri, 26 Apr 2024 20:20:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4B55E384AB59 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine 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 4B55E384AB59 Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=205.220.177.32 ARC-Seal: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1714162862; cv=pass; b=vMT7c2wvU9yeYkTPUDmEhIbzLzTXvGYxjUmYciRMeRKfwdsvPTtMdSpJluD58AW3tpS33EkWt8cJozHGoMBaO0mPulfQAsw/nZpyosX64AlVUQfKt1PnZxuR30Ip+1pRmxKDLktTpuWx0XJ+zGpMeqBXG6D6gDC+EhtyN4wD/DU= ARC-Message-Signature: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1714162862; c=relaxed/simple; bh=sehqcXUDcu0dy8Emzb4CBa0HiPrBSEoGj1HNdcMf6vM=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-ID: MIME-Version; b=EhCqr5yNpoouSlOujdhiE5UcdxCDz+o9Gxc69C7z9K/+wiSdyR3o7/4nKVc+rD2uwx4htsca53WKISNT7cWYEkG3f7V4CUTV9TMd4tQpJA50iUnQshsiDKCND2/wzoSibXqoRDiirouwIEt3IhBBGJxfcDr2xtqp4sUVoUvQkmg= ARC-Authentication-Results: i=2; server2.sourceware.org Received: from pps.filterd (m0333520.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 43QKABRS002707 for ; Fri, 26 Apr 2024 20:20:59 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references : content-transfer-encoding : content-type : mime-version; s=corp-2023-11-20; bh=L2Hc8nBKgki4XlLaMB1mAcnG7pht9uCLMkGxsDYwjaM=; b=VNhHyIJt0bCcvr/OlmnH9owGLDZxFv3PldNDq27p4K+dd6O3ydcftWRgsp8P0dKl7uY3 wzVbNBqxopRSVmFtlRfnn1/IKtVZPDWsU190EDodfAn0hIkeE7pqcecb0YNXvyitstJP k1nMkNUVnfnxgDljJ1EZXMSUEsTLZI4DyKQbBHOm8Lkzr6mHIxNhJJtsjr+j3kn+3fQ9 2u4RhDC97x/smA6zEYPcHHxRi8+pETlKTpcS221d9YHB/455Z1qNXkNFGjFww1kecEWr 8cUJAfcB2A/gerRVmVpdCQ+2C+Sl7A+pFKyf0Xd9fWVm3seI4z31m95DesaHZCNvisHt TQ== Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3xm5re6c49-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 26 Apr 2024 20:20:58 +0000 Received: from pps.filterd (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 43QKCmRT030797 for ; Fri, 26 Apr 2024 20:20:57 GMT Received: from nam10-bn7-obe.outbound.protection.outlook.com (mail-bn7nam10lp2100.outbound.protection.outlook.com [104.47.70.100]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 3xm45c3tt0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 26 Apr 2024 20:20:57 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gVWAsI2r/HRcdKl0k4vnd6DpHvkpMC25u4TZOj5cLUXcQsAk1vZ5+dNb26hztJqS1zVW5EwnpwmTEoEq6SI08FCIJ+cUG1qq7nGMM71VCCA9zd0XhQ+FJM9i1XmINC9JSojxysgOX9xa8BHOxcHd7h/XyibaSDzR+TTnE/kkWJPLpVMfKvH158h32u24r397iQTP4N8l60FrgNkvnjbU8N0KXVkyr+JMELx1N1Qdk/NX5dcrm95aNPBFbZ4TvFR4V6nk/K3muMFkK4UUoERrkPmQftGZgc5GCKQnJXuud3GJaeFNqXF3WYgKV4p0riZsAOayEUuK16mqWJL5d9FBTQ== 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=L2Hc8nBKgki4XlLaMB1mAcnG7pht9uCLMkGxsDYwjaM=; b=W9Va9JUEOFbQOkUBYx7FX4vG+wfpredpQlXKDFm21Do7QhrQmj9+tIzVdNhHKpl6pye3clfVS0JGjlDWiK2sXgtlaw0lsmVcEfajS5d7970M9DqCx2FGwht7qcjMGRHV22b16pJOe3QjbA4o+5kGj2zf1c8q3SgkBKwux28HVSy2QZI3bGPVDdDk5hwQ8132I694CK9ReHEejCCH2olOBJHylwFVyTQPwpf9ag5D3rkPlILsdbMGus2N4FLANaHevT09K40BYW6SQs+naafCOtkA4wkPZC1f/shzhj6Zo6Rk3ommn5FwIUoRXzm27b/aCgmSrc1lLgBK0HmkvFr2Yw== 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=L2Hc8nBKgki4XlLaMB1mAcnG7pht9uCLMkGxsDYwjaM=; b=gEvlX+4EYjVNhYKIWPCAvJ2fDjM238KLt6903ObK4pMPMI8KMsw6o5x9cx9aJ+PQKgB27+xZFHflXFJdJicWK5bhMJQB/VmRWMelK7JZcc6ZYUIO0mEdUPltwJARCrHrMXgev7740aLt1G8jyjKU0b0cwoVFl2ONANL12vcI3/k= Received: from MW4PR10MB6608.namprd10.prod.outlook.com (2603:10b6:303:22e::8) by SA1PR10MB7791.namprd10.prod.outlook.com (2603:10b6:806:3a9::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.31; Fri, 26 Apr 2024 20:20:55 +0000 Received: from MW4PR10MB6608.namprd10.prod.outlook.com ([fe80::67a4:9544:7249:7751]) by MW4PR10MB6608.namprd10.prod.outlook.com ([fe80::67a4:9544:7249:7751%7]) with mapi id 15.20.7472.044; Fri, 26 Apr 2024 20:20:55 +0000 From: Nick Alcock To: binutils@sourceware.org Subject: [PATCH 7/7] libctf: fix leak of entire dict when dict opening fails Date: Fri, 26 Apr 2024 21:20:23 +0100 Message-ID: <20240426202023.423064-8-nick.alcock@oracle.com> X-Mailer: git-send-email 2.44.0.273.ge0bd14271f In-Reply-To: <20240426202023.423064-1-nick.alcock@oracle.com> References: <20240426202023.423064-1-nick.alcock@oracle.com> Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: LO2P265CA0303.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:a5::27) To MW4PR10MB6608.namprd10.prod.outlook.com (2603:10b6:303:22e::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MW4PR10MB6608:EE_|SA1PR10MB7791:EE_ X-MS-Office365-Filtering-Correlation-Id: 26c31993-157b-4678-c1ca-08dc662e6059 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230031|366007|376005|1800799015; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?GcKD6F5C+vgi4cS9tj8UFDvq/pjttVgbmU0yCzX25urPYHnBWBMnXMfCIdUe?= =?us-ascii?Q?HF7Nr0HeZMqDYJgXqkEOpJ7NwMqrZbRs3JRW9K0XO11S6KUdQaItP2J314+3?= =?us-ascii?Q?AJI/6LhsEHbaoOlODVwCmQZLndNew3+vJ8HNb7yZKbScmLQw9mNKAFkCiZjS?= =?us-ascii?Q?ZmevkccJj/u5jlxv2Wi5CyJWnUPGd6/pFeL1/iL/mBZiiB/zomTySp64tApi?= =?us-ascii?Q?xQCJYl7Zsb+qk2XaZrWjEkuDJ8AhKNy25ngRtoQjQrAUVEVIFKfZOdvXwmQB?= =?us-ascii?Q?Qdpp4BpQyIKn/C4MvE7EDTKgOUQORQvNzWiLnip415SHEqe4b+dcGQL4f2xm?= =?us-ascii?Q?Xp/Hggr5u+paJnJFizUEgpB8BhKorfj6krI7Kngid+1iC55ER/j7WvuHK/yb?= =?us-ascii?Q?a8fnl3qnH0i8OKVbY5IcdTr/VPqu4jYrSYpUHzZLZVRXPKiilgYBWjCMgP+s?= =?us-ascii?Q?BI1meaudi8JUtw+00ElwaNbZVxDjpydidi6G7BHti22V8eGVBqrqTvzhDFU4?= =?us-ascii?Q?/qhzi8CFPF7mdVikvt0G/t19QfDBoi3hVIgBiMetHSVruFQrIVAzc7JmlBgW?= =?us-ascii?Q?/lBR1lrqDxtvYIU1tY5ICT+cIRr8yQDm79S/osPaHKVmppK0aMACNJnWFX8s?= =?us-ascii?Q?MYECw7W0z5m1A/vwe91k9YqbDq5ZwaRAAGskkSKmDc8nxVE0CpzcQbxSduOq?= =?us-ascii?Q?wOT5/83dU/gfrYF5ZqvziLiG5DKIDp7/3e0pg46r7KWtW1HJI+nk19DcjVWM?= =?us-ascii?Q?v+ykyFEqWctabCL+D+EtEsEmMVPiH7JG0udfdRdNI80/S6gwJqdh9LZUs57E?= =?us-ascii?Q?aexA6eu74mc4DSVu4qkhcXy33DyzmsC+PRv3h+2iHZ2517K+ik/TMlB5cBBW?= =?us-ascii?Q?qAWYZAfbDR0GpX9wjzelEEc4BhrKOgBSIFSMCSAVjsoqxrCFN8GF1xgx9HZR?= =?us-ascii?Q?F3v7jN6kRy60VvobTW2A1xFEWgPaDlLDJ6HM60jnxLsoZJlARjlyJ5rH5ErM?= =?us-ascii?Q?TY+WJ0k4SCpIRZLgespxNo30VWX9xb5AVU+1A0muu5/WS7zjCZyCugEWpXbE?= =?us-ascii?Q?g5edafcsbo82IDNiphdnD36HUnLMGUUxtFGUxSLKzBcpPz+Ou2QTQL+weH6w?= =?us-ascii?Q?cUGqmtkWN6sqrcIsAsZN1c74EV3pqnUZuCIKsedvGyPeKZgzpytyt+rKHoFW?= =?us-ascii?Q?KZC2vHH/l0cV1CZge8XBXf9DSUIg35ZBptfDt76by4IaLSFO92QTDHks9c9N?= =?us-ascii?Q?v1qQCydnGUrRNcaavmpy3oDFqLaWPjeAmo1pq2y9Sg=3D=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MW4PR10MB6608.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(366007)(376005)(1800799015);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?VAXm28MfyNIevTfFppEb+JV5BexrMqb21/mnITQ5qF83/EJkMIK+Rl3H7NGV?= =?us-ascii?Q?OQvx5v4wERUfw3Bmzd4i43F/yyTfvFL1l07FkYVk7Eg2EeNHBeD2bxXt8+DW?= =?us-ascii?Q?jfs9kN2jnOjtgjzqdfm8UbjpeMmIgp+6rwcvykIPZOjlubPkYLGMUAiqCRdK?= =?us-ascii?Q?Z/taUUKxzlQQiLnouhTLfo9gKe1JHEWuUIh3iCjzamVf5I2/K8yE4pJzxAot?= =?us-ascii?Q?9Yqn4R0tXyrEhQvWEkDIQEgQy5D2kAHjK62e9grdFAPYr6bToLp1NOpP1KhO?= =?us-ascii?Q?q+NpGqgSU/YoGdRpy4Hq5V8NuU7Nuvwg6c/DxILaupCxkFGCmKLPhO9Hia5t?= =?us-ascii?Q?rQm3KTbBhyOZ/+2JyeRyoNb7GLYhE++gjlEbTN1fB2gruqPh8gjBNV2eV0mu?= =?us-ascii?Q?632lznQCh6qMPYsgt4RBJjE9R+qXoAYRjzn9NOVpQxXyQk0R9sxqRAt9lu80?= =?us-ascii?Q?fEr5k0ueapvA0y8SXutLjuowV1pwEvjGZh6LM0cSAZznii420l/QB4hOWH8z?= =?us-ascii?Q?lyoQZmxPO8vxZ5Yyb+mJgRHCVd5/zDJHkQbbfNVeK7ltSKc6iYemEEMg72Md?= =?us-ascii?Q?8JxOH2aMuYBZVekAqcz9xI3HqnNyPi6fOTBxbnlGe7jTUsJ2fGP9qNuR4xvH?= =?us-ascii?Q?7SgQB/ISMv/58bvMGP6LSaNaIkSokOKvEl8kemoPQoG8ecnrvPmAt5MAw6Ts?= =?us-ascii?Q?I/96tgRfjOunufbDhD5bm8R7y9pkSgM3GUXdn4uuElXtS3+eVTKsEosDJqIj?= =?us-ascii?Q?OIQF4SZKmUyYre+yz7lhno5yM/HJjp030lJbGs6pB3i1NYOJKsFuQD4j746h?= =?us-ascii?Q?18DopsY4UwRWwJICdT3bS2INkUPKRotK82dS1zC+Sw69DWuixON7ndrk+uii?= =?us-ascii?Q?DV7/AXWi1cXflEzAgw1mB7FRwgyHIpELA6eCNaFaIppXpBZ3LgGyJ7W5rkY6?= =?us-ascii?Q?sODUl03legE5pvHRTRtDkoGFvF2djeJriDliXptKXTDEzbMvO2dzHBvnubPo?= =?us-ascii?Q?2nRy88BWo3HJBjGarKWrDypDAgZrMtVrB9Aod4O59aW/T97Yd6uIGEM4xpZv?= =?us-ascii?Q?+N9SM1a+o8znuZVx6UFgWeJhimU9zVVfK2BxbLNDo8mgZ3snjGORpyGXWphX?= =?us-ascii?Q?V22uVvpynLyODgKcvfWv/nhxpUWWaCjVi2mcNKpzrjYBdP7mdSnMHKEjB6BB?= =?us-ascii?Q?De22PIn7DFTpdJ6QfzO59BMn2bEPxAuyJrtz+UvUW0pV99xrkScxfxRy5Bn3?= =?us-ascii?Q?jpVt2wfCTVQiwA3zQ3CZF/0rejRlE3esIhhxE7Mxao9udfIpIMXeW7UyHtVa?= =?us-ascii?Q?fr/ZYojbPGoAMBub15IBX0s2oFgRoMFYz8XzArVEJf0wVz3sSNXTFANSs9Su?= =?us-ascii?Q?8oCipM3lEASM2B4JI/Z52fjeBJTLJXx7Q07+oiyRiaCyt5MH1ARPGmrHIRf2?= =?us-ascii?Q?JsWnw9zSvrZuc1GLvcL5WOedX+O9ZSBYGuicWu5Kmq1zHafHzvxgIcLr1VZJ?= =?us-ascii?Q?ciw8z7UbDqPVOpzcXkevCDC5nzxvufP6XfYBeuB/gJasVANyDITJGF13j4wM?= =?us-ascii?Q?+CDJQUUyaCVscE19mPwObl6QTMsFE7vIhL4P5JVxQn/95lI+tfKgB4oFD1L3?= =?us-ascii?Q?9Q=3D=3D?= X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: sWJH8jYV48UeYw5dBigECO6AUzY0DjNwS0P1wg5oMXCobd36Ay17XeQfUpwqMPA9xaqIT5aSF8llumlIzcxc01tcuOY4Un5fZoDlNLR6FAOrgfwpRuTu4qNdhcWiQjmDvzMXyH6Y2F/QaJEJxngXrnansRdgyYBDdviKkzTYU2ZLFTx+g23ONR2l6VT2EkNpHWz9egbVT40znYUeuLkB2YjNYoxUFTIbC2A0LjHOYYSCgsGEkDWhUc8CSzd8B5ovIOS8/BkvKjcA+1P7OWWRnDuLnG6boNCtrosFrIzYijgmYDalhoK7/ZL7BKdLV6cwKmqcsyT7dra7kXsORTHPY3C4e6jRvGj5xBKqA33Z1BSUvVMTaz5mGugebI9BK0mSFDBVuAHb5vO9eBcA3jUtXeCh8N0ovXtqeysGOrar1KlTIlZpmampWOjhnijyVOXkn6y5EU6gXhBpv0QVNszsy34JPpg8Csf7XV1qaZGvUfWzlqYs2zo1jAcMTL1l7/+jCaPlWDHAFyRHaL0q5qsoHhP4tCIn6K+wxNc0jgJ9brz/xBDLSCHydq2X/zhPlAyqU47Xi49AzKmhrf+LVAIqzIMGUf/PYwW58SKa/dcf2f8= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 26c31993-157b-4678-c1ca-08dc662e6059 X-MS-Exchange-CrossTenant-AuthSource: MW4PR10MB6608.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Apr 2024 20:20:55.3188 (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: FwmtodgXJWa5vXWPowcUHuFo3jepcd7SzyM4XMkjWDlO4NWAs9rqGi/j6omTj/P5LG5UtX0I+187NvZq4bQcxg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA1PR10MB7791 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-04-26_17,2024-04-26_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 malwarescore=0 spamscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2404260141 X-Proofpoint-ORIG-GUID: UaJ39BSUtDAg1yhkHX4xlXTIqeH9Daqd X-Proofpoint-GUID: UaJ39BSUtDAg1yhkHX4xlXTIqeH9Daqd X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Ever since commit 1fa7a0c24e78e7f ("libctf: sort out potential refcount loops") ctf_dict_close has only freed anything if the refcount on entry to the function is precisely 1. >1 obviously just decrements the refcount, but the linker machinery can sometimes cause freeing to recurse from a dict to another dict and then back to the first dict again, so we interpret a refcount of 0 as an indication that this is a recursive call and we should just return, because a caller is already freeing this dict. Unfortunately there is one situation in which this is not true: the bad: codepath in ctf_bufopen entered when opening fails. Because the refcount is bumped only at the very end of ctf_bufopen, any failure causes ctf_dict_close to be entered with a refcount of zero, and it frees nothing and we leak the entire dict. The solution is to bump the refcount to 1 right before freeing... but this codepath is clearly delicate enough that we need to properly validate it, so we add a test that uses malloc interposition to count allocations and frees, creates a dict, writes it out, intentionally corrupts it (by setting a bunch of bytes after the header to a value high enough that it is definitely not a valid CTF type kind), then tries to open it again and counts the malloc/free pairs to make sure they're matched. (Test run only on *-linux-gnu, because malloc interposition is not a thing you can rely upon working everywhere, and this test is not arch-dependent so if it passes on one arch it can be assumed to pass on all of them.) libctf/ * ctf-open.c (ctf_bufopen): Bump the refcount on failure. * testsuite/libctf-regression/open-error-free.*: New test. --- libctf/ctf-open.c | 4 + .../libctf-regression/open-error-free.c | 185 ++++++++++++++++++ .../libctf-regression/open-error-free.lk | 5 + 3 files changed, 194 insertions(+) create mode 100644 libctf/testsuite/libctf-regression/open-error-free.c create mode 100644 libctf/testsuite/libctf-regression/open-error-free.lk diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c index 03faf2d886f..59c6ed0622a 100644 --- a/libctf/ctf-open.c +++ b/libctf/ctf-open.c @@ -1724,6 +1724,10 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, bad: ctf_set_open_errno (errp, err); ctf_err_warn_to_open (fp); + /* Without this, the refcnt is zero on entry and ctf_dict_close() won't + actually do anything on the grounds that this is a recursive call via + another dict being closed. */ + fp->ctf_refcnt = 1; ctf_dict_close (fp); return NULL; } diff --git a/libctf/testsuite/libctf-regression/open-error-free.c b/libctf/testsuite/libctf-regression/open-error-free.c new file mode 100644 index 00000000000..8319a09d5f5 --- /dev/null +++ b/libctf/testsuite/libctf-regression/open-error-free.c @@ -0,0 +1,185 @@ +/* Make sure that, on error, an opened dict is properly freed. */ + +#define _GNU_SOURCE 1 +#include +#include +#include +#include +#include +#include + +static unsigned long long malloc_count; +static unsigned long long free_count; + +static void *(*real_malloc) (size_t size); +static void (*real_free) (void *ptr); +static void *(*real_realloc) (void *ptr, size_t size); +static void *(*real_calloc) (size_t nmemb, size_t size); + +/* Interpose malloc/free functionss and count calls to spot unbalanced ones. + Extra complexity to deal with dlsym() calling dlerror() and thus calloc() -- + luckily it handles malloc failure fine, so we can just always fail before the + hooks are installed. */ + +static int in_hooks; + +static void hook_init (void) +{ + if (!real_calloc) + { + in_hooks = 1; + real_calloc = (void *(*) (size_t, size_t)) dlsym (RTLD_NEXT, "calloc"); + real_malloc = (void *(*) (size_t)) dlsym (RTLD_NEXT, "malloc"); + real_free = (void (*) (void *)) dlsym (RTLD_NEXT, "free"); + real_realloc = (void *(*) (void *, size_t)) dlsym (RTLD_NEXT, "realloc"); + if (!real_malloc || !real_free || !real_realloc || !real_calloc) + { + fprintf (stderr, "Cannot hook malloc\n"); + exit(1); + } + in_hooks = 0; + } +} + +void *malloc (size_t size) +{ + if (in_hooks) + return NULL; + + hook_init(); + malloc_count++; + return real_malloc (size); +} + +void *realloc (void *ptr, size_t size) +{ + void *new_ptr; + + if (in_hooks) + return NULL; + + hook_init(); + new_ptr = real_realloc (ptr, size); + + if (!ptr) + malloc_count++; + + if (size == 0) + free_count++; + + return new_ptr; +} + +void *calloc (size_t nmemb, size_t size) +{ + void *ptr; + + if (in_hooks) + return NULL; + + hook_init(); + ptr = real_calloc (nmemb, size); + + if (ptr) + malloc_count++; + return ptr; +} + +void free (void *ptr) +{ + hook_init(); + + if (in_hooks) + return; + + if (ptr != NULL) + free_count++; + + return real_free (ptr); +} + +int main (void) +{ + ctf_dict_t *fp; + ctf_encoding_t e = { CTF_INT_SIGNED, 0, sizeof (long) }; + int err; + ctf_id_t type; + size_t i; + char *written; + size_t written_size; + char *foo; + ctf_next_t *it = NULL; + unsigned long long frozen_malloc_count, frozen_free_count; + + if ((fp = ctf_create (&err)) == NULL) + goto open_err; + + /* Define an integer, then a pile of unconnected pointers to it, just to + use up space.. */ + + if ((type = ctf_add_integer (fp, CTF_ADD_ROOT, "long", &e)) == CTF_ERR) + goto err; + + for (i = 0; i < 100; i++) + { + if (ctf_add_pointer (fp, CTF_ADD_ROOT, type) == CTF_ERR) + goto err; + } + + /* Write the dict out, uncompressed (to stop it failing to open due to decompression + failure after we corrupt it: the leak is only observable if the dict gets + malloced, which only happens after that point.) */ + + if ((written = ctf_write_mem (fp, &written_size, (size_t) -1)) == NULL) + goto write_err; + + ctf_dict_close (fp); + + /* Corrupt the dict. */ + + memset (written + sizeof (ctf_header_t), 64, 64); + + /* Reset the counters: we are interested only in leaks at open + time. */ + malloc_count = 0; + free_count = 0; + + if ((ctf_simple_open (written, written_size, NULL, 0, 0, NULL, 0, &err)) != NULL) + { + fprintf (stderr, "wildly corrupted dict still opened OK?!\n"); + exit (1); + } + + /* The error log will have accumulated errors which need to be + consumed and freed if they are not to appear as a spurious leak. */ + + while ((foo = ctf_errwarning_next (NULL, &it, NULL, NULL)) != NULL) + free (foo); + + frozen_malloc_count = malloc_count; + frozen_free_count = free_count; + + if (frozen_malloc_count == 0) + fprintf (stderr, "Allocation count after failed open is zero: likely hook failure.\n"); + else if (frozen_malloc_count > frozen_free_count) + fprintf (stderr, "Memory leak is present: %lli allocations (%lli allocations, %lli frees).\n", + frozen_malloc_count - frozen_free_count, frozen_malloc_count, frozen_free_count); + else if (frozen_malloc_count < frozen_free_count) + fprintf (stderr, "Possible double-free: %li allocations, %li frees.\n", + frozen_malloc_count, frozen_free_count); + + printf ("All OK.\n"); + exit (0); + + open_err: + fprintf (stderr, "Cannot open/create: %s\n", ctf_errmsg (err)); + exit (1); + + err: + fprintf (stderr, "Cannot add: %s\n", ctf_errmsg (ctf_errno (fp))); + exit (1); + + write_err: + fprintf (stderr, "Cannot write: %s\n", ctf_errmsg (ctf_errno (fp))); + exit (1); +} diff --git a/libctf/testsuite/libctf-regression/open-error-free.lk b/libctf/testsuite/libctf-regression/open-error-free.lk new file mode 100644 index 00000000000..383cfff20d5 --- /dev/null +++ b/libctf/testsuite/libctf-regression/open-error-free.lk @@ -0,0 +1,5 @@ +# source: pptrtab-a.c +# source: pptrtab-b.c +# host: *-linux-gnu +# lookup-link: -ldl +All OK. -- 2.44.0.273.ge0bd14271f