From patchwork Fri Sep 13 10:33:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1985152 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Al8ZDcBC; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X4rHx71hmz1y1y for ; Fri, 13 Sep 2024 20:33:32 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 113533858283 for ; Fri, 13 Sep 2024 10:33:30 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 046763858D28 for ; Fri, 13 Sep 2024 10:33:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 046763858D28 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 046763858D28 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726223590; cv=none; b=ArxsO0YpLX8yO2YYOlbjUEZVXrsRvID/ZvgtC2O7nE0RBRbyJPUFcgkbo2RNJqw5L3ptFt+Da4HucNEjJbT3iqjLDhnp9z3RkE+Jx9YNxmfNIAwHro2IxsS0BTq1IsQ7pxfSbF7oi7Iny4bhWRjZjrnS1kjdKZ6IB9W6OKxcC3k= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726223590; c=relaxed/simple; bh=RUL8FAqMbV+gJ+CjYXZ0mtcmdkg/h9/7KlNY7zwljAw=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=BUVCMn525+E/l3ZiNdc2kX6SOnDNrlJFbmaeWOTPeRH4PLk1fHtyeZWUFqM3L6+FJJ8TL4LS80EKeEW3/gMTPzigYHLjyUwnjC2TWd+QR0SyoBG2JxtbCP9ZT5cPyxQEF2WhREMgRSZTEtmOcETzp/rIwbKIWs9guCM38E5GZOg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1726223587; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type; bh=0j0/nKWGzeI38I10F+SU7w1a3vQNzwZWrsvmO4YNr6c=; b=Al8ZDcBCK3n8Ok0aFEzABrPW2mAps4r9aFwxJuGBl4E5fgA9No7tIB/ZkPoYxgZJ/mUuhg hzuFQunfufCeVDdG6Dn6TxaDmlgh/4jAy4KJqzS03DNmJarkc9IbApSqBcRznb3E8u1hnn bnhXlGdTRmuxsg47CUHP81ymlg01osM= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-655-I-tFTd9JOTWMXig1bHn6SA-1; Fri, 13 Sep 2024 06:33:06 -0400 X-MC-Unique: I-tFTd9JOTWMXig1bHn6SA-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6BA01197700A for ; Fri, 13 Sep 2024 10:33:05 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.224.29]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 38AC719560A3; Fri, 13 Sep 2024 10:33:04 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 48DAX1C12983134 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 13 Sep 2024 12:33:01 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 48DAX1xb2983133; Fri, 13 Sep 2024 12:33:01 +0200 Date: Fri, 13 Sep 2024 12:33:00 +0200 From: Jakub Jelinek To: "Joseph S. Myers" , Jason Merrill , Marek Polacek Cc: gcc-patches@gcc.gnu.org, Jonathan Wakely Subject: [PATCH] libcpp: Fix up UB in finish_embed Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, 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 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: , Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Hi! Jonathan reported on IRC that certain unnamed proprietary static analyzer is unhappy about the new finish_embed function and it is actually right. On a testcase like: #embed __FILE__ limit (0) if_empty (0) params->if_empty.count is 1, limit is 0, so count is 0 (we need just a single token and one fits into pfile->directive_result). Because count is 0, we don't allocate toks, so it stays NULL, and then in 1301 if (prefix->count) 1302 { 1303 *tok = *prefix->base_run.base; 1304 tok = toks; 1305 tokenrun *cur_run = &prefix->base_run; 1306 while (cur_run) 1307 { 1308 size_t cnt = (cur_run->next ? cur_run->limit 1309 : prefix->cur_token) - cur_run->base; 1310 cpp_token *t = cur_run->base; 1311 if (cur_run == &prefix->base_run) 1312 { 1313 t++; 1314 cnt--; 1315 } 1316 memcpy (tok, t, cnt * sizeof (cpp_token)); 1317 tok += cnt; 1318 cur_run = cur_run->next; 1319 } 1320 } the *tok = *prefix->base_run.base; assignment will copy the only token. cur_run is still non-NULL, cnt will be initially 1 and then decremented to 0, but we invoke UB because we do memcpy (NULL, cur_run->base + 1, 0 * sizeof (cpp_token)); and then the loop stops because cur_run->next must be NULL. As we don't really copy anything, toks can be anything non-NULL, so the following patch fixes that by initializing toks also to &pfile->directive_result (just something known to be non-NULL). This should be harmless even for the #embed __FILE__ limit (1) case (no non-empty prefix/suffix) where toks isn't allocated either, but in that case prefix->count will be 0 and in the 1321 for (size_t i = 0; i < limit; ++i) 1322 { 1323 tok->src_loc = params->loc; 1324 tok->type = CPP_NUMBER; 1325 tok->flags = NO_EXPAND; 1326 if (i == 0) 1327 tok->flags |= PREV_WHITE; 1328 tok->val.str.text = s; 1329 tok->val.str.len = sprintf ((char *) s, "%d", buffer[i]); 1330 s += tok->val.str.len + 1; 1331 if (tok == &pfile->directive_result) 1332 tok = toks; 1333 else 1334 tok++; 1335 if (i < limit - 1) 1336 { 1337 tok->src_loc = params->loc; 1338 tok->type = CPP_COMMA; 1339 tok->flags = NO_EXPAND; 1340 tok++; 1341 } 1342 } loop limit will be 1, so tok is initially &pfile->directive_result, that is stilled in, then tok = toks; (previously setting tok to NULL, now to &pfile->directive_result again) and because 0 < 1 - 1 is false, nothing further will happen and the loop will finish (and as params->suffix.count will be 0, nothing further will use tok). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-09-12 Jakub Jelinek * files.cc (finish_embed): Initialize toks to tok rather than NULL. Jakub --- libcpp/files.cc.jj 2024-09-12 18:16:49.995409074 +0200 +++ libcpp/files.cc 2024-09-12 22:55:01.619765364 +0200 @@ -1284,7 +1284,7 @@ finish_embed (cpp_reader *pfile, _cpp_fi } uchar *s = len ? _cpp_unaligned_alloc (pfile, len) : NULL; _cpp_buff *tok_buff = NULL; - cpp_token *toks = NULL, *tok = &pfile->directive_result; + cpp_token *tok = &pfile->directive_result, *toks = tok; size_t count = 0; if (limit) count = (params->prefix.count + limit * 2 - 1