From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM10-MW2-obe.outbound.protection.outlook.com (mail-mw2nam10olkn2068.outbound.protection.outlook.com [40.92.42.68]) by sourceware.org (Postfix) with ESMTPS id 94AD33858297 for ; Fri, 29 Jul 2022 16:29:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 94AD33858297 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=R3qbWjYn+kDxwMP7e37Yc3e1smECWiNDbJHEHpdYczO6dUWdKCHNqU9AeI+ng/4VOadaivQvDeIzugJUl+RGyLsmVhU44ZwVpJ6QYmiEbO8Jcue3C7CDnQdhGha3YeDF7jA+cQOrn7TKlt7rO4Q4wjmeLIjJEtQlykknxXWNvD6L8vqCk1PQWSE6Sk+rCzrIEnou0FMRFcU/MvXsqcPFzJswcAqffSC5clgTuVZNm3JAV84C+36AjMRbqIlkqu04cC8dsmytYDt3KdIxfLu2sjENHgZRAWrQsj1t83gKjgio7xYNxVnOqMGwKjTRr6+wnS/iq3E1jUdPnlST3lFalQ== 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=18XPfP1qXMpW7MJYu1fOm2Huj2JBzKOwXHD3DtEwTVc=; b=BRtrTFyne4nHBO/Vzbewe4WX/9F2zN0Iljbs8ro22LL/aqj/MUeoKAdle+sTXP/1yNr8CCG5RUVxlpZWWICCNb8VZGRxVgk6VWYAg23MNth/w4K5ssvLMwRriSkR7Mgz1FI1H7pW77y7sAeG35musggOoFjtYkIlqUgxHUq2bCz/95FBYeCVA1cTTJjUE6leWTAHMgloc4YUKu3u+3t4QKeLgUus3TfvbNbm3hjckhlc/U2XagpfP71YySqKNXLK+SG1SuE08N1RoIxZjYYuZBPypBiPgLBvfxXDAKlGaDw+/Gm36Fw34IshId4uXH3k929+M7vyhS4CF+MyildtWA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none Received: from CY4PR1801MB1910.namprd18.prod.outlook.com (2603:10b6:910:79::14) by MWHPR18MB0943.namprd18.prod.outlook.com (2603:10b6:300:9a::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5482.12; Fri, 29 Jul 2022 16:29:41 +0000 Received: from CY4PR1801MB1910.namprd18.prod.outlook.com ([fe80::c5c4:ae52:8e5f:e5c5]) by CY4PR1801MB1910.namprd18.prod.outlook.com ([fe80::c5c4:ae52:8e5f:e5c5%6]) with mapi id 15.20.5458.024; Fri, 29 Jul 2022 16:29:41 +0000 From: Immad Mir To: gcc-patches@gcc.gnu.org Cc: dmalcolm@redhat.com, mirimnan017@gmail.com, Immad Mir Subject: [PATCH] analyzer: support for creat, dup, dup2 and dup3 in sm-fd.cc [PR106300] Date: Fri, 29 Jul 2022 21:59:21 +0530 Message-ID: X-Mailer: git-send-email 2.25.1 Reply-To: mirimnan017@gmail.com Content-Transfer-Encoding: 8bit Content-Type: text/plain X-TMN: [4MOdA+PIWKozc72DHMO9pzBxsCwISCESLnTixfcEn8k6AY34Pq9NmjY8nE7U5h2R] X-ClientProxiedBy: PN0PR01CA0032.INDPRD01.PROD.OUTLOOK.COM (2603:1096:c01:4e::22) To CY4PR1801MB1910.namprd18.prod.outlook.com (2603:10b6:910:79::14) X-Microsoft-Original-Message-ID: <20220729162921.30432-1-mirimmad@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2fa34820-2be3-4c0b-fef8-08da717f89b1 X-MS-Exchange-SLBlob-MailProps: aa/WAlXx4eTAgnIwsmYPVUcSW8neIt/O96kac7piL+xBlagTgZrDyU3SVuN02ZoHwRZ/NAXJGWJ7j6tJhN0TDkMkqZRomeS9Dmdf4ajIsWiql9RaUQi2liiwzQ5OpKtRccvqfP95Y+GHVw3F8gvCxGEcQskhIcbdfDIZdKllzfXBzH0F1fBvKSuv7QsFKv1FLVyAH2/IthLRGFYFr1RlGxi9jXyWtO2BxRboD7+vMSVpcTyqMW9ARRQsPCmkIngbEhwQEibTopF+4v6BJoGGbxTR4ZSXIw8PdDtntXC7BzE7DKIpz+OavZ2yfZLEjrlQz1fe3auwFnQM3aWrtbS5dxpSl/dMWp+75pkI8dFeTvENdGjVm5/VWjnXLJQyckSNVV3hkUZMLPG42IVfm6D91FjfHTTUFif9M+oW1squIhqHF/MYkEWXkeU+M17gf1rdvLN6WqVWLQSKp9sndBcKy6la2bE8rtQbQgZixon9qhVcKM2M7tpWfaSqk/S4eD6K6P+KBXUVLGBBEL66CHkHjicbiM2w7da/4Va+LQBnU3SvruxMsPETXSW1E54eyVoupp+rAYBSIO5pWM1LUwTUkPdG97p76xOffRfEMQjYvYTY6Gra/t5xmZpcrcOuqrrOIR0m9ggvqXCf3HZU6iROHCOxbNyj/Sx12hNPXdKi4Ndbhh6wxdAg4eFY0g+X8F4/IiXL4VRKPJu+81u3gTZ6MQ6S3GwVvjCTRrdNZLSFDMcMdMVq497ZQqTtgX0gyAvE1KW7s55vFYvBzAEh7Yg3YXIWASaiqkYc X-MS-TrafficTypeDiagnostic: MWHPR18MB0943:EE_ X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ACXNfVLJ/5WyGspYzcdZwSzGYrjLZDUsuDNq0Pgf7/N5fjN3rRgSdNpRzuLYGX/ow3T0TzGE0G3M1/BOEn4Yhygu+BbQownznbBTXk79+ytCaEuSiig0v2T+0EcLB0Ul1WbwEP/3g2DKtcX+Vx51o7FKdOLOfx7ynXe6hZ0XpxTueeSemEhjnY1fz7SRaa1Qmz8TdNRpTDtq1wlV4JbG/RlDuo0i9nMk7p59cLV1uHc8aBvXbinSreoclI/VTHpU2VNdrDKRpi1e/VHphag4JOqAzU4cc+Sxu8qXPqVqzCC2YTqKhtng8m7m/0GqmbbaNU95cNopjXRMJn7ogh0n5TuI2SJSLT9law6ZehnngAd98gSVAK9Ah1IsvoSTelwm1Q/kRFluK0pZ+I8HKdlf2ONtXYUBPxytGSnCujxsNNyo1OvYpFyuNnrGK5ymgn8z8ThiUcVOvWDC6blVWX4nQMxY8m5ARC3SHFYp8Hk+soWBEY/K8Oa+QdksKwnwL68hXQDwAOKLkn9PHwZsPegxIWL1q6vR+rwkuLhR8PkV6/LCvRmTzR0lIfLMImgwiiYw8lrrSkQ3Vip0nHIGViMYaaUcF52NEZ0dJzaWyJ8vRYwR+opq8K3bMVxtJxtGJmh5 X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?wC9My/aoIcLVZE/FIXl9sRxG/Km+t1hKIKClad7E0chu7vZuJ01bHEo+kuCI?= =?us-ascii?Q?tB8vP3Q4cYHzJqdly1e5nC+CtZO3l+LOrIQO/2X4lmJELiQ7W4cb8nS/nMQz?= =?us-ascii?Q?ZdstOzriOj0b93O2OcYfNv01xZMusOhRCyFXNByGykS5y7Rsxgxdu55lItVR?= =?us-ascii?Q?ok/Tm8Qu0NRoo7VaYZGoIFbcuGWgS/O2azuEfKI/gaCzroas4mtXZRSSJKaG?= =?us-ascii?Q?uOXOpaiUsmh/2sxeKtoXyhsttHN1dwPUP0U5YdI5PGzLWd7ddgjqbMYiFb+Z?= =?us-ascii?Q?HtnaMsEd0i1K2sgGA0HhfwF9jytWz+sAJF3ysNOdM9y6D8tpcyY0iIrdpCgg?= =?us-ascii?Q?tuaD7cYflf852SKDJxUpacTW1Pxbd56JPOPCJuzYlXq385ncGzs9oBaUvtpd?= =?us-ascii?Q?9i9n/2jZSbJ8l3AvILqJzc7/d+bdZQOeTm7sP/UbrfYNYdYM+sK3XhAKgPYp?= =?us-ascii?Q?Tbwnn13A2d9Ctu2qON/AcgaDcR+lRaYH0iVpPCkd+ngZRgjfELvcRng+U1Yx?= =?us-ascii?Q?XMRrfrNSyh5vo3i+ZjbECTW2GxqvdC2T4bbzjZyeUUNdHLbTwBrXP0hrLQP6?= =?us-ascii?Q?a5uMN8iLGgG6t44vDAsvH1F1CMPy3eQ/pQwYI+adKHiEwxASb6bExdE06oqS?= =?us-ascii?Q?b8dk4qV5ueECLSEubtmKjKNsVeL8/9u0rWf0XPxCkdL2bFE3BG71EuNJEvSh?= =?us-ascii?Q?MJKllVy82clR2S+RJCjQLLu0BIGcRq8rRE9fz3Qk3Z9xb33XB/5cyWhB7tKp?= =?us-ascii?Q?EY5isoXbfDOqQyfVNSL6e5OvL3crS/GDw9cnWWkPe5csedmvQ/y7Cjj5kRQS?= =?us-ascii?Q?+tj7fhDLbstOAkRLq92bVnniX1lj9PnU0mw4RUWGEjpRI4nuSp24D/mJ/qGu?= =?us-ascii?Q?p9RWIpPCT9+sbF9qqx/qwic4KKveRg+C9Q6XNoDiTtaWZpeIYgvQPZdXrl3S?= =?us-ascii?Q?GCjMbjsLWRlicbJ3ujAJMG+NPcu2yQcNF9yirB+XVcYDEBhT9tI0Yr5Ri6H1?= =?us-ascii?Q?UnwO3i2xwGhCbKi/6B4Lca6IT35sBRKsuH31I6qOE+f4mt0OGZdrgSVEK6UO?= =?us-ascii?Q?hOsEcp8PaEw+/huDM5YaKYmSe0pI1cbFwsl+S8/vGHA57p9AVWEYT9S9HAgz?= =?us-ascii?Q?8YM/hu+fh1rPShO3b/I0CuE1IfZp6QJNLqAqHQl0Wl4Vvl6n2hetzPiGBT1n?= =?us-ascii?Q?8T401FU1VYBI0XbVcZvsvAnmUz5hjMVXAkkZoU0RU3rFk/BTaw/pVok+M2OY?= =?us-ascii?Q?1Ddo97um/JTo+wrOeJZ/CoFpMHF7RrjHSNPIqQ5lAu+ZVVMrAet2eL+bKjDF?= =?us-ascii?Q?aF7QXViW+xVSNLbBjyMCPeZEBAo7NewqwKdRe7I8sWA6Bg=3D=3D?= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2fa34820-2be3-4c0b-fef8-08da717f89b1 X-MS-Exchange-CrossTenant-AuthSource: CY4PR1801MB1910.namprd18.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Jul 2022 16:29:41.5806 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR18MB0943 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, FREEMAIL_REPLYTO, FREEMAIL_REPLYTO_END_DIGIT, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Jul 2022 16:29:45 -0000 This patch extends the state machine in sm-fd.cc to support creat, dup, dup2 and dup3 functions. Lightly tested on x86_64 Linux. gcc/analyzer/ChangeLog: PR analyzer/106300 * sm-fd.cc (fd_state_machine::on_open): Add creat, dup, dup2 and dup3 functions. (enum dup): New. (fd_state_machine::valid_to_unchecked_state): New. (fd_state_machine::on_creat): New. (fd_state_machine::on_dup): New. gcc/testsuite/ChangeLog: PR analyzer/106300 * gcc.dg/analyzer/fd-1.c: Add tests for 'creat'. * gcc.dg/analyzer/fd-2.c: Likewise. * gcc.dg/analyzer/fd-4.c: Likewise. * gcc.dg/analyzer/fd-6.c: New tests. Signed-off-by: Immad Mir --- gcc/analyzer/sm-fd.cc | 117 ++++++++++++++++++- gcc/testsuite/gcc.dg/analyzer/fd-1.c | 21 ++++ gcc/testsuite/gcc.dg/analyzer/fd-2.c | 15 +++ gcc/testsuite/gcc.dg/analyzer/fd-4.c | 31 ++++- gcc/testsuite/gcc.dg/analyzer/fd-6.c | 168 +++++++++++++++++++++++++++ 5 files changed, 350 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/fd-6.c diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc index ed923ade100..7906034599c 100644 --- a/gcc/analyzer/sm-fd.cc +++ b/gcc/analyzer/sm-fd.cc @@ -69,6 +69,13 @@ enum access_directions DIRS_WRITE }; +enum dup +{ + DUP_1, + DUP_2, + DUP_3 +}; + class fd_state_machine : public state_machine { public: @@ -114,7 +121,9 @@ public: bool is_readonly_fd_p (state_t s) const; bool is_writeonly_fd_p (state_t s) const; enum access_mode get_access_mode_from_flag (int flag) const; - + /* Function for one-to-one correspondence between valid + and unchecked states. */ + state_t valid_to_unchecked_state (state_t state) const; /* State for a constant file descriptor (>= 0) */ state_t m_constant_fd; @@ -147,6 +156,8 @@ public: private: void on_open (sm_context *sm_ctxt, const supernode *node, const gimple *stmt, const gcall *call) const; + void on_creat (sm_context *sm_ctxt, const supernode *node, const gimple *stmt, + const gcall *call) const; void on_close (sm_context *sm_ctxt, const supernode *node, const gimple *stmt, const gcall *call) const; void on_read (sm_context *sm_ctxt, const supernode *node, const gimple *stmt, @@ -170,6 +181,9 @@ private: const gimple *stmt, const gcall *call, const tree callee_fndecl, const char *attr_name, access_directions fd_attr_access_dir) const; + void check_for_dup (sm_context *sm_ctxt, const supernode *node, + const gimple *stmt, const gcall *call, const tree callee_fndecl, + enum dup kind) const; }; /* Base diagnostic class relative to fd_state_machine. */ @@ -723,6 +737,20 @@ fd_state_machine::is_constant_fd_p (state_t state) const return (state == m_constant_fd); } +fd_state_machine::state_t +fd_state_machine::valid_to_unchecked_state (state_t state) const +{ + if (state == m_valid_read_write) + return m_unchecked_read_write; + else if (state == m_valid_write_only) + return m_unchecked_write_only; + else if (state == m_valid_read_only) + return m_unchecked_read_only; + else + gcc_unreachable (); + return NULL; +} + bool fd_state_machine::on_stmt (sm_context *sm_ctxt, const supernode *node, const gimple *stmt) const @@ -736,6 +764,11 @@ fd_state_machine::on_stmt (sm_context *sm_ctxt, const supernode *node, return true; } // "open" + if (is_named_call_p (callee_fndecl, "creat", call, 2)) + { + on_creat (sm_ctxt, node, stmt, call); + } // "creat" + if (is_named_call_p (callee_fndecl, "close", call, 1)) { on_close (sm_ctxt, node, stmt, call); @@ -754,6 +787,23 @@ fd_state_machine::on_stmt (sm_context *sm_ctxt, const supernode *node, return true; } // "read" + if (is_named_call_p (callee_fndecl, "dup", call, 1)) + { + check_for_dup (sm_ctxt, node, stmt, call, callee_fndecl, DUP_1); + return true; + } + + if (is_named_call_p (callee_fndecl, "dup2", call, 2)) + { + check_for_dup (sm_ctxt, node, stmt, call, callee_fndecl, DUP_2); + return true; + } + + if (is_named_call_p (callee_fndecl, "dup3", call, 3)) + { + check_for_dup (sm_ctxt, node, stmt, call, callee_fndecl, DUP_3); + return true; + } { // Handle __attribute__((fd_arg)) @@ -899,6 +949,71 @@ fd_state_machine::on_open (sm_context *sm_ctxt, const supernode *node, } } +void +fd_state_machine::on_creat (sm_context *sm_ctxt, const supernode *node, + const gimple *stmt, const gcall *call) const +{ + tree lhs = gimple_call_lhs (call); + if (lhs) + sm_ctxt->on_transition (node, stmt, lhs, m_start, m_unchecked_write_only); + else + sm_ctxt->warn (node, stmt, NULL_TREE, new fd_leak (*this, NULL_TREE)); +} + +void +fd_state_machine::check_for_dup (sm_context *sm_ctxt, const supernode *node, + const gimple *stmt, const gcall *call, + const tree callee_fndecl, enum dup kind) const +{ + tree lhs = gimple_call_lhs (call); + tree arg_1 = gimple_call_arg (call, 0); + state_t state_arg_1 = sm_ctxt->get_state (stmt, arg_1); + tree diag_arg_1 = sm_ctxt->get_diagnostic_tree (arg_1); + if (state_arg_1 == m_stop) + return; + if (!(is_constant_fd_p (state_arg_1) || is_valid_fd_p (state_arg_1))) + { + sm_ctxt->warn ( + node, stmt, arg_1, + new fd_use_without_check (*this, diag_arg_1, callee_fndecl)); + if (kind == DUP_1) + return; + } + switch (kind) + { + case DUP_1: + if (!is_constant_fd_p (state_arg_1)) + if (lhs) + sm_ctxt->set_next_state (stmt, lhs, + valid_to_unchecked_state (state_arg_1)); + break; + + case DUP_2: + case DUP_3: + tree arg_2 = gimple_call_arg (call, 1); + state_t state_arg_2 = sm_ctxt->get_state (stmt, arg_2); + tree diag_arg_2 = sm_ctxt->get_diagnostic_tree (arg_2); + if (state_arg_2 == m_stop) + return; + if (!(is_constant_fd_p (state_arg_2) || is_valid_fd_p (state_arg_2))) + { + sm_ctxt->warn ( + node, stmt, arg_2, + new fd_use_without_check (*this, diag_arg_2, callee_fndecl)); + return; + } + + if (!is_constant_fd_p (state_arg_2)) + { + if (lhs) + sm_ctxt->set_next_state (stmt, lhs, + valid_to_unchecked_state (state_arg_2)); + } + + break; + } +} + void fd_state_machine::on_close (sm_context *sm_ctxt, const supernode *node, const gimple *stmt, const gcall *call) const diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-1.c b/gcc/testsuite/gcc.dg/analyzer/fd-1.c index 8a72e63833c..5b85a3316e8 100644 --- a/gcc/testsuite/gcc.dg/analyzer/fd-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/fd-1.c @@ -3,6 +3,13 @@ int open(const char *, int mode); #define O_WRONLY 1 #define O_RDWR 2 +typedef enum { + S_IRWXU + // etc +} mode_t; + +int creat (const char *, mode_t mode); + void test_1 (const char *path) { @@ -37,3 +44,17 @@ void test_4 (const char *path) /* { dg-message "\\(1\\) leaks here" "" { target *-*-* } .-1 } */ } +void +test_5 (const char *path, mode_t mode) +{ + creat (path, mode); /* { dg-warning "leak of file descriptor \\\[CWE-775\\\]" } */ +} + +void +test_6 (const char *path, mode_t mode) +{ + int fd = creat (path, mode); + return; /* { dg-warning "leak of file descriptor 'fd' \\\[CWE-775\\\]" } */ +} + + diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-2.c b/gcc/testsuite/gcc.dg/analyzer/fd-2.c index d794b460a2e..10c9ecdb09d 100644 --- a/gcc/testsuite/gcc.dg/analyzer/fd-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/fd-2.c @@ -5,6 +5,13 @@ void close(int fd); #define O_RDWR 2 #define STDIN 0 +typedef enum { + S_IRWXU + // etc +} mode_t; + +int creat (const char *, mode_t mode); + void test_1 (const char *path) { @@ -46,4 +53,12 @@ test_4 () int fd = -1; close(fd); close(fd); +} + +void +test_5 (const char *path, mode_t mode) +{ + int fd = creat (path, mode); + close(fd); + close(fd); /* { dg-warning "double 'close' of file descriptor 'fd' \\\[CWE-1341\\\]" "warning" } */ } \ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-4.c b/gcc/testsuite/gcc.dg/analyzer/fd-4.c index ecd787caff7..6b8fca5408f 100644 --- a/gcc/testsuite/gcc.dg/analyzer/fd-4.c +++ b/gcc/testsuite/gcc.dg/analyzer/fd-4.c @@ -9,6 +9,12 @@ int read (int fd, void *buf, int nbytes); #define O_WRONLY 1 #define O_RDWR 2 +typedef enum { + S_IRWXU + // etc +} mode_t; + +int creat (const char *, mode_t mode); void test_1 (const char *path, void *buf) @@ -69,4 +75,27 @@ test_5 (const char *path) int fd = open (path, O_RDWR); close(fd); printf("%d", fd); /* { dg-bogus "'printf' on a closed file descriptor 'fd'" } */ -} \ No newline at end of file +} + + +void +test_6 (const char *path, mode_t mode, void *buf) +{ + int fd = creat (path, mode); + if (fd != -1) + { + read (fd, buf, 1); /* { dg-warning "'read' on write-only file descriptor 'fd'" } */ + close(fd); + } +} + +void +test_7 (const char *path, mode_t mode, void *buf) +{ + int fd = creat (path, mode); + if (fd != -1) + { + write (fd, buf, 1); + close(fd); + } +} diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-6.c b/gcc/testsuite/gcc.dg/analyzer/fd-6.c new file mode 100644 index 00000000000..5c58cd1519c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/fd-6.c @@ -0,0 +1,168 @@ +int open(const char *, int mode); +void close(int fd); +int dup (int old_fd); +int dup2 (int old_fd, int new_fd); +int dup3 (int old_fd, int new_fd, int flags); +int write (int fd, void *buf, int nbytes); +int read (int fd, void *buf, int nbytes); +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +void test_1 (const char *path) +{ + int old_fd = open (path, O_RDWR); + int new_fd = dup (old_fd); /* { dg-warning "'dup' on possibly invalid file descriptor 'old_fd'" } */ + close(old_fd); + close(new_fd); +} + +void test_2 (const char *path) +{ + int old_fd = open (path, O_RDWR); + if (old_fd != -1) + { + int new_fd = dup (old_fd); + close(old_fd); + return; /* { dg-warning "leak of file descriptor 'new_fd' \\\[CWE-775\\\]" } */ + } +} + +void test_3 (const char *path, void *buf) +{ + int old_fd = open (path, O_RDWR); + if (old_fd != -1) + { + int new_fd = dup (old_fd); + write (new_fd, buf, 1); /* { dg-warning "'write' on possibly invalid file descriptor 'new_fd'" } */ + close (new_fd); + close(old_fd); + } +} + + +void test_5 (const char *path, void *buf) +{ + int old_fd = open (path, O_RDWR); + if (old_fd != -1) + { + int new_fd = dup (old_fd); + if (new_fd != -1) + { + write (new_fd, buf, 1); + close (new_fd); + + } + close(old_fd); + } +} + + +void test_7 (const char *path) +{ + int old_fd = open (path, O_RDWR); + dup2 (old_fd, 4); /* { dg-warning "'dup2' on possibly invalid file descriptor 'old_fd'" } */ + close(old_fd); +} + +void test_8 (const char *path) +{ + int old_fd = open (path, O_RDWR); + int new_fd = open (path, O_RDWR); + if (old_fd != -1) + { + dup2 (old_fd, new_fd); /* { dg-warning "'dup2' on possibly invalid file descriptor 'new_fd'" } */ + close (old_fd); + } + close (new_fd); +} + +void test_9 (const char *path, void *buf) +{ + int old_fd = open (path, O_RDWR); + + if (old_fd != -1) + { + int new_fd = open (path, O_RDWR); + if (new_fd != -1) + { + int lhs = dup2 (old_fd, new_fd); + write (lhs, buf, 1); /* { dg-warning "'write' on possibly invalid file descriptor 'lhs'" } */ + close(new_fd); + close(lhs); + } + close(old_fd); + } +} + +void test_10 (const char *path, int flags) +{ + int old_fd = open (path, O_RDWR); + int new_fd = open (path, O_RDWR); + if (old_fd != -1) + { + dup3 (old_fd, new_fd, flags); /* { dg-warning "'dup3' on possibly invalid file descriptor 'new_fd'" } */ + close(old_fd); + + } + close(new_fd); +} + +void test_11 (const char *path, int flags) +{ + int old_fd = open (path, O_RDWR); + int new_fd = open (path, O_RDWR); + if (new_fd != -1) + { + dup3 (old_fd, new_fd, flags); /* { dg-warning "'dup3' on possibly invalid file descriptor 'old_fd'" } */ + close(new_fd); + + } + close(old_fd); +} + +void test_12 (const char *path, void *buf) +{ + int old_fd = open (path, O_RDONLY); + if (old_fd != -1) + { + int new_fd = dup (old_fd); + if (new_fd != -1) + { + write (new_fd, buf, 1); /* { dg-warning "'write' on read-only file descriptor 'new_fd'" } */ + close(new_fd); + } + close(old_fd); + } +} + +void test_13 (const char *path, void *buf) +{ + int old_fd = open (path, O_WRONLY); + if (old_fd != -1) + { + int new_fd = dup (old_fd); + if (new_fd != -1) + { + read (new_fd, buf, 1); /* { dg-warning "'read' on write-only file descriptor 'new_fd'" } */ + close(new_fd); + } + close(old_fd); + } +} + +void test_14 (const char *path, void *buf) +{ + int old_fd = open (path, O_RDWR); + if (old_fd != -1) + { + int new_fd = dup (old_fd); + if (new_fd != -1) + { + write (new_fd, buf, 1); + read (new_fd, buf, 1); + close(new_fd); + } + close(old_fd); + } +} \ No newline at end of file -- 2.25.1