syzbot


ID Workflow Result Correct Bug Created Started Finished Revision Error
7005ffbc-3cd2-4306-a9e6-4334035f959a assessment-kcsan Benign: ✅  KCSAN: data-race in pipe_release / pipe_wait_readable (10) 2026/01/12 15:06 2026/01/12 15:06 2026/01/12 15:28 dc57dbf3ee402bd8ad9c3037d56ee9d9940a9bc6
Benign: ✅   

Explanation:
The KCSAN report indicates a data race on `pipe->files` between `pipe_release` (writer) and `pipe_wait_readable` -> `pipe_lock` (reader).

**Analysis:**
1.  **Consistency:** The report is consistent. The stack traces point to `fs/pipe.c`.
    *   **Writer:** `pipe_release` calls `put_pipe_info`, which decrements `pipe->files` under `inode->i_lock` (Line 713/714 in `fs/pipe.c`).
    *   **Reader:** `pipe_wait_readable` calls `pipe_lock`. `pipe_lock` reads `pipe->files` to check if it is non-zero before locking `pipe->mutex` (Line 89 in `fs/pipe.c`).
    *   The accessed address matches `pipe->files` (offset within `struct pipe_inode_info`).
    *   The value change `2 -> 1` corresponds to closing one end of the pipe while another end is still open (or held).

2.  **Benign vs. Harmful:**
    *   The variable `pipe->files` counts the number of open file objects referring to the pipe.
    *   The `pipe_lock` function checks `if (pipe->files)` before acquiring the mutex. This check appears to be an optimization or a sanity check.
    *   In the reported trace, `pipe_wait_readable` is called from `splice_from_pipe_next`. This path implies that the caller holds a reference to a `struct file` associated with the pipe (the input file for splice).
    *   Since the caller holds a file reference, `pipe->files` must be at least 1 (accounting for that file).
    *   The race occurs when another file referring to the same pipe is closed (decrementing `pipe->files` from 2 to 1).
    *   In this scenario, `pipe->files` remains non-zero. The reader (`pipe_lock`) will see either 2 or 1. In both cases, the condition `if (pipe->files)` evaluates to true, and the function proceeds to acquire the mutex.
    *   The `pipe` structure is freed only when `pipe->files` drops to 0. Since the reader holds a reference, `pipe->files` cannot drop to 0 during this access, ensuring the `pipe` structure remains valid and no use-after-free occurs.
    *   Therefore, the outcome of the function execution is identical regardless of the race ordering. The race does not lead to corruption, inconsistent state, or logical errors.

**Conclusion:**
The data race is **benign**. The read of `pipe->files` in `pipe_lock` is racy but safe because the existence of a reference held by the caller guarantees the value is non-zero, making the check always true and the subsequent locking action deterministic. The redundant check `if (pipe->files)` could be removed or annotated to silence the warning, but the race itself is not harmful.

Crash report:
==================================================================
BUG: KCSAN: data-race in pipe_release / pipe_wait_readable

read-write to 0xffff88810d02796c of 4 bytes by task 5305 on cpu 0:
 put_pipe_info fs/pipe.c:714 [inline]
 pipe_release+0x16a/0x1d0 fs/pipe.c:744
 __fput+0x29b/0x650 fs/file_table.c:468
 ____fput+0x1c/0x30 fs/file_table.c:496
 task_work_run+0x131/0x1a0 kernel/task_work.c:233
 resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
 __exit_to_user_mode_loop kernel/entry/common.c:44 [inline]
 exit_to_user_mode_loop+0x1fe/0x740 kernel/entry/common.c:75
 __exit_to_user_mode_prepare include/linux/irq-entry-common.h:226 [inline]
 syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:256 [inline]
 syscall_exit_to_user_mode_work include/linux/entry-common.h:159 [inline]
 syscall_exit_to_user_mode include/linux/entry-common.h:194 [inline]
 do_syscall_64+0x1dd/0x2b0 arch/x86/entry/syscall_64.c:100
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

read to 0xffff88810d02796c of 4 bytes by task 5306 on cpu 1:
 pipe_lock fs/pipe.c:90 [inline]
 pipe_wait_readable+0x1c2/0x210 fs/pipe.c:1077
 splice_from_pipe_next+0x220/0x380 fs/splice.c:544
 iter_file_splice_write+0x1b1/0xa20 fs/splice.c:693
 do_splice_from fs/splice.c:938 [inline]
 do_splice+0x972/0x10b0 fs/splice.c:1351
 __do_splice fs/splice.c:1433 [inline]
 __do_sys_splice fs/splice.c:1636 [inline]
 __se_sys_splice+0x26c/0x3a0 fs/splice.c:1618
 __x64_sys_splice+0x78/0x90 fs/splice.c:1618
 x64_sys_call+0x2e82/0x3000 arch/x86/include/generated/asm/syscalls_64.h:276
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xca/0x2b0 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

value changed: 0x00000002 -> 0x00000001

Reported by Kernel Concurrency Sanitizer on:
CPU: 1 UID: 0 PID: 5306 Comm: syz.0.612 Not tainted syzkaller #0 PREEMPT(voluntary) 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025
==================================================================

Trajectory:
Seq Timestamp Type Name Duration
0/0 2026/01/12 15:06 flow assessment-kcsan
21m Model:
unknown

Results:
map[Benign:true Explanation:The KCSAN report indicates a data race on `pipe->files` between `pipe_release` (writer) and `pipe_wait_readable` -> `pipe_lock` (reader).

**Analysis:**
1.  **Consistency:** The report is consistent. The stack traces point to `fs/pipe.c`.
    *   **Writer:** `pipe_release` calls `put_pipe_info`, which decrements `pipe->files` under `inode->i_lock` (Line 713/714 in `fs/pipe.c`).
    *   **Reader:** `pipe_wait_readable` calls `pipe_lock`. `pipe_lock` reads `pipe->files` to check if it is non-zero before locking `pipe->mutex` (Line 89 in `fs/pipe.c`).
    *   The accessed address matches `pipe->files` (offset within `struct pipe_inode_info`).
    *   The value change `2 -> 1` corresponds to closing one end of the pipe while another end is still open (or held).

2.  **Benign vs. Harmful:**
    *   The variable `pipe->files` counts the number of open file objects referring to the pipe.
    *   The `pipe_lock` function checks `if (pipe->files)` before acquiring the mutex. This check appears to be an optimization or a sanity check.
    *   In the reported trace, `pipe_wait_readable` is called from `splice_from_pipe_next`. This path implies that the caller holds a reference to a `struct file` associated with the pipe (the input file for splice).
    *   Since the caller holds a file reference, `pipe->files` must be at least 1 (accounting for that file).
    *   The race occurs when another file referring to the same pipe is closed (decrementing `pipe->files` from 2 to 1).
    *   In this scenario, `pipe->files` remains non-zero. The reader (`pipe_lock`) will see either 2 or 1. In both cases, the condition `if (pipe->files)` evaluates to true, and the function proceeds to acquire the mutex.
    *   The `pipe` structure is freed only when `pipe->files` drops to 0. Since the reader holds a reference, `pipe->files` cannot drop to 0 during this access, ensuring the `pipe` structure remains valid and no use-after-free occurs.
    *   Therefore, the outcome of the function execution is identical regardless of the race ordering. The race does not lead to corruption, inconsistent state, or logical errors.

**Conclusion:**
The data race is **benign**. The read of `pipe->files` in `pipe_lock` is racy but safe because the existence of a reference held by the caller guarantees the value is non-zero, making the check always true and the subsequent locking action deterministic. The redundant check `if (pipe->files)` could be removed or annotated to silence the warning, but the race itself is not harmful.]

1/1 2026/01/12 15:06 action kernel-checkouter
0m Model:
unknown

Results:
map[KernelSrc:/usr/local/google/home/dvyukov/syzkaller/agent/workdir/cache/src/5d240f2140874f6657aee9957ead4428b65a3a7d]

2/1 2026/01/12 15:07 action kernel-builder
3m Model:
unknown

Results:
map[KernelObj:/usr/local/google/home/dvyukov/syzkaller/agent/workdir/cache/build/7a2e2b5e87cdeb02007ac751242ddff9c6a45c7d]

3/1 2026/01/12 15:11 action codesearch-prepare
12m Model:
unknown

Results:
map[Index:codesearch-index]

4/1 2026/01/12 15:24 agent expert
3m Model:
unknown

Results:
map[Benign:true]

Instruction:
You are an experienced Linux kernel developer tasked with determining if the given kernel bug
report is actionable or not. Actionable means that it contains enough info to root cause
the underlying bug, and that the report is self-consistent and makes sense, rather than
a one-off nonsensical crash induced by a previous memory corruption.

Use the provided tools to confirm any assumptions, what variables/fields being accessed, etc.
In particular, don't make assumptions about the kernel source code,
use codesearch tools to read the actual source code.

The bug report is a data race report from KCSAN tool.
It contains 2 stack traces of the memory accesses that constitute a data race.
The report would be inconsistent, if the stacks point to different subsystems,
or if they access different fields.
The report would be non-actionable, if the underlysing data race is "benign".
That is, the race is on a simple int/bool or similar field, and the accesses
are not supposed to be protected by any mutual exclusion primitives.
Common examples of such "benign" data races are accesses to various flags fields,
statistics counters, and similar.
An actionable race is "harmful", that is can lead to corruption/crash even with
a conservative compiler that compiles memory accesses to primitive types
effectively as atomic. A common example of a "harmful" data races is race on
a complex container (list/hashmap/etc), where accesses are supposed to be protected
by a mutual exclusion primitive.
In the final reply explain why you think the report is consistent and the data race is harmful.


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 bug report is:

==================================================================
BUG: KCSAN: data-race in pipe_release / pipe_wait_readable

read-write to 0xffff88810d02796c of 4 bytes by task 5305 on cpu 0:
 put_pipe_info fs/pipe.c:714 [inline]
 pipe_release+0x16a/0x1d0 fs/pipe.c:744
 __fput+0x29b/0x650 fs/file_table.c:468
 ____fput+0x1c/0x30 fs/file_table.c:496
 task_work_run+0x131/0x1a0 kernel/task_work.c:233
 resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
 __exit_to_user_mode_loop kernel/entry/common.c:44 [inline]
 exit_to_user_mode_loop+0x1fe/0x740 kernel/entry/common.c:75
 __exit_to_user_mode_prepare include/linux/irq-entry-common.h:226 [inline]
 syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:256 [inline]
 syscall_exit_to_user_mode_work include/linux/entry-common.h:159 [inline]
 syscall_exit_to_user_mode include/linux/entry-common.h:194 [inline]
 do_syscall_64+0x1dd/0x2b0 arch/x86/entry/syscall_64.c:100
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

read to 0xffff88810d02796c of 4 bytes by task 5306 on cpu 1:
 pipe_lock fs/pipe.c:90 [inline]
 pipe_wait_readable+0x1c2/0x210 fs/pipe.c:1077
 splice_from_pipe_next+0x220/0x380 fs/splice.c:544
 iter_file_splice_write+0x1b1/0xa20 fs/splice.c:693
 do_splice_from fs/splice.c:938 [inline]
 do_splice+0x972/0x10b0 fs/splice.c:1351
 __do_splice fs/splice.c:1433 [inline]
 __do_sys_splice fs/splice.c:1636 [inline]
 __se_sys_splice+0x26c/0x3a0 fs/splice.c:1618
 __x64_sys_splice+0x78/0x90 fs/splice.c:1618
 x64_sys_call+0x2e82/0x3000 arch/x86/include/generated/asm/syscalls_64.h:276
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xca/0x2b0 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

value changed: 0x00000002 -> 0x00000001

Reported by Kernel Concurrency Sanitizer on:
CPU: 1 UID: 0 PID: 5306 Comm: syz.0.612 Not tainted syzkaller #0 PREEMPT(voluntary) 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025
==================================================================


Reply:
The KCSAN report indicates a data race on `pipe->files` between `pipe_release` (writer) and `pipe_wait_readable` -> `pipe_lock` (reader).

**Analysis:**
1.  **Consistency:** The report is consistent. The stack traces point to `fs/pipe.c`.
    *   **Writer:** `pipe_release` calls `put_pipe_info`, which decrements `pipe->files` under `inode->i_lock` (Line 713/714 in `fs/pipe.c`).
    *   **Reader:** `pipe_wait_readable` calls `pipe_lock`. `pipe_lock` reads `pipe->files` to check if it is non-zero before locking `pipe->mutex` (Line 89 in `fs/pipe.c`).
    *   The accessed address matches `pipe->files` (offset within `struct pipe_inode_info`).
    *   The value change `2 -> 1` corresponds to closing one end of the pipe while another end is still open (or held).

2.  **Benign vs. Harmful:**
    *   The variable `pipe->files` counts the number of open file objects referring to the pipe.
    *   The `pipe_lock` function checks `if (pipe->files)` before acquiring the mutex. This check appears to be an optimization or a sanity check.
    *   In the reported trace, `pipe_wait_readable` is called from `splice_from_pipe_next`. This path implies that the caller holds a reference to a `struct file` associated with the pipe (the input file for splice).
    *   Since the caller holds a file reference, `pipe->files` must be at least 1 (accounting for that file).
    *   The race occurs when another file referring to the same pipe is closed (decrementing `pipe->files` from 2 to 1).
    *   In this scenario, `pipe->files` remains non-zero. The reader (`pipe_lock`) will see either 2 or 1. In both cases, the condition `if (pipe->files)` evaluates to true, and the function proceeds to acquire the mutex.
    *   The `pipe` structure is freed only when `pipe->files` drops to 0. Since the reader holds a reference, `pipe->files` cannot drop to 0 during this access, ensuring the `pipe` structure remains valid and no use-after-free occurs.
    *   Therefore, the outcome of the function execution is identical regardless of the race ordering. The race does not lead to corruption, inconsistent state, or logical errors.

**Conclusion:**
The data race is **benign**. The read of `pipe->files` in `pipe_lock` is racy but safe because the existence of a reference held by the caller guarantees the value is non-zero, making the check always true and the subsequent locking action deterministic. The redundant check `if (pipe->files)` could be removed or annotated to silence the warning, but the race itself is not harmful.

5/2 2026/01/12 15:24 llm expert
0m Model:
unknown

6/2 2026/01/12 15:24 tool codesearch-definition-source
0m Model:
unknown

Args:
map[IncludeLines:true Name:put_pipe_info SourceFile:fs/pipe.c]

Results:
map[Missing:false SourceCode: 708:	static void put_pipe_info(struct inode *inode, struct pipe_inode_info *pipe)
 709:	{
 710:		int kill = 0;
 711:	
 712:		spin_lock(&inode->i_lock);
 713:		if (!--pipe->files) {
 714:			inode->i_pipe = NULL;
 715:			kill = 1;
 716:		}
 717:		spin_unlock(&inode->i_lock);
 718:	
 719:		if (kill)
 720:			free_pipe_info(pipe);
 721:	}
 SourceFile:fs/pipe.c]

7/2 2026/01/12 15:24 tool codesearch-definition-source
0m Model:
unknown

Args:
map[IncludeLines:true Name:pipe_lock SourceFile:fs/pipe.c]

Results:
map[Missing:false SourceCode:  87:	void pipe_lock(struct pipe_inode_info *pipe)
  88:	{
  89:		if (pipe->files)
  90:			mutex_lock(&pipe->mutex);
  91:	}
 SourceFile:fs/pipe.c]

8/2 2026/01/12 15:24 llm expert
0m Model:
unknown

9/2 2026/01/12 15:24 tool codesearch-definition-source
0m Model:
unknown

Args:
map[IncludeLines:false Name:pipe_inode_info SourceFile:include/linux/pipe_fs_i.h]

Results:
map[Missing:true SourceCode: SourceFile:]

10/2 2026/01/12 15:25 llm expert
0m Model:
unknown

11/2 2026/01/12 15:25 tool codesearch-definition-source
0m Model:
unknown

Args:
map[IncludeLines:true Name:pipe_wait_readable SourceFile:fs/pipe.c]

Results:
map[Missing:false SourceCode:1063:	/*
1064:	 * This is the stupid "wait for pipe to be readable or writable"
1065:	 * model.
1066:	 *
1067:	 * See pipe_read/write() for the proper kind of exclusive wait,
1068:	 * but that requires that we wake up any other readers/writers
1069:	 * if we then do not end up reading everything (ie the whole
1070:	 * "wake_next_reader/writer" logic in pipe_read/write()).
1071:	 */
1072:	void pipe_wait_readable(struct pipe_inode_info *pipe)
1073:	{
1074:		pipe_unlock(pipe);
1075:		wait_event_interruptible(pipe->rd_wait, pipe_readable(pipe));
1076:		pipe_lock(pipe);
1077:	}
 SourceFile:fs/pipe.c]

12/2 2026/01/12 15:25 llm expert
0m Model:
unknown

13/2 2026/01/12 15:25 tool codesearch-file-index
0m Model:
unknown

Args:
map[SourceFile:include/linux/pipe_fs_i.h]

Results:
map[Entities:[map[Kind:function Name:account_pipe_buffers] map[Kind:function Name:alloc_pipe_info] map[Kind:function Name:create_pipe_files] map[Kind:function Name:free_pipe_info] map[Kind:function Name:generic_pipe_buf_get] map[Kind:function Name:generic_pipe_buf_release] map[Kind:function Name:generic_pipe_buf_try_steal] map[Kind:function Name:get_pipe_info] map[Kind:function Name:pipe_buf] map[Kind:function Name:pipe_buf_confirm] map[Kind:function Name:pipe_buf_get] map[Kind:function Name:pipe_buf_release] map[Kind:function Name:pipe_buf_try_steal] map[Kind:function Name:pipe_buf_usage] map[Kind:function Name:pipe_double_lock] map[Kind:function Name:pipe_empty] map[Kind:function Name:pipe_fcntl] map[Kind:function Name:pipe_full] map[Kind:function Name:pipe_has_watch_queue] map[Kind:function Name:pipe_head_buf] map[Kind:function Name:pipe_is_empty] map[Kind:function Name:pipe_is_full] map[Kind:function Name:pipe_is_unprivileged_user] map[Kind:function Name:pipe_lock] map[Kind:function Name:pipe_occupancy] map[Kind:function Name:pipe_resize_ring] map[Kind:function Name:pipe_unlock] map[Kind:function Name:pipe_wait_readable] map[Kind:function Name:pipe_wait_writable] map[Kind:function Name:round_pipe_size] map[Kind:function Name:too_many_pipe_buffers_hard] map[Kind:function Name:too_many_pipe_buffers_soft]] Missing:false]

14/2 2026/01/12 15:25 llm expert
0m Model:
unknown

15/2 2026/01/12 15:25 tool codesearch-definition-source
0m Model:
unknown

Args:
map[IncludeLines:true Name:alloc_pipe_info SourceFile:include/linux/pipe_fs_i.h]

Results:
map[Missing:false SourceCode: 314:	struct pipe_inode_info *alloc_pipe_info(void);
 SourceFile:include/linux/pipe_fs_i.h]

16/2 2026/01/12 15:25 llm expert
0m Model:
unknown

17/2 2026/01/12 15:26 tool codesearch-definition-source
0m Model:
unknown

Args:
map[IncludeLines:true Name:pipe_lock SourceFile:include/linux/pipe_fs_i.h]

Results:
map[Missing:false SourceCode: 305:	/* Pipe lock and unlock operations */
 306:	void pipe_lock(struct pipe_inode_info *);
 SourceFile:include/linux/pipe_fs_i.h]

18/2 2026/01/12 15:26 llm expert
1m Model:
unknown

19/2 2026/01/12 15:27 tool set-results
0m Model:
unknown

Args:
map[Benign:true]

Results:
map[Benign:true]

20/2 2026/01/12 15:27 llm expert
0m Model:
unknown

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)