From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 47lCOQFlRWroiSEAWB0awg (envelope-from ) for ; Wed, 01 Jul 2026 15:05:37 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=amd.com header.i=@amd.com header.a=rsa-sha256 header.s=selector1 header.b=BpcANCnP; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id D00B21E024; Wed, 01 Jul 2026 15:05:37 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id BF6851E024 for ; Wed, 01 Jul 2026 15:05:36 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A951A4BA2E1F for ; Wed, 1 Jul 2026 19:05:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A951A4BA2E1F Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=amd.com header.i=@amd.com header.a=rsa-sha256 header.s=selector1 header.b=BpcANCnP Received: from CH4PR04CU002.outbound.protection.outlook.com (mail-northcentralusazlp170130007.outbound.protection.outlook.com [IPv6:2a01:111:f403:c105::7]) by sourceware.org (Postfix) with ESMTPS id 7406A4BA5434 for ; Wed, 1 Jul 2026 19:05:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7406A4BA5434 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=amd.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7406A4BA5434 Authentication-Results: sourceware.org; arc=pass smtp.remote-ip=2a01:111:f403:c105::7 ARC-Seal: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1782932707; cv=pass; b=dsI9eHsQMeAxpV7D1fliHaf2rqf2I1HjjZa0bmlKNoEiEjKRI84nwqs/jQ6zjamyeVoMHfp2aibjz503FbARADu9KGbAvfelcr4Ij4CxYwRAp1D/yLWnKrmE1NQSkuvUDulk8SI6w+bahKdfEV9ie4tp62Ti3E+HYkQ+oQhJ1Aw= ARC-Message-Signature: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1782932707; c=relaxed/simple; bh=AmlZ13HKxAO3d/ftboIorTXq8UXPrOqrO/In1XFa3MY=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=pmjckBE3cDkXQOT2/tAXlTaY51Fjj4LOomWjmT7RxzJjilYpMmwlTb5VHuSGpjWOy93ZyIzes4R4cC2ZSBt7BGMr11GDIGq8Eopc8RZuvMVtujYdpZTFb9vSf5wIewjyqY7UvBp8sW3c+Fk1eQhGFaEDAAgabwd6DCBm+d61HPs= ARC-Authentication-Results: i=2; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=amd.com header.i=@amd.com header.a=rsa-sha256 header.s=selector1 header.b=BpcANCnP DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7406A4BA5434 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=kJGboViztNM1PAbu3rYrs+uBUbc9XJpk/94sXqLhJHvsW1z9lA88wm0jDCfpyUb0/RXh0XimbHdD43gwnqBWcx9W5WJ7DX0pxht+W+79n84Gtds7P7cC7wo6iF7+QVIZQw7KgrUee5ziKktV6I5hCff4kt9zyWkU3V8b0RLRtPOUaycckEO1+kh1bVt0ekGoWHROiMNCU7Ri+leVfQ1w/+zyYG8O/teXl7fH6x7GL+dmR3yq5H7X0BE2kFfMyE4KefyFS86XGO3ntKQXfcOSWqq7cemAJb7c/7kdeP2Ly5s0su6+L9a4Myfx5RkGafrhoRLPCrIAsUXIQDxcALUj8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=uJTzDk40pXV2+I8tFXjl9QZVyqKtD/YCA3gEv4IfA/A=; b=WdfQtGT9QmQDNXExC3vfxQxpOEKoaW70vs7am9Rus5VjTvMZn1aqWlxS8410Q2+oheAGJHtzP7Hd2cvaP+LagRqb4MY+ajL3jnmlrqjp2QIb8D20+7y717TbeW3JZdIR9KshIWurLU04i2lSmLJ3s0NOW8qddWDxm+CvYQFHFvhfYrnTRTxlxD7Yi8QN0kc6gc51lMF01CoC0mZo5IIP4axb2s3FPSFRLo4vQJvWqxDCbYuv3orJ29bpCZNleY6/8P25n7UNKRT+vDUJQgwH1MjPvo01vVT0sZqMuyYFCubvQf28Vl0H3eMFaI+mRik1ni0p9HjbVfB2NqdQEebyHg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=sourceware.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=uJTzDk40pXV2+I8tFXjl9QZVyqKtD/YCA3gEv4IfA/A=; b=BpcANCnPqcfTDySIJ1WJOBRupQwNJOv990rUZS+Jx4bzJNXrQVnyMdBt1/BxWGNUliNJ6L3NIJk6Zh5/tiZpJj7Jvt5+rh8NOC+/VlS1vjYqChHHz01Zjmn67IghueugY8ARQubQaYNT0H6REjZRktQi5ell4YRwBOZLSInbPaI= Received: from SJ0PR13CA0238.namprd13.prod.outlook.com (2603:10b6:a03:2c1::33) by DS2PR12MB9776.namprd12.prod.outlook.com (2603:10b6:8:2bd::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.181.8; Wed, 1 Jul 2026 19:04:59 +0000 Received: from SJ1PEPF000023DA.namprd21.prod.outlook.com (2603:10b6:a03:2c1:cafe::37) by SJ0PR13CA0238.outlook.office365.com (2603:10b6:a03:2c1::33) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.181.8 via Frontend Transport; Wed, 1 Jul 2026 19:04:59 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by SJ1PEPF000023DA.mail.protection.outlook.com (10.167.244.75) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.202.0 via Frontend Transport; Wed, 1 Jul 2026 19:04:59 +0000 Received: from Satlexmb09.amd.com (10.181.42.218) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Wed, 1 Jul 2026 14:04:58 -0500 Received: from ctr-rack32-mi300x-1.amd.com (10.180.168.240) by satlexmb09.amd.com (10.181.42.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Wed, 1 Jul 2026 12:02:09 -0700 From: Luis Machado To: CC: , Subject: [PATCH v3] gdb: replace alloca with gdb::unique_xmalloc_ptr in remote-fileio.c Date: Wed, 1 Jul 2026 14:01:56 -0500 Message-ID: <20260701190156.3900537-1-luis.machado@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260630095238.1700797-1-luis.machado@amd.com> References: <20260630095238.1700797-1-luis.machado@amd.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: satlexmb08.amd.com (10.181.42.217) To satlexmb09.amd.com (10.181.42.218) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023DA:EE_|DS2PR12MB9776:EE_ X-MS-Office365-Filtering-Correlation-Id: 596eeafe-1147-4a7d-ac88-08ded7a3a5ac X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|23010399003|376014|82310400026|36860700016|1800799024|18002099003|22082099003|56012099006|5023799004|11063799006; X-Microsoft-Antispam-Message-Info: 8C1K4RQhEgzcTVBz22acEyBvMOM3P3VzD8NsD5zQCE8Ctz1r/IjCArqHwsyQdm921j3IOWPAQGKbqwhJ+HbNi4zCccieALejfcxL0dvfXiLRRufmwKUtqakO+GrReYK/hFhJgxHv0s6rq6hH7fFhi5RA0tSGRwjKixPQARmsownwuZXfgGg/vJszyWl0yww/2SMXqqP8b4KMNfgO25vAIakpKSuLUdMrPbYDwfC3KKeahWbcNyk3p9JkGy6VDELJsAeagK0BGuMANLKF4D9u2l+IeBb7H/lSzWAyj6qn6YPdr4/BIQs1D/pEIAiuHAy+Y8Svatti9gSvLlxqJ/bK0ZcCPupjR44vyuRc7q53Obm3Ev2vfglAmB1oh3eeHGoAX2S3PDfAR7W/5Qj+fWyveLBzVCQLJV6er7JPTzOZDEoXQ5osI4pKX7XZapDYC92uPZBlK0M5oqdzG8n537pBQQpRtDsAOF17/w/ZjGOs46fj725RAnRvqLwf4UaUl8IqmjvWoWDa2k+dqeNGKjzXiAReG5/HwQNHQ8VX7kUfvNCv3HUM2/JQtbDVg3rgC4hyHd7+jekEoxSlB/9Ae44U6fDT2yQJU47ad7EGvImvAIlt8vUOFZ6Lwn4sDweJKIJgSmzS1tbzByTl4BP7frnOROAv7Yv77Kq+4AODt1HB+jeWTn+TrNKXwfm9F8FIn3L8UAEC7OKXzbZE+7F9LdD0oQ== X-Forefront-Antispam-Report: CIP:165.204.84.17; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:satlexmb08.amd.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(23010399003)(376014)(82310400026)(36860700016)(1800799024)(18002099003)(22082099003)(56012099006)(5023799004)(11063799006); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 5RVAmLSzLZOvDrU9/A98V1Ur8mIWXQAR4c7ttfpVgprPDbyVOqQuxA+/hpl+awhLCgB7lN61qmXH+lhMEIunUIjU1e+0KwliXO+SHWcHFh8Tn8rRCp7QNtMH3iuJczo0h9YpBmz5gWQimgzRXMo0H2s1DXvfUPpBq9Q0AIiq/AZEbCkYE3pV/CL3zHW8EFsGVSfkiWgqY2HH4g0vCCWi9auGfQPbiqxxs01sdPVZwHoSWn7URKQfrvKyyfM5jc374m/y5RvVLgO84ubdmFnAuBkyAGqAbeFPxXfiGZqANyGhai28SipcLNyneMP0unGvr1aNYLgAFtHGsszvbjVkauSwr3fIsBlDfnRmiJ3jncgrswpMXgvicNHhWOCpgP0dfGgO+MrCfU7O85lBUrRjOwG80q7ONOu/KV2S5bOoOoNV/4HPA0fCthz3ci1Cf7ct X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Jul 2026 19:04:59.1690 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 596eeafe-1147-4a7d-ac88-08ded7a3a5ac X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17]; Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023DA.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS2PR12MB9776 X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org remote_fileio_extract_ptr_w_len parsed a debuggee controlled 64 bit length, narrowed it to int with no bounds check, and the value flowed directly into alloca() across RSP File I/O handlers (Fopen, Frename, Funlink, Fstat, Fsystem). A malicious inferior or remote stub could send a crafted packet with a large path length, displacing the stack pointer by up to 2 GiB and potentially crashing the debugger. remote_fileio_extract_ptr_w_len now rejects negative lengths, lengths that would overflow the int result (greater than INT_MAX), and zero. An allow_zero_length flag lets the Fsystem handler opt in to the zero length sentinel that signals a NULL cmdline query. All other handlers use the default and are protected without any per call checks. Oversized names are rejected naturally by the underlying syscall with ENAMETOOLONG. All alloca(length) calls have been replaced with gdb::unique_xmalloc_ptr, so an oversized but positive length now fails as a graceful heap allocation error rather than corrupting the stack. Add a selftest that exercises various problematic cases. Signed-off-by: Luis Machado --- gdb/remote-fileio.c | 142 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 111 insertions(+), 31 deletions(-) diff --git a/gdb/remote-fileio.c b/gdb/remote-fileio.c index ef608cabfab..a151161371d 100644 --- a/gdb/remote-fileio.c +++ b/gdb/remote-fileio.c @@ -31,6 +31,7 @@ #include "target.h" #include "filenames.h" #include "gdbsupport/filestuff.h" +#include "gdbsupport/selftest.h" #include #include "gdbsupport/gdb_sys_time.h" @@ -194,7 +195,8 @@ remote_fileio_extract_int (char **buf, long *retint) } static int -remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length) +remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length, + bool allow_zero_length = false) { char *c; LONGEST retlong; @@ -211,6 +213,11 @@ remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length) *buf = c; if (remote_fileio_extract_long (buf, &retlong)) return -1; + /* Reject negative lengths, values that would overflow the int length and + zero (unless the caller permits it for the Fsystem NULL-cmdline sentinel). + Oversized names are caught by the syscall. */ + if (retlong < 0 || retlong > INT_MAX || (!allow_zero_length && retlong == 0)) + return -1; *length = (int) retlong; return 0; } @@ -305,7 +312,6 @@ remote_fileio_func_open (remote_target *remote, char *buf) long num; int flags, fd; mode_t mode; - char *pathname; struct stat st; /* 1. Parameter: Ptr to pathname / length incl. trailing zero. */ @@ -339,8 +345,8 @@ remote_fileio_func_open (remote_target *remote, char *buf) } /* Request pathname. */ - pathname = (char *) alloca (length); - if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0) + gdb::unique_xmalloc_ptr pathname ((char *) xmalloc (length)); + if (target_read_memory (ptrval, (gdb_byte *) pathname.get (), length) != 0) { remote_fileio_ioerror (remote); return; @@ -349,7 +355,7 @@ remote_fileio_func_open (remote_target *remote, char *buf) /* Check if pathname exists and is not a regular file or directory. If so, return an appropriate error code. Same for trying to open directories for writing. */ - if (!stat (pathname, &st)) + if (!stat (pathname.get (), &st)) { if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)) { @@ -364,7 +370,7 @@ remote_fileio_func_open (remote_target *remote, char *buf) } } - fd = gdb_open_cloexec (pathname, flags, mode).release (); + fd = gdb_open_cloexec (pathname.get (), flags, mode).release (); if (fd < 0) { remote_fileio_return_errno (remote, -1); @@ -659,7 +665,6 @@ remote_fileio_func_rename (remote_target *remote, char *buf) { CORE_ADDR old_ptr, new_ptr; int old_len, new_len; - char *oldpath, *newpath; int ret, of, nf; struct stat ost, nst; @@ -678,24 +683,24 @@ remote_fileio_func_rename (remote_target *remote, char *buf) } /* Request oldpath using 'm' packet */ - oldpath = (char *) alloca (old_len); - if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0) + gdb::unique_xmalloc_ptr oldpath ((char *) xmalloc (old_len)); + if (target_read_memory (old_ptr, (gdb_byte *) oldpath.get (), old_len) != 0) { remote_fileio_ioerror (remote); return; } /* Request newpath using 'm' packet */ - newpath = (char *) alloca (new_len); - if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0) + gdb::unique_xmalloc_ptr newpath ((char *) xmalloc (new_len)); + if (target_read_memory (new_ptr, (gdb_byte *) newpath.get (), new_len) != 0) { remote_fileio_ioerror (remote); return; } /* Only operate on regular files and directories. */ - of = stat (oldpath, &ost); - nf = stat (newpath, &nst); + of = stat (oldpath.get (), &ost); + nf = stat (newpath.get (), &nst); if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode)) || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode))) { @@ -703,7 +708,7 @@ remote_fileio_func_rename (remote_target *remote, char *buf) return; } - ret = rename (oldpath, newpath); + ret = rename (oldpath.get (), newpath.get ()); if (ret == -1) { @@ -726,10 +731,10 @@ remote_fileio_func_rename (remote_target *remote, char *buf) char newfullpath[PATH_MAX]; int len; - cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath, - PATH_MAX); - cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath, - PATH_MAX); + cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath.get (), + oldfullpath, PATH_MAX); + cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath.get (), + newfullpath, PATH_MAX); len = strlen (oldfullpath); if (IS_DIR_SEPARATOR (newfullpath[len]) && !filename_ncmp (oldfullpath, newfullpath, len)) @@ -752,7 +757,6 @@ remote_fileio_func_unlink (remote_target *remote, char *buf) { CORE_ADDR ptrval; int length; - char *pathname; int ret; struct stat st; @@ -763,8 +767,8 @@ remote_fileio_func_unlink (remote_target *remote, char *buf) return; } /* Request pathname using 'm' packet */ - pathname = (char *) alloca (length); - if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0) + gdb::unique_xmalloc_ptr pathname ((char *) xmalloc (length)); + if (target_read_memory (ptrval, (gdb_byte *) pathname.get (), length) != 0) { remote_fileio_ioerror (remote); return; @@ -772,13 +776,14 @@ remote_fileio_func_unlink (remote_target *remote, char *buf) /* Only operate on regular files (and directories, which allows to return the correct return code). */ - if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)) + if (!stat (pathname.get (), &st) && !S_ISREG (st.st_mode) + && !S_ISDIR (st.st_mode)) { remote_fileio_reply (remote, -1, FILEIO_ENODEV); return; } - ret = unlink (pathname); + ret = unlink (pathname.get ()); if (ret == -1) remote_fileio_return_errno (remote, -1); @@ -791,7 +796,6 @@ remote_fileio_func_stat (remote_target *remote, char *buf) { CORE_ADDR statptr, nameptr; int ret, namelength; - char *pathname; LONGEST lnum; struct stat st; struct fio_stat fst; @@ -812,14 +816,15 @@ remote_fileio_func_stat (remote_target *remote, char *buf) statptr = (CORE_ADDR) lnum; /* Request pathname using 'm' packet */ - pathname = (char *) alloca (namelength); - if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0) + gdb::unique_xmalloc_ptr pathname ((char *) xmalloc (namelength)); + if (target_read_memory (nameptr, (gdb_byte *) pathname.get (), + namelength) != 0) { remote_fileio_ioerror (remote); return; } - ret = stat (pathname, &st); + ret = stat (pathname.get (), &st); if (ret == -1) { @@ -997,24 +1002,28 @@ remote_fileio_func_system (remote_target *remote, char *buf) { CORE_ADDR ptrval; int ret, length; - char *cmdline = NULL; /* Parameter: Ptr to commandline / length incl. trailing zero */ - if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length)) + if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length, true)) { remote_fileio_ioerror (remote); return; } + gdb::unique_xmalloc_ptr cmdline_buf; + const char *cmdline = nullptr; + if (length) { /* Request commandline using 'm' packet */ - cmdline = (char *) alloca (length); - if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0) + cmdline_buf.reset ((char *) xmalloc (length)); + if (target_read_memory (ptrval, (gdb_byte *) cmdline_buf.get (), + length) != 0) { remote_fileio_ioerror (remote); return; } + cmdline = cmdline_buf.get (); } /* Check if system(3) has been explicitly allowed using the @@ -1244,6 +1253,73 @@ show_system_call_allowed (const char *args, int from_tty) remote_fio_system_call_allowed ? "" : "not "); } +#if GDB_SELF_TEST + +namespace selftests { + +/* Verify that remote_fileio_extract_ptr_w_len rejects negative and zero + lengths, and accepts valid ones. The packet buffer format is + "ptr/len[,...]" with both fields as hex integers. */ + +static void +test_remote_fileio_extract_ptr_w_len () +{ + CORE_ADDR ptrval; + int length; + + /* Build a writable "ptr/len" buffer and parse it, with and without + the Fsystem zero-length allowance. */ + auto parse = [&] (const char *s) -> int + { + std::string buf (s); + char *p = buf.data (); + return remote_fileio_extract_ptr_w_len (&p, &ptrval, &length); + }; + auto parse_allow_zero = [&] (const char *s) -> int + { + std::string buf (s); + char *p = buf.data (); + return remote_fileio_extract_ptr_w_len (&p, &ptrval, &length, true); + }; + + /* Valid: length 1 (minimum positive). Verify both fields are parsed. */ + SELF_CHECK (parse ("deadbeef/1") == 0); + SELF_CHECK (ptrval == 0xdeadbeef); + SELF_CHECK (length == 1); + + /* Valid: packet with trailing fields. */ + SELF_CHECK (parse ("deadbeef/4,0,1a4") == 0); + SELF_CHECK (ptrval == 0xdeadbeef); + SELF_CHECK (length == 4); + + /* Valid: length 0 with allow_zero_length (Fsystem). */ + SELF_CHECK (parse_allow_zero ("0/0") == 0); + SELF_CHECK (length == 0); + + /* Invalid: length 0 without allow_zero_length (pathname handlers). */ + SELF_CHECK (parse ("0/0") == -1); + + /* Valid: largest positive length accepted (technically INT_MAX). */ + SELF_CHECK (parse ("1/7fffffff") == 0); + SELF_CHECK (length == 0x7fffffff); + + /* Invalid: one past INT_MAX overflows the int length. */ + SELF_CHECK (parse ("1/80000000") == -1); + + /* Invalid: a length whose 64-bit value is negative is rejected. */ + SELF_CHECK (parse ("1/8000000000000000") == -1); + + /* Invalid: negative length. */ + SELF_CHECK (parse ("1/-1") == -1); + + /* Invalid: missing '/' separator. */ + SELF_CHECK (parse ("deadbeef") == -1); +} + +} /* namespace selftests */ + +#endif /* GDB_SELF_TEST */ + void initialize_remote_fileio (struct cmd_list_element **remote_set_cmdlist, struct cmd_list_element **remote_show_cmdlist) @@ -1256,4 +1332,8 @@ initialize_remote_fileio (struct cmd_list_element **remote_set_cmdlist, show_system_call_allowed, _("Show if the host system(3) call is allowed for the target."), remote_show_cmdlist); +#if GDB_SELF_TEST + selftests::register_test ("remote_fileio_extract_ptr_w_len", + selftests::test_remote_fileio_extract_ptr_w_len); +#endif } -- 2.34.1