From nobody Tue Jun 16 01:16:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 29A143597B; Thu, 16 Apr 2026 00:14:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776298478; cv=none; b=PeDIspxXkzhkAvHiPgIoor/O64cWQNEoYx5rKSXICHg9sZBav6MRVm5JlcjVwlieZVLkLlnS/89MuR5xrQB2SOjKei7cnHkS9F8LDpPvFMqOCGg3c5tKNrgghlaO4lgcqi4czw7JdKiLN4Is2TeONK+IGHmTmqqUWAlx0n4pcvI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776298478; c=relaxed/simple; bh=CIgnSUhZM+Rbymb25i8EGATOe7/4cgcm168q46PN6Q4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GTzd5zDc4NoYIhclUE3cMSa9CywB1OfyxmBfSzyruQnrZEnsaPmsPGnEHzWO/vbejRz0Rx5AlUqtuvfg+hcV9/iK+LYhgccHZpul6/FekBFtQPrbv9BMBdxyWkRtbyYIogvxDUDcC85Q0I1ein9e7ec4vaZbecpnTiz3eJXNF6U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CuMIzVeN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CuMIzVeN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 70E51C19424; Thu, 16 Apr 2026 00:14:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776298477; bh=CIgnSUhZM+Rbymb25i8EGATOe7/4cgcm168q46PN6Q4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CuMIzVeNTE7RCppsfMLnJSGYXi9r3grijy1ELJK3cTLJiNrTTM/KIVIhPnOMYKEQ2 8apfG3UNAQEyseVJwjbKXpQtdxbs1WALorUYcmyGMOuwT0h3Wuo8KVbkP3fBdWzCeb YnM5T4mwRECOlwBrIcDLos+UEtim/KiabLCkjzrCMfXGd6imP28e/IGHAPOlaBJkN6 ChqOy2BkSa027VRp+nKEW3eHAdpvZNh1tvXtrm6kDskvLYQTIGbLaNy3oFSCUiH9zd DPXeSjXhntQq8bCg9RxcQxdFjZR70Wt9QhECS/1t+D98m2HB4BwS9pLCHRFXShdHvD Oxr+ZfO2gOmfw== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH 1/5] perf header: Add section bounds checking to the fd read path Date: Wed, 15 Apr 2026 21:14:20 -0300 Message-ID: <20260416001424.362797-2-acme@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260416001424.362797-1-acme@kernel.org> References: <20260416001424.362797-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo __do_read_buf() validates reads against ff->size (section size), but __do_read_fd() had no such check, so a malformed perf.data with an understated section size could cause reads past the end of the current section into the next section's data. Add the bounds check in __do_read(), the common caller of both helpers, so it is enforced uniformly for both the fd and buf paths. This requires two supporting changes: - perf_file_section__process(): initialize ff->offset to 0 so it tracks bytes consumed from the section start (consistent with the buf path), rather than the absolute file position. - process_build_id(): use lseek(ff->fd, 0, SEEK_CUR) to discover the current file position instead of reading ff->offset. Cc: Ian Rogers Assisted-by: Claude Code:claude-opus-4-6 Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by, please check when it get to the mailing list. Reviewed-by: James Clark --- tools/perf/util/header.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index f30e48eb3fc32da2..13bbf8df15f66cab 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -213,23 +213,23 @@ static int __do_read_fd(struct feat_fd *ff, void *add= r, ssize_t size) =20 if (ret !=3D size) return ret < 0 ? (int)ret : -1; + ff->offset +=3D size; return 0; } =20 static int __do_read_buf(struct feat_fd *ff, void *addr, ssize_t size) { - if (size > (ssize_t)ff->size - ff->offset) - return -1; - memcpy(addr, ff->buf + ff->offset, size); ff->offset +=3D size; =20 return 0; - } =20 static int __do_read(struct feat_fd *ff, void *addr, ssize_t size) { + if (size > (ssize_t)ff->size - ff->offset) + return -1; + if (!ff->buf) return __do_read_fd(ff, addr, size); return __do_read_buf(ff, addr, size); @@ -2713,7 +2713,12 @@ static int process_tracing_data(struct feat_fd *ff _= _maybe_unused, void *data __ =20 static int process_build_id(struct feat_fd *ff, void *data __maybe_unused) { - if (perf_header__read_build_ids(ff->ph, ff->fd, ff->offset, ff->size)) + off_t offset =3D lseek(ff->fd, 0, SEEK_CUR); + + if (offset =3D=3D (off_t)-1) + return -1; + + if (perf_header__read_build_ids(ff->ph, ff->fd, offset, ff->size)) pr_debug("Failed to read buildids, continuing...\n"); return 0; } @@ -4687,7 +4692,7 @@ static int perf_file_section__process(struct perf_fil= e_section *section, .fd =3D fd, .ph =3D ph, .size =3D section->size, - .offset =3D section->offset, + .offset =3D 0, }; =20 if (lseek(fd, section->offset, SEEK_SET) =3D=3D (off_t)-1) { --=20 2.53.0 From nobody Tue Jun 16 01:16:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F0D8D286AC; Thu, 16 Apr 2026 00:14:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776298483; cv=none; b=Rru3tMh5wJGgXYn4oKpNavfpXquVQmqfjbsjU0K9DyFdT8tTIT6/LccfKEiSdjtly/7m2DTaSdP/aZNsgeYwDwYqGAvFzyPPP1vEc3zhDWoZDIJu9L2DzYp8hNdKWYk/Kr+7IA3ehbyMv+XHSoOKpvl+fIq0TCYvK2T/nZOY6hw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776298483; c=relaxed/simple; bh=H6liez7WESmbfgSAy1NtmogDKAjTD1AhH+U1x5vV9kQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lvKMsutY9fvnMH0j/jRPuFRQtRHdAzrWIpiGOm5UtTCGsH5v0rQaDMpiJyjAm+fwCIRz9b2u/oHo69t7R5HnAo4CiLWzvKrahtbOKt7DQawa9wHS6wF3KvxwVQ7aB7aGqQ1SpaU3eEvbCZC2G8TWw8KHw9zZ3udw/Xp/4DTkKLU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MKxQ6lFG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MKxQ6lFG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7261CC19424; Thu, 16 Apr 2026 00:14:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776298482; bh=H6liez7WESmbfgSAy1NtmogDKAjTD1AhH+U1x5vV9kQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MKxQ6lFGmnimHMvPanb0oddpjDqxWe1weKqjw1pMtrD+DU8YVs2AaRzUZEm9zpGAI lIAA4p8yU3gIJnwoABIJOGejLVn42/a8n1UVoA9ZNASF17deSqu0JsTm/tnvKtJKTA H52kjoimrVaTO1M40KESN9Hloo/kJnxkYu5h+MSFxAgq+zOSFMPoIq+3yVFsTNbF2G HXHYGnmCSHI6X3QQa9KcylnEUfaxsfrIFp0t/g+537cR+Gi4lCovi5D4cHnrFmFn/V RP+XaDYRCu3V1md3b9FRLms9JF4DccGMOPSDOvNt2+25rWAnQq+qrpmPqYbxWRlINy Ip2FX03WCCYmQ== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH 2/5] perf header: Validate string length before allocating in do_read_string() Date: Wed, 15 Apr 2026 21:14:21 -0300 Message-ID: <20260416001424.362797-3-acme@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260416001424.362797-1-acme@kernel.org> References: <20260416001424.362797-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo do_read_string() reads a u32 length from the file and immediately allocates that many bytes. A crafted perf.data could claim a huge string length, triggering a large allocation that would only be freed moments later when __do_read() rejects the read against the section bounds. Check len against the remaining section size before the malloc(). Cc: Ian Rogers Assisted-by: Claude Code:claude-opus-4-6 Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by, please check when it get to the mailing list. Reviewed-by: James Clark --- tools/perf/util/header.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 13bbf8df15f66cab..c27ed90727ea6629 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -269,6 +269,9 @@ static char *do_read_string(struct feat_fd *ff) if (do_read_u32(ff, &len)) return NULL; =20 + if (len > ff->size - ff->offset) + return NULL; + buf =3D malloc(len); if (!buf) return NULL; --=20 2.53.0 From nobody Tue Jun 16 01:16:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 141C41C695; Thu, 16 Apr 2026 00:14:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776298488; cv=none; b=PEro8UcLaaPzXgrjEeawXX2SQK67RclomlRCSsK3KtTpMHscWbI0QAvr22jL/OtWZY7In89BMtWDdkMp/OrtWiAM2UcPbGzzTK1QYotM2y//ipI++l2O5E9JW4kzvioSbREePrqg3JjxeeIoA+MSrgYk6RYqGQYOp7Kr40yivKs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776298488; c=relaxed/simple; bh=bm3oJ/JS6e4E9s6WCF4O1PS1zkEWdUb9lIYo23abs3k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ml2P/zx89bXdDMFAHPrJK6wLwyIosI2uyjMrjoqKCC3QOChyhUZiqwP6xMHbMTveFETwt2YU4uIPTdN/t1akEyEL9rH8TZCtriMzxbrBdEjlc86wkQ2pePp09fA11xMoTt49fijZuVWLhmOqtdmCB/BEC/cvwVst/PGdvL8c4xA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jc7Ueqcy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jc7Ueqcy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 77296C2BCB8; Thu, 16 Apr 2026 00:14:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776298487; bh=bm3oJ/JS6e4E9s6WCF4O1PS1zkEWdUb9lIYo23abs3k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jc7UeqcycnGEHHO+/wicSfxCaOpWOpDojTi0MaIl7zylXnE5v823z4EPexBzE+NDl SwIByA6BaYslYARvYTYjvzx6uNDlAVGLxzjyYkaYo/oF+Q2qbK0w1lQBlcCiGs/I3/ 5euuVdM4To4Hg0X4eCKsvNfme6bEf7UdKZwdxrWGWC5N4mlDz0ZO3klWB2D/Evp+WU nfw4a8kgprm9pWeLI6P0wxJNOoTyZf+k3cwqZOvLOY8mNcz7TWVH4NeYOFUdrkhQg0 Yrl2ANJyt/EnZIr5+I8s8QK6yLZUpu0hkBlDajwtgc8puLPF0Jmhi29FkGkVQslfZm cstqk0mX7hgWA== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH 3/5] perf header: Sanity check HEADER_EVENT_DESC Date: Wed, 15 Apr 2026 21:14:22 -0300 Message-ID: <20260416001424.362797-4-acme@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260416001424.362797-1-acme@kernel.org> References: <20260416001424.362797-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo read_event_desc() reads nre (event count), sz (attr size), and nr (IDs per event) from the file and uses them to control allocations and loops without validating them against the section size. A crafted perf.data could trigger large allocations or many loop iterations before __do_read() eventually rejects the reads. Add bounds checks: - Reject sz =3D=3D 0 or sz exceeding the section size. - Check that nre events fit in the remaining section, using the minimum per-event footprint of sz + sizeof(u32). - Check that nr IDs fit in the remaining section before allocating. Cc: Jiri Olsa Cc: Ian Rogers Assisted-by: Claude Code:claude-opus-4-6 Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by, please check when it get to the mailing list. Reviewed-by: James Clark --- tools/perf/util/header.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index c27ed90727ea6629..3302748bac786fdf 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -2141,6 +2141,13 @@ static struct evsel *read_event_desc(struct feat_fd = *ff) if (do_read_u32(ff, &sz)) goto error; =20 + /* + * The minimum section footprint per event is sz bytes for the attr + * plus a u32 for the id count, check that nre events fit. + */ + if (sz =3D=3D 0 || sz > ff->size || nre > (ff->size - ff->offset) / (sz += sizeof(u32))) + goto error; + /* buffer to hold on file attr struct */ buf =3D malloc(sz); if (!buf) @@ -2186,6 +2193,9 @@ static struct evsel *read_event_desc(struct feat_fd *= ff) if (!nr) continue; =20 + if (nr > (ff->size - ff->offset) / sizeof(*id)) + goto error; + id =3D calloc(nr, sizeof(*id)); if (!id) goto error; --=20 2.53.0 From nobody Tue Jun 16 01:16:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5A0D45038; Thu, 16 Apr 2026 00:14:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776298492; cv=none; b=B7xKZvNU/0x9sK8LnPSayyUczz4/mDv3Cgfuh4dsDMQedw3Qe1YoxiJQGP+sSnse6GpbZjCBmMf+vT01ZhowoOeKokuv0G8tjJRnnXcDKlyd+swjCxSh6SLIPd1gv+swFpTt8Ayf5p5C9VDPCStbgJoX7a1D8+Gj/t2ck3eCnLU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776298492; c=relaxed/simple; bh=Am0ZlfVcYLK1tQUibREREbOUED8fvS23fUj/JUt2YnA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dYpZAtO91EZ7QGgQRl6oPyIy2ud0e/mDW7nO6mdJL/pvCcGRTTpoc1A2XskRyMZ9gjoyiFxqrniJNeDC7SQxjjDABOcBnNEnZIlDWN58rgI4g9ueE6eGGzvcwdowTQPLVgXAf+zPBt66gHz66kfGXOTiS+1zQ5aJlrrUg4JY+s8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tV/PjF/v; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tV/PjF/v" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 33BE7C19424; Thu, 16 Apr 2026 00:14:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776298492; bh=Am0ZlfVcYLK1tQUibREREbOUED8fvS23fUj/JUt2YnA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tV/PjF/vQQFEmdKai5aJpvnh9zGCwO2d1e/IORrjyra7pHOesEPigU29q1hlo9iUQ wknijgUXayNFXetHm1PXo9+jrClBJeThG0mwUg0Ka1w3DT6e4fDrEDR5l47kqwW7Rs KG4ziGpZo8F9Bz17eoHjfpbe036Ghufs2P5rxkoZXZ4uNYb4Oy7ACVxvjtXxbWWXhA gIAEwiCm4/omiSFpKm2EZXoMjq3K/8wfZcoLKrriQx/Q10xTSH0ySdih6eRVHU6OXT KXpy4H5Wo3NbXFcg+gxrB0QTZ50j9/pGjL5PTNeGrfjOebkS41TasaT9o+gK4eKbd+ uIqzwulH2797w== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo , sashiko-bot@kernel.org Subject: [PATCH 4/5] perf header: Validate bitmap size before allocating in do_read_bitmap() Date: Wed, 15 Apr 2026 21:14:23 -0300 Message-ID: <20260416001424.362797-5-acme@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260416001424.362797-1-acme@kernel.org> References: <20260416001424.362797-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo do_read_bitmap() reads a u64 bit count from the file and passes it to bitmap_zalloc() without checking it against the remaining section size. A crafted perf.data could trigger a large allocation that would only fail later when the per-element reads exceed section bounds. Additionally, bitmap_zalloc() takes an int parameter, so a crafted size with bits set above bit 31 (e.g. 0x100000040) would pass the section bounds check but truncate when passed to bitmap_zalloc(), allocating a much smaller buffer than the subsequent read loop expects. Reject size values that exceed INT_MAX, and check that the data needed (BITS_TO_U64(size) u64 values) fits in the remaining section before allocating. Currently used by process_mem_topology() for HEADER_MEM_TOPOLOGY. Reported-by: sashiko-bot@kernel.org Link: https://lore.kernel.org/linux-perf-users/20260414224622.2AE69C19425@s= mtp.kernel.org/ Cc: Jiri Olsa Cc: Ian Rogers Assisted-by: Claude Code:claude-opus-4-6 Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by, please check when it get to the mailing list. Reviewed-by: James Clark --- tools/perf/util/header.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 3302748bac786fdf..e1fed6f1c5e2fa4b 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -300,6 +300,11 @@ static int do_read_bitmap(struct feat_fd *ff, unsigned= long **pset, u64 *psize) if (ret) return ret; =20 + /* bitmap_zalloc() takes an int; reject u64 values that truncate. */ + if (size > INT_MAX || + BITS_TO_U64(size) > (ff->size - ff->offset) / sizeof(u64)) + return -1; + set =3D bitmap_zalloc(size); if (!set) return -ENOMEM; --=20 2.53.0 From nobody Tue Jun 16 01:16:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79A0F4086A; Thu, 16 Apr 2026 00:14:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776298498; cv=none; b=S85PjsXNCIwA8/aAx/3r3AMS0qODCHpbTT09hsPBNvRn7oCSzbBGKHooKJm3ldxiPn7nPuTGtt3fGHxrsop9KQ3e5OPyR9OhbJyZK9yK85SriKvwTXw3sz4sLM9SVPeVaCswcO+JfUEulXtaB+EbfX3Q6WfAZAe3OwB7MwP3424= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776298498; c=relaxed/simple; bh=TwNuMHx951fkAA9em4BtdZisD/tSjQAtRnun21WJoGI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CEXS0lg7dMP9UjpndtKnP9aydLpCZTwiBhqCbKVHlfH9V8m1uN2uF408N3fgXG2Kw+TtGgsHy1QldAAJD59lNIscyDNpCDtklJz31pmC53gDz1ZnqYk9diteYiWL+NHGEj5Au7d5/D/hDv/l2e9o53Q9yYKlOK4RU0aqqDAlFQI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EwWJ+TPk; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EwWJ+TPk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 02BB1C19424; Thu, 16 Apr 2026 00:14:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776298498; bh=TwNuMHx951fkAA9em4BtdZisD/tSjQAtRnun21WJoGI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EwWJ+TPkf49dGGcThusuYESWfDuvahkodW9UjGvN4d1do3is0cGNwdh6IZCq5oD8o Dv4PJve/b/+qLo+5TDhmSG7Mi0iDTfjacONhXhYudQYoUmPPBfUNJ1tHdyJeSji1Ew ZAlA/Z9yynXVCSM6ybJ4Bau2o8a9S9CH99KTL3/+GZkloeKdUF1AI+HiS9H7HSirN0 7XbO9Rfi4kgyfeAsYvYzEettCQCZzK6EJBxgLCL/wuy+0qkIT/BPQyPbHB8aVqsP0r KYHFl81x1TfoDBKb4X/JWSlcQrCa5RfGD5Hzb6Y3dJCPLiol3+BoKRa85PQPQl9RUU P4QLRF6hmKb5A== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo , sashiko-bot@kernel.org Subject: [PATCH 5/5] perf header: Fix 32-bit incompatibility in bitmap serialization Date: Wed, 15 Apr 2026 21:14:24 -0300 Message-ID: <20260416001424.362797-6-acme@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260416001424.362797-1-acme@kernel.org> References: <20260416001424.362797-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo do_write_bitmap() and do_read_bitmap() serialize bitmaps to/from perf.data using u64 elements, but the in-memory representation uses unsigned long, which is 4 bytes on 32-bit architectures and 8 bytes on 64-bit. Both functions cast the unsigned long * bitmap to u64 * and iterate in 8-byte steps. When BITS_TO_LONGS(size) is odd on a 32-bit system the bitmap occupies an odd number of 4-byte longs, but the loop accesses it in 8-byte chunks, making the last chunk extend 4 bytes past the allocation: Write side: reads 4 bytes of heap data beyond the bitmap and writes it into the perf.data file (heap info leak). Read side: writes 8 bytes into a 4-byte tail, corrupting the 4 bytes following the allocation on the heap. Fix the write side by using memcpy with the actual remaining byte count instead of blindly casting to u64 *. Fix the read side by allocating in u64 units (calloc(BITS_TO_U64(size), sizeof(u64))) instead of bitmap_zalloc(), which allocates in unsigned long units, so the buffer is always large enough for the u64 read loop. On 64-bit architectures sizeof(unsigned long) =3D=3D sizeof(u64), so the behavior is unchanged. Reported-by: sashiko-bot@kernel.org Link: https://lore.kernel.org/linux-perf-users/20260414224622.2AE69C19425@s= mtp.kernel.org/ Cc: Jiri Olsa Cc: Ian Rogers Assisted-by: Claude Code:claude-opus-4-6 Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by, please check when it get to the mailing list. Reviewed-by: James Clark --- tools/perf/util/header.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index e1fed6f1c5e2fa4b..a12f3f4ef0b38e8f 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -158,15 +158,25 @@ int do_write(struct feat_fd *ff, const void *buf, siz= e_t size) /* Return: 0 if succeeded, -ERR if failed. */ static int do_write_bitmap(struct feat_fd *ff, unsigned long *set, u64 siz= e) { - u64 *p =3D (u64 *) set; + size_t byte_size =3D BITS_TO_LONGS(size) * sizeof(unsigned long); int i, ret; =20 ret =3D do_write(ff, &size, sizeof(size)); if (ret < 0) return ret; =20 + /* + * The on-disk format uses u64 elements, but the in-memory bitmap + * uses unsigned long, which is only 4 bytes on 32-bit architectures. + * Copy with bounded size so the last element doesn't read past the + * bitmap allocation when BITS_TO_LONGS(size) is odd. + */ for (i =3D 0; (u64) i < BITS_TO_U64(size); i++) { - ret =3D do_write(ff, p + i, sizeof(*p)); + u64 val =3D 0; + size_t off =3D i * sizeof(val); + + memcpy(&val, (char *)set + off, min(sizeof(val), byte_size - off)); + ret =3D do_write(ff, &val, sizeof(val)); if (ret < 0) return ret; } @@ -300,12 +310,18 @@ static int do_read_bitmap(struct feat_fd *ff, unsigne= d long **pset, u64 *psize) if (ret) return ret; =20 - /* bitmap_zalloc() takes an int; reject u64 values that truncate. */ + /* Bitmap APIs use int for nbits; reject u64 values that truncate. */ if (size > INT_MAX || BITS_TO_U64(size) > (ff->size - ff->offset) / sizeof(u64)) return -1; =20 - set =3D bitmap_zalloc(size); + /* + * bitmap_zalloc() allocates in unsigned long units, which are only + * 4 bytes on 32-bit architectures. The read loop below casts the + * buffer to u64 * and writes 8-byte elements, so allocate in u64 + * units to ensure the buffer is large enough. + */ + set =3D calloc(BITS_TO_U64(size), sizeof(u64)); if (!set) return -ENOMEM; =20 --=20 2.53.0