| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/08/03 20:14 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"SWAP",
"FS_ENCRYPTION"
],
"FocusSymbols": [
"sys_swapon"
],
"Reasoning": "The patch adds a check to prevent using encrypted files as swapfiles, returning -EINVAL. This is a functional change in the swapon syscall.",
"WorthFuzzing": true
} |
| 1/1 | 2026/08/03 20:14 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 8af9c94adbbfbd7bf9d1d00f0bddabff9674b2ad\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Mon Aug 3 20:14:25 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst\nindex c0dd35f1af12b..e4882b73120e3 100644\n--- a/Documentation/filesystems/fscrypt.rst\n+++ b/Documentation/filesystems/fscrypt.rst\n@@ -1238,6 +1238,10 @@ astute users may notice some differences in behavior:\n \n - DAX (Direct Access) is not supported on encrypted files.\n \n+- Encrypted files cannot be used directly as swap files. To swap to\n+ an encrypted file, set up a loopback device on top of it.\n+ Alternatively, encrypted swap can use a dm-crypt device.\n+\n - The maximum length of an encrypted symlink is 2 bytes shorter than\n the maximum length of an unencrypted symlink. For example, on an\n EXT4 filesystem with a 4K block size, unencrypted symlinks can be up\ndiff --git a/mm/swapfile.c b/mm/swapfile.c\nindex 78b49b0658add..8538659acb9ee 100644\n--- a/mm/swapfile.c\n+++ b/mm/swapfile.c\n@@ -3650,6 +3650,13 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)\n \t\terror = -EBUSY;\n \t\tgoto bad_swap_unlock_inode;\n \t}\n+\tif (IS_ENCRYPTED(inode)) {\n+\t\tpr_warn_once(\n+\t\t\t\"Filesystem-level encrypted swapfile '%s' is unsupported. Create a loop device over it, or use dm-crypt\\n\",\n+\t\t\tname-\u003ename);\n+\t\terror = -EINVAL;\n+\t\tgoto bad_swap_unlock_inode;\n+\t}\n \n \t/*\n \t * The swap subsystem needs a major overhaul to support this.\n"
} |
| 2/1 | 2026/08/03 20:14 | agent | patch-evaluator |
0mModel:best-expensive Args: null Results: {
"EnableConfigs": [
"SWAP",
"FS_ENCRYPTION"
],
"FocusSymbols": [
"sys_swapon"
],
"Reasoning": "The patch adds a check to prevent using encrypted files as swapfiles, returning -EINVAL. This is a functional change in the swapon syscall.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU. - Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove) that are executed only during PCI hot-unplug or sysfs driver unbind operations. If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. Prefer non-static, non-inlined API entrypoint functions over internal static helper functions (which are inlined by the compiler and do not have distinct symbol addresses). 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). 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: For your convenience, here is the diff of the changes:
commit 8af9c94adbbfbd7bf9d1d00f0bddabff9674b2ad
Author: syz-cluster <triage@syzkaller.com>
Date: Mon Aug 3 20:14:25 2026 +0000
syz-cluster: applied patch under review
diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
index c0dd35f1af12b..e4882b73120e3 100644
--- a/Documentation/filesystems/fscrypt.rst
+++ b/Documentation/filesystems/fscrypt.rst
@@ -1238,6 +1238,10 @@ astute users may notice some differences in behavior:
- DAX (Direct Access) is not supported on encrypted files.
+- Encrypted files cannot be used directly as swap files. To swap to
+ an encrypted file, set up a loopback device on top of it.
+ Alternatively, encrypted swap can use a dm-crypt device.
+
- The maximum length of an encrypted symlink is 2 bytes shorter than
the maximum length of an unencrypted symlink. For example, on an
EXT4 filesystem with a 4K block size, unencrypted symlinks can be up
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 78b49b0658add..8538659acb9ee 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -3650,6 +3650,13 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
error = -EBUSY;
goto bad_swap_unlock_inode;
}
+ if (IS_ENCRYPTED(inode)) {
+ pr_warn_once(
+ "Filesystem-level encrypted swapfile '%s' is unsupported. Create a loop device over it, or use dm-crypt\n",
+ name->name);
+ error = -EINVAL;
+ goto bad_swap_unlock_inode;
+ }
/*
* The swap subsystem needs a major overhaul to support this.
|
| 3/2 | 2026/08/03 20:14 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 2329 output: 27 thoughts: 324 Thoughts: **Analyzing the Swapfile Patch** Okay, so I'm looking at this patch that touches `Documentation/filesystems/fscrypt.rst` and, more importantly, `mm/swapfile.c`. The core functional change is right here, inside `sys_swapon`. They're adding a check: if the inode of the swapfile is encrypted (`IS_ENCRYPTED(inode)`), we throw an error. Makes sense, encrypted swap isn't supported. The warning message is pretty clear about the workaround – use a loop device or dm-crypt. So, this modifies the `sys_swapon` function, specifically. No big surprises there. Now, let me see... I'll need to check the config options. `CONFIG_SWAP` is probably enabled by default, but I'll double-check just to be thorough. Then, I need to understand what's going on with `mm/swapfile.c` and this `IS_ENCRYPTED` macro. Right, `IS_ENCRYPTED` is defined in `include/linux/fs.h` – that's where the inode flags are. And the dependency is on `CONFIG_FS_ENCRYPTION`. That's the important one. It's just a check on a flag within the inode. Easy. But... do we *really* need `CONFIG_SWAP`? Let me look at `mm/swapfile.c`. Yep, it looks like this file is only compiled if `CONFIG_SWAP` is set. Okay, makes sense. Let me quickly check the `mm/Makefile` to make sure there aren't any sneaky gotchas. Okay, just to make sure. That's good. Looks like we are good to go. |
| 4/2 | 2026/08/03 20:14 | tool | grepper |
0mArgs:{
"Expression": "swapfile.o",
"PathPrefix": "mm/Makefile"
}Results: {
"Output": "mm/Makefile=76=endif\nmm/Makefile-77-\nmm/Makefile:78:obj-$(CONFIG_SWAP)\t+= page_io.o swap_state.o swapfile.o\nmm/Makefile-79-obj-$(CONFIG_ZSWAP)\t+= zswap.o\n"
} |
| 5/2 | 2026/08/03 20:14 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 3139 output: 33 thoughts: 47 Thoughts: Okay, here's my take on those thoughts, framed as my own: **Investigating Swap and Encryption Dependencies** Alright, it's clear we're going to need `CONFIG_SWAP`. No surprises there. Now, the question is about `CONFIG_FS_ENCRYPTION`. Is that going to be a requirement too? I seem to recall that `IS_ENCRYPTED` is defined in `include/linux/fs.h`. That's the key. Let's dig into that include file and verify whether the presence of the `IS_ENCRYPTED` macro has any bearing on the configuration we're trying to determine. Need to make sure there are no subtle dependencies I'm missing. |
| 6/2 | 2026/08/03 20:14 | tool | grepper |
0mArgs:{
"Expression": "define IS_ENCRYPTED",
"PathPrefix": "include/linux/fs.h"
}Results: {
"Output": "include/linux/fs.h=2091=extern loff_t vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,\n--\ninclude/linux/fs.h-2169-#define IS_DAX(inode)\t\t((inode)-\u003ei_flags \u0026 S_DAX)\ninclude/linux/fs.h:2170:#define IS_ENCRYPTED(inode)\t((inode)-\u003ei_flags \u0026 S_ENCRYPTED)\ninclude/linux/fs.h-2171-#define IS_CASEFOLDED(inode)\t((inode)-\u003ei_flags \u0026 S_CASEFOLD)\n"
} |
| 7/2 | 2026/08/03 20:14 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 3540 output: 79 thoughts: 635 Thoughts: **My Analysis of the Swap Encryption Patch** Okay, so I'm looking at this patch and it's pretty straightforward. It appears to be a check for `S_ENCRYPTED`, which is ultimately tied to `CONFIG_SWAP` and, more importantly in this context, `CONFIG_FS_ENCRYPTION`. The key is that to *reach* this code path and get the `-EINVAL` return, you need an encrypted file, meaning you need both features enabled *and* a filesystem that supports encryption – something like ext4, f2fs, ubifs, or ceph. The function I need to focus on is definitely `sys_swapon` – or rather, the actual syscall entry point – the code generated by `SYSCALL_DEFINE2(swapon, ...)`. Yep, that confirms it: `sys_swapon` is the target symbol. Double-checked that just in case, no surprises there. The patch itself is simple; it's a conditional check that returns `-EINVAL`. It's clearly a functional addition, preventing a situation that was previously allowed (even if probably undesirable or buggy). That's a good candidate for fuzzing, so I'll set `WorthFuzzing=true`. For the configuration, I'm going to set `SWAP` and `FS_ENCRYPTION`. Those are the two necessary ingredients to trigger this code. As for the focus symbols, definitely `sys_swapon`. I was thinking there might be some kind of symbol name generation, but no, the symbol is literally `sys_swapon`. Even if there were some other variations, syzkaller’s symbol coverage pulls from vmlinux, so that’s the canonical name. Wait, looking closer at the actual code in `SYSCALL_DEFINE2(swapon, ...)`, it seems this is it, right there in `sys_swapon`. It's a simple, targeted check right in the syscall itself. So I'm setting: `WorthFuzzing: true`, `FocusSymbols: ["sys_swapon"]`, `EnableConfigs: ["SWAP", "FS_ENCRYPTION"]`. The reasoning is: "The patch adds a check to prevent using encrypted files as swapfiles, returning -EINVAL. This is a functional change in the swapon syscall." That should be a concise and correct summary for the fuzzing analysis. |
| 8/2 | 2026/08/03 20:14 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"SWAP",
"FS_ENCRYPTION"
],
"FocusSymbols": [
"sys_swapon"
],
"Reasoning": "The patch adds a check to prevent using encrypted files as swapfiles, returning -EINVAL. This is a functional change in the swapon syscall.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"SWAP",
"FS_ENCRYPTION"
],
"FocusSymbols": [
"sys_swapon"
],
"Reasoning": "The patch adds a check to prevent using encrypted files as swapfiles, returning -EINVAL. This is a functional change in the swapon syscall.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|