A collection of recent small fixes and quirks.
We still see a bit more changes than wished, but most of them are
device-specific ones that are pretty safe to apply, while a core fix
is a typical UAF fix for PCM core that was recently caught by fuzzer;
so overall nothing looks really worrisome.
* Core:
- Fix a UAF in PCM OSS proc interface
* HD-audio:
- Fix memory leaks in CS35L56 driver
- Various device-specific quirks for Realtek and CS420x codecs
* USB-audio:
- Quirk for TAE1160 USB Audio
- Fix for Scarlett2 Gen4 direct monitor gain
* ASoC:
- Fixes for QCom q6asm-dai, Intel bytcht_es8316, and simple-mux codec
* FireWire:
- Fix for Motu DSP event queue protection
-----BEGIN PGP SIGNATURE-----
iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmoZTLUOHHRpd2FpQHN1
c2UuZGUACgkQLtJE4w1nLE8RMxAAmdvBYW7xB64onopKCTjdHewCx3nsK9V9jiWi
0xsQDEs1+JukXG4Bag06R2W9EJLrdFewa88QnuwtEG+wMxJO30oJxm/b6k5EkwNu
ai8Vd8pFkcxmpAC7cL/ROtQurqW9Tfr+w9qGUTcS12tRuvQV+AjfHvGSlwqiS3K0
ZFPozyPVD6kQ5g3io/GH3HW76ZTLB+jtVx+VYvQsJ43Bii3g2pfNW6HlWQyundPt
Q6vLgUHEhvf9fgA76YztQedtoxBxQyuWrZCOV2+qzobW5sJHdOAlh4XmR6VjYzui
Gp6Xn4U1wPsP722kqzm+uK6QDVsaGGzKOuwKWYpGBwRYVol0CY/YFC1ZcT19VCMI
k6J93OMYZRoAl+ECbbWQjhVN4g8Ut7CQlvcZpPVwr5+HgcoitvuBt41KGUesKFkp
0h8kgy/X59JCJJ+AaZlxKOKoPL+WeVCXm1z9GF3VcS1h9kT1ZXfB1d3nSi9383xR
ho+YJYQQiyvXK7ZfESKZgChmC9LBSU5joW77HslXU5tM9ZkLGW1w8O7Zasas7cSm
xeNhhR6J3AnfTLX2XHDKWR/w32kqaEYTUr+t1Z997Vm33D7idcOtQIr20AgQon+0
EfKLijHFQB0HCkqgndMXdgjnus9TnXOoJE9aQudRr8rSUgu3dONrPguv+z23y25n
9u7awX4=
=IHLg
-----END PGP SIGNATURE-----
Merge tag 'sound-7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"A collection of recent small fixes and quirks.
We still see a bit more changes than wished, but most of them are
device-specific ones that are pretty safe to apply, while a core fix
is a typical UAF fix for PCM core that was recently caught by fuzzer;
so overall nothing looks really worrisome.
Core:
- Fix a UAF in PCM OSS proc interface
HD-audio:
- Fix memory leaks in CS35L56 driver
- Various device-specific quirks for Realtek and CS420x codecs
USB-audio:
- Quirk for TAE1160 USB Audio
- Fix for Scarlett2 Gen4 direct monitor gain
ASoC:
- Fixes for QCom q6asm-dai, Intel bytcht_es8316, and simple-mux codec
FireWire:
- Fix for Motu DSP event queue protection"
* tag 'sound-7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ASoC: codecs: simple-mux: Fix enum control bounds check
ALSA: usb-audio: Add iface reset and delay quirk for TAE1160 USB Audio
ALSA: hda/cs420x: Add CS4208 fixup for iMac16,1
ALSA: hda/realtek: add quirk for HP Dragonfly Folio G3 2-in-1
ALSA: hda/realtek: Fix speaker output on ASUS ROG Strix G615LP
ASoC: qcom: q6asm-dai: use pointer type with kzalloc_obj()
ASoC: qcom: q6asm-dai: remove unnecessary braces
ASoC: qcom: q6asm-dai: fix error handling in prepare and set_params
ASoC: qcom: q6asm-dai: close stream only when running
ASoC: qcom: q6asm-dai: do not set stream state in event and trigger callbacks
ASoC: Intel: bytcht_es8316: Fix MCLK leak on init errors
ALSA: hda/realtek: Limit mic boost on Positivo DN140
ALSA: scarlett2: Fix 2i2 Gen 4 direct monitor gain on firmware 2417
ALSA: pcm: oss: Fix setup list UAF on proc write error
ALSA: hda: cs35l56: Fix system name string leaks
ALSA: hda/realtek: Add HDA_CODEC_QUIRK for Lenovo Yoga Slim 7 14AGP11
ALSA: hda/realtek: Fix incorrect comment for ALC299_FIXUP_PREDATOR_SPK
ALSA: firewire-motu: Protect register DSP event queue positions
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEoEVH9lhNrxiMPSyI7MXwXhnZSjYFAmoYZ3EACgkQ7MXwXhnZ
SjY8QQ/8DjopbIJ9mJzOLRRzCyKf/+JthOL48Vg7lu7uftRkgZ/IfOp9n7dWguG2
yiOI2/yyQDL3wsd3DoUEtMwTPhd/JNpc7qJ+N19l/tpcnup+PaDxpiZWD1k1zKz6
cNROdNtGKyBlSl80qWNDN65u/AkEv7QTcvZS2Nw/Kh+0jmiOf/FqplyjNwHXsDsi
VCSfkpAAPz3zaHaJcaWMMImV/s6MOwVAI+2PlO/Kbgv62BrzGXTJBdiWK2LIbxPh
Udo/fXwnX/I/SuQ+j5IGRMJOokbWXugyKnstpDIv/1brVEmrTzp0CB0yoKGNTjy0
S8/ZYJBsnCAXMA9pcpzM86jtB2yrA/HHwtOo+mH2AD3z9r25qHTiWbTh9/tnSAiW
MYNcwvpbgvFHmwWrjpt7jrndlFhbXT2fHjyMZg3j9tmisXZCqwmU972J1jXTb8wL
xjhkKJFjjgTkRwXXx3BP51I+W+15P1DKhsAOqJS2K19At5dgZTD5KY6wQXkDVbk7
c+o9Duq7PoBGzHz/gl1Z2nqA5KEgP17HQIAhM+HEjvrmOscnKpGdHLTpMSwqyKhF
e/4yLeZdpvn6KB/B1fXYIPhTAmjKI2JxNNsae4ir7m7S6HxwamXZ406A05NoCGIQ
XDm3B1xDYcS4NYKE9G6oO5+HcanZD1QBAJBa5k8COTyIQ42svnY=
=pFq/
-----END PGP SIGNATURE-----
Merge tag 'hid-for-linus-2026052801' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID fixes from Benjamin Tissoires:
- buffer overflow fix for lenovo (Kean) and wacom (Lee Jones) drivers
- segfaults prevention in lenovo-go driver when used with an emulated
device (Louis Clinckx)
- cleanup of resources in u2fzero (Myeonghun Pak)
- a quirk for a USB mouse and a cleanup in hid.h (hlleng and Liu Kai)
* tag 'hid-for-linus-2026052801' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
HID: wacom: Fix OOB write in wacom_hid_set_device_mode()
HID: lenovo-go: drop dead NULL check on to_usb_interface()
HID: lenovo-go: reject non-USB transports in probe
HID: lenovo: Fix buffer over-read and unaligned access in X12 Tab raw_event handler
HID: quirks: Add ALWAYS_POLL quirk for SIGMACHIP USB mouse
HID: remove duplicate hid_warn_ratelimited definition
HID: u2fzero: free allocated URB on probe errors
Nova Lake-H SoCs share similar memory controller registers and IBECC
(In-Band ECC) registers with Panther Lake-H SoCs but use a new memory
subsystem register for IBECC presence detection.
Add Nova Lake-H SoC compute die IDs and create a new configuration
structure for Nova Lake-H SoCs to enable EDAC support.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Jie Wang <jie.wang@intel.com>
Link: https://patch.msgid.link/20260521123812.3961038-3-qiuxu.zhuo@intel.com
Some Intel CPUs with IBECC (In-Band ECC) capability use different registers
to indicate IBECC presence. Make IBECC detection registers CPU-model
specific and configure them properly for scalable IBECC detection.
No functional changes intended.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Jie Wang <jie.wang@intel.com>
Link: https://patch.msgid.link/20260521123812.3961038-2-qiuxu.zhuo@intel.com
Compared to previous generations, Diamond Rapids RRL (Retry Read error Log)
operates at DDR sub-channel granularity and adds an extra register per set.
It also increases the CORRERRCNT register width from 4 to 8 bytes while
reducing the number of registers from 8 to 4.
Add the Diamond Rapids RRL register configuration table and enable support.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Yi Lai <yi1.lai@intel.com>
Link: https://patch.msgid.link/20260521073112.3881223-9-qiuxu.zhuo@intel.com
To prepare for enabling Diamond Rapids server RRL (Retry Read error Log),
which operates at sub-channel granularity by converting struct
res_config::reg_rrl_ddr from a single pointer to an array (reg_rrl_ddr[2])
and updating all users in i10nm_edac and skx_common accordingly.
Initialize only reg_rrl_ddr[0] for existing platforms and prepare for
supporting two RRL set groups per DDR channel (one per sub-channel)
when present.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Yi Lai <yi1.lai@intel.com>
Link: https://patch.msgid.link/20260521073112.3881223-8-qiuxu.zhuo@intel.com
Diamond Rapids server RRL (Retry Read error Log) operates at sub-channel
granularity. Add SubChannel support to ADXL decoding in preparation for
enabling this feature.
Also introduce adxl_component_required() to validate mandatory ADXL
components to improve code readability.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Yi Lai <yi1.lai@intel.com>
Link: https://patch.msgid.link/20260521073112.3881223-7-qiuxu.zhuo@intel.com
Move RRL (Retry Read error Log) handling from i10nm_edac to skx_common
so it can be shared across EDAC drivers (e.g. imh_edac).
- Move RRL enable/disable and log dumping helpers to skx_common
to avoid code duplication and enable reuse by other drivers.
- Export skx_enable_rrl() and skx_show_rrl()
so common RRL handling can be used by i10nm_edac and imh_edac.
No functional change intended.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Yi Lai <yi1.lai@intel.com>
Link: https://patch.msgid.link/20260521073112.3881223-6-qiuxu.zhuo@intel.com
RRL (Retry Read error Log) ownership is currently inferred from
retry_rd_err_log magic values, making control semantics implicit
and harder to understand.
Introduce rrl_ctrl_mode to explicitly describe whether RRL is
controlled by none, BIOS, or Linux, and replace direct checks with
named control states to improve readability and maintainability.
No functional change intended.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Yi Lai <yi1.lai@intel.com>
Link: https://patch.msgid.link/20260521073112.3881223-5-qiuxu.zhuo@intel.com
The RRL (Retry Read error Log) values describe where an error was logged
from (first/last read and scrub/demand), not an operating mode.
Rename rrl_mode to rrl_source_type and "modes" to "sources" to better
reflect their meaning and improve code readability.
No functional changes intended.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Yi Lai <yi1.lai@intel.com>
Link: https://patch.msgid.link/20260521073112.3881223-4-qiuxu.zhuo@intel.com
skx_set_decode() currently handles both address decoding and Retry
Read error Log (RRL) reporting, coupling two independent functions
in a single API. This complicates setup/teardown and forces callers
to update unrelated state.
Introduce skx_set_show_rrl() and keep skx_set_decode() focused on
decode setup, allowing decode and RRL handling to be managed
independently.
Also rename the callback type and variable to skx_show_rrl_f and
show_rrl for clearer RRL terminology and consistency.
No functional changes intended.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Yi Lai <yi1.lai@intel.com>
Link: https://patch.msgid.link/20260521073112.3881223-3-qiuxu.zhuo@intel.com
Both i10nm_basic.c and imh_basic.c use identical helpers for accessing
memory controller MMIO-based registers. Move these helpers to skx_common.c
to eliminate code duplication. This change also prepares for an upcoming
patch that will move RRL(retry_rd_err_log) code from i10nm_basic.c to
skx_common.c, which requires these helpers to be available in skx_common.c.
Additionally, prefix these function names with 'skx_' to maintain naming
consistency within the file.
No functional changes intended.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Yi Lai <yi1.lai@intel.com>
Link: https://patch.msgid.link/20260521073112.3881223-2-qiuxu.zhuo@intel.com
When the skx_get_dimm_attr() helper returns -EINVAL,
skx_get_dimm_info() does not validate these return values before using
them in a shift operation:
size = ((1ull << (rows + cols + ranks)) * banks) >> (20 - 3);
If all three values are -22, the shift exponent becomes -66, triggering
a UBSAN shift-out-of-bounds error:
UBSAN: shift-out-of-bounds in drivers/edac/skx_common.c
shift exponent -66 is negative
Fixes: 88a242c987 ("EDAC, skx_common: Separate common code out from skx_edac")
Signed-off-by: zhoumin <teczm@foxmail.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://patch.msgid.link/tencent_2A0CC835A18366643CBD2865B169948AB409@qq.com
Panther Lake-H SoC memory controller registers for memory topology have
been updated, but the current igen6_edac driver still uses old generation
ones to incorrectly parse memory topology.
Fix the issue by adding memory topology parsing function pointers to the
'struct res_config' and creating a new configuration structure for Panther
Lake-H SoCs to enable igen6_edac to parse memory correctly.
Fixes: 0be9f1af39 ("EDAC/igen6: Add Intel Panther Lake-H SoCs support")
Fixes: 4c36e61069 ("EDAC/igen6: Add more Intel Panther Lake-H SoCs support")
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://patch.msgid.link/20260403054029.3950383-3-qiuxu.zhuo@intel.com
When unloading the igen6_edac driver, there is a call trace:
Device '(null)' does not have a release() function, it is broken and must be fixed.
See Documentation/core-api/kobject.rst.
WARNING: drivers/base/core.c:2567 at device_release+0x84/0x90, CPU#5: rmmod/127209
...
RIP: 0010:device_release+0x84/0x90
Call Trace:
<TASK>
kobject_put+0x8c/0x220
put_device+0x17/0x30
igen6_unregister_mcis+0xa2/0xe0 [igen6_edac]
igen6_remove+0x82/0xb0 [igen6_edac]
...
Fix the call trace by providing empty release() functions for the
memory controller devices.
Fixes: 10590a9d4f ("EDAC/igen6: Add EDAC driver for Intel client SoCs using IBECC")
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://patch.msgid.link/20260403054029.3950383-2-qiuxu.zhuo@intel.com
Fix the warning in sb_decode_ddr3() by adding the missing verb "is" and
using "supported" instead of "support" to match the LockStep warning in
sb_decode_ddr4().
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Link: https://patch.msgid.link/20260508143844.2996-3-thorsten.blum@linux.dev
If error reporting is enabled during initialization but initialization
fails immediately after, or during normal driver teardown, error reporting
is left enabled in the mask register even after exit.
Replace i5400_enable_error_reporting() with i5400_set_error_reporting()
to combine enabling/disabling. Disable reporting at initialization
failure and driver exit, before call to i5400_put_devices() for cleanup.
This ensures clean hardware handling by disabling any unused error
reporting bits before exiting.
Signed-off-by: Tushar Tibude <tushar.tibude1000@gmail.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Link: https://patch.msgid.link/20260430084223.9298-4-tushar.tibude1000@gmail.com
Error reporting is enabled during init but not reverted when init fails.
It is also not disabled at normal driver teardown.
Create i5100_set_error_reporting() to enable/disable reporting. Move
enable reporting write to after initialization success. Disable reporting
at driver teardown.
Signed-off-by: Tushar Tibude <tushar.tibude1000@gmail.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Link: https://patch.msgid.link/20260430084223.9298-3-tushar.tibude1000@gmail.com
If error reporting is enabled during initialization but initialization
fails immediately after, or during normal driver teardown, error reporting
is left enabled in the mask register even after exit.
Replace i5000_enable_error_reporting() with i5000_set_error_reporting()
to combine enabling/disabling. Disable reporting at initialization
failure and driver exit, before call to i5000_put_devices() for cleanup.
This ensures clean hardware handling by disabling any unused error
reporting bits before exiting.
Signed-off-by: Tushar Tibude <tushar.tibude1000@gmail.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Link: https://patch.msgid.link/20260430084223.9298-2-tushar.tibude1000@gmail.com
If error reporting is enabled during initialization but initialization
fails immediately after, or during normal driver exit, error reporting
is left enabled in the mask register even after exit.
Replace i7300_enable_error_reporting() with i7300_set_error_reporting()
to combine enabling/disabling. Disable reporting at initialization
failure and driver exit, before call to i7300_put_devices() for cleanup.
Add enabled reporting flag to i7300_pvt.
This ensures clean hardware handling by disabling any unused error
reporting bits before exiting.
Signed-off-by: Tushar Tibude <tushar.tibude1000@gmail.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Link: https://patch.msgid.link/20260429094806.25097-1-tushar.tibude1000@gmail.com
perf_ftrace_function_unregister() unconditionally calls
unregister_ftrace_function() without checking whether the ftrace_ops
was ever successfully registered. This triggers a WARN_ON in
__unregister_ftrace_function() when the ops doesn't have
FTRACE_OPS_FL_ENABLED set.
This can happen during perf_event_alloc() error cleanup when
perf_trace_destroy() is called via __free_event() on an event whose
ftrace_ops registration failed or was already torn down by
perf_try_init_event()'s err_destroy path.
The call path is:
perf_event_alloc() error cleanup
-> __free_event()
-> event->destroy() [tp_perf_event_destroy]
-> perf_trace_destroy()
-> perf_trace_event_close()
-> TRACE_REG_PERF_CLOSE
-> perf_ftrace_function_unregister()
-> unregister_ftrace_function()
-> __unregister_ftrace_function()
-> WARN_ON(!(ops->flags & FTRACE_OPS_FL_ENABLED))
Fix this by checking FTRACE_OPS_FL_ENABLED before attempting to
unregister. If the ops is not enabled, just free the filter and
return success.
Link: https://patch.msgid.link/20260527111301.2d0d8256@fangorn
Signed-off-by: Rik van Riel <riel@surriel.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Revert commit 54067bacb4 ("selinux: hooks: use __getname() to allocate
path buffer") as it improperly assumed that PATH_MAX == PAGE_SIZE
everywhere. Moving away from __get_free_page() is still a good thing and
will be revisited in the future.
Cc: Mike Rapoport (Microsoft) <rppt@kernel.org>
Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
When KCOV runs its boot selftest with whole-kernel instrumentation
enabled, it sets current->kcov_mode to KCOV_MODE_TRACE_PC without
installing a coverage area. Any instrumented code accepted as task-context
coverage in that window dereferences current->kcov_area and crashes.
On ARMv5 Versatile PB with CONFIG_KCOV_SELFTEST=y,
CONFIG_KCOV_INSTRUMENT_ALL=y and CONFIG_IRQSOFF_TRACER=y, boot hits a
NULL pointer fault during the selftest:
kcov: running self test
Internal error: Oops: 5 [#1] ARM
PC is at __sanitizer_cov_trace_pc+0x4c/0x90
Kernel panic - not syncing: Fatal exception
A diagnostic run showed the unwanted coverage comes from the IRQs-off
tracer callbacks reached from ARM IRQ entry before hardirq context is
visible to KCOV:
__sanitizer_cov_trace_pc from tracer_hardirqs_off+0x18/0x1cc
tracer_hardirqs_off from trace_hardirqs_off+0x34/0x54
trace_hardirqs_off from __irq_svc+0x58/0xb0
__irq_svc from kcov_init+0x7c/0xdc
and similarly through tracer_hardirqs_on().
trace_preemptirq.o is already excluded because this tracing path can run
from early interrupt code and produce coverage unrelated to syscall
inputs. Exclude trace_irqsoff.o as well, instead of requiring users to
turn off CONFIG_KCOV_INSTRUMENT_ALL=y, which is the default whole-kernel
KCOV mode.
With the exclusion in place, the same ARMv5 Versatile PB QEMU test boots
through the KCOV selftest and reaches userspace.
Tested on ARMv5 Versatile PB QEMU with CONFIG_KCOV_SELFTEST=y,
CONFIG_KCOV_INSTRUMENT_ALL=y and CONFIG_IRQSOFF_TRACER=y.
Link: https://patch.msgid.link/20260525170428.67211-1-kmehltretter@gmail.com
Assisted-by: Codex:gpt-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
The field_var_str array was allocated separately via kcalloc() with its
length already known at elt_data allocation time. Convert it to a
flexible array member and fold the two allocations into a single
kzalloc_flex(), reordering hist_trigger_elt_data_alloc() so n_str is
computed and bounds-checked before the struct allocation.
hist_elt_data is only reached through tracing_map_elt::private_data
(a void *), never embedded, so adding a FAM imposes no tail-position
constraint on any enclosing struct.
Added __counted_by for extra runtime analysis.
Link: https://patch.msgid.link/20260522214407.18120-1-rosenp@gmail.com
Assisted-by: Claude:Opus-4.7
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
The remoteproc framework has capability to start (or attach to) the remote
processor automatically if auto boot flag is set by the driver during
probe. If the 'firmware-name' property is available for the remoteproc
node, then that firmware will be loaded and started during auto boot. If
the remote core is started by the bootloader then during auto-boot
remoteproc framework will try to attach to the remote processor.
The current architecture allocates and adds the remoteproc instance before
all the hardware such as sram, mbox, TCM is initialized. This design has
to be changed for auto boot to work. So, rename zynqmp_r5_rproc_add()
function to zynqmp_r5_rproc_alloc() and move adding the remoteproc
instance at the end of cluster initialization. This makes sure that all
the required hardware is initialized before starting the remote
processor.
Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
Link: https://lore.kernel.org/r/20260527051611.194844-3-tanmay.shah@amd.com
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
The firmware-name property indicates which firmware to load on RPU
during the Linux boot time. It is possible to stop the RPU after boot
and load different firmware and start RPU.
Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20260527051611.194844-2-tanmay.shah@amd.com
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Since the leafloop test program was moved into the main Perf binary as a
workload, it inherited the same compiler options as Perf. In this case
the -fstack-protector option broke the assumption that simple leaf
frames don't have a stack frame on Arm. This causes
test_arm_callgraph_fp.sh to pass even if the stack isn't augmented with
the link register, making the test useless.
Fix it by rewriting the leaf function in assembly seeing as it's so
simple. Adding -fno-stack-protector would also work, but wouldn't be
robust against other future compiler option additions.
The local variables and 'a' variable were never needed so remove them to
simplify.
Reviewed-by: Ian Rogers <irogers@google.com>
Assisted-by: GitHub-Copilot:GPT-5.5
Signed-off-by: James Clark <james.clark@linaro.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Add a shell test that verifies perf report handles truncated perf.data
files gracefully — exiting with an error code rather than crashing with
SIGSEGV or SIGABRT.
The test records a simple workload, then truncates the resulting
perf.data at four offsets that exercise different parsing stages:
8 bytes — file header magic only
64 bytes — partial file header (attr section incomplete)
256 bytes — into the first events (partial event headers)
75% size — mid-stream truncation (partial event data)
For each truncation, perf report is run and the exit code is checked:
- Exit code 0 (success) fails the test — a truncated file should
never parse without error.
- Crash signals are detected portably via kill -l, which maps the
signal number to a name on the running system. This handles
architectures where signal numbers differ (e.g. SIGBUS is 7 on
x86/ARM but 10 on MIPS/SPARC). Core-dump and fatal signals
(KILL, ILL, ABRT, BUS, FPE, SEGV, TRAP, SYS) fail the test.
- Higher exit codes (200+) are perf's own negative-errno returns
(e.g. -EINVAL = 234) and are expected.
This exercises the bounds checking, minimum-size validation, and error
propagation added by the preceding patches in this series.
Testing it:
root@number:~# perf test truncat
84: Test that perf report handles truncated perf.data gracefully (no crash, no segfault — clean error exit).: Ok
root@number:~# perf test -vv truncat
84: Test that perf report handles truncated perf.data gracefully (no crash, no segfault — clean error exit).:
--- start ---
test child forked, pid 62890
---- end(0) ----
84: Test that perf report handles truncated perf.data gracefully (no crash, no segfault — clean error exit).: Ok
root@number:~#
Changes in v2:
- Add SIGKILL to the list of fatal signals so OOM kills from
resource exhaustion bugs are detected (Reported-by: sashiko-bot@kernel.org)
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
[ Fixed the SPDX on the line where 'perf test' expects the test description, reviewed by Ian Rogers ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
On native-endian files, events are read from MAP_SHARED memory.
Multiple reads of event->header.size can return different values
if the file is concurrently modified, allowing an attacker to
bypass bounds checks performed on an earlier read.
Snapshot header.size into a local variable at function entry using
READ_ONCE() to prevent compiler rematerialization, and use it for
all size-dependent arithmetic within the function. This ensures
every bounds calculation uses the same value that was validated
by the reader.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
work->cpu comes from sample->cpu which is (u32)-1 when
PERF_SAMPLE_CPU is absent. Stored as int, this becomes -1
which passes the signed BUG_ON(work->cpu >= MAX_NR_CPUS) but
causes an out-of-bounds access on cpus_runtime[-1].
Replace the BUG_ON in top_calc_total_runtime() with an unsigned
bounds check that skips entries with invalid CPU values, counting
them for a summary warning.
Guard the same index in profile_event_match() (bitmap OOB),
top_calc_idle_time(), top_calc_irq_runtime(), top_calc_cpu_usage(),
and top_calc_load_runtime(). Also guard against division by zero
in top_calc_cpu_usage() when no runtime was accumulated.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Yang Jihong <yangjihong@bytedance.com>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Several downstream consumers (timechart, kwork, sched) use fixed-size
arrays indexed by CPU. A crafted perf.data can supply arbitrary CPU
values that index past these arrays, causing out-of-bounds access.
Validate sample.cpu against min(nr_cpus_avail, MAX_NR_CPUS) in
perf_session__deliver_event() before any tool callback runs. The
cap at MAX_NR_CPUS protects fixed-size downstream arrays; the true
nr_cpus_avail is preserved in env for header parsing (e.g.
process_cpu_topology) which needs the real count.
Fall back to MAX_NR_CPUS when HEADER_NRCPUS is missing (truncated
files, pipe mode, pre-2017 perf).
Only validate when PERF_SAMPLE_CPU is set in sample_type — when
absent, evsel__parse_sample() leaves sample.cpu as (u32)-1, a
sentinel that downstream tools (script, inject) check to identify
events without CPU info. Clamping it to 0 would break those checks.
Inline evlist__parse_sample() into perf_session__deliver_event()
so the evsel lookup needed for sample_type checking reuses the same
evsel that parsed the sample, avoiding a second evlist__event2evsel()
call on every event.
For pipe-mode streams where HEADER_NRCPUS may arrive late or not at
all, the MAX_NR_CPUS fallback ensures the bounds check is still
effective against the fixed-size downstream arrays.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
On 32-bit systems, sizeof(struct decomp) + decomp_len can wrap
size_t when comp_mmap_len is large. The preceding patch validates
comp_mmap_len alignment but does not cap the upper bound, so two
additions can still overflow:
1. decomp_len += decomp_last_rem: on 32-bit, adding a u64 to
size_t silently truncates, producing a corrupted decomp_len
that would bypass the subsequent overflow check and result
in an undersized buffer allocation.
2. sizeof(struct decomp) + decomp_len: the final addition could
overflow on systems with small size_t.
Add explicit overflow checks before each addition as
defense-in-depth.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Add several hardening checks to the compressed event decompression
pipeline:
1. Guard against decomp_last_rem underflow: check that
decomp_last->head does not exceed decomp_last->size before
subtracting. A u64 underflow here would produce a huge
decomp_len, causing an oversized mmap allocation.
2. Validate comp_mmap_len from the HEADER_COMPRESSED feature
section: reject values that are not 4K-aligned or smaller than
4096. The downstream decompression path checks allocation
sizes against SIZE_MAX, which handles 32-bit safety.
3. Validate COMPRESSED event header size: reject events where
header.size is too small to contain the fixed struct fields,
preventing underflow in the payload size calculation.
4. Validate COMPRESSED2 event data_size: check that data_size
does not exceed the available payload (header.size minus the
fixed struct fields) for the newer compressed format.
5. Reject compressed events when the HEADER_COMPRESSED feature
is missing from the file header, which means no decompression
context was initialized.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
PERF_RECORD_COMPRESSED2 events carry a data_size field that must be
byte-swapped when reading cross-endian perf.data files. Without a
swap handler, reading COMPRESSED2 events on a different-endian machine
would misinterpret data_size as a garbage value, causing the
decompression path to read the wrong number of bytes.
The compressed payload itself is a raw byte stream and needs no
swapping.
Fixes: 208c0e1683 ("perf record: Add 8-byte aligned event type PERF_RECORD_COMPRESSED2")
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Chun-Tse Shao <ctshao@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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. Switch from bitmap_zalloc() to calloc() of u64
units so the allocation size matches the u64 read/write granularity
and avoids unsigned long vs u64 mismatch on 32-bit architectures.
Fix do_write_bitmap() to use memcpy to read u64-sized chunks from
the unsigned long bitmap, preventing out-of-bounds reads on 32-bit
systems where sizeof(unsigned long) is 4 but the bitmap is stored
in u64 units.
Fix process_mem_topology() minimum section size: the check used
nr * 2 * sizeof(u64) per node, but do_read_bitmap() reads an
additional u64 for the bitmap size, so the minimum is 3 * sizeof(u64).
Fix memory leak in process_mem_topology() error paths: replace
free(nodes) with memory_node__delete_nodes() to free per-node
bitmaps allocated by do_read_bitmap().
Currently used by process_mem_topology() for HEADER_MEM_TOPOLOGY.
Fixes: a881fc5603 ("perf header: Sanity check HEADER_MEM_TOPOLOGY")
Closes: https://lore.kernel.org/linux-perf-users/20260414224622.2AE69C19425@smtp.kernel.org/
Closes: https://lore.kernel.org/linux-perf-users/20260410223242.DD76FC19421@smtp.kernel.org/
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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 in read_event_desc():
- Reject sz smaller than PERF_ATTR_SIZE_VER0.
- Require at least one event (nre > 0).
- Check that nre events fit in the remaining section, using the
minimum per-event footprint of sz + sizeof(u32).
- Pre-swap attr->size to native byte order, then reject values
below PERF_ATTR_SIZE_VER0 or above sz before calling
perf_event__attr_swap() to prevent heap out-of-bounds access.
- Handle ABI0 (attr.size == 0): substitute PERF_ATTR_SIZE_VER0,
and on native-endian files write the value back so
free_event_desc() does not treat the zero as its end-of-array
sentinel (it iterates while attr.size != 0). The swap path
skips the write-back — perf_event__attr_swap() has its own
ABI0 fallback that sets VER0 after swapping.
- Check that nr IDs fit in the remaining section before allocating.
Fixes: b30b617292 ("perf tools: Fix a problem when opening old perf.data with different byte order")
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Harden feature section parsing against crafted perf.data files:
1. perf_header__process_sections() reads the feature section table
and passes each section's offset and size directly to the
processing callbacks without validating them against the actual
file size. A crafted section size would make all downstream
bounds checks against ff->size ineffective since they compare
against the untrusted, inflated bound. Add an fstat() check
with S_ISREG() guard and verify that each section's offset +
size does not extend past EOF.
2. __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.
Track the section-relative offset in __do_read_fd() so the
check works for the fd path. Reject negative sizes which on
32-bit can occur when a u32 >= 0x80000000 is passed as ssize_t.
3. do_read_string() relied on file data being null-padded. Add
explicit null-termination (buf[len-1] = '\0') after reading
and validate length (>= 1, fits within section) before
allocating, so callers like process_cpu_topology() never
receive an unterminated string.
4. Initialize feat_fd.offset to 0 (section-relative) instead of
section->offset (file-absolute) so the bounds tracking is
consistent with __do_read()'s section-relative comparison.
Adjust process_build_id() to use lseek() for its file-absolute
offset needs since it cannot rely on ff->offset for that.
5. Propagate ff->size to perf_file_section__fprintf_info() so its
reads are also bounded.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: David Carrillo-Cisneros <davidcc@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
perf_session__read_header() reads f_attr.ids.size from the perf.data
file and divides it by sizeof(u64) to compute nr_ids, which is
declared as int. No validation is performed on the value before it
is used to allocate arrays and drive a read loop.
On 32-bit architectures, a crafted f_attr.ids.size of 0x100000000
(4 GB) produces nr_ids = 0x20000000, but the allocation size
1 * 0x20000000 * 8 overflows size_t to 0, so zalloc(0) returns a
valid pointer. The subsequent loop writes 0x20000000 IDs into that
zero-length buffer, corrupting the heap.
On 64-bit, the u64-to-int truncation silently drops high bits,
processing fewer IDs than the file claims. While not exploitable,
this is a data integrity issue.
Add validation before using f_attr.ids:
- Cap nr_attrs (attrs.size / attr_size) to MAX_NR_ATTRS (1 << 16)
with overflow-safe u64 comparison before assigning to int
- Reject ids.size not aligned to sizeof(u64)
- Cap ids.size / sizeof(u64) to MAX_IDS_PER_ATTR (1 << 24) to
prevent int truncation and size_t overflow on 32-bit
- Reject ids sections that extend past the end of the file,
guarded by S_ISREG() so non-regular files (block devices,
pipes) are not falsely rejected
Also fix perf_header__getbuffer64() to set errno = EIO when
readn() returns 0 (EOF). Without this, the out_errno path in
perf_session__read_header() returns -errno which is 0 (success)
on truncated files, causing downstream NULL dereferences.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
perf_session__read_header() discards the return value from
perf_header__process_sections(), so any error from a feature
section processor (process_nrcpus, process_compressed, etc.)
is silently ignored and the session opens as if nothing went
wrong.
This defeats the validation added by subsequent commits in this
series: a crafted perf.data that fails a feature section check
would still be processed with partially-initialized state.
Check the return value and fail the session if any feature
section processor returns an error.
For truncated files (data.size == 0, i.e. recording was
interrupted before the header was finalized), skip feature
section processing entirely and clear the feature bitmap so
tools use their "feature not present" fallbacks instead of
accessing uninitialized env fields.
Change the feature processor stubs for optional libraries
(libtraceevent, libbpf) from returning -1 to returning 0,
so that perf.data files containing these features can still be
opened on builds without the optional library — the feature is
simply skipped rather than causing a fatal error.
Also propagate evlist__prepare_tracepoint_events() failure as
-ENOMEM, since the function can fail due to strdup() allocation
failure inside evsel__prepare_tracepoint_event().
Fixes: 1c0b04d12ae9 ("perf tools: Add perf_session__read_header function")
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
perf_event_attr__fprintf() accessed all struct fields unconditionally,
but attrs from older perf.data files or BPF-captured syscall payloads
may have a smaller size than the current struct. Fields beyond the
recorded size contain uninitialized or zero-filled data.
Add size-guarded macros (PRINT_ATTRn, PRINT_ATTRn_bf) that compare
each field's offset against attr->size before accessing it.
Guard the bitfield block (disabled, inherit, ... defer_output) with
attr_size >= 48. These bitfields share a single __u64 at offset 40,
which is within PERF_ATTR_SIZE_VER0 for validated perf.data attrs,
but BPF-captured attrs from perf trace can have a smaller size when
the tracee passes a minimal struct to sys_perf_event_open.
Also fix the BPF trace path: when perf trace intercepts
sys_perf_event_open via BPF, the program copies PERF_ATTR_SIZE_VER0
bytes when the tracee passes size=0, but leaves the size field as 0.
Set attr->size to PERF_ATTR_SIZE_VER0 in the augmented syscall
handler so the bounds checks match the actual copied size.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
strdup(ev->unit) and strdup(ev->name) read until '\0' with no
guarantee the string is null-terminated within event->header.size.
The dump_trace fprintf path has the same problem with %s.
Validate before either path runs — same class of bug fixed for
MMAP/MMAP2/COMM/CGROUP by perf_event__check_nul().
Also harden the event_update swap handler to:
- Validate SCALE event size before swapping the double at
offset 24, which exceeds the 24-byte min_size.
- Validate CPUS event size before accessing the cpu_map
type/nr/long_size fields, which also start at the min_size
boundary.
- Swap CPUS variant fields (type, nr, long_size) so the
processing path sees native byte order.
Add validation in perf_event__process_event_update() for all
event update variants (UNIT, NAME, SCALE, CPUS) before
dump_trace or processing.
Validate CPUS nr against payload size for both PERF_CPU_MAP__CPUS
and PERF_CPU_MAP__MASK types on the fprintf (dump_trace) path:
- CPUS: check nr does not exceed available cpu entries
- MASK: check nr does not exceed available mask entries for
both mask32 (long_size == 4) and mask64 (long_size == 8)
layouts, with underflow guards on the offsetof subtraction
Fix a missing break before the default case in the CPUS
switch path.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
PERF_RECORD_BPF_METADATA has no entry in perf_event__swap_ops[], so its
nr_entries field is never byte-swapped when reading a cross-endian
perf.data file. Downstream processing in
perf_event__fprintf_bpf_metadata() loops over nr_entries, so a
foreign-endian value causes out-of-bounds reads.
Add a swap handler that byte-swaps nr_entries after validating that
header.size is large enough. The entries[] array contains only char
arrays (key/value strings), so no per-entry swap is needed — but ensure
NUL-termination on the writable cross-endian path.
Validate header.size, nr_entries, and string NUL-termination in the
common event delivery path so that native-endian files with malicious
values are also rejected. Snapshot nr_entries via READ_ONCE() before
validation — the event is on a MAP_SHARED mmap that could theoretically
change between the bounds check and the loop.
Changes in v2:
- Snapshot event->header.size via READ_ONCE() into a local variable
to prevent a double-fetch underflow in the max_entries calculation
(Reported-by: sashiko-bot@kernel.org)
- Write back clamped nr_entries to the event on the swap path,
consistent with NAMESPACES and STAT_CONFIG handlers — without
writeback the native path sees the inflated nr and skips the
event entirely (Reported-by: sashiko-bot@kernel.org)
Fixes: ab38e84ba9 ("perf record: collect BPF metadata from existing BPF programs")
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Blake Jones <blakejones@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Fix four issues in PERF_RECORD_AUXTRACE_ERROR handling:
1. auxtrace_error_name() takes a signed int parameter, but e->type
is __u32. A crafted value like 0xFFFFFFFF converts to -1, passes
the bounds check, and causes a negative array index. Fix by
changing the parameter to unsigned int.
2. The msg field is printed via %s without a length bound. The
min_size table only guarantees fields up to msg (offset 48), so
a truncated event has zero msg bytes within the event boundary.
Compute the available msg length from header.size, cap at
sizeof(e->msg), and use %.*s.
3. fmt >= 2 adds machine_pid and vcpu fields after msg[64]. Older
files may have fmt >= 2 but an event size that doesn't include
these fields. Add a size check in the swap handler to downgrade
fmt before the conditional field access, and a matching size
guard in the fprintf path for native-endian events (which are
mmap'd read-only and can't be modified in place).
4. python_process_auxtrace_error() had the same issues: msg was
passed to tuple_set_string() unbounded, and machine_pid/vcpu
were accessed unconditionally without checking fmt or event
size. Apply the same bounds checks.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
cpu_map__from_range() computes nr_cpus as end_cpu - start_cpu + 1.
When a crafted perf.data has start_cpu > end_cpu, this wraps to a
huge value, causing perf_cpu_map__empty_new() to attempt a massive
allocation.
Return NULL when the range is inverted.
Also clamp any_cpu to boolean (0 or 1) since it is added to the
allocation count — a crafted value > 1 would inflate the map size.
Harden cpu_map__from_mask() to reject unsupported long_size values
(anything other than 4 or 8), preventing misinterpretation of the
mask data layout.
Snapshot mmap'd fields via READ_ONCE() into locals to prevent
TOCTOU re-reads — the data pointer references MAP_SHARED mmap'd
memory that could theoretically change between reads on a
FUSE-backed file:
- cpu_map__from_range(): snapshot start_cpu, end_cpu, any_cpu
- cpu_map__from_entries(): snapshot nr and each cpu[i] element
- cpu_map__from_mask(): snapshot long_size (before validation,
closing the check-then-read gap), mask_nr
- perf_record_cpu_map_data__read_one_mask(): add u16 long_size
parameter so callers pass the validated copy instead of
re-reading data->mask32_data.long_size from mmap'd memory
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
perf_header__read_build_ids() swaps the event header fields for cross-endian
perf.data files but not bev.pid. This causes perf_session__findnew_machine()
to look up the wrong machine for guest VM build IDs, misattributing them.
Swap bev.pid alongside the header fields.
Also add a build_id_swap callback for stream-mode build ID events,
and validate NUL-termination of build_id.filename on the native-endian
delivery path (perf_session__process_user_event) — events with
unterminated filenames are skipped.
Harden perf_header__read_build_ids() against crafted perf.data files:
- Add overflow check on offset + size to prevent wrap past ULLONG_MAX.
- Reject bev.header.size == 0 which would loop forever.
- Reject bev.header.size > remaining section to prevent reading past
the section boundary.
- Guard memcmp(filename, "nel.kallsyms]", 13) with len >= 13 to avoid
reading uninitialized stack memory on short filenames.
- Force NUL-termination of filename before passing it to functions
like machine__findnew_dso() that use strlen/strcmp.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Several event types use an nr field to control iteration over
variable-length arrays. The swap handlers byte-swap and loop using
these fields without bounds checks, and the native processing path
trusts them as well.
Add bounds checks on both paths for:
- PERF_RECORD_THREAD_MAP: validate nr against payload, return -1
on the swap path. On the native path, reject with -EINVAL.
- PERF_RECORD_NAMESPACES: clamp nr on the swap path (safe because
each entry is indexed by type; missing entries just won't be
resolved). Skip the event on the native path.
- PERF_RECORD_CPU_MAP: clamp nr for CPUS and MASK sub-types on
the swap path. Add bounds checks for mask64 which previously
had no nr validation. Skip the event on the native path.
- PERF_RECORD_STAT_CONFIG: clamp nr on the swap path (safe because
each config entry is self-describing via its tag). Skip the
event on the native path.
The swap path (cross-endian, writable MAP_PRIVATE mapping) can
safely clamp by writing back to the event. The native path
(read-only MAP_SHARED mapping) must skip instead of clamping
because writing to the mmap'd event would segfault.
Also fix stat_config swap range: change size += 1 to
size += sizeof(event->stat_config.nr) for clarity. The old +1
happened to work because mem_bswap_64 processes 8-byte chunks,
but the intent is to include the 8-byte nr field in the swap
range.
Changes in v2:
- Document that PERF_RECORD_NAMESPACES max_nr includes trailing
sample_id space when sample_id_all is present — harmless on the
swap path because both per-element bswap_64 and swap_sample_id_all()
perform the same u64 byte swap (Reported-by: sashiko-bot@kernel.org)
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Harden PERF_RECORD_HEADER_ATTR handling against crafted perf.data:
- Validate attr.size: must be >= PERF_ATTR_SIZE_VER0, a multiple
of sizeof(u64), and fit within the event payload.
- Copy only min(attr.size, sizeof(struct perf_event_attr)) bytes
into a local attr, zeroing the rest so legacy files don't leak
adjacent event data into new fields.
- Keep the original attr.size so perf_event__synthesize_attr()
uses it for both allocation and ID-array placement.
Fix perf_event__synthesize_attr() to use attr->size (not the
compiled sizeof) for event allocation and layout, so perf inject
correctly re-synthesizes attrs from files recorded by a different
perf version. Without this, the ID array destination pointer
(computed via perf_record_header_attr_id()) would be inconsistent
with the allocation when attr->size differs from sizeof.
Also fix the parse-no-sample-id-all test to set attr.size, which
is now validated, and improve error handling in read_attr() for
short reads and invalid attr sizes.
Handle ABI0 pipe/inject events where attr.size is 0: use a local
attr_size variable set to PERF_ATTR_SIZE_VER0 for both the bounded
copy and ID array position, instead of writing back to the event.
Native-endian files may be MAP_SHARED (read-only mmap), so writing
to the event buffer would SIGSEGV. The swap path handles ABI0 in
perf_event__attr_swap() which writes to the MAP_PRIVATE copy.
header.size alignment is now validated centrally in
perf_session__process_event() (see "Add minimum event size and
alignment validation").
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
session->time_conv = event->time_conv copies sizeof(struct
perf_record_time_conv) bytes unconditionally, but older kernels
emit shorter TIME_CONV events without the time_cycles, time_mask,
cap_user_time_zero, and cap_user_time_short fields.
For a 32-byte event (the original format), this reads 24 bytes
past the event boundary into adjacent mmap'd data. The garbage
values end up in session->time_conv and can cause incorrect TSC
conversion if cap_user_time_zero happens to be non-zero.
Replace the struct assignment with a bounded memcpy capped at
event->header.size, zeroing the remainder so extended fields
default to off when absent.
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Change swap callbacks from void to int return so handlers can
propagate errors. All 28 existing handlers are converted to
return 0 on success, -1 on error. Three new handlers (KSYMBOL,
BPF_EVENT, HEADER_FEATURE) are added returning int from the
start, with sample_id_all handling for the kernel event types.
event_swap() propagates the return to its callers (process_event
and peek_event), which skip events that fail to swap.
Add perf_event__check_nul() for null-termination enforcement
on the common event delivery path for MMAP, MMAP2, COMM,
CGROUP, and KSYMBOL events. Events with
unterminated strings are skipped — native-endian files are
mapped read-only, so writing a NUL byte in place would segfault.
Swap handler hardening:
- Use strnlen bounded by event size (instead of strlen) in
COMM/MMAP/MMAP2/CGROUP swap handlers, returning -1 on
unterminated strings.
- Bounds check text_poke old_len+new_len before computing the
sample_id offset, returning -1 on overflow. Use offsetof()
for the native-path check in machines__deliver_event() since
sizeof() includes struct padding past the flexible array.
- Fix PERF_RECORD_SWITCH sample_id_all: non-CPU_WIDE SWITCH
events have sample_id immediately after the 8-byte header,
not at sizeof(struct perf_record_switch) which is the
CPU_WIDE variant size.
- Fix perf_event__time_conv_swap(): decouple time_cycles and
time_mask into independent per-field event_contains() checks,
so each field is only swapped when the event is large enough
to contain it. The original code guarded both fields under
a single time_cycles check, which would swap time_mask on a
short event that contains time_cycles but not time_mask.
- Handle ABI0 (attr.size == 0) in perf_event__attr_swap()
by substituting PERF_ATTR_SIZE_VER0, so bswap_safe()
correctly swaps VER0 fields instead of skipping everything.
- peek_events: on swap failure, advance past the malformed
entry instead of aborting the loop.
Note: the nr-field bounds checks for namespaces, thread_map,
cpu_map, and stat_config arrays are added by a subsequent
patch ("perf session: Validate nr fields against event size
on both swap and common paths"). The HEADER_ATTR attr.size
validation is added by ("perf session: Validate HEADER_ATTR
attr.size before swapping").
By establishing the int-returning swap infrastructure first,
all subsequent hardening patches can use direct error returns
from day one — no poison values, no workarounds for void return.
Changes in v2:
- peek_events: abort instead of skip for AUXTRACE events on
validation failure — skipping only header.size would land
inside the raw trace payload, causing subsequent iterations
to misparse data as events (Reported-by: sashiko-bot@kernel.org)
Fixes: 9aa0bfa370 ("perf tools: Handle PERF_RECORD_KSYMBOL")
Fixes: 45178a928a ("perf tools: Handle PERF_RECORD_BPF_EVENT")
Fixes: e9def1b2e7 ("perf tools: Add feature header record to pipe-mode")
Reported-by: sashiko-bot@kernel.org # Running on a local machine
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Carrillo-Cisneros <davidcc@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Song Liu <songliubraving@fb.com>
Assisted-by: Claude:claude-opus-4.6-1m
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>