| 0/0 |
2026/08/09 09:53 |
flow |
assessment-security |
26m
Results: map[DenialOfService:false Explanation:The bug report describes a Kernel Concurrency Sanitizer (KCSAN) data-race in the
`vsnprintf` function, triggered via `acpi_os_vprintf`.
### Root Cause Analysis
Looking at the source code for `acpi_os_vprintf` in `drivers/acpi/osl.c`:
```c
void __printf(1, 0) acpi_os_vprintf(const char *fmt, va_list args)
{
static char buffer[512];
vsprintf(buffer, fmt, args);
// ... printk calls ...
}
```
The function uses a `static char buffer[512]` to format ACPI debug messages
before passing them to `printk`. Because the buffer is static and there is no
locking mechanism around it, concurrent calls to `acpi_os_vprintf` from multiple
threads will result in a data race where both threads write to the same memory
buffer simultaneously.
The stack traces in the report show two different threads (`async_resume_noirq`
workers) concurrently executing ACPI power management operations and emitting
ACPI debug prints, which leads to the race condition.
### Security Impact Assessment
**Exploitable: No**
This is a benign data race from a memory safety perspective. The `vsprintf`
function (which internally calls `vsnprintf`) uses local pointers on the stack
to track the current write position within the buffer. Concurrent executions
will not corrupt these local pointers, nor will they cause the write position to
exceed the length of the formatted string. The threads will simply overwrite
each other's characters within the 512-byte buffer.
There is no memory corruption, no out-of-bounds read/write, and no control-flow
hijack possible. The only consequence is that the resulting debug log messages
printed to `dmesg` may be garbled.
**Denial of Service: No**
The race condition does not cause kernel panics, hangs, deadlocks, or resource
leaks. It only affects the contents of a debug print buffer.
**Accessibility:**
ACPI debug logging (`CONFIG_ACPI_DEBUG`) is typically disabled or set to a very
low verbosity level in production kernel builds, making this code path largely
unreachable in normal circumstances. Even if enabled, the bug provides no
privilege escalation or exploitation primitives.
In conclusion, this is a harmless data race in a debug logging facility with no
security implications. Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:false VMGuestTrigger:false VMHostTrigger:false]
|
| 1/1 |
2026/08/09 09:53 |
action |
syz-repro-to-c-repro |
0m
Results:
|
| 2/1 |
2026/08/09 09:53 |
action |
kernel-checkouter |
0m
Results: map[KernelSrc:/app/workdir/cache/src/0bd482cc9fd6a5c3cdf3e7f636a3906397462859]
|
| 3/1 |
2026/08/09 09:53 |
action |
kernel-builder |
16m
Results: map[KernelObj:/app/workdir/cache/build/c74dae594c3a60776c3332c6f0edd4bae8630b5f]
|
| 4/1 |
2026/08/09 10:09 |
action |
codesearch-prepare |
8m
Results: map[Index:codesearch-index]
|
| 5/1 |
2026/08/09 10:17 |
agent |
expert |
2m
Model:
Results: map[DenialOfService:false Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:false VMGuestTrigger:false VMHostTrigger:false]
Instruction: You are an experienced Linux kernel security engineer. Your task is to analyze given kernel bug report
and determine its security impact based on the following dimensions.
Use the provided tools to examine the source code, check for capability checks (e.g., capable(), ns_capable()),
and understand the nature of the bug. Analyze the given kernel build and configuration.
You can check the kernel config by grepping ".config" file; you can check kernel cmdline by grepping
".config" file for "CONFIG_CMDLINE=". Assume sysctl parameters have default values.
But analyze for the corresponding production build w/o debugging tools enabled (like KASAN, KMSAN, UBSAN).
Try different strategies when analyzing the bug:
- think of ways in which the vulnerable code is unreachable
- or the other way around: try to come up with different ideas of how an unprivileged user can reach the bug
If still unsure err on the side of the bug being non-exploitable/not-accessible.
In the final reply, provide a reasoning for your assessment.
Analysis dimensions:
* Exploitable:
Determine if the bug can result in memory corruption, elevated privileges, or an information leak.
Memory safety issues are almost always exploitable (KASAN or UBSAN reports for use-after-free, out-of-bounds;
refcounting issues, corrupted lists, etc). When kernel is crashing on a completely wild pointer access
(e.g. user-space address, or non-canonical address, but not on NULL or address corresponding to KASAN shadow
for NULL address), including both data accesses and control transfers, that also usually implies possibility
of exploitation. Such reports usually say "unable to handle kernel paging request".
Uses of uninitialized values detected by KMSAN may be exploitable b/c attacker frequently can affect uninit
values with spraying techniques. However, for these exploitability depends on how exactly the uninit value
is used in the code, and what it affects.
Information leaks are exploitable on their own and should be classified as such. A bug that copies kernel
memory contents to userspace (e.g. an out-of-bounds read whose result is returned to the caller, or
uninitialized stack/heap bytes written to a user buffer) is exploitable: it can reveal kernel pointer
values and defeat KASLR, expose sensitive data such as cryptographic keys or other processes' memory, and
serves as a necessary building block in most modern kernel privilege-escalation exploit chains. Do not classify
an information leak as non-exploitable solely because it does not directly cause a memory write or control-flow
hijack; the leak itself is the exploit primitive.
Think of what happens after the bug is triggered. Some bugs cause kernel panic and halt execution,
they are harder to exploit. For example, BUG reports halts the kernel. However, WARNING reports don't halt
execution in production builds. Debug bug detection tools (like KASAN, KMSAN, KCSAN, UBSAN) are also not enabled
in production builds, so attacker can freely exploit these bugs w/o being detected by these tools.
If you see an integer overflow, think how the overflowed value used later (if it's used as allocation size,
or an array index). If you see an out-of-bounds read, think if it's followed by an out-of-bounds write as well.
Some KCSAN data-races may be exploitable by skilled attackers as well. Think what data structures got corrupted
as the result of data races and how. However, note that kernel has lots of "benign" data races that don't lead
to any runtime misbehavior at all.
* Denial Of Service:
Determine if the bug can result in denial-of-service. Most bugs can, since they cause system crash,
hangs, deadlocks, or resource leaks. This is mostly applicable to WARNING bugs that won't cause system crash
in production. For these think what will be consequences of the violation of the kernel assumptions flagged
by the WARNING. In some cases the unexpected condition is also properly handled by the normal control flow
(e.g. with "if (WARN_ON(...))"), these won't cause denial-of-service. If the condition is not handled,
then it may or may not cause denial-of-service.
* Accessible From Unprivileged Processes:
Determine if the bug can be reached from a typical (non-root) user process that does NOT have any special capabilities
(like CAP_SYS_ADMIN, CAP_NET_ADMIN, CAP_NET_RAW, CAP_PERFMON) or access to device nodes restricted to root.
Assume that unprivileged_bpf_disabled=1, that is eBPF loading is not accessible. However, cBPF (classical BPF)
is still accessible to non-root processes.
Assume that user namespaces are not accessible, that is, the process cannot get the mentioned capabilities even
within a new user namespace (checked by ns_capable() function in the kernel sources).
* Accessible From User Namespaces:
Determine if the bug can be reached within a user-namespace where the process has all capabilities
(including CAP_SYS_ADMIN, CAP_NET_ADMIN, CAP_NET_RAW, CAP_PERFMON). Such capabilities are checked with ns_capable()
function in the kernel sources.
* VM Guest Trigger:
Determine if the bug can be triggered from the context of a typical KVM guest (e.g., set up by a QEMU VMM).
Consider accesses to standard Linux host paravirtualized features (virtio-blk, virtio-net, etc.),
and handling of VM exits in the KVM code.
* VM Host Trigger in The Confidential Computing Context:
Determine if the bug can be triggered in a confidential computing guest kernel from the context of a KVM host.
Consider access to standard Linux guest paravirtualized features (virtio-blk, virtio-net, etc.).
* Ethernet Network Trigger:
Determine if the bug can be triggered by processing ingress network Ethernet traffic, either directly (network stack)
or via drivers exposed to network data.
* Other Remote Trigger:
Determine if the bug can be triggered by processing remote traffic other than Ethernet (Wifi, Bluetooth, NFC, etc).
* Peripheral Trigger:
Determine if the bug can be triggered via an untrusted peripheral device that can be physically plugged
into a system, such as a USB device or a niche hardware driver handling external hardware inputs.
This is particularly important for mobile and desktop environments where users can plug in unknown devices.
* Malicious Filesystem Trigger:
Determine if the bug can be triggered by the kernel mounting and parsing a malicious filesystem image.
This is highly critical for Desktop and Mobile environments where external media or downloaded images
might be auto-mounted.
Don't make assumptions about the kernel source code (it may be different from what you assume it is).
Extensively use the provided code access tools (codesearch-*, git-*, grepper, etc)
to examine the actual source code, and confirm any assumptions.
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt:
The kernel bug report is:
**** Context Switch from TID 36034112 to TID 2691392 ****
nsutils-0719 ns_get_node : ----Entry ffffffff86882de5
utmutex-0235 ut_acquire_mutex :
----Entry
**** Cont1292
==================================================================
BUG: KCSAN: data-race in vsnprintf / vsnprintf
write to 0xffffffff89405bd8 of 1 bytes by task 39 on cpu 1:
vsnprintf+0x815/0x8c0 lib/vsprintf.c:2977
vsprintf+0x2a/0x40 lib/vsprintf.c:3090
acpi_os_vprintf drivers/acpi/osl.c:162 [inline]
acpi_os_printf+0x87/0x200 drivers/acpi/osl.c:153
acpi_debug_print+0x1a9/0x200 drivers/acpi/acpica/utdebug.c:197
acpi_ns_build_internal_name+0x589/0x5d0 drivers/acpi/acpica/nsutils.c:-1
acpi_ns_internalize_name+0x265/0x310 drivers/acpi/acpica/nsutils.c:339
acpi_ns_get_node_unlocked+0xed/0x2d0 drivers/acpi/acpica/nsutils.c:666
acpi_ns_get_node+0x76/0xc0 drivers/acpi/acpica/nsutils.c:726
acpi_get_handle+0xfd/0x180 drivers/acpi/acpica/nsxfname.c:98
acpi_has_method+0x46/0x80 drivers/acpi/utils.c:672
acpi_pci_set_power_state+0x5d/0x190 drivers/pci/pci-acpi.c:1084
platform_pci_set_power_state drivers/pci/pci.c:1068 [inline]
pci_power_up+0x40/0x3b0 drivers/pci/pci.c:1306
pci_pm_power_up_and_verify_state+0x29/0x130 drivers/pci/pci.c:3153
pci_pm_default_resume_early drivers/pci/pci-driver.c:591 [inline]
pci_pm_resume_noirq+0xcb/0x320 drivers/pci/pci-driver.c:996
dpm_run_callback+0x53/0x2f0 drivers/base/power/main.c:510
device_resume_noirq+0x851/0x880 drivers/base/power/main.c:857
async_resume_noirq+0x2c/0x40 drivers/base/power/main.c:879
async_run_entry_fn+0x52/0x180 kernel/async.c:129
process_one_work kernel/workqueue.c:3322 [inline]
process_scheduled_works+0x4d4/0x9a0 kernel/workqueue.c:3405
worker_thread+0x569/0x750 kernel/workqueue.c:3486
kthread+0x221/0x270 kernel/kthread.c:436
ret_from_fork+0x146/0x330 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
write to 0xffffffff89405bd8 of 1 bytes by task 12 on cpu 0:
vsnprintf+0x815/0x8c0 lib/vsprintf.c:2977
vsprintf+0x2a/0x40 lib/vsprintf.c:3090
acpi_os_vprintf drivers/acpi/osl.c:162 [inline]
acpi_os_printf+0x87/0x200 drivers/acpi/osl.c:153
acpi_debug_print+0x1a9/0x200 drivers/acpi/acpica/utdebug.c:197
acpi_os_wait_semaphore+0x11b/0x2b0 drivers/acpi/osl.c:1292
acpi_ut_acquire_mutex+0x242/0x4a0 drivers/acpi/acpica/utmutex.c:241
acpi_ns_get_node+0x46/0xc0 drivers/acpi/acpica/nsutils.c:721
acpi_get_handle+0xfd/0x180 drivers/acpi/acpica/nsxfname.c:98
acpi_has_method+0x46/0x80 drivers/acpi/utils.c:672
acpi_pci_set_power_state+0x5d/0x190 drivers/pci/pci-acpi.c:1084
platform_pci_set_power_state drivers/pci/pci.c:1068 [inline]
pci_power_up+0x40/0x3b0 drivers/pci/pci.c:1306
pci_pm_power_up_and_verify_state+0x29/0x130 drivers/pci/pci.c:3153
pci_pm_default_resume_early drivers/pci/pci-driver.c:591 [inline]
pci_pm_resume_noirq+0xcb/0x320 drivers/pci/pci-driver.c:996
dpm_run_callback+0x53/0x2f0 drivers/base/power/main.c:510
device_resume_noirq+0x851/0x880 drivers/base/power/main.c:857
async_resume_noirq+0x2c/0x40 drivers/base/power/main.c:879
async_run_entry_fn+0x52/0x180 kernel/async.c:129
process_one_work kernel/workqueue.c:3322 [inline]
process_scheduled_works+0x4d4/0x9a0 kernel/workqueue.c:3405
worker_thread+0x569/0x750 kernel/workqueue.c:3486
kthread+0x221/0x270 kernel/kthread.c:436
ret_from_fork+0x146/0x330 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
value changed: 0x6d -> 0x65
Reported by Kernel Concurrency Sanitizer on:
CPU: 0 UID: 0 PID: 12 Comm: kworker/u8:0 Tainted: G W syzkaller #0 PREEMPT(lazy)
Tainted: [W]=WARN
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026
Workqueue: async async_run_entry_fn
==================================================================
]
Waiting for semaphore[ffff8881000c3390|1|65535]
**** Context Switch from TID 29995968 to TID 2691392 ****
osl-1310 os_wait_semaphore : Acquired semaphore[ffff8881000c3390|1|65535] utmutex-0244 ut_acquire_mutex : Thread 2691392 acquired Mutex [ACPI_MTX_Namespace]
nsutils-0644 ns_get_node_unlocked : ----Entry ffffffff86882de5
nsutils-0318 ns_internalize_name : ----Entry
nsutils-0208 ns_build_internal_name: ----Entry
nsutils-0289 ns_build_internal_name: Returning [ffff88810163f348] (rel) "_EJ0"
nsutils-0293 ns_build_internal_name: ----Exit- AE_OK
nsutils-0346 ns_internalize_name : ----Exit- AE_OK
nsaccess-0303 ns_lookup : ----Entry
nsaccess-0399 ns_lookup : Searching relative to prefix scope [S04_] (ffff888100a953f0)
nsaccess-0522 ns_lookup : Simple Pathname (1 segment, Flags=2)
nsdump-0064 ns_print_pathname : [_EJ0]
nssearch-0261 ns_search_and_enter : ----Entry
nssearch-0066 ns_search_one_scope : ----Entry
nsnames-0301 ns_get_normalized_path: ----Entry ffff888100a953f0
nsnames-0202 ns_build_normalized_pa: ----Entry ffff888100a953f0
nsnames-0275 ns_build_normalized_pa: ----Exit- 000000000000000E
nsnames-0202 ns_build_normalized_pa: ----Entry ffff888100a953f0
nsnames-0275 ns_build_normalized_pa: ----Exit- 000000000000000E
acpi_ns_get_normalized_pathname: Path "\_SB.PCI0.S04"
nsnames-0326 ns_get_normalized_path: ----Exit- ffff888100aaad10
nssearch-0074 ns_search_one_scope : Searching \_SB.PCI0.S04 (ffff888100a953f0) For [_EJ0] (Untyped)
nssearch-0126 ns_search_one_scope : Name [_EJ0] (Untyped) not found in search in scope [S04_] ffff888100a953f0 first child ffff888100a953c0
nssearch-0134 ns_search_one_scope : ----Exit- ****Exception****: AE_NOT_FOUND
nssearch-0364 ns_search_and_enter : _EJ0 Not found in ffff888100a953f0 [Not adding]
nssearch-0368 ns_search_and_enter : ----Exit- ****Exception****: AE_NOT_FOUND
nsaccess-0605 ns_lookup : Name [_EJ0] not found in scope [S04_] ffff888100a953f0
nsaccess-0644 ns_lookup : ----Exit- ****Exception****: AE_NOT_FOUND
nsutils-0682 ns_get_node_unlocked : _EJ0, AE_NOT_FOUND
nsutils-0687 ns_get_node_unlocked : ----Exit- ****Exception****: AE_NOT_FOUND
utmutex-0277 ut_release_mutex : Thread 2691392 releasing Mutex [ACPI_MTX_Namespace]
osl-1334 os_signal_semaphore : Signaling semaphore[ffff8881000c3390|1]
nsutils-0730 ns_get_node : ----Exit- ****Exception****: AE_NOT_FOUND
Reply: The bug report describes a Kernel Concurrency Sanitizer (KCSAN) data-race in the `vsnprintf` function, triggered via `acpi_os_vprintf`.
### Root Cause Analysis
Looking at the source code for `acpi_os_vprintf` in `drivers/acpi/osl.c`:
```c
void __printf(1, 0) acpi_os_vprintf(const char *fmt, va_list args)
{
static char buffer[512];
vsprintf(buffer, fmt, args);
// ... printk calls ...
}
```
The function uses a `static char buffer[512]` to format ACPI debug messages before passing them to `printk`. Because the buffer is static and there is no locking mechanism around it, concurrent calls to `acpi_os_vprintf` from multiple threads will result in a data race where both threads write to the same memory buffer simultaneously.
The stack traces in the report show two different threads (`async_resume_noirq` workers) concurrently executing ACPI power management operations and emitting ACPI debug prints, which leads to the race condition.
### Security Impact Assessment
**Exploitable: No**
This is a benign data race from a memory safety perspective. The `vsprintf` function (which internally calls `vsnprintf`) uses local pointers on the stack to track the current write position within the buffer. Concurrent executions will not corrupt these local pointers, nor will they cause the write position to exceed the length of the formatted string. The threads will simply overwrite each other's characters within the 512-byte buffer.
There is no memory corruption, no out-of-bounds read/write, and no control-flow hijack possible. The only consequence is that the resulting debug log messages printed to `dmesg` may be garbled.
**Denial of Service: No**
The race condition does not cause kernel panics, hangs, deadlocks, or resource leaks. It only affects the contents of a debug print buffer.
**Accessibility:**
ACPI debug logging (`CONFIG_ACPI_DEBUG`) is typically disabled or set to a very low verbosity level in production kernel builds, making this code path largely unreachable in normal circumstances. Even if enabled, the bug provides no privilege escalation or exploitation primitives.
In conclusion, this is a harmless data race in a debug logging facility with no security implications.
|
| 6/2 |
2026/08/09 10:17 |
llm |
expert |
0m
Model:
Tokens:
input: 8768
output: 29
thoughts: 576
Thoughts: **Data Race in `vsnprintf` During System Resume**
Okay, so I've got a KCSAN data-race report that's snagged my attention, and it's pointing squarely at `vsnprintf`. The stack traces are essentially identical between Task 39 and Task 12, which is pretty telling. Both threads are deep within the system resume process, specifically hitting `async_resume_noirq`. Digging deeper, it looks like `acpi_debug_print` is the common thread, which then calls `acpi_os_printf`, cascades down to `acpi_os_vprintf`, into the standard `vsprintf`, and finally hits `vsnprintf`.
The report is flagging a problem in `vsnprintf` itself, specifically around `lib/vsprintf.c:2977` β or close to that line number, I'll need to check the exact line number on my setup. This implies a shared resource is being accessed concurrently within that function. Given the context of system resume, the issue is likely occurring while ACPI is interacting with power states or during name internalization, as suggested by `acpi_ns_build_internal_name` and the calls to `acpi_ns_get_node` and `acpi_get_handle` further up the stack.
I need to pull up `lib/vsprintf.c` and start scrutinizing the code around line 2977. I'll be looking for any unprotected access to shared data structures, particularly within the ACPI or PCI power management context, since that's what both tasks seem to be contending over. The fact that the stack trace shows `acpi_os_wait_semaphore` in one of the tasks gives me a pointer to check if there is some kind of synchronization issue. This is clearly a critical path issue, and if not addressed properly could lead to system instability, corrupted output, or potentially even hangs during resume. My next step is to analyze the `vsnprintf` implementation in that section, along with the calling code paths and potentially the arguments being passed to `vsnprintf` to identify and understand the root cause of the data race.
|
| 7/2 |
2026/08/09 10:18 |
tool |
grepper |
0m
Args: map[Expression:vsnprintf PathPrefix:lib/vsprintf.c]
Results: map[Output:lib/vsprintf.c-14- * Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
lib/vsprintf.c:15: * - changed to provide snprintf and vsnprintf functions
lib/vsprintf.c-16- * So Feb 1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
--
lib/vsprintf.c=1716=static char *va_format(char *buf, char *end, struct va_format *va_fmt,
--
lib/vsprintf.c-1724- va_copy(va, *va_fmt->va);
lib/vsprintf.c:1725: buf += vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va);
lib/vsprintf.c-1726- va_end(va);
--
lib/vsprintf.c=2388=early_param("no_hash_pointers", no_hash_pointers_enable);
--
lib/vsprintf.c-2459- * - 'V' For a struct va_format which contains a format string * and va_list *,
lib/vsprintf.c:2460: * call vsnprintf(->format, *->va_list).
lib/vsprintf.c:2461: * Implements a "recursive vsnprintf".
lib/vsprintf.c-2462- * Do not use this feature without some mechanism to verify the
--
lib/vsprintf.c-2516- * or user (u) memory to probe, and:
lib/vsprintf.c:2517: * s a string, equivalent to "%s" on direct vsnprintf() use
lib/vsprintf.c-2518- *
--
lib/vsprintf.c=2822=static unsigned long long convert_num_spec(unsigned int val, int size, struct printf_spec spec)
--
lib/vsprintf.c-2832-/**
lib/vsprintf.c:2833: * vsnprintf - Format a string and place it in a buffer
lib/vsprintf.c-2834- * @buf: The buffer to place the result into
--
lib/vsprintf.c-2838- *
lib/vsprintf.c:2839: * This function generally follows C99 vsnprintf, but has some
lib/vsprintf.c-2840- * extensions and a few limitations:
--
lib/vsprintf.c-2859- */
lib/vsprintf.c:2860:int vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
lib/vsprintf.c-2861-{
--
lib/vsprintf.c-2989-}
lib/vsprintf.c:2990:EXPORT_SYMBOL(vsnprintf);
lib/vsprintf.c-2991-
--
lib/vsprintf.c-3004- *
lib/vsprintf.c:3005: * See the vsnprintf() documentation for format string extensions over C99.
lib/vsprintf.c-3006- */
lib/vsprintf.c=3007=int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
--
lib/vsprintf.c-3013-
lib/vsprintf.c:3014: i = vsnprintf(buf, size, fmt, args);
lib/vsprintf.c-3015-
--
lib/vsprintf.c=3021=EXPORT_SYMBOL(vscnprintf);
--
lib/vsprintf.c-3034- *
lib/vsprintf.c:3035: * See the vsnprintf() documentation for format string extensions over C99.
lib/vsprintf.c-3036- */
lib/vsprintf.c=3037=int snprintf(char *buf, size_t size, const char *fmt, ...)
--
lib/vsprintf.c-3042- va_start(args, fmt);
lib/vsprintf.c:3043: i = vsnprintf(buf, size, fmt, args);
lib/vsprintf.c-3044- va_end(args);
--
lib/vsprintf.c=3072=EXPORT_SYMBOL(scnprintf);
--
lib/vsprintf.c-3080- * The return value is the number of characters written into @buf not including
lib/vsprintf.c:3081: * the trailing '\0'. Use vsnprintf() or vscnprintf() in order to avoid
lib/vsprintf.c-3082- * buffer overflows.
--
lib/vsprintf.c-3085- *
lib/vsprintf.c:3086: * See the vsnprintf() documentation for format string extensions over C99.
lib/vsprintf.c-3087- */
lib/vsprintf.c=3088=int vsprintf(char *buf, const char *fmt, va_list args)
lib/vsprintf.c-3089-{
lib/vsprintf.c:3090: return vsnprintf(buf, INT_MAX, fmt, args);
lib/vsprintf.c-3091-}
lib/vsprintf.c=3092=EXPORT_SYMBOL(vsprintf);
--
lib/vsprintf.c-3103- *
lib/vsprintf.c:3104: * See the vsnprintf() documentation for format string extensions over C99.
lib/vsprintf.c-3105- */
lib/vsprintf.c=3106=int sprintf(char *buf, const char *fmt, ...)
--
lib/vsprintf.c-3111- va_start(args, fmt);
lib/vsprintf.c:3112: i = vsnprintf(buf, INT_MAX, fmt, args);
lib/vsprintf.c-3113- va_end(args);
--
lib/vsprintf.c=3117=EXPORT_SYMBOL(sprintf);
--
lib/vsprintf.c-3132- *
lib/vsprintf.c:3133: * The format follows C99 vsnprintf, except %n is ignored, and its argument
lib/vsprintf.c-3134- * is skipped.
--
lib/vsprintf.c=3259=EXPORT_SYMBOL_GPL(vbin_printf);
--
lib/vsprintf.c-3267- *
lib/vsprintf.c:3268: * This function like C99 vsnprintf, but the difference is that vsnprintf gets
lib/vsprintf.c-3269- * arguments from stack, and bstr_printf gets arguments from @bin_buf which is
--
lib/vsprintf.c-3271- *
lib/vsprintf.c:3272: * The format follows C99 vsnprintf, but has some extensions:
lib/vsprintf.c:3273: * see vsnprintf comment for details.
lib/vsprintf.c-3274- *
]
|
| 8/2 |
2026/08/09 10:18 |
llm |
expert |
0m
Model:
Tokens:
input: 11638
output: 35
thoughts: 37
Thoughts: Here's a first-person summary of the provided text, assuming an expert user:
**Data Race Investigation: vsnprintf Suspect**
Okay, so we've got a data race flagged, and my spidey-sense is telling me it's likely nestled within `vsnprintf`. Specifically, the warning points to the vicinity of line 2977. Alright, let's dive right into the source code. I'm going to pull up `lib/vsprintf.c` and zero in around that line. Time to see what's happening in there and what variables are being accessed. Knowing `vsnprintf`βs complexity, there are a few likely candidates that I can start looking for: potentially shared buffers, concurrent access to format string pointers, or issues related to argument processing. Let's see what the compiler is getting so upset about!
|
| 9/2 |
2026/08/09 10:18 |
tool |
read-file |
0m
Args: map[File:lib/vsprintf.c FirstLine:2950 LineCount:50]
Results: map[Contents:2950: spec);
2951: while (isalnum(*fmt.str))
2952: fmt.str++;
2953: continue;
2954:
2955: case FORMAT_STATE_PERCENT_CHAR:
2956: if (str < end)
2957: *str = '%';
2958: ++str;
2959: continue;
2960:
2961: default:
2962: /*
2963: * Presumably the arguments passed gcc's type
2964: * checking, but there is no safe or sane way
2965: * for us to continue parsing the format and
2966: * fetching from the va_list; the remaining
2967: * specifiers and arguments would be out of
2968: * sync.
2969: */
2970: goto out;
2971: }
2972: }
2973:
2974: out:
2975: if (size > 0) {
2976: if (str < end)
2977: *str = '\0';
2978: else
2979: end[-1] = '\0';
2980: }
2981:
2982: /* the trailing null byte doesn't count towards the total */
2983: ret_size = str - buf;
2984:
2985: /* Make sure the return value is within the positive integer range */
2986: if (WARN_ON_ONCE(ret_size > INT_MAX))
2987: ret_size = INT_MAX;
2988: return ret_size;
2989: }
2990: EXPORT_SYMBOL(vsnprintf);
2991:
2992: /**
2993: * vscnprintf - Format a string and place it in a buffer
2994: * @buf: The buffer to place the result into
2995: * @size: The size of the buffer, including the trailing null space
2996: * @fmt: The format string to use
2997: * @args: Arguments for the format string
2998: *
2999: * The return value is the number of characters which have been written into
]
|
| 10/2 |
2026/08/09 10:18 |
llm |
expert |
0m
Model:
Tokens:
input: 12539
output: 37
thoughts: 110
Thoughts: **Race Condition in `vsnprintf`**
Okay, so I've pinpointed the issue. The race condition, the thing that's causing this unexpected behavior, appears to be occurring within the `vsnprintf` function. Specifically, it's happening right around the point where `*str = '\0';` is executed. That's a classic signal of multiple threads writing to the same memory location, the same buffer `buf`, concurrently.
Now, where is this `buf` coming from? I need to trace back the calls to figure out the context of `vsnprintf`. Looking at the code, it seems the buffer is being passed to `vsnprintf` from `vsprintf`. And digging a little deeper, `vsprintf` is called from `acpi_os_vprintf`. Aha, `acpi_os_vprintf` is called in `drivers/acpi/osl.c` at line 162. Let me pull up that file and take a look at what's happening around that line. That's where I need to focus my attention. It will be the key to understanding the full context of this race condition.
|
| 11/2 |
2026/08/09 10:18 |
tool |
read-file |
0m
Args: map[File:drivers/acpi/osl.c FirstLine:140 LineCount:50]
Results: map[Contents: 140:
141: if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
142: acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
143: acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
144:
145: return 0;
146: }
147: fs_initcall_sync(acpi_reserve_resources);
148:
149: void acpi_os_printf(const char *fmt, ...)
150: {
151: va_list args;
152: va_start(args, fmt);
153: acpi_os_vprintf(fmt, args);
154: va_end(args);
155: }
156: EXPORT_SYMBOL(acpi_os_printf);
157:
158: void __printf(1, 0) acpi_os_vprintf(const char *fmt, va_list args)
159: {
160: static char buffer[512];
161:
162: vsprintf(buffer, fmt, args);
163:
164: #ifdef ENABLE_DEBUGGER
165: if (acpi_in_debugger) {
166: kdb_printf("%s", buffer);
167: } else {
168: if (printk_get_level(buffer))
169: printk("%s", buffer);
170: else
171: printk(KERN_CONT "%s", buffer);
172: }
173: #else
174: if (acpi_debugger_write_log(buffer) < 0) {
175: if (printk_get_level(buffer))
176: printk("%s", buffer);
177: else
178: printk(KERN_CONT "%s", buffer);
179: }
180: #endif
181: }
182:
183: #ifdef CONFIG_KEXEC
184: static unsigned long acpi_rsdp;
185: static int __init setup_acpi_rsdp(char *arg)
186: {
187: return kstrtoul(arg, 16, &acpi_rsdp);
188: }
189: early_param("acpi_rsdp", setup_acpi_rsdp);
]
|
| 12/2 |
2026/08/09 10:18 |
llm |
expert |
0m
Model:
Tokens:
input: 13669
output: 41
thoughts: 1307
Thoughts: **Analyzing a Data Race in ACPI Debug Printing**
Okay, so I've been digging into this `acpi_os_vprintf` function, and the first thing that jumps out is that it's using a `static char buffer[512]` without any locking mechanism. That's a classic recipe for a data race if multiple threads happen to call it concurrently. This is what KCSAN has reported.
My immediate thought is: can this actually be exploited? Two threads, both trying to write to the same `buffer` at the same time, is a bad situation. Digging deeper, I see that `vsprintf` is used and expands to `vsnprintf` which *doesn't* limit the length to 512, it's limited to `INT_MAX`, so it's a potential buffer overflow if the formatted string is larger than 512 bytes. Even without an overflow, two threads stomping on the same memory region is still a problem, though.
However, the real issue is the data race itself. Let's see if we can get an overflow. Looking at the code: `vsprintf(buffer, fmt, args);` means that if the formatted string is longer than 512 bytes, it *will* overflow `buffer`. But the question is: is this even likely? Usually, ACPI debug prints are fairly short.
The crash report KCSAN gave me, it was that data race itself. So, what is the impact? Since this is a static buffer in the BSS/data segment, is this overwriting of data actually exploitable? If two threads are writing to `buffer` concurrently, they just overwrite each other's characters, which is not good, but is this just garbled output, or could it lead to more serious memory corruption?
Thinking it through, `vsprintf` writes characters into the buffer and increments a pointer, so each thread has it's local `str` pointer. Thread 1 has `str = buf;` and Thread 2 has `str = buf;`. But, if neither thread's formatted string goes beyond 512 bytes, there is no out-of-bounds write. If one *does* exceed 512, there is an out-of-bounds write, but that's a *separate* buffer overflow bug. So, let's look for a buffer overflow.
I'm trying to figure out if there are any calls to `acpi_os_vprintf` that might generate strings longer than 512 bytes. While ACPI debug prints are usually short, let's keep an eye out for this.
But, back to the data race: is it exploitable *directly*? No, the data race corrupts the debug print buffer. The output will be garbled, and there is a potential for other issues with race conditions due to how the buffer is used. Wait a second, what happens if this corrupted buffer then gets passed to `printk`?
```c
if (acpi_debugger_write_log(buffer) < 0) {
if (printk_get_level(buffer))
printk("%s", buffer);
else
printk(KERN_CONT "%s", buffer);
}
```
If the buffer isn't null-terminated due to the race, `printk` relies on `\0`. `vsnprintf` *should* always null-terminate, but what if one thread finishes writing and sets `\0` at say `buffer[10]`, and the other thread is still writing and overwrites `buffer[10]` with a non-null character? Then, the first thread calls `printk`?
`printk` is going to read until it finds a `\0`, but since it is a static array, what's *after* `buffer` in memory? If one thread eventually writes a `\0`, `printk` will stop. If a thread writes past the other thread's `\0`, `printk` might read into uninitialized data, or *other* static variables, up to the 512 byte boundary of `buffer`. If there's no `\0` within 512 bytes, it reads past the end.
But wait, `buffer` is static and zero-initialized. It's likely zeroed by the runtime. If both threads generate strings of less than 512, the end of `buffer` is probably still zero. However, if there's *continuous* overwriting, they could potentially *remove* all null terminators. But, `vsnprintf` *should* always write a `\0`, so each writes a `\0` after their own data. Even if one overwrites the `\0` written by another,
|
| 13/2 |
2026/08/09 10:18 |
tool |
read-file |
0m
Args: map[File:drivers/acpi/acpica/utdebug.c FirstLine:170 LineCount:50]
Results: map[Contents: 170: */
171: acpi_os_printf("%9s-%04d ", module_name, line_number);
172:
173: #ifdef ACPI_APPLICATION
174: /*
175: * For acpi_exec/iASL only, emit the thread ID and nesting level.
176: * Note: nesting level is really only useful during a single-thread
177: * execution. Otherwise, multiple threads will keep resetting the
178: * level.
179: */
180: if (ACPI_LV_THREADS & acpi_dbg_level) {
181: acpi_os_printf("[%u] ", (u32)thread_id);
182: }
183:
184: fill_count = 48 - acpi_gbl_nesting_level -
185: strlen(acpi_ut_trim_function_name(function_name));
186: if (fill_count < 0) {
187: fill_count = 0;
188: }
189:
190: acpi_os_printf("[%02d] %*s",
191: acpi_gbl_nesting_level, acpi_gbl_nesting_level + 1, " ");
192: acpi_os_printf("%s%*s: ",
193: acpi_ut_trim_function_name(function_name), fill_count,
194: " ");
195:
196: #else
197: acpi_os_printf("%-22.22s: ", acpi_ut_trim_function_name(function_name));
198: #endif
199:
200: va_start(args, format);
201: acpi_os_vprintf(format, args);
202: va_end(args);
203: }
204:
205: ACPI_EXPORT_SYMBOL(acpi_debug_print)
206:
207: /*******************************************************************************
208: *
209: * FUNCTION: acpi_debug_print_raw
210: *
211: * PARAMETERS: requested_debug_level - Requested debug print level
212: * line_number - Caller's line number
213: * function_name - Caller's procedure name
214: * module_name - Caller's module name
215: * component_id - Caller's component ID
216: * format - Printf format field
217: * ... - Optional printf arguments
218: *
219: * RETURN: None
]
|
| 14/2 |
2026/08/09 10:18 |
llm |
expert |
0m
Model:
Tokens:
input: 16837
output: 41
thoughts: 66
Thoughts: **Debugging ACPI: A Quick Look Under the Hood**
Okay, so I see a call to `acpi_debug_print`. That's interesting. Before I dive too deep into the code that's calling it, I should probably understand how this function actually *works*. Wait a minute... I remember now. `acpi_debug_print` doesn't just spew output directly. It first checks `acpi_dbg_level` and `acpi_dbg_layer`. Ah, yes, the classic debug level and layer filtering. Smart. That's good practice. It's designed to prevent an overwhelming amount of output and only prints data that's relevant to the current debug focus. So, the first thing I need to do is see how this filtering is implemented. Let's trace this and look at the beginning of `acpi_debug_print` to confirm that. I need to understand this check to be able to appropriately interpret the output.
|
| 15/2 |
2026/08/09 10:18 |
tool |
read-file |
0m
Args: map[File:drivers/acpi/acpica/utdebug.c FirstLine:120 LineCount:50]
Results: map[Contents: 120: * function_name - Caller's procedure name
121: * module_name - Caller's module name
122: * component_id - Caller's component ID
123: * format - Printf format field
124: * ... - Optional printf arguments
125: *
126: * RETURN: None
127: *
128: * DESCRIPTION: Print error message with prefix consisting of the module name,
129: * line number, and component ID.
130: *
131: ******************************************************************************/
132:
133: void ACPI_INTERNAL_VAR_XFACE
134: acpi_debug_print(u32 requested_debug_level,
135: u32 line_number,
136: const char *function_name,
137: const char *module_name,
138: u32 component_id, const char *format, ...)
139: {
140: acpi_thread_id thread_id;
141: va_list args;
142: #ifdef ACPI_APPLICATION
143: int fill_count;
144: #endif
145:
146: /* Check if debug output enabled */
147:
148: if (!ACPI_IS_DEBUG_ENABLED(requested_debug_level, component_id)) {
149: return;
150: }
151:
152: /*
153: * Thread tracking and context switch notification
154: */
155: thread_id = acpi_os_get_thread_id();
156: if (thread_id != acpi_gbl_previous_thread_id) {
157: if (ACPI_LV_THREADS & acpi_dbg_level) {
158: acpi_os_printf
159: ("\n**** Context Switch from TID %u to TID %u ****\n\n",
160: (u32)acpi_gbl_previous_thread_id, (u32)thread_id);
161: }
162:
163: acpi_gbl_previous_thread_id = thread_id;
164: acpi_gbl_nesting_level = 0;
165: }
166:
167: /*
168: * Display the module name, current line number, thread ID (if requested),
169: * current procedure nesting level, and the current procedure name
]
|
| 16/2 |
2026/08/09 10:18 |
llm |
expert |
0m
Model:
Tokens:
input: 17896
output: 29
thoughts: 66
Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience:
**Debugging ACPI in Production Kernels**
Alright, so I'm digging into some ACPI code, and I need to figure out the debug output situation. I know that in a production kernel environment, it's quite likely `CONFIG_ACPI_DEBUG` isn't enabled, or, if it is, `acpi_dbg_level` is probably set to zero by default. That's the typical configuration, for performance and stability reasons. So, before I go any further down this rabbit hole, I need to check the state of `ACPI_IS_DEBUG_ENABLED`. It's the first sensible step β determine if any debugging output is even active before I waste time assuming it is. That check tells me which path to follow to further diagnose the issue.
|
| 17/2 |
2026/08/09 10:18 |
tool |
grepper |
0m
Args: map[Expression:define ACPI_IS_DEBUG_ENABLED PathPrefix:]
Results: map[Output:include/acpi/acoutput.h-266-
include/acpi/acoutput.h:267:#define ACPI_IS_DEBUG_ENABLED(level, component) \
include/acpi/acoutput.h-268- ((level & acpi_dbg_level) && (component & acpi_dbg_layer))
--
include/acpi/acoutput.h-455-#define ACPI_DUMP_BUFFER(a, b)
include/acpi/acoutput.h:456:#define ACPI_IS_DEBUG_ENABLED(level, component) 0
include/acpi/acoutput.h-457-#define ACPI_TRACE_POINT(a, b, c, d)
]
|
| 18/2 |
2026/08/09 10:18 |
llm |
expert |
0m
Model:
Tokens:
input: 18360
output: 31
thoughts: 787
Thoughts: **Analyzing a Potential Data Race in ACPI Debug Printing**
Okay, so I'm looking at this data race report in `acpi_os_vprintf` and I need to figure out what's going on. First, if `CONFIG_ACPI_DEBUG` isn't enabled, then `ACPI_IS_DEBUG_ENABLED` will be zero. I'm assuming that in production kernels, this debug configuration is usually disabled, or at least the debug level is set so that not much prints. The bug report says this race is in `vsnprintf` within `acpi_os_vprintf` involving a data race on the `buffer`. I need to figure out if this is exploitable. The buffer size is 512 bytes, so my initial thought is a buffer overflow.
I can see that `vsprintf` is used: `vsprintf(buffer, fmt, args);`. If the formatted string and arguments generate output larger than 512 bytes, then we have a classic overflow, right? But looking at how these print statements are used, it seems the format strings are hardcoded within the kernel. For example, things like `acpi_os_printf("%-22.22s: ", acpi_ut_trim_function_name(function_name));` are typical. In `acpi_ns_build_internal_name`, there's `ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", ...));`. These format strings look pretty short. Even if there's concurrent writing, they'll just overwrite each other's bytes within the buffer.
The problem comes from the fact that `vsprintf` calls `vsnprintf`. When I look at the source, it doesn't appear as though it limits the size of the output to the `buffer`'s size (it passes `INT_MAX` for the size argument to `vsnprintf`). Meaning that `vsnprintf` would write as much as the formatted string requires. That's a potential issue.
But then, I need to remind myself that these formatted strings are short. Therefore, they won't cause the buffer to overflow. So, the data race itself is the main issue. Thread A can write to the `buffer`, then Thread B can write. Each writes a null terminator. If A's string is longer, then A's null terminator stays. If B is longer, then B's null terminator stays. I don't see an out-of-bounds write caused by the data race. That's good.
So, the worst-case scenario is garbled output in `printk`. That isn't exploitable. It doesn't look like a denial-of-service, either. Just a messed-up print. Can an unprivileged user even trigger this? I need to think about how ACPI debug prints work. They're usually triggered by ACPI events or operations. Some of these operations *can* be triggered from userspace, such as reading from `/sys/firmware/acpi/` or through power management. But it's just a data race in the debug print buffer.
Hang on. I need to make sure I'm not missing anything. Is there *any* possibility of a buffer overflow? Can an attacker somehow control the format string *or* the arguments to make the output larger than 512 bytes? The arguments are typically ACPI names, paths, or integers. ACPI paths can be long, but even a really long one probably won't get past 512 bytes. So, I need to go back and check the code to see if there's any ACPI print that I missed that *could* create a string longer than 512 bytes.
|
| 19/2 |
2026/08/09 10:19 |
tool |
grepper |
0m
Args: map[Expression:ACPI_DEBUG_PRINT PathPrefix:drivers/acpi/]
Results: map[Output:
Full output is too long, showing 500 out of 2005 lines.
Use more precise expression if possible.
drivers/acpi/acpica/dsargs.c=146=acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
--
drivers/acpi/acpica/dsargs.c-165-
drivers/acpi/acpica/dsargs.c:166: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
drivers/acpi/acpica/dsargs.c-167- acpi_ut_get_node_name(node)));
--
drivers/acpi/acpica/dsargs.c=191=acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
--
drivers/acpi/acpica/dsargs.c-210-
drivers/acpi/acpica/dsargs.c:211: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
drivers/acpi/acpica/dsargs.c-212- acpi_ut_get_node_name(node)));
--
drivers/acpi/acpica/dsargs.c=242=acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
--
drivers/acpi/acpica/dsargs.c-262-
drivers/acpi/acpica/dsargs.c:263: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
drivers/acpi/acpica/dsargs.c-264-
--
drivers/acpi/acpica/dsargs.c=286=acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
--
drivers/acpi/acpica/dsargs.c-306-
drivers/acpi/acpica/dsargs.c:307: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Argument Init, AML Ptr: %p\n",
drivers/acpi/acpica/dsargs.c-308- obj_desc->package.aml_start));
--
drivers/acpi/acpica/dsargs.c=332=acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
--
drivers/acpi/acpica/dsargs.c-355-
drivers/acpi/acpica/dsargs.c:356: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dsargs.c-357- "[%4.4s] OpRegion Arg Init at AML %p\n",
--
drivers/acpi/acpica/dscontrol.c=35=acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dscontrol.c-42-
drivers/acpi/acpica/dscontrol.c:43: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n",
drivers/acpi/acpica/dscontrol.c-44- op, op->common.aml_opcode, walk_state));
--
drivers/acpi/acpica/dscontrol.c=134=acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dscontrol.c-144-
drivers/acpi/acpica/dscontrol.c:145: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
drivers/acpi/acpica/dscontrol.c-146-
--
drivers/acpi/acpica/dscontrol.c-168-
drivers/acpi/acpica/dscontrol.c:169: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
drivers/acpi/acpica/dscontrol.c-170-
--
drivers/acpi/acpica/dscontrol.c-200-
drivers/acpi/acpica/dscontrol.c:201: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dscontrol.c-202- "[WHILE_OP] termination! Op=%p\n", op));
--
drivers/acpi/acpica/dscontrol.c-212-
drivers/acpi/acpica/dscontrol.c:213: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dscontrol.c-214- "[RETURN_OP] Op=%p Arg=%p\n", op,
--
drivers/acpi/acpica/dscontrol.c-302-
drivers/acpi/acpica/dscontrol.c:303: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dscontrol.c-304- "Completed RETURN_OP State=%p, RetVal=%p\n",
--
drivers/acpi/acpica/dsdebug.c=41=acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
--
drivers/acpi/acpica/dsdebug.c-49- if (!node) {
drivers/acpi/acpica/dsdebug.c:50: ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[NULL NAME]"));
drivers/acpi/acpica/dsdebug.c-51- return_VOID;
--
drivers/acpi/acpica/dsdebug.c-60- if (message) {
drivers/acpi/acpica/dsdebug.c:61: ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "%s ",
drivers/acpi/acpica/dsdebug.c-62- message));
--
drivers/acpi/acpica/dsdebug.c-64-
drivers/acpi/acpica/dsdebug.c:65: ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[%s] (Node %p)",
drivers/acpi/acpica/dsdebug.c-66- (char *)buffer.pointer, node));
--
drivers/acpi/acpica/dsdebug.c=89=acpi_ds_dump_method_stack(acpi_status status,
--
drivers/acpi/acpica/dsdebug.c-109- if (walk_state->deferred_node) {
drivers/acpi/acpica/dsdebug.c:110: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsdebug.c-111- "Executing subtree for Buffer/Package/Region\n"));
--
drivers/acpi/acpica/dsdebug.c-126-
drivers/acpi/acpica/dsdebug.c:127: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsdebug.c-128- "\n**** Exception %s during execution of method ",
--
drivers/acpi/acpica/dsdebug.c-134-
drivers/acpi/acpica/dsdebug.c:135: ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsdebug.c-136- "\n\nMethod Execution Stack:\n"));
--
drivers/acpi/acpica/dsdebug.c-148-
drivers/acpi/acpica/dsdebug.c:149: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsdebug.c-150- " Method [%4.4s] executing: ",
--
drivers/acpi/acpica/dsdebug.c-182- */
drivers/acpi/acpica/dsdebug.c:183: ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsdebug.c-184- "Call to method "));
--
drivers/acpi/acpica/dsdebug.c-189- next_walk_state = next_walk_state->next;
drivers/acpi/acpica/dsdebug.c:190: ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "\n"));
drivers/acpi/acpica/dsdebug.c-191- }
--
drivers/acpi/acpica/dsinit.c=157=acpi_ds_initialize_objects(u32 table_index,
--
drivers/acpi/acpica/dsinit.c-171-
drivers/acpi/acpica/dsinit.c:172: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsinit.c-173- "**** Starting initialization of namespace objects ****\n"));
--
drivers/acpi/acpica/dsinit.c-203- if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT)) {
drivers/acpi/acpica/dsinit.c:204: ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
drivers/acpi/acpica/dsinit.c-205- "\nACPI table initialization:\n"));
--
drivers/acpi/acpica/dsinit.c-209-
drivers/acpi/acpica/dsinit.c:210: ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
drivers/acpi/acpica/dsinit.c-211- "Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u Devices, "
--
drivers/acpi/acpica/dsinit.c-219-
drivers/acpi/acpica/dsinit.c:220: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n",
drivers/acpi/acpica/dsinit.c-221- info.method_count, info.op_region_count));
--
drivers/acpi/acpica/dsmethod.c=55=acpi_ds_auto_serialize_method(struct acpi_namespace_node *node,
--
drivers/acpi/acpica/dsmethod.c-63-
drivers/acpi/acpica/dsmethod.c:64: ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
drivers/acpi/acpica/dsmethod.c-65- "Method auto-serialization parse [%4.4s] %p\n",
--
drivers/acpi/acpica/dsmethod.c=122=acpi_ds_detect_named_opcodes(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dsmethod.c-149-
drivers/acpi/acpica/dsmethod.c:150: ACPI_DEBUG_PRINT((ACPI_DB_INFO,
drivers/acpi/acpica/dsmethod.c-151- "Method serialized [%4.4s] %p - [%s] (%4.4X)\n",
--
drivers/acpi/acpica/dsmethod.c=456=acpi_ds_call_control_method(struct acpi_thread_state *thread,
--
drivers/acpi/acpica/dsmethod.c-467-
drivers/acpi/acpica/dsmethod.c:468: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsmethod.c-469- "Calling method %p, currentstate=%p\n",
--
drivers/acpi/acpica/dsmethod.c-556-
drivers/acpi/acpica/dsmethod.c:557: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsmethod.c-558- "**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
--
drivers/acpi/acpica/dsmethod.c-566-
drivers/acpi/acpica/dsmethod.c:567: ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION,
drivers/acpi/acpica/dsmethod.c-568- "%-26s: %*s%s\n", " Nested method call",
--
drivers/acpi/acpica/dsmethod.c=615=acpi_ds_restart_control_method(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dsmethod.c-622-
drivers/acpi/acpica/dsmethod.c:623: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsmethod.c-624- "****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n",
--
drivers/acpi/acpica/dsmethod.c-627-
drivers/acpi/acpica/dsmethod.c:628: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsmethod.c-629- " ReturnFromThisMethodUsed?=%X ResStack %p Walk %p\n",
--
drivers/acpi/acpica/dsmethod.c=705=acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
--
drivers/acpi/acpica/dsmethod.c-838- */
drivers/acpi/acpica/dsmethod.c:839: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsmethod.c-840- "*** Completed execution of one thread, %u threads remaining\n",
--
drivers/acpi/acpica/dsmthdat.c=102=void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state)
--
drivers/acpi/acpica/dsmthdat.c-111- if (walk_state->local_variables[index].object) {
drivers/acpi/acpica/dsmthdat.c:112: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Local%u=%p\n",
drivers/acpi/acpica/dsmthdat.c-113- index,
--
drivers/acpi/acpica/dsmthdat.c-127- if (walk_state->arguments[index].object) {
drivers/acpi/acpica/dsmthdat.c:128: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Arg%u=%p\n",
drivers/acpi/acpica/dsmthdat.c-129- index,
--
drivers/acpi/acpica/dsmthdat.c=158=acpi_ds_method_data_init_args(union acpi_operand_object **params,
--
drivers/acpi/acpica/dsmthdat.c-167- if (!params) {
drivers/acpi/acpica/dsmthdat.c:168: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dsmthdat.c-169- "No parameter list passed to method\n"));
--
drivers/acpi/acpica/dsmthdat.c-192-
drivers/acpi/acpica/dsmthdat.c:193: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%u args passed to method\n", index));
drivers/acpi/acpica/dsmthdat.c-194- return_ACPI_STATUS(AE_OK);
--
drivers/acpi/acpica/dsmthdat.c=280=acpi_ds_method_data_set_value(u8 type,
--
drivers/acpi/acpica/dsmthdat.c-289-
drivers/acpi/acpica/dsmthdat.c:290: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dsmthdat.c-291- "NewObj %p Type %2.2X, Refs=%u [%s]\n", object,
--
drivers/acpi/acpica/dsmthdat.c=499=acpi_ds_store_object_to_local(u8 type,
--
drivers/acpi/acpica/dsmthdat.c-509- ACPI_FUNCTION_TRACE(ds_store_object_to_local);
drivers/acpi/acpica/dsmthdat.c:510: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n",
drivers/acpi/acpica/dsmthdat.c-511- type, index, obj_desc));
--
drivers/acpi/acpica/dsmthdat.c-527- if (current_obj_desc == obj_desc) {
drivers/acpi/acpica/dsmthdat.c:528: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p already installed!\n",
drivers/acpi/acpica/dsmthdat.c-529- obj_desc));
--
drivers/acpi/acpica/dsmthdat.c-583- ACPI_REFCLASS_REFOF)) {
drivers/acpi/acpica/dsmthdat.c:584: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dsmthdat.c-585- "Arg (%p) is an ObjRef(Node), storing in node %p\n",
--
drivers/acpi/acpica/dsobject.c=151=acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dsobject.c-214- obj_desc->buffer.pointer = NULL;
drivers/acpi/acpica/dsobject.c:215: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dsobject.c-216- "Buffer defined with zero length in AML, creating\n"));
--
drivers/acpi/acpica/dsopcode.c=353=acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dsopcode.c-428-
drivers/acpi/acpica/dsopcode.c:429: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
drivers/acpi/acpica/dsopcode.c-430- obj_desc,
--
drivers/acpi/acpica/dsopcode.c=460=acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dsopcode.c-535-
drivers/acpi/acpica/dsopcode.c:536: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
drivers/acpi/acpica/dsopcode.c-537- obj_desc,
--
drivers/acpi/acpica/dspkginit.c=55=acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dspkginit.c-141-
drivers/acpi/acpica/dspkginit.c:142: ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
drivers/acpi/acpica/dspkginit.c-143- "%s: Deferring resolution of Package elements\n",
--
drivers/acpi/acpica/dspkginit.c-293- */
drivers/acpi/acpica/dspkginit.c:294: ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
drivers/acpi/acpica/dspkginit.c-295- "%s: Package List length (%u) smaller than NumElements "
--
drivers/acpi/acpica/dspkginit.c=381=acpi_ds_resolve_package_element(union acpi_operand_object **element_ptr)
--
drivers/acpi/acpica/dspkginit.c-396- if (element->reference.resolved) {
drivers/acpi/acpica/dspkginit.c:397: ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
drivers/acpi/acpica/dspkginit.c-398- "%s: Package element is already resolved\n",
--
drivers/acpi/acpica/dsutils.c=34=void acpi_ds_clear_implicit_return(struct acpi_walk_state *walk_state)
--
drivers/acpi/acpica/dsutils.c-50- */
drivers/acpi/acpica/dsutils.c:51: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsutils.c-52- "Removing reference on stale implicit return obj %p\n",
--
drivers/acpi/acpica/dsutils.c=79=acpi_ds_do_implicit_return(union acpi_operand_object *return_desc,
--
drivers/acpi/acpica/dsutils.c-91-
drivers/acpi/acpica/dsutils.c:92: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsutils.c-93- "Result %p will be implicitly returned; Prev=%p\n",
--
drivers/acpi/acpica/dsutils.c=133=acpi_ds_is_result_used(union acpi_parse_object * op,
--
drivers/acpi/acpica/dsutils.c-171-
drivers/acpi/acpica/dsutils.c:172: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsutils.c-173- "At Method level, result of [%s] not used\n",
--
drivers/acpi/acpica/dsutils.c-265-result_used:
drivers/acpi/acpica/dsutils.c:266: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsutils.c-267- "Result of [%s] used by Parent [%s] Op=%p\n",
--
drivers/acpi/acpica/dsutils.c-274-result_not_used:
drivers/acpi/acpica/dsutils.c:275: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsutils.c-276- "Result of [%s] not used by Parent [%s] Op=%p\n",
--
drivers/acpi/acpica/dsutils.c=422=acpi_ds_create_operand(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dsutils.c-440- !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
drivers/acpi/acpica/dsutils.c:441: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n",
drivers/acpi/acpica/dsutils.c-442- arg));
--
drivers/acpi/acpica/dsutils.c-583-
drivers/acpi/acpica/dsutils.c:584: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsutils.c-585- "Null namepath: Arg=%p\n", arg));
--
drivers/acpi/acpica/dsutils.c=663=acpi_ds_create_operands(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dsutils.c-694-
drivers/acpi/acpica/dsutils.c:695: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsutils.c-696- "NumOperands %d, ArgCount %d, Index %d\n",
--
drivers/acpi/acpica/dsutils.c-711-
drivers/acpi/acpica/dsutils.c:712: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dsutils.c-713- "Created Arg #%u (%p) %u args total\n",
--
drivers/acpi/acpica/dswexec.c=58=acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dswexec.c-144-
drivers/acpi/acpica/dswexec.c:145: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswexec.c-146- "Completed a predicate eval=%X Op=%p\n",
--
drivers/acpi/acpica/dswexec.c=183=acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dswexec.c-205- if (acpi_ns_opens_scope(walk_state->op_info->object_type)) {
drivers/acpi/acpica/dswexec.c:206: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswexec.c-207- "(%s) Popping scope for Op %p\n",
--
drivers/acpi/acpica/dswexec.c-235- ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
drivers/acpi/acpica/dswexec.c:236: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswexec.c-237- "Exec predicate Op=%p State=%p\n",
--
drivers/acpi/acpica/dswexec.c=327=acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
--
drivers/acpi/acpica/dswexec.c-475- AML_VARIABLE_PACKAGE_OP))) {
drivers/acpi/acpica/dswexec.c:476: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswexec.c-477- "Method Reference in a Package, Op=%p\n",
--
drivers/acpi/acpica/dswexec.c-486-
drivers/acpi/acpica/dswexec.c:487: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswexec.c-488- "Method invocation, Op=%p\n", op));
--
drivers/acpi/acpica/dswexec.c-537-
drivers/acpi/acpica/dswexec.c:538: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswexec.c-539- "Executing CreateField Buffer/Index Op=%p\n",
--
drivers/acpi/acpica/dswexec.c-577-
drivers/acpi/acpica/dswexec.c:578: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswexec.c-579- "Executing CreateObject (Buffer/Package) Op=%p Child=%p ParentOpcode=%4.4X\n",
--
drivers/acpi/acpica/dswexec.c-643- if (op->common.aml_opcode == AML_REGION_OP) {
drivers/acpi/acpica/dswexec.c:644: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswexec.c-645- "Executing OpRegion Address/Length Op=%p\n",
--
drivers/acpi/acpica/dswexec.c-654- } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
drivers/acpi/acpica/dswexec.c:655: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswexec.c-656- "Executing DataTableRegion Strings Op=%p\n",
--
drivers/acpi/acpica/dswexec.c-665- } else if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
drivers/acpi/acpica/dswexec.c:666: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswexec.c-667- "Executing BankField Op=%p\n",
--
drivers/acpi/acpica/dswexec.c-686-
drivers/acpi/acpica/dswexec.c:687: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswexec.c-688- "Internal opcode=%X type Op=%p\n",
--
drivers/acpi/acpica/dswload.c=103=acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dswload.c-115- op = walk_state->op;
drivers/acpi/acpica/dswload.c:116: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
drivers/acpi/acpica/dswload.c-117- walk_state));
--
drivers/acpi/acpica/dswload.c-140-
drivers/acpi/acpica/dswload.c:141: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload.c-142- "State=%p Op=%p [%s]\n", walk_state, op,
--
drivers/acpi/acpica/dswload.c-205- */
drivers/acpi/acpica/dswload.c:206: ACPI_DEBUG_PRINT((ACPI_DB_INFO,
drivers/acpi/acpica/dswload.c-207- "Type override - [%4.4s] had invalid type (%s) "
--
drivers/acpi/acpica/dswload.c-283- flags |= ACPI_NS_OVERRIDE_IF_FOUND;
drivers/acpi/acpica/dswload.c:284: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload.c-285- "[%s] Override allowed\n",
--
drivers/acpi/acpica/dswload.c-289- flags |= ACPI_NS_ERROR_IF_FOUND;
drivers/acpi/acpica/dswload.c:290: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload.c-291- "[%s] Cannot already exist\n",
--
drivers/acpi/acpica/dswload.c-295- } else {
drivers/acpi/acpica/dswload.c:296: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload.c-297- "[%s] Both Find or Create allowed\n",
--
drivers/acpi/acpica/dswload.c=396=acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
--
drivers/acpi/acpica/dswload.c-407- op = walk_state->op;
drivers/acpi/acpica/dswload.c:408: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
drivers/acpi/acpica/dswload.c-409- walk_state));
--
drivers/acpi/acpica/dswload.c-550- */
drivers/acpi/acpica/dswload.c:551: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload.c-552- "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
--
drivers/acpi/acpica/dswload.c-587- acpi_ns_opens_scope(object_type)) {
drivers/acpi/acpica/dswload.c:588: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload.c-589- "(%s): Popping scope for Op %p\n",
--
drivers/acpi/acpica/dswload2.c=38=acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
--
drivers/acpi/acpica/dswload2.c-50- op = walk_state->op;
drivers/acpi/acpica/dswload2.c:51: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
drivers/acpi/acpica/dswload2.c-52- walk_state));
--
drivers/acpi/acpica/dswload2.c-101-
drivers/acpi/acpica/dswload2.c:102: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload2.c-103- "State=%p Op=%p Type=%X\n", walk_state, op,
--
drivers/acpi/acpica/dswload2.c-317- if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
drivers/acpi/acpica/dswload2.c:318: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload2.c-319- "***New Node [%4.4s] %p is temporary\n",
--
drivers/acpi/acpica/dswload2.c=369=acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
--
drivers/acpi/acpica/dswload2.c-386- op = walk_state->op;
drivers/acpi/acpica/dswload2.c:387: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
drivers/acpi/acpica/dswload2.c-388- walk_state->op_info->name, op, walk_state));
--
drivers/acpi/acpica/dswload2.c-396- if (op->common.aml_opcode == AML_SCOPE_OP) {
drivers/acpi/acpica/dswload2.c:397: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload2.c-398- "Ending scope Op=%p State=%p\n", op,
--
drivers/acpi/acpica/dswload2.c-420- (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
drivers/acpi/acpica/dswload2.c:421: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload2.c-422- "(%s) Popping scope for Op %p\n",
--
drivers/acpi/acpica/dswload2.c-458-
drivers/acpi/acpica/dswload2.c:459: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload2.c-460- "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
--
drivers/acpi/acpica/dswload2.c-652- */
drivers/acpi/acpica/dswload2.c:653: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload2.c-654- "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
--
drivers/acpi/acpica/dswload2.c-697-
drivers/acpi/acpica/dswload2.c:698: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
drivers/acpi/acpica/dswload2.c-699- "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
--
drivers/acpi/acpica/dswscope.c=29=void acpi_ds_scope_stack_clear(struct acpi_walk_state *walk_state)
--
drivers/acpi/acpica/dswscope.c-41-
drivers/acpi/acpica/dswscope.c:42: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswscope.c-43- "Popped object type (%s)\n",
--
drivers/acpi/acpica/dswscope.c=67=acpi_ds_scope_stack_push(struct acpi_namespace_node *node,
--
drivers/acpi/acpica/dswscope.c-104-
drivers/acpi/acpica/dswscope.c:105: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswscope.c-106- "[%.2d] Pushed scope ",
--
drivers/acpi/acpica/dswscope.c-110- if (old_scope_info) {
drivers/acpi/acpica/dswscope.c:111: ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
drivers/acpi/acpica/dswscope.c-112- "[%4.4s] (%s)",
--
drivers/acpi/acpica/dswscope.c-117- } else {
drivers/acpi/acpica/dswscope.c:118: ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, ACPI_NAMESPACE_ROOT));
drivers/acpi/acpica/dswscope.c-119- }
drivers/acpi/acpica/dswscope.c-120-
drivers/acpi/acpica/dswscope.c:121: ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
drivers/acpi/acpica/dswscope.c-122- ", New scope -> [%4.4s] (%s)\n",
--
drivers/acpi/acpica/dswscope.c=144=acpi_status acpi_ds_scope_stack_pop(struct acpi_walk_state *walk_state)
--
drivers/acpi/acpica/dswscope.c-160-
drivers/acpi/acpica/dswscope.c:161: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswscope.c-162- "[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
--
drivers/acpi/acpica/dswscope.c-168- if (new_scope_info) {
drivers/acpi/acpica/dswscope.c:169: ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[%4.4s] (%s)\n",
drivers/acpi/acpica/dswscope.c-170- acpi_ut_get_node_name(new_scope_info->
--
drivers/acpi/acpica/dswscope.c-174- } else {
drivers/acpi/acpica/dswscope.c:175: ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "%s\n",
drivers/acpi/acpica/dswscope.c-176- ACPI_NAMESPACE_ROOT));
--
drivers/acpi/acpica/dswstate.c=38=acpi_ds_result_pop(union acpi_operand_object **object,
--
drivers/acpi/acpica/dswstate.c-89-
drivers/acpi/acpica/dswstate.c:90: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswstate.c-91- "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object,
--
drivers/acpi/acpica/dswstate.c=112=acpi_ds_result_push(union acpi_operand_object *object,
--
drivers/acpi/acpica/dswstate.c-159-
drivers/acpi/acpica/dswstate.c:160: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
drivers/acpi/acpica/dswstate.c-161- object,
--
drivers/acpi/acpica/dswstate.c=183=static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state)
--
drivers/acpi/acpica/dswstate.c-209-
drivers/acpi/acpica/dswstate.c:210: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n",
drivers/acpi/acpica/dswstate.c-211- state, walk_state));
--
drivers/acpi/acpica/dswstate.c=228=static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state)
--
drivers/acpi/acpica/dswstate.c-236- if (walk_state->results == NULL) {
drivers/acpi/acpica/dswstate.c:237: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswstate.c-238- "Result stack underflow - State=%p\n",
--
drivers/acpi/acpica/dswstate.c-254-
drivers/acpi/acpica/dswstate.c:255: ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
drivers/acpi/acpica/dswstate.c-256- "Result=%p RemainingResults=%X State=%p\n",
--
drivers/acpi/acpica/dswstate.c=276=acpi_ds_obj_stack_push(void *object, struct acpi_walk_state *walk_state)
--
drivers/acpi/acpica/dswstate.c-297-
drivers/acpi/acpica/dswstate.c:298: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
drivers/acpi/acpica/dswstate.c-299- object,
--
drivers/acpi/acpica/dswstate.c=323=acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state *walk_state)
--
drivers/acpi/acpica/dswstate.c-346-
drivers/acpi/acpica/dswstate.c:347: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
drivers/acpi/acpica/dswstate.c-348- pop_count, walk_state, walk_state->num_operands));
--
drivers/acpi/acpica/dswstate.c=368=acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
--
drivers/acpi/acpica/dswstate.c-394-
drivers/acpi/acpica/dswstate.c:395: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
drivers/acpi/acpica/dswstate.c-396- pop_count, walk_state, walk_state->num_operands));
--
drivers/acpi/acpica/dswstate.c=412=struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state
--
drivers/acpi/acpica/dswstate.c-420-
drivers/acpi/acpica/dswstate.c:421: ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Current WalkState %p\n",
drivers/acpi/acpica/dswstate.c-422- thread->walk_state_list));
--
drivers/acpi/acpica/evevent.c=167=u32 acpi_ev_fixed_event_detect(void)
--
drivers/acpi/acpica/evevent.c-187-
]
|
| 20/2 |
2026/08/09 10:19 |
llm |
expert |
0m
Model:
Tokens:
input: 32345
output: 66
thoughts: 2276
Thoughts: **Analysis of the ACPI Debug Print Data Race**
Okay, so I've been digging into this `ACPI_DEBUG_PRINT` issue and the KCSAN report. There are thousands of these calls, mostly just churning out short strings. It's pretty clear that these calls are using a shared, static 512-byte buffer in `acpi_os_vprintf`. My initial thought is, even if two threads are printing at the same time, the `vsnprintf` function should prevent any writes outside of the intended buffer due to its limits on write size based on the formatted string's length. Since the strings are short, no buffer overflows should occur. The worst-case scenario is garbled debug output, right?
But, what about if `acpi_os_vprintf` _is_ called with a string longer than 512 bytes? That could be a buffer overflow, separate from the data race. I need to make sure this isn't happening. I also need to verify that this isn't causing any out-of-bounds reads if `printk` is called before the buffer is fully written. However, `vsnprintf` should always null-terminate the string, meaning that `printk` would stop at the null character, avoiding any read issues. So, there should be no out-of-bounds writes or reads.
Let's look at exploitability. No memory corruption, no privilege escalation, no information leaks (beyond possibly some mangled debug output), and definitely not a denial-of-service, it's just garbled text. The ACPI debug prints are typically disabled in production, and if they're enabled, triggering them might require root, or at least elevated privileges. Even if some methods can be accessed unprivileged, the fact that there's no real impact makes it less of a concern.
Now, let's make absolutely sure there are no other consequences to this data race. Does concurrent execution of `vsnprintf` actually risk a crash? It doesn't seem like it, as each thread gets its own `str` and `end` pointers, so there's no chance of corrupting each other's pointers. They're just writing to the same memory region. This is classic "benign" data race from a memory safety perspective, even if the output is corrupted.
After a review, it looks like `acpi_os_vprintf` is the root of the issue, with `acpi_os_printf` at the center. These functions are used for logging through various ACPI functions like `acpi_debug_print` and others. All these logging functions ultimately call `acpi_os_vprintf`, so concurrent logging will result in garbled output due to the lack of locking on the static buffer. This is a known issue, and it's pretty inherent to ACPICA's OS-independent design. I wonder why they don't just use `vprintk` since that one handles concurrent calls safely. It looks like it does now, but formats the string first. However, why not use a local stack buffer? It seems a stack-buffer may be too large for deep call stacks in the kernel. But, static buffers are dangerous because of data races.
The summary of this is:
* Exploitable: No. It's a benign data race on a debug buffer with no security implications, such as memory corruption or info leaks.
* Denial of Service: No.
* Unprivileged: No (or irrelevant because no real impact).
Let me check to make sure there's no edge case where `vsprintf` can crash due to concurrent writes. `vsprintf` reads from the format string, and arguments, but it writes to the static buffer. So, writing to the same buffer doesn't cause a crash. Now, the KCSAN report is showing this issue is a race condition in `acpi_pci_set_power_state` or `acpi_ns_get_node`, but the report is specific to the data race in `vsnprintf` inside `acpi_os_vprintf`. Both tasks in the KCSAN trace are calling debug messages; the race happens on the static `buffer`. It looks like this is just garbled output from the ACPI debug messages.
Therefore, this is nothing more than a benign data race in a debug logging function that has no security implications.
All results will be set to False.
|
| 21/2 |
2026/08/09 10:19 |
tool |
set-results |
0m
Args: map[DenialOfService:false Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:false VMGuestTrigger:false VMHostTrigger:false]
Results: map[DenialOfService:false Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:false VMGuestTrigger:false VMHostTrigger:false]
|
| 22/2 |
2026/08/09 10:19 |
llm |
expert |
0m
Model:
Tokens:
input: 35697
output: 521
thoughts: 251
Thoughts: **Final Thoughts on the ACPI Debug Logging Data Race**
Okay, the results are in, and now it's time to craft the final response, articulating my reasoning concisely. Here's how I see it: The core of the issue stems from the use of a shared, static bufferβ`static char buffer[512]`βwithin `acpi_os_vprintf`. This function is the formatting engine for ACPI debug messages, feeding them to `printk`. The problem arises when multiple threads simultaneously attempt to log these debug messages. They're all racing to write into that single, shared buffer.
Specifically, it boils down to this: `vsprintf`, which internally calls `vsnprintf`, manipulates the buffer using local pointers. This means while the messages are getting overwritten by each other, we're not running into memory corruption or out-of-bounds writes. The worst-case scenario? Garbled or interleaved debug messages in dmesg.
I've got to emphasize, though, that this race doesn't introduce any exploitable security vulnerabilities. There's no memory corruption, no risk of out-of-bounds reads or writes, no information leakage, and certainly no denial-of-service potential. And, let's be realistic, in most production kernel builds, ACPI debug logging is typically disabled. This means this code path is practically unreachable under normal circumstances. So, while it's a data race, it's ultimately benign in this context. It's more of an aesthetic issue (garbled logs) than a functional or security one.
|
| 23/1 |
2026/08/09 10:20 |
action |
format-explanation |
0m
Results: map[Explanation:The bug report describes a Kernel Concurrency Sanitizer (KCSAN) data-race in the
`vsnprintf` function, triggered via `acpi_os_vprintf`.
### Root Cause Analysis
Looking at the source code for `acpi_os_vprintf` in `drivers/acpi/osl.c`:
```c
void __printf(1, 0) acpi_os_vprintf(const char *fmt, va_list args)
{
static char buffer[512];
vsprintf(buffer, fmt, args);
// ... printk calls ...
}
```
The function uses a `static char buffer[512]` to format ACPI debug messages
before passing them to `printk`. Because the buffer is static and there is no
locking mechanism around it, concurrent calls to `acpi_os_vprintf` from multiple
threads will result in a data race where both threads write to the same memory
buffer simultaneously.
The stack traces in the report show two different threads (`async_resume_noirq`
workers) concurrently executing ACPI power management operations and emitting
ACPI debug prints, which leads to the race condition.
### Security Impact Assessment
**Exploitable: No**
This is a benign data race from a memory safety perspective. The `vsprintf`
function (which internally calls `vsnprintf`) uses local pointers on the stack
to track the current write position within the buffer. Concurrent executions
will not corrupt these local pointers, nor will they cause the write position to
exceed the length of the formatted string. The threads will simply overwrite
each other's characters within the 512-byte buffer.
There is no memory corruption, no out-of-bounds read/write, and no control-flow
hijack possible. The only consequence is that the resulting debug log messages
printed to `dmesg` may be garbled.
**Denial of Service: No**
The race condition does not cause kernel panics, hangs, deadlocks, or resource
leaks. It only affects the contents of a debug print buffer.
**Accessibility:**
ACPI debug logging (`CONFIG_ACPI_DEBUG`) is typically disabled or set to a very
low verbosity level in production kernel builds, making this code path largely
unreachable in normal circumstances. Even if enabled, the bug provides no
privilege escalation or exploitation primitives.
In conclusion, this is a harmless data race in a debug logging facility with no
security implications.]
|