| 0/0 |
2026/03/10 03:21 |
flow |
repro |
13m
Results: map[ReproOpts:-threaded ReproSyz:```
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./link0\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000d0)='./link1\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000e0)='./link2\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000f0)='./link3\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000100)='./link4\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000110)='./link5\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000120)='./link6\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000130)='./link7\x00')
unlink(&(0x7f00000000c0)='./link0\x00') (async)
readlink(&(0x7f00000000c0)='./link0\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000d0)='./link1\x00') (async)
readlink(&(0x7f00000000d0)='./link1\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000e0)='./link2\x00') (async)
readlink(&(0x7f00000000e0)='./link2\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000f0)='./link3\x00') (async)
readlink(&(0x7f00000000f0)='./link3\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000100)='./link4\x00') (async)
readlink(&(0x7f0000000100)='./link4\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000110)='./link5\x00') (async)
readlink(&(0x7f0000000110)='./link5\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000120)='./link6\x00') (async)
readlink(&(0x7f0000000120)='./link6\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000130)='./link7\x00') (async)
readlink(&(0x7f0000000130)='./link7\x00', &(0x7f0000000200)="", 0x64) (async)
``` SyzkallerCommit:6972f30219093b03bcc1a54487e12a7097245c01]
|
| 1/1 |
2026/03/10 03:21 |
action |
kernel-checkouter |
0m
Results: map[KernelSrc:/usr/local/google/home/dvyukov/syzkaller/agent/workdir/cache/src/1244da8713a7b9651347df1a6951d3bcf4225f5a]
|
| 2/1 |
2026/03/10 03:21 |
action |
kernel-builder |
0m
Results: map[KernelObj:/usr/local/google/home/dvyukov/syzkaller/agent/workdir/cache/build/7f1a4d5badb31b5ddb843d4f0109e09f84512011]
|
| 3/1 |
2026/03/10 03:21 |
action |
codesearch-prepare |
0m
Results: map[Index:codesearch-index]
|
| 4/1 |
2026/03/10 03:21 |
agent |
crash-repro-finder |
13m
Model:
Results:
Instruction:
You are an expert in the Linux kernel fuzzing. Your goal is to write a syzkaller program to trigger a specific bug.
In the final output provide only the syz program that triggers the bug, and could be executed directly,
without backticks.
Don't make assumptions about the kernel source code, use the provided codesearch tools
to examine the kernel code instead.
Document about syzkaller program syntax:
===
# Program syntax
Syzkaller uses a compact domain-specific language (DSL) for programs
to log executed programs, test its code, and persist programs in the
corpus. This page provides a brief description of the corresponding
syntax. Some useful information can also be found in the
[existing examples](/sys/linux/test) and in the program
[deserialization code](/prog/encoding.go).
Together with execution options, the DSL provides everything that
syz-executor needs to run a program.
For example, consider the program:
```
r0 = syz_open_dev$loop(&(0x7f00000011c0), 0x0, 0x0)
r1 = openat$6lowpan_control(0xffffffffffffff9c, &(0x7f00000000c0), 0x2, 0x0)
ioctl$LOOP_SET_FD(r0, 0x4c00, r1)
```
Each line in this program describes a particular syscall invocation,
with the first two calls saving the result in temporary variables `r0`
and `r1`, which are passed to the third call.
```
line = assignment | call
assignment = variable " = " call
call = syscall-name "(" [arg ["," arg]*] ")" ["(" [call-prop ["," call-prop*] ")"]
arg = "nil" | "AUTO" | const-arg | resource-arg | result-arg | pointer-arg | string-arg | struct-arg | array-arg | union-arg
const-arg = "0x" hex-integer
resource-arg = variable ["/" hex-integer] ["+" hex-integer]
result-arg = "<" variable "=>" arg
pointer-arg = "&" pointer-arg-addr ["=ANY"] "=" arg
pointer-arg-addr = "AUTO" | "(" pointer-addr ["/" region-size] ")"
string-arg = "'" escaped-string "'" | "\"" escaped-string "\"" | "\"$" escaped-string "\""
struct-arg = "{" [arg ["," arg]*] "}"
array-arg = "[" [arg ["," arg]*] "]"
union-arg = "@" field-name ["=" arg]
call-prop = prop-name ": " prop-value
variable = "r" dec-integer
pointer-addr = hex-integer
region-size = hex-integer
```
Programs may also contain blank lines and comments.
```
# Obtain a file handle
r0 = openat(0xffffffffffffff9c, &AUTO='./file1\x00', 0x42, 0x1ff)
# Perform a write operation
write(r0, &AUTO="01010101", 0x4)
```
### Memory management
Memory management is performed by syzkaller itself. It will allocate
virtual memory regions of the necessary size and set the final values
of pointer arguments.
By using the `AUTO` keyword, programs can give syzkaller the full
control over storing the data. This may be convenient e.g. when a
parameter must be passed by reference, but the exact location of its
value is not of particular importance.
```
r1 = syz_genetlink_get_family_id$nl80211(&AUTO='nl80211\x00', 0xffffffffffffffff)
ioctl$sock_SIOCGIFINDEX_80211(r0, 0x8933, &AUTO={'wlan0\x00', <r2=>0x0})
```
Alternatively, some data can be "anchored" to specific addresses. It
may be especially important when a memory region must be shared
between multiple calls. In this case, pointer addresses must be given
at the 0x7f0000000000 offset. Before the actual execution, syzkaller
will adjust pointers to the start of the actual mmap'ed region.
### Call properties
Call properties specify extra information about how a specific call
must be executed. Each call within a program has its own set of call
properties. If no properties are provided, syzkaller takes the default
ones.
Currently, syzkaller supports the following call properties.
#### Fault injection
Syntax: `fail_nth: N`.
It takes an integer (base 10) argument `N`. If the argument is
non-negative, a fault will be injected into the `N`-th occasion.
```
r0 = openat$6lowpan_control(0xffffffffffffff9c, &(0x7f00000000c0), 0x2, 0x0)
ioctl$LOOP_SET_FD(r0, 0x4c00, r0) (fail_nth: 5)
```
#### Async
Syntax: `async`.
Instructs `syz-executor` not to wait until the call completes and
to proceed immediately to the next call.
```
r0 = openat(0xffffffffffffff9c, &AUTO='./file1\x00', 0x42, 0x1ff)
write(r0, &AUTO="01010101", 0x4) (async)
read(r0, &AUTO=""/4, 0x4)
close(r0)
```
When setting `async` flags be aware of the following considerations:
* Such programs should only be executed in threaded mode (i.e. `-threaded`
flag must be passed to `syz-executor`.
* Each `async` call is executed in a separate thread and there's a
limited number of available threads (`kMaxThreads = 16`).
* If an `async` call produces a resource, keep in mind that some other call
might take it as input and `syz-executor` will just pass 0 if the resource-
producing call has not finished by that time.
===
Document about syzlang system call descriptions syntax:
===
# Syscall description language
aka `syzlang` (`[siːzˈlæŋg]`)
Pseudo-formal grammar of syscall description:
```
syscallname "(" [arg ["," arg]*] ")" [type] ["(" attribute* ")"]
arg = argname type
argname = identifier
type = typename [ "[" type-options "]" ]
typename = "const" | "intN" | "intptr" | "flags" | "array" | "ptr" |
"string" | "filename" | "glob" | "len" |
"bytesize" | "bytesizeN" | "bitsize" | "vma" | "proc" |
"compressed_image"
type-options = [type-opt ["," type-opt]]
```
common type-options include:
```
"opt" - the argument is optional (like mmap fd argument, or accept peer argument)
```
rest of the type-options are type-specific:
```
"const": integer constant, type-options:
value, underlying type (one of "intN", "intptr")
"intN"/"intptr": an integer without a particular meaning, type-options:
either an optional range of values (e.g. "5:10", or "100:200")
or a reference to flags description (see below),
or a single value
optionally followed by an alignment parameter if using a range
"flags": a set of values, type-options:
reference to flags description (see below), underlying int type (e.g. "int32")
"array": a variable/fixed-length array, type-options:
type of elements, optional size (fixed "5", or ranged "5:10", boundaries inclusive)
"ptr"/"ptr64": a pointer to an object, type-options:
direction (in/out/inout); type of the object
ptr64 has size of 8 bytes regardless of target pointer size
"string": a zero-terminated memory buffer (no pointer indirection implied), type-options:
either a string value in quotes for constant strings (e.g. "foo" or `deadbeef` for hex literal),
or a reference to string flags (special value `filename` produces file names),
optionally followed by a buffer size (string values will be padded with \x00 to that size)
"stringnoz": a non-zero-terminated memory buffer (no pointer indirection implied), type-options:
either a string value in quotes for constant strings (e.g. "foo" or `deadbeef` for hex literal),
or a reference to string flags,
"glob": glob pattern to match on the target files, type-options:
a pattern string in quotes (syntax: https://golang.org/pkg/path/filepath/#Match)
(e.g. "/sys/" or "/sys/**/*"),
or include exclude glob too (e.g. "/sys/**/*:-/sys/power/state")
"fmt": a string representation of an integer (not zero-terminated), type-options:
format (one of "dec", "hex", "oct") and the value (a resource, int, flags or proc)
the resulting data is always fixed-size (formatted as "%020llu", "0x%016llx" or "%023llo", respectively)
"len": length of another field (for array it is number of elements), type-options:
argname of the object
"bytesize": similar to "len", but always denotes the size in bytes, type-options:
argname of the object
"bitsize": similar to "len", but always denotes the size in bits, type-options:
argname of the object
"offsetof": offset of the field from the beginning of the parent struct, type-options:
field
"vma"/"vma64": a pointer to a set of pages (used as input for mmap/munmap/mremap/madvise), type-options:
optional number of pages (e.g. vma[7]), or a range of pages (e.g. vma[2-4])
vma64 has size of 8 bytes regardless of target pointer size
"proc": per process int (see description below), type-options:
value range start, how many values per process, underlying type
"compressed_image": zlib-compressed disk image
syscalls accepting compressed images must be marked with `no_generate`
and `no_minimize` call attributes. if the content of the decompressed image
can be checked by a `fsck`-like command, use the `fsck` syscall attribute
"text": machine code of the specified type, type-options:
text type (x86_real, x86_16, x86_32, x86_64, arm64)
"void": type with static size 0
mostly useful inside of templates and varlen unions, can't be syscall argument
```
flags/len/flags also have trailing underlying type type-option when used in structs/unions/pointers.
Flags are described as:
```
flagname = const ["," const]*
```
or for string flags as:
```
flagname = "\"" literal "\"" ["," "\"" literal "\""]*
```
Call attributes are:
```
"disabled": the call will not be used in fuzzing; useful to temporary disable some calls
or prohibit particular argument combinations.
"timeout[N]": additional execution timeout (in ms) for the call on top of some default value.
"prog_timeout[N]": additional execution timeout (in ms) for the whole program if it contains this call;
if a program contains several such calls, the max value is used.
"ignore_return": ignore return value of this syscall in fallback feedback; need to be used for calls
that don't return fixed error codes but rather something else (e.g. the current time).
"breaks_returns": ignore return values of all subsequent calls in the program in fallback feedback (can't be trusted).
"no_generate": do not try to generate this syscall, i.e. use only seed descriptions to produce it.
"no_minimize": do not modify instances of this syscall when trying to minimize a crashing program.
"no_squash": do not attempt to pass squashed arguments to this syscall.
Without that, the fuzzer will sometimes attempt to replace complex structures with arrays of bytes,
possibly triggering interesting mutations, but also making programs hard to reason about.
"fsck": the content of the compressed buffer argument for this syscall is a file system and the
string argument is a fsck-like command that will be called to verify the filesystem.
"remote_cover": wait longer to collect remote coverage for this call.
"kfuzz_test": the call is a kfuzztest target.
"snapshot": the call is enabled by default only in snapshot fuzzing mode, but can also be enabled in
the non-snasphot mode when listed in "enable_syscalls" with its full name (as opposed to a wildcard match).
It can also always be disabled via "disable_syscalls".
The attribute is generally used to mark calls that are not safe to execute in non-snapshot mode
(can lead to false positives, or lost connections to test machines.
```
## Ints
`int8`, `int16`, `int32` and `int64` denote an integer of the corresponding size.
`intptr` denotes a pointer-sized integer, i.e. C `long` type.
By appending `be` suffix (e.g. `int16be`) integers become big-endian.
It's possible to specify a range of values for an integer in the format of `int32[0:100]` or `int32[0:4096, 512]` for a 512-aligned int.
Integers can also take a reference to flags description or a value as its first type-option.
In that case, the alignment parameter is not supported.
To denote a bitfield of size N use `int64:N`.
It's possible to use these various kinds of ints as base types for `const`, `flags`, `len` and `proc`.
```
example_struct {
f0 int8 # random 1-byte integer
f1 const[0x42, int16be] # const 2-byte integer with value 0x4200 (big-endian 0x42)
f2 int32[0:100] # random 4-byte integer with values from 0 to 100 inclusive
f3 int32[1:10, 2] # random 4-byte integer with values {1, 3, 5, 7, 9}
f4 int64:20 # random 20-bit bitfield
f5 int8[10] # const 1-byte integer with value 10
f6 int32[flagname] # random 4-byte integer from the set of values referenced by flagname
}
```
## Structs
Structs are described as:
```
structname "{" "\n"
(fieldname type ("(" fieldattribute* ")")? (if[expression])? "\n")+
"}" ("[" attribute* "]")?
```
Fields can have attributes specified in parentheses after the field, independent
of their type. `in/out/inout` attribute specify per-field direction, for example:
```
foo {
field0 const[1, int32] (in)
field1 int32 (inout)
field2 fd (out)
}
```
You may specify conditions that determine whether a field will be included:
```
foo {
field0 int32
field1 int32 (if[value[field0] == 0x1])
}
```
See [the corresponding section](syscall_descriptions_syntax.md#conditional-fields)
for more details.
`out_overlay` attribute allows to have separate input and output layouts for the struct.
Fields before the `out_overlay` field are input, fields starting from `out_overlay` are output.
Input and output fields overlap in memory (both start from the beginning of the struct in memory).
For example:
```
foo {
in0 const[1, int32]
in1 flags[bar, int8]
in2 ptr[in, string]
out0 fd (out_overlay)
out1 int32
}
```
Structs can have attributes specified in square brackets after the struct.
Attributes are:
- `packed`: the struct does not have paddings between fields and has alignment 1; this is similar to GNU C `__attribute__((packed))`; struct alignment can be overridden with `align` attribute
- `align[N]`: the struct has alignment N and padded up to multiple of `N`; contents of the padding are unspecified (though, frequently are zeros); similar to GNU C `__attribute__((aligned(N)))`
- `size[N]`: the struct is padded up to the specified size `N`; contents of the padding are unspecified (though, frequently are zeros)
## Unions
Unions are described as:
```
unionname "[" "\n"
(fieldname type (if[expression])? "\n")+
"]" ("[" attribute* "]")?
```
During fuzzing, syzkaller randomly picks one of the union options.
You may also specify conditions that determine whether the corresponding
option may or may not be selected, depending on values of other fields. See
[the corresponding section](syscall_descriptions_syntax.md#conditional-fields)
for more details.
Unions can have attributes specified in square brackets after the union.
Attributes are:
- `varlen`: union size is the size of the particular chosen option (not statically known); without this attribute unions are statically sized as maximum of all options (similar to C unions)
- `size[N]`: the union is padded up to the specified size `N`; contents of the padding are unspecified (though, frequently are zeros)
## Resources
Resources represent values that need to be passed from output of one syscall to input of another syscall. For example, `close` syscall requires an input value (fd) previously returned by `open` or `pipe` syscall. To achieve this, `fd` is declared as a resource. This is a way of modelling dependencies between syscalls, as defining a syscall as the producer of a resource and another syscall as the consumer defines a loose sense of ordering between them. Resources are described as:
```
"resource" identifier "[" underlying_type "]" [ ":" const ("," const)* ]
```
`underlying_type` is either one of `int8`, `int16`, `int32`, `int64`, `intptr` or another resource (which models inheritance, for example, a socket is a subtype of fd). The optional set of constants represent resource special values, for example, `0xffffffffffffffff` (-1) for "no fd", or `AT_FDCWD` for "the current dir". Special values are used once in a while as resource values. If no special values specified, special value of `0` is used. Resources can then be used as types, for example:
```
resource fd[int32]: 0xffffffffffffffff, AT_FDCWD, 1000000
resource sock[fd]
resource sock_unix[sock]
socket(...) sock
accept(fd sock, ...) sock
listen(fd sock, backlog int32)
```
Resources don't have to be necessarily returned by a syscall. They can be used as any other data type. For example:
```
resource my_resource[int32]
request_producer(..., arg ptr[out, my_resource])
request_consumer(..., arg ptr[inout, test_struct])
test_struct {
...
attr my_resource
}
```
For more complex producer/consumer scenarios, field attributes can be utilized.
For example:
```
resource my_resource_1[int32]
resource my_resource_2[int32]
request_produce1_consume2(..., arg ptr[inout, test_struct])
test_struct {
...
field0 my_resource_1 (out)
field1 my_resource_2 (in)
}
```
Each resource type must be "produced" (used as an output) by at least one syscall
(outside of unions and optional pointers) and "consumed" (used as an input)
by at least one syscall.
## Type Aliases
Complex types that are often repeated can be given short type aliases using the
following syntax:
```
type identifier underlying_type
```
For example:
```
type signalno int32[0:65]
type net_port proc[20000, 4, int16be]
```
Then, type alias can be used instead of the underlying type in any contexts.
Underlying type needs to be described as if it's a struct field, that is,
with the base type if it's required. However, type alias can be used as syscall
arguments as well. Underlying types are currently restricted to integer types,
`ptr`, `ptr64`, `const`, `flags` and `proc` types.
There are some builtin type aliases:
```
type bool8 int8[0:1]
type bool16 int16[0:1]
type bool32 int32[0:1]
type bool64 int64[0:1]
type boolptr intptr[0:1]
type fileoff[BASE] BASE
type filename string[filename]
type buffer[DIR] ptr[DIR, array[int8]]
```
## Type Templates
Type templates can be declared as follows:
```
type buffer[DIR] ptr[DIR, array[int8]]
type fileoff[BASE] BASE
type nlattr[TYPE, PAYLOAD] {
nla_len len[parent, int16]
nla_type const[TYPE, int16]
payload PAYLOAD
} [align_4]
```
and later used as follows:
```
syscall(a buffer[in], b fileoff[int64], c ptr[in, nlattr[FOO, int32]])
```
There is builtin type template `optional` defined as:
```
type optional[T] [
val T
void void
] [varlen]
```
## Length
You can specify length of a particular field in struct or a named argument by
using `len`, `bytesize` and `bitsize` types, for example:
```
write(fd fd, buf ptr[in, array[int8]], count len[buf])
sock_fprog {
len len[filter, int16]
filter ptr[in, array[sock_filter]]
}
```
If `len`'s argument is a pointer, then the length of the pointee argument is used.
To denote the length of a field in N-byte words use `bytesizeN`, possible values
for N are 1, 2, 4 and 8.
To denote the length of the parent struct, you can use `len[parent, int8]`.
To denote the length of the higher level parent when structs are embedded into
one another, you can specify the type name of the particular parent:
```
s1 {
f0 len[s2] # length of s2
}
s2 {
f0 s1
f1 array[int32]
f2 len[parent, int32]
}
```
`len` argument can also be a path expression which allows more complex
addressing. Path expressions are similar to C field references, but also allow
referencing parent and sibling elements. A special reference `syscall` used
in the beginning of the path allows to refer directly to the syscall arguments.
For example:
```
s1 {
a ptr[in, s2]
b ptr[in, s3]
c array[int8]
}
s2 {
d array[int8]
}
s3 {
# This refers to the array c in the parent s1.
e len[s1:c, int32]
# This refers to the array d in the sibling s2.
f len[s1:a:d, int32]
# This refers to the array k in the child s4.
g len[i:j, int32]
# This refers to syscall argument l.
h len[syscall:l, int32]
i ptr[in, s4]
}
s4 {
j array[int8]
}
foo(k ptr[in, s1], l ptr[in, array[int8]])
```
## Proc
The `proc` type can be used to denote per process integers.
The idea is to have a separate range of values for each executor, so they don't interfere.
The simplest example is a port number.
The `proc[20000, 4, int16be]` type means that we want to generate an `int16be`
integer starting from `20000` and assign `4` values for each process.
As a result the executor number `n` will get values in the `[20000 + n * 4, 20000 + (n + 1) * 4)` range.
## Integer Constants
Integer constants can be specified as decimal literals, as `0x`-prefixed
hex literals, as `'`-surrounded char literals, or as symbolic constants
extracted from kernel headers or defined by `define` directives. For example:
```
foo(a const[10], b const[-10])
foo(a const[0xabcd])
foo(a int8['a':'z'])
foo(a const[PATH_MAX])
foo(a int32[PATH_MAX])
foo(a ptr[in, array[int8, MY_PATH_MAX]])
define MY_PATH_MAX PATH_MAX + 2
```
## Conditional fields
### In structures
In syzlang, it's possible to specify a condition for every struct field that
determines whether the field should be included or omitted:
```
header_fields {
magic const[0xabcd, int16]
haveInteger int8
} [packed]
packet {
header header_fields
integer int64 (if[value[header:haveInteger] == 0x1])
body array[int8]
} [packed]
some_call(a ptr[in, packet])
```
In this example, the `packet` structure will include the field `integer` only
if `header.haveInteger == 1`. In memory, `packet` will have the following
layout:
| header.magic = 0xabcd | header.haveInteger = 0x1 | integer | body |
| --------------------- | ------------------------ | ------- | ---- |
That corresponds to e.g. the following program:
```
some_call(&AUTO={{AUTO, 0x1}, @value=0xabcd, []})
```
If `header.haveInteger` is not `1`, syzkaller will just pretend that the field
`integer` does not exist.
```
some_call(&AUTO={{AUTO, 0x0}, @void, []})
```
| header.magic = 0xabcd | header.haveInteger = 0x0 | body |
| --------------------- | ------------------------ | ---- |
Every conditional field is assumed to be of variable length and so is the struct
to which this field belongs.
When a variable length field appears in the middle of a structure, the structure
must be marked with `[packed].`
Conditions on bitfields are prohibited:
```
struct {
f0 int
f1 int:3 (if[value[f0] == 0x1]) # It will not compile.
}
```
But you may reference bitfields in your conditions:
```
struct {
f0 int:1
f1 int:7
f2 int (if[value[f0] == value[f1]])
} [packed]
```
### In unions
Let's consider the following example.
```
struct {
type int
body alternatives
}
alternatives [
int int64 (if[value[struct:type] == 0x1])
arr array[int64, 5] (if[value[struct:type] == 0x2])
default int32
] [varlen]
some_call(a ptr[in, struct])
```
In this case, the union option will be selected depending on the value of the
`type` field. For example, if `type` is `0x1`, then it can be either `int` or
`default`:
```
some_call(&AUTO={0x1, @int=0x123})
some_call(&AUTO={0x1, @default=0x123})
```
If `type` is `0x2`, it can be either `arr` or `default`.
If `type` is neither `0x1` nor `0x2`, syzkaller may only select `default`:
```
some_call(&AUTO={0x0, @default=0xabcd})
```
To ensure that a union can always be constructed, the last union field **must always
have no condition**.
Thus, the following definition would fail to compile:
```
alternatives [
int int64 (if[value[struct:type] == 0x1])
arr array[int64, 5] (if[value[struct:type] == 0x1])
] [varlen]
```
During prog mutation and generation syzkaller will select a random union field
whose condition is satisfied.
### Expression syntax
Currently, only `==`, `!=`, `&` and `||` operators are supported. However, the
functionality was designed in such a way that adding more operators is easy.
Feel free to file a GitHub issue or write us an email in case it's needed.
Expressions are evaluated as `int64` values. If the final result of an
expression is not 0, it's assumed to be satisfied.
If you want to reference a field's value, you can do it via
`value[path:to:field]`, which is similar to the `len[]` argument.
```
sub_struct {
f0 int
# Reference a field in a parent struct.
f1 int (if[value[struct:f2]]) # Same as if[value[struct:f2] != 0].
}
struct {
f2 int
f3 sub_struct
f4 int (if[value[f2] == 0x2]) # Reference a sibling field.
f5 int (if[value[f3:f0] == 0x1]) # Reference a nested field.
f6 int (if[value[f3:f0] == 0x1 || value[f3:f0] == 0x2]) # Reference a nested field which either equals to 0x1 or 0x2.
} [packed]
call(a ptr[in, struct])
```
The referenced field must be of integer type and there must be no
conditional fields in the path to it. For example, the following
descriptions will not compile.
```
struct {
f0 int
f1 int (if[value[f0] == 0x1])
f2 int (if[value[f1] == 0x1])
}
```
You may also reference constants in expressions:
```
struct {
f0 int
f1 int
f2 int (if[value[f0] & SOME_CONST == OTHER_CONST])
}
```
## Meta
Description files can also contain `meta` directives that specify meta-information for the whole file.
```
meta noextract
```
Tells `make extract` to not extract constants for this file.
Though, `syz-extract` can still be invoked manually on this file.
```
meta arches["arch1", "arch2"]
```
Restricts this file only to the given set of architectures.
`make extract` and `make generate` will not use it on other architectures.
## Misc
Description files also contain `include` directives that refer to Linux kernel header files,
`incdir` directives that refer to custom Linux kernel header directories
and `define` directives that define symbolic constant values.
The syzkaller executor defines some [pseudo system calls](./pseudo_syscalls.md)
that can be used as any other syscall in a description file. These pseudo
system calls expand to literal C code and can perform user-defined
custom actions. You can find some examples in
[executor/common_linux.h](../executor/common_linux.h).
Also see [tips](syscall_descriptions.md#tips) on writing good descriptions.
===
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:
Bug title: KCSAN: data-race in d_make_discardable / do_readlinkat
The bug report to reproduce:
==================================================================
BUG: KCSAN: data-race in d_make_discardable / do_readlinkat
write to 0xffff888107ad6840 of 4 bytes by task 3306 on cpu 0:
d_make_discardable+0x4f/0xa0 fs/dcache.c:936
simple_unlink+0x68/0x80 fs/libfs.c:809
shmem_unlink+0x12d/0x140 mm/shmem.c:4005
vfs_unlink+0x1c7/0x490 fs/namei.c:5470
filename_unlinkat+0x1e2/0x410 fs/namei.c:5540
__do_sys_unlink fs/namei.c:5575 [inline]
__se_sys_unlink+0x2b/0xe0 fs/namei.c:5572
__x64_sys_unlink+0x1f/0x30 fs/namei.c:5572
x64_sys_call+0x2eb6/0x3020 arch/x86/include/generated/asm/syscalls_64.h:88
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x12c/0x370 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
read to 0xffff888107ad6840 of 4 bytes by task 3001 on cpu 1:
__d_entry_type include/linux/dcache.h:416 [inline]
d_is_symlink include/linux/dcache.h:446 [inline]
do_readlinkat+0xa0/0x2f0 fs/stat.c:578
__do_sys_readlink fs/stat.c:605 [inline]
__se_sys_readlink fs/stat.c:602 [inline]
__x64_sys_readlink+0x47/0x60 fs/stat.c:602
x64_sys_call+0x2b51/0x3020 arch/x86/include/generated/asm/syscalls_64.h:90
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x12c/0x370 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
value changed: 0x08300080 -> 0x00300180
Reported by Kernel Concurrency Sanitizer on:
CPU: 1 UID: 0 PID: 3001 Comm: udevd Tainted: G W syzkaller #0 PREEMPT(full)
Tainted: [W]=WARN
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
==================================================================
The list of existing description files:
acpi_thermal_rel.txt
aio.txt
auto.txt
binfmt.txt
bpf.txt
bpf_prog.txt
bpf_trace.txt
cgroup.txt
damon.txt
dev_ashmem.txt
dev_bifrost.txt
dev_binder.txt
dev_binderfs.txt
dev_block.txt
dev_bsg.txt
dev_bus_usb.txt
dev_camx.txt
dev_cdrom.txt
dev_cec.txt
dev_char_usb.txt
dev_comedi.txt
dev_dma_heap.txt
dev_dri.txt
dev_dsp.txt
dev_dvb_demux.txt
dev_dvb_dvr.txt
dev_dvb_frontend.txt
dev_fb.txt
dev_floppy.txt
dev_hidraw.txt
dev_i2c.txt
dev_i915.txt
dev_img_rogue.txt
dev_infiniband_rdma.txt
dev_infiniband_rdma_cm.txt
dev_input.txt
dev_iommu.txt
dev_kvm.txt
dev_kvm_amd64.txt
dev_kvm_arm64.txt
dev_kvm_extra.txt
dev_kvm_riscv64.txt
dev_loop.txt
dev_mali.txt
dev_media.txt
dev_msm.txt
dev_msr.txt
dev_nbd.txt
dev_net_tun.txt
dev_panthor.txt
dev_ppp.txt
dev_ptmx.txt
dev_ptp.txt
dev_qat_adf_ctl.txt
dev_qrtr_tun.txt
dev_random.txt
dev_rfkill.txt
dev_rtc.txt
dev_sequencer.txt
dev_sg.txt
dev_snapshot.txt
dev_snd_control.txt
dev_snd_hw.txt
dev_snd_midi.txt
dev_snd_pcm.txt
dev_snd_seq.txt
dev_snd_timer.txt
dev_sr.txt
dev_sw_sync.txt
dev_tlk_device.txt
dev_trusty.txt
dev_udmabuf.txt
dev_uhid.txt
dev_uinput.txt
dev_usb_hiddev.txt
dev_usbmon.txt
dev_userio.txt
dev_vfio.txt
dev_vga_arbiter.txt
dev_vhci.txt
dev_video4linux.txt
dev_video4linux_vim2m.txt
dev_virtual_nci.txt
dev_vtpm.txt
fanotify.txt
filesystem.txt
fs_9p.txt
fs_fuse.txt
fs_incfs.txt
fs_ioctl.txt
fs_ioctl_autofs.txt
fs_ioctl_btrfs.txt
fs_ioctl_ext4.txt
fs_ioctl_f2fs.txt
fs_ioctl_fat.txt
fs_ioctl_fscrypt.txt
fs_ioctl_fsverity.txt
fs_ioctl_xfs.txt
futex.txt
hafnium.txt
inotify.txt
io_uring.txt
ipc.txt
key.txt
kfuzztest.txt
l2cap.txt
landlock.txt
lsm.txt
namespaces.txt
net_80211.txt
netfilter.txt
netfilter_arp.txt
netfilter_bridge.txt
netfilter_ipv4.txt
netfilter_ipv6.txt
netfilter_ipvs.txt
netfilter_targets.txt
pagemap_ioctl.txt
perf.txt
prctl.txt
quotactl.txt
seccomp.txt
security_apparmor.txt
security_selinux.txt
security_smack.txt
socket.txt
socket_alg.txt
socket_ax25.txt
socket_bluetooth.txt
socket_caif.txt
socket_can.txt
socket_ieee802154.txt
socket_inet.txt
socket_inet6.txt
socket_inet_dccp.txt
socket_inet_icmp.txt
socket_inet_igmp.txt
socket_inet_l2tp.txt
socket_inet_sctp.txt
socket_inet_tcp.txt
socket_inet_udp.txt
socket_ip_tunnel.txt
socket_isdn.txt
socket_kcm.txt
socket_key.txt
socket_llc.txt
socket_netlink.txt
socket_netlink_audit.txt
socket_netlink_crypto.txt
socket_netlink_generic.txt
socket_netlink_generic_80211.txt
socket_netlink_generic_batadv.txt
socket_netlink_generic_devlink.txt
socket_netlink_generic_ethtool.txt
socket_netlink_generic_fou.txt
socket_netlink_generic_gtp.txt
socket_netlink_generic_mptcp.txt
socket_netlink_generic_net_dm.txt
socket_netlink_generic_netlabel.txt
socket_netlink_generic_nfc.txt
socket_netlink_generic_seg6.txt
socket_netlink_generic_smc.txt
socket_netlink_generic_team.txt
socket_netlink_generic_wireguard.txt
socket_netlink_netfilter.txt
socket_netlink_netfilter_acct.txt
socket_netlink_netfilter_conntrack.txt
socket_netlink_netfilter_conntrack_exp.txt
socket_netlink_netfilter_conntrack_helper.txt
socket_netlink_netfilter_ipset.txt
socket_netlink_netfilter_log.txt
socket_netlink_netfilter_nft_compat.txt
socket_netlink_netfilter_nftables.txt
socket_netlink_netfilter_osf.txt
socket_netlink_netfilter_queue.txt
socket_netlink_netfilter_timeout.txt
socket_netlink_rdma.txt
socket_netlink_route.txt
socket_netlink_route_sched.txt
socket_netlink_route_sched_retired.txt
socket_netlink_sock_diag.txt
socket_netlink_xfrm.txt
socket_netrom.txt
socket_nfc.txt
socket_nvme_of_tcp.txt
socket_packet.txt
socket_phonet.txt
socket_pppox.txt
socket_qipcrtr.txt
socket_rds.txt
socket_rose.txt
socket_rxrpc.txt
socket_tipc.txt
socket_tipc_netlink.txt
socket_unix.txt
socket_vnet.txt
socket_x25.txt
socket_xdp.txt
sys.txt
uffd.txt
usbip.txt
vmw_vmci.txt
vnet.txt
vnet_mptcp.txt
vusb.txt
watch_queue.txt
xattr.txt
Reply: ```
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./link0\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000d0)='./link1\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000e0)='./link2\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000f0)='./link3\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000100)='./link4\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000110)='./link5\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000120)='./link6\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000130)='./link7\x00')
unlink(&(0x7f00000000c0)='./link0\x00') (async)
readlink(&(0x7f00000000c0)='./link0\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000d0)='./link1\x00') (async)
readlink(&(0x7f00000000d0)='./link1\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000e0)='./link2\x00') (async)
readlink(&(0x7f00000000e0)='./link2\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000f0)='./link3\x00') (async)
readlink(&(0x7f00000000f0)='./link3\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000100)='./link4\x00') (async)
readlink(&(0x7f0000000100)='./link4\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000110)='./link5\x00') (async)
readlink(&(0x7f0000000110)='./link5\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000120)='./link6\x00') (async)
readlink(&(0x7f0000000120)='./link6\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000130)='./link7\x00') (async)
readlink(&(0x7f0000000130)='./link7\x00', &(0x7f0000000200)="", 0x64) (async)
```
|
| 5/2 |
2026/03/10 03:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 13104
output: 41
thoughts: 178
Thoughts: **Analyzing a Data Race in the Filesystem**
Okay, so I've got a potential data-race brewing, specifically between `d_make_discardable` and `do_readlinkat`. The write operation appears to be happening within `d_make_discardable`, which gets called down a chain: `simple_unlink` -> `shmem_unlink` -> `vfs_unlink` -> `filename_unlinkat` -> `unlink`. That's the write path. The read is happening in `do_readlinkat`, triggered by a call to `readlink`.
My immediate question is: which specific memory location is getting clobbered? Is it `dentry->d_flags` or `dentry->d_type`, or something else within the dentry? Let me trace this.
Wait, looking at the crash dump, the value of the memory location changed from `0x08300080` to `0x00300180`. That tells me *something* is definitely changing. I need to nail down exactly what's being written to by diving into the `d_make_discardable` source code. Let's get that up.
|
| 6/2 |
2026/03/10 03:21 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:fs/dcache.c IncludeLines:true Name:d_make_discardable]
Results: map[SourceCode: 932: void d_make_discardable(struct dentry *dentry)
933: {
934: spin_lock(&dentry->d_lock);
935: WARN_ON(!(dentry->d_flags & DCACHE_PERSISTENT));
936: dentry->d_flags &= ~DCACHE_PERSISTENT;
937: dentry->d_lockref.count--;
938: rcu_read_lock();
939: finish_dput(dentry);
940: }
SourceFile:fs/dcache.c]
|
| 7/2 |
2026/03/10 03:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 13760
output: 43
thoughts: 71
Thoughts: Here's my take on the situation:
**Investigating a Potential Symlink Issue**
Okay, so I'm looking at this code and something's caught my eye. Line 936, specifically `dentry->d_flags &= ~DCACHE_PERSISTENT;` is where things get interesting. I remember seeing `do_readlinkat` calling `__d_entry_type(dentry)`. This connection makes me wonder if there's an interaction, or perhaps a bug, related to how symlinks are handled. It seems like it's worth digging into `__d_entry_type` and `d_is_symlink` to see if the clearing of that cache flag has any knock-on effects when combined with symlink resolution. Gotta check the cache handling logic, to see if there is an interaction with symbolic link resolution. This could be nothing, but it's a suspicious area based on the calls involved, and I should make sure there aren't any subtle implications for persistent caches and symlinks.
|
| 8/2 |
2026/03/10 03:21 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:include/linux/dcache.h IncludeLines:true Name:__d_entry_type]
Results: map[SourceCode: 411: /*
412: * Directory cache entry type accessor functions.
413: */
414: static inline unsigned __d_entry_type(const struct dentry *dentry)
415: {
416: return dentry->d_flags & DCACHE_ENTRY_TYPE;
417: }
SourceFile:include/linux/dcache.h]
|
| 9/2 |
2026/03/10 03:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 14220
output: 39
thoughts: 107
Thoughts: **Analyzing a Potential Race Condition in `do_readlinkat`**
Okay, so I'm looking at this code and something's bugging me. Specifically, I'm concerned about the interaction between `do_readlinkat` and the `dentry` flags. I see that `dentry->d_flags` is being read within `do_readlinkat` *without* any locking. Now, I know that `d_make_discardable` – which I believe is a utility function, and I'll need to double-check that – modifies those very same `dentry->d_flags`, but it does so *with* the `d_lock` held.
The red flag is that we've got a read *without* a lock, and a write *with* a lock. That screams race condition to me. Let me just clarify something... Right, `do_readlinkat` calls `d_is_symlink`, and *that's* where it reads `dentry->d_flags`. So it's not a direct read, but the dependency is clear.
I'm thinking this warrants a deeper dive into `do_readlinkat` and its specific implementation to confirm what I'm suspecting is correct.
|
| 10/2 |
2026/03/10 03:21 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:fs/stat.c IncludeLines:true Name:do_readlinkat]
Results: map[SourceCode: 559: static int do_readlinkat(int dfd, const char __user *pathname,
560: char __user *buf, int bufsiz)
561: {
562: struct path path;
563: int error;
564: unsigned int lookup_flags = 0;
565:
566: if (bufsiz <= 0)
567: return -EINVAL;
568:
569: CLASS(filename_flags, name)(pathname, LOOKUP_EMPTY);
570: retry:
571: error = filename_lookup(dfd, name, lookup_flags, &path, NULL);
572: if (unlikely(error))
573: return error;
574:
575: /*
576: * AFS mountpoints allow readlink(2) but are not symlinks
577: */
578: if (d_is_symlink(path.dentry) ||
579: d_backing_inode(path.dentry)->i_op->readlink) {
580: error = security_inode_readlink(path.dentry);
581: if (!error) {
582: touch_atime(&path);
583: error = vfs_readlink(path.dentry, buf, bufsiz);
584: }
585: } else {
586: error = (name->name[0] == '\0') ? -ENOENT : -EINVAL;
587: }
588: path_put(&path);
589: if (retry_estale(error, lookup_flags)) {
590: lookup_flags |= LOOKUP_REVAL;
591: goto retry;
592: }
593: return error;
594: }
SourceFile:fs/stat.c]
|
| 11/2 |
2026/03/10 03:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 15187
output: 142
thoughts: 503
Thoughts: **Debugging a Data Race in the Filesystem**
Okay, so I've pinpointed a potential bug: it seems like there's a data race happening with `dentry->d_flags`. Specifically, `d_make_discardable` is clearing the `DCACHE_PERSISTENT` flag by writing `dentry->d_flags &= ~DCACHE_PERSISTENT;`, while `do_readlinkat` is reading `d_is_symlink(path.dentry)`, which checks `dentry->d_flags & DCACHE_ENTRY_TYPE`. This looks like a classic race condition.
To reproduce this reliably, I figure we need to trigger a race between an `unlink` and a `readlink` operation on a shared memory file, like something in tmpfs. Hmm, `d_make_discardable` gets called from `simple_unlink`, which then calls `shmem_unlink`. So, tmpfs is definitely the key here. Okay, we need a `readlink` on a symlink within tmpfs. So, if we can create a symlink in a tmpfs file system, and race the `unlink` of the symlink and `readlink` on it, that should be enough to trigger the race.
Time to write a syzkaller program to demonstrate this. My first thought was `memfd_create`, but that makes a regular file, not a symlink. How to create a symlink in tmpfs, then? We can either use `/tmp` or `/dev/shm` which are usually tmpfs. Or, we could mount a tmpfs. Or we can just use `symlink` in the current directory, which is usually tmpfs in syzkaller.
Let's quickly check if syzkaller is running in a tmpfs. It usually does. So, I can just do:
```
symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
```
And then race an `unlink` of the symlink: `unlink(&(0x7f0000000100)='link\x00')` with a `readlink` call: `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200), 100)`.
Now, let's test this and see if it works.
|
| 12/2 |
2026/03/10 03:21 |
tool |
crash-reproducer |
0m
Error:
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200), 100)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 13/2 |
2026/03/10 03:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 16469
output: 18
thoughts: 22
Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and presented as if it were my own internal monologue:
**Navigating `readlink` and System Context**
Alright, *`readlink` syntax*. That's a familiar territory. My first instinct, given the context (implied by the brevity of the thought), is to quickly ground myself with the system's current state. "Let's check `readlink` in `sys.txt`." That tells me immediately that I'm considering the system call as it relates to a file named `sys.txt`. I'm likely interested in how `readlink` would work or is documented within that specific context, perhaps a configuration file, a system documentation file, or some file containing system documentation. The quick mental jump to `sys.txt` implies I'm probably looking for details concerning the behavior, implementation, or perhaps restrictions/limitations of `readlink` within the system's defined state. I'm implicitly assuming `sys.txt` is the appropriate place to find the details, be it a documentation file or a configuration file. I anticipate the relevant details to be found there.
|
| 14/2 |
2026/03/10 03:21 |
tool |
read-description |
0m
Args:
Results: map[Output:# Copyright 2015 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
# Description of syscall arguments. See README.md for details.
include <linux/socket.h>
include <linux/ptrace.h>
include <linux/resource.h>
include <linux/stat.h>
include <linux/mman.h>
include <linux/time.h>
include <linux/mount.h>
include <linux/fs.h>
include <linux/eventpoll.h>
include <linux/signalfd.h>
include <linux/eventfd.h>
include <linux/timerfd.h>
include <linux/personality.h>
include <linux/wait.h>
include <linux/user.h>
include <linux/un.h>
include <linux/ioctl.h>
include <linux/fadvise.h>
include <linux/falloc.h>
include <linux/kexec.h>
include <linux/elf.h>
include <linux/fiemap.h>
include <linux/kd.h>
include <linux/vt.h>
include <linux/if_alg.h>
include <linux/nfc.h>
include <linux/sockios.h>
include <linux/net_tstamp.h>
include <linux/termios.h>
include <linux/fcntl.h>
include <linux/sched.h>
include <linux/mqueue.h>
include <linux/mempolicy.h>
include <linux/in.h>
include <linux/ip.h>
include <linux/tcp.h>
include <linux/udp.h>
include <linux/kcmp.h>
include <linux/nfs.h>
include <linux/syslog.h>
include <linux/exportfs.h>
include <linux/splice.h>
include <linux/filelock.h>
include <fs/overlayfs/overlayfs.h>
include <uapi/linux/memfd.h>
include <uapi/linux/module.h>
include <linux/ioprio.h>
include <linux/membarrier.h>
include <uapi/linux/kcov.h>
include <uapi/linux/membarrier.h>
include <uapi/linux/capability.h>
include <uapi/linux/seccomp.h>
include <uapi/linux/wait.h>
include <uapi/linux/watch_queue.h>
include <kernel/sched/sched.h>
include <uapi/linux/close_range.h>
include <uapi/linux/netfilter/xt_cgroup.h>
include <fs/smb/client/cifsglob.h>
include <xen/interface/io/xs_wire.h>
include <uapi/linux/prctl.h>
include <asm/prctl.h>
include <linux/reboot.h>
include <linux/swap.h>
resource fd[int32]: -1
resource fd_dir[fd]: AT_FDCWD
# alignptr/align32/align64/padto64 can be used when ABI uses int64/intptr to hold a smaller type.
# E.g. pid/uid stored as intptr/int64.
type alignptr[T] {
v T
} [align[PTR_SIZE]]
type align32[T] {
v T
} [align[4]]
type align64[T] {
v T
} [align[8]]
type padto32[T] {
v T
} [size[4]]
type padto64[T] {
v T
} [size[8]]
type signalno int32[0:65]
type signalnoptr intptr[0:65]
# syz_execute_func caused multiple problems:
# 1. First it lead to corpus explosion. The program used existing values in registers
# to pollute output area. We tried to zero registers (though, not reliably).
# 2. It lead to explosion again. The exact mechanics are unknown, here is one sample:
# syz_execute_func(&(0x7f0000000440)="f2af91930f0124eda133fa20430fbafce842f66188d0d4
# 430fc7f314c1ab5bf9e2f9660f3a0fae5e090000ba023c1fb63ac4817d73d74ec482310d46f44
# 9f216c863fa438036a91bdbae95aaaa420f383c02c401405c6bfd49d768d768f833fefbab6464
# 660f38323c8f26dbc1a1fe5ff6f6df0804f4c4efa59c0f01c4288ba6452e000054c4431d5cc100")
# 3. The code can also execute syscalls (and it is know to), but it's not subject to
# target.SanitizeCall. As the result it can do things that programs are not supposed to do.
# 4. Besides linux, corpus explosion also happens on freebsd and is clearly attributable
# to syz_execute_func based on corpus contents. Mechanics are also not known.
# It also did not cause finding of any new bugs (at least not that I know of).
# So it's disabled on all OSes until we figure out how to resolve all these problems.
syz_execute_func(text ptr[in, text[target]]) (disabled)
# Exclude /sys/power/state as reported in https://lkml.org/lkml/2021/5/27/653
openat$sysfs(fd const[AT_FDCWD], dir ptr[in, glob["/sys/**/*:-/sys/power/state"]], flags flags[open_flags], mode flags[open_mode]) fd
open(file ptr[in, filename], flags flags[open_flags], mode flags[open_mode]) fd (automatic_helper)
# Just so that we have something that creates fd_dir resources.
open$dir(file ptr[in, filename], flags flags[open_flags], mode flags[open_mode]) fd_dir (automatic_helper)
openat$dir(fd const[AT_FDCWD], file ptr[in, filename], flags flags[open_flags], mode flags[open_mode]) fd_dir (automatic_helper)
openat(fd fd_dir[opt], file ptr[in, filename], flags flags[open_flags], mode flags[open_mode]) fd
openat2$dir(fd const[AT_FDCWD], file ptr[in, filename], how ptr[in, open_how], size bytesize[how]) fd_dir (automatic_helper)
openat2(fd fd_dir[opt], file ptr[in, filename], how ptr[in, open_how], size bytesize[how]) fd
creat(file ptr[in, filename], mode flags[open_mode]) fd
close(fd fd)
read(fd fd, buf buffer[out], count len[buf])
pread64(fd fd, buf buffer[out], count len[buf], pos fileoff)
readv(fd fd, vec ptr[in, array[iovec_out]], vlen len[vec])
preadv(fd fd, vec ptr[in, array[iovec_out]], vlen len[vec], off_low int32, off_high int32)
preadv2(fd fd, vec ptr[in, array[iovec_out]], vlen len[vec], off_low int32, off_high int32, flags flags[rwf_flags])
write(fd fd, buf buffer[in], count len[buf])
pwrite64(fd fd, buf buffer[in], count len[buf], pos fileoff)
writev(fd fd, vec ptr[in, array[iovec_in]], vlen len[vec])
pwritev(fd fd, vec ptr[in, array[iovec_in]], vlen len[vec], off_low int32, off_high int32)
pwritev2(fd fd, vec ptr[in, array[iovec_in]], vlen len[vec], off_low int32, off_high int32, flags flags[rwf_flags])
# lseek can return negative offsets when the file has FMODE_UNSIGNED_OFFSET flag:
# https://elixir.bootlin.com/linux/v6.11-rc7/source/fs/read_write.c#L56
# It's unclear how it's then even possible to distinguish error from valid offset, but it's not our problem.
# We just have to ignore return values of lseek.
lseek(fd fd, offset fileoff, whence flags[seek_whence]) (ignore_return)
copy_file_range(fd_in fd, off_in ptr[inout, fileoff[int64], opt], fd_out fd, off_out ptr[inout, fileoff[int64], opt], len intptr, flags flags[copy_file_range_flags])
rwf_flags = RWF_DSYNC, RWF_HIPRI, RWF_SYNC, RWF_NOWAIT, RWF_APPEND
copy_file_range_flags = 0
dup(oldfd fd) fd
dup2(oldfd fd, newfd fd) fd
dup3(oldfd fd, newfd fd, flags flags[dup_flags]) fd
pipe(pipefd ptr[out, pipefd])
pipe2(pipefd ptr[out, pipefd], flags flags[pipe_flags])
tee(fdin fd, fdout fd, len intptr, f flags[splice_flags])
splice(fdin fd, offin ptr[in, fileoff[int64]], fdout fd, offout ptr[in, fileoff[int64]], len intptr, f flags[splice_flags])
vmsplice(fd fd, vec ptr[in, array[iovec_in]], vlen len[vec], f flags[splice_flags])
sendfile(fdout fd, fdin fd, off ptr[inout, fileoff[intptr], opt], count intptr)
sendfile64(fdout fd, fdin fd, off ptr[inout, fileoff[int64], opt], count intptr)
cachestat_range {
off fileoff[int64]
len int64
}
cachestat {
nr_cache int64
nr_dirty int64
nr_writeback int64
nr_evicted int64
nr_recently_evicted int64
}
stat(file ptr[in, filename], statbuf ptr[out, stat])
lstat(file ptr[in, filename], statbuf ptr[out, stat])
fstat(fd fd, statbuf ptr[out, stat])
newfstatat(dfd const[AT_FDCWD], file ptr[in, filename], statbuf ptr[out, stat], flag flags[statx_flags])
stat64(file ptr[in, filename], statbuf ptr[out, stat64])
lstat64(file ptr[in, filename], statbuf ptr[out, stat64])
fstat64(fd fd, statbuf ptr[out, stat64])
fstatat64(dfd const[AT_FDCWD], file ptr[in, filename], statbuf ptr[out, stat64], flag flags[statx_flags])
statx(fd fd_dir, file ptr[in, filename], flags flags[statx_flags], mask flags[statx_mask], statxbuf ptr[out, statx])
cachestat(fd fd, cstat_range ptr[in, cachestat_range], cstat ptr[out, cachestat], flags const[0])
poll(fds ptr[in, array[pollfd]], nfds len[fds], timeout int32)
ppoll(fds ptr[in, array[pollfd]], nfds len[fds], tsp ptr[in, timespec], sigmask ptr[in, sigset_t], size len[sigmask])
select(n len[inp], inp ptr[inout, fd_set], outp ptr[inout, fd_set], exp ptr[inout, fd_set], tvp ptr[inout, timeval])
pselect6(n len[inp], inp ptr[inout, fd_set], outp ptr[inout, fd_set], exp ptr[inout, fd_set], tvp ptr[inout, timespec], sig ptr[in, sigset_size])
resource fd_epoll[fd]
epoll_create(size int32) fd_epoll
epoll_create1(flags flags[epoll_flags]) fd_epoll
epoll_ctl$EPOLL_CTL_ADD(epfd fd_epoll, op const[EPOLL_CTL_ADD], fd fd, ev ptr[in, epoll_event])
epoll_ctl$EPOLL_CTL_MOD(epfd fd_epoll, op const[EPOLL_CTL_MOD], fd fd, ev ptr[in, epoll_event])
epoll_ctl$EPOLL_CTL_DEL(epfd fd_epoll, op const[EPOLL_CTL_DEL], fd fd)
epoll_wait(epfd fd_epoll, events ptr[out, array[epoll_event]], maxevents len[events], timeout int32)
epoll_pwait(epfd fd_epoll, events ptr[out, array[epoll_event]], maxevents len[events], timeout int32, sigmask ptr[in, sigset_t], size bytesize[sigmask])
epoll_pwait2(epfd fd_epoll, events ptr[out, array[epoll_event]], maxevents len[events], timeout ptr[in, timespec], sigmask ptr[in, sigset_t], size bytesize[sigmask])
resource fd_timer[fd]
signalfd(fd fd, mask ptr[in, sigset_t], size len[mask]) fd
signalfd4(fd fd, mask ptr[in, sigset_t], size len[mask], flags flags[signalfd_flags]) fd
timerfd_create(clockid flags[clock_type], flags flags[timerfd_create_flags]) fd_timer
timerfd_settime(fd fd_timer, flags flags[timerfd_settime_flags], new ptr[in, itimerspec], old ptr[out, itimerspec])
timerfd_gettime(fd fd_timer, cur ptr[out, itimerspec])
ioctl$TFD_IOC_SET_TICKS(fd fd_timer, cmd const[TFD_IOC_SET_TICKS], arg ptr[in, int64])
resource fd_event[fd]
eventfd(initval int32) fd_event
eventfd2(initval int32, flags flags[eventfd_flags]) fd_event
read$eventfd(fd fd_event, val ptr[out, int64], len len[val])
write$eventfd(fd fd_event, val ptr[in, int64], len len[val])
brk(brk intptr)
mmap(addr vma, len len[addr], prot flags[mmap_prot], flags flags[mmap_flags], fd fd, offset intptr[0:0xffffffff, 0x1000])
munmap(addr vma, len len[addr])
mremap(addr vma, len len[addr], newlen len[newaddr], flags flags[mremap_flags], newaddr vma)
remap_file_pages(addr vma, size len[addr], prot flags[mmap_prot], pgoff intptr, flags flags[mmap_flags])
mprotect(addr vma, len len[addr], prot flags[mmap_prot])
msync(addr vma, len len[addr], f flags[msync_flags])
madvise(addr vma, len len[addr], advice flags[madvise_flags])
process_madvise(pidfd fd_pidfd, vec ptr[in, array[iovec_in]], vlen len[vec], advice flags[madvise_flags], flags const[0])
process_mrelease(pidfd fd_pidfd, flags const[0])
fadvise64(fd fd, offset fileoff, len intptr, advice flags[fadvise_flags])
readahead(fd fd, off intptr, count intptr)
mbind(addr vma, len len[addr], mode flags[mbind_mode], nodemask ptr[in, int64], maxnode intptr, flags flags[mbind_flags])
move_pages(pid pid, nr len[pages], pages ptr[in, array[vma]], nodes ptr[in, array[int32], opt], status ptr[out, array[int32]], flags flags[move_pages_flags])
migrate_pages(pid pid, maxnode intptr, old ptr[in, int64], new ptr[in, int64])
set_mempolicy(mode flags[mbind_mode], nodemask ptr[in, int64], maxnode intptr)
get_mempolicy(mode ptr[out, int32], nodemask ptr[out, int64], maxnode intptr, addr vma, flags flags[mempolicy_flags])
set_mempolicy_home_node(addr vma, len len[addr], home_node intptr[0:3], flags const[0])
mincore(addr vma, size len[addr], vec buffer[out])
mlock(addr vma, size len[addr])
mlock2(addr vma, size len[addr], flags flags[mlock_flags])
munlock(addr vma, size len[addr])
mlockall(flags flags[mlockall_flags])
munlockall()
kcmp(pid1 pid, pid2 pid, type flags[kcmp_flags], fd1 fd, fd2 fd)
kcmp$KCMP_EPOLL_TFD(pid1 pid, pid2 pid, type const[KCMP_EPOLL_TFD], fd1 fd, idx2 ptr[in, kcmp_epoll_slot])
resource fd_memfd[fd]
memfd_create(name ptr[in, string], flags flags[memfd_flags]) fd_memfd
memfd_flags = MFD_CLOEXEC, MFD_ALLOW_SEALING, MFD_HUGETLB
_ = MFD_HUGE_SHIFT, MFD_HUGE_MASK, MFD_HUGE_64KB, MFD_HUGE_512KB, MFD_HUGE_1MB, MFD_HUGE_2MB, MFD_HUGE_8MB, MFD_HUGE_16MB
memfd_secret(flags flags[memfd_secret_flags]) fd
memfd_secret_flags = O_CLOEXEC
resource pkey[int32]: -1
pkey_alloc(flags const[0], val flags[pkey_flags]) pkey
pkey_free(key pkey)
pkey_mprotect(addr vma, len len[addr], prot flags[mmap_prot], key pkey)
syz_pkey_set(key pkey, val flags[pkey_flags])
pkey_flags = PKEY_DISABLE_ACCESS, PKEY_DISABLE_WRITE
restart_syscall()
# Almighty!
ioctl(fd fd, cmd int32, arg buffer[in])
ioctl$int_in(fd fd, cmd flags[ioctl_int_in], v ptr[in, int64])
ioctl$int_out(fd fd, cmd flags[ioctl_int_out], v ptr[out, intptr])
ioctl$FIOCLEX(fd fd, cmd const[FIOCLEX])
ioctl$FIONCLEX(fd fd, cmd const[FIONCLEX])
ioctl$FITHAW(fd fd, cmd const[FITHAW])
# FIFREEZE is enabled in sandbox mode only because it can easily kill the machine.
ioctl$FIFREEZE(fd fd, cmd const[FIFREEZE]) (snapshot)
fcntl$dupfd(fd fd, cmd flags[fcntl_dupfd], arg fd) fd
fcntl$getflags(fd fd, cmd flags[fcntl_getflags])
fcntl$setflags(fd fd, cmd const[F_SETFD], flags flags[fcntl_flags])
fcntl$setstatus(fd fd, cmd const[F_SETFL], flags flags[fcntl_status])
fcntl$lock(fd fd, cmd flags[fcntl_lock], lock ptr[in, flock])
fcntl$getown(fd fd, cmd const[F_GETOWN]) pid (automatic_helper)
fcntl$setown(fd fd, cmd const[F_SETOWN], pid pid)
fcntl$getownex(fd fd, cmd const[F_GETOWN_EX], arg ptr[out, f_owner_ex])
fcntl$setownex(fd fd, cmd const[F_SETOWN_EX], arg ptr[in, f_owner_ex])
fcntl$setsig(fd fd, cmd const[F_SETSIG], sig signalnoptr)
fcntl$setlease(fd fd, cmd const[F_SETLEASE], typ flags[flock_type])
fcntl$notify(fd fd, cmd const[F_NOTIFY], typ flags[fcntl_notify])
fcntl$setpipe(fd fd, cmd const[F_SETPIPE_SZ], sz intptr)
fcntl$addseals(fd fd, cmd const[F_ADD_SEALS], seals flags[seal_types])
fcntl$F_GET_RW_HINT(fd fd, cmd const[F_GET_RW_HINT], hint ptr[out, int64])
fcntl$F_GET_FILE_RW_HINT(fd fd, cmd const[F_GET_FILE_RW_HINT], hint ptr[out, int64])
fcntl$F_SET_RW_HINT(fd fd, cmd const[F_SET_RW_HINT], hint ptr[in, flags[fcntl_rw_hint, int64]])
fcntl$F_SET_FILE_RW_HINT(fd fd, cmd const[F_SET_FILE_RW_HINT], hint ptr[in, flags[fcntl_rw_hint, int64]])
# Only some commands break return values.
# When/if we have stricter enforcement of arguments, we may remove some of breaks_returns attributes.
ptrace(req flags[ptrace_req], pid pid) (breaks_returns)
ptrace$peek(req flags[ptrace_req_peek], pid pid, addr ptr[out, intptr]) (breaks_returns)
ptrace$poke(req flags[ptrace_req_poke], pid pid, addr ptr[out, intptr], data intptr) (breaks_returns)
ptrace$peekuser(req const[PTRACE_PEEKUSR], pid pid, addr intptr) (breaks_returns)
ptrace$pokeuser(req const[PTRACE_POKEUSR], pid pid, addr intptr, data intptr) (breaks_returns)
ptrace$getregs(req flags[ptrace_req_getregs], pid pid, ignored intptr, data buffer[out]) (breaks_returns)
ptrace$getregset(req const[PTRACE_GETREGSET], pid pid, what flags[pthread_regset], data ptr[in, iovec_out]) (breaks_returns)
ptrace$setregs(req flags[ptrace_req_setregs], pid pid, ignored intptr, data buffer[in]) (breaks_returns)
ptrace$setregset(req const[PTRACE_SETREGSET], pid pid, what flags[pthread_regset], data ptr[in, iovec_in]) (breaks_returns)
ptrace$getsig(req const[PTRACE_GETSIGINFO], pid pid, ignored intptr, data ptr[out, siginfo]) (breaks_returns)
ptrace$setsig(req const[PTRACE_SETSIGINFO], pid pid, ignored intptr, data ptr[in, siginfo]) (breaks_returns)
ptrace$setopts(req flags[ptrace_req_setopts], pid pid, ignored intptr, flags flags[ptrace_options]) (breaks_returns)
ptrace$getenv(req const[PTRACE_GETEVENTMSG], pid pid, ignored intptr, data ptr[out, intptr]) (breaks_returns)
ptrace$cont(req flags[ptrace_req_cont], pid pid, ignored intptr, data intptr) (breaks_returns)
ptrace$PTRACE_SECCOMP_GET_FILTER(req const[PTRACE_SECCOMP_GET_FILTER], pid pid, addr intptr, data ptr[out, array[int8]]) (breaks_returns)
ptrace$PTRACE_SECCOMP_GET_METADATA(req const[PTRACE_SECCOMP_GET_METADATA], pid pid, addr len[data], data ptr[in, seccomp_metadata]) (breaks_returns)
ptrace$PTRACE_SETSIGMASK(req const[PTRACE_SETSIGMASK], pid pid, size bytesize[data], data ptr[in, sigset_t]) (breaks_returns)
ptrace$PTRACE_GETSIGMASK(req const[PTRACE_GETSIGMASK], pid pid, size bytesize[data], data ptr[out, sigset_t]) (breaks_returns)
ptrace$ARCH_GET_FS(req const[PTRACE_ARCH_PRCTL], pid pid, arg ptr[out, intptr], code const[ARCH_GET_FS]) (breaks_returns)
ptrace$ARCH_GET_GS(req const[PTRACE_ARCH_PRCTL], pid pid, arg ptr[out, intptr], code const[ARCH_GET_GS]) (breaks_returns)
ptrace$ARCH_SET_GS(req const[PTRACE_ARCH_PRCTL], pid pid, arg ptr[out, intptr], code const[ARCH_SET_GS]) (breaks_returns)
ptrace$ARCH_GET_CPUID(req const[PTRACE_ARCH_PRCTL], pid pid, arg const[0], code const[ARCH_GET_CPUID]) (breaks_returns)
ptrace$ARCH_SET_CPUID(req const[PTRACE_ARCH_PRCTL], pid pid, arg boolptr, code const[ARCH_SET_CPUID]) (breaks_returns)
ptrace$ARCH_MAP_VDSO_X32(req const[PTRACE_ARCH_PRCTL], pid pid, arg intptr, code const[ARCH_MAP_VDSO_X32]) (breaks_returns)
ptrace$ARCH_MAP_VDSO_32(req const[PTRACE_ARCH_PRCTL], pid pid, arg intptr, code const[ARCH_MAP_VDSO_32]) (breaks_returns)
ptrace$ARCH_MAP_VDSO_64(req const[PTRACE_ARCH_PRCTL], pid pid, arg intptr, code const[ARCH_MAP_VDSO_64]) (breaks_returns)
ptrace$ARCH_SHSTK_STATUS(req const[PTRACE_ARCH_PRCTL], pid pid, res ptr[out, intptr], cmd const[ARCH_SHSTK_STATUS]) (breaks_returns)
ptrace$ARCH_SHSTK_LOCK(req const[PTRACE_ARCH_PRCTL], pid pid, features flags[shadow_stack_features], cmd const[ARCH_SHSTK_LOCK]) (breaks_returns)
ptrace$ARCH_SHSTK_UNLOCK(req const[PTRACE_ARCH_PRCTL], pid pid, features flags[shadow_stack_features], cmd const[ARCH_SHSTK_UNLOCK]) (breaks_returns)
ptrace$ARCH_SHSTK_ENABLE(req const[PTRACE_ARCH_PRCTL], pid pid, features flags[shadow_stack_features], cmd const[ARCH_SHSTK_ENABLE]) (breaks_returns)
ptrace$ARCH_SHSTK_DISABLE(req const[PTRACE_ARCH_PRCTL], pid pid, features flags[shadow_stack_features], cmd const[ARCH_SHSTK_DISABLE]) (breaks_returns)
ptrace$ARCH_GET_UNTAG_MASK(req const[PTRACE_ARCH_PRCTL], pid pid, arg ptr[out, intptr], cmd const[ARCH_GET_UNTAG_MASK]) (breaks_returns)
ptrace$ARCH_GET_MAX_TAG_BITS(req const[PTRACE_ARCH_PRCTL], pid pid, arg ptr[out, intptr], cmd const[ARCH_GET_MAX_TAG_BITS]) (breaks_returns)
ptrace$ARCH_ENABLE_TAGGED_ADDR(req const[PTRACE_ARCH_PRCTL], pid pid, arg intptr[1:6], cmd const[ARCH_ENABLE_TAGGED_ADDR]) (breaks_returns)
ptrace$ARCH_FORCE_TAGGED_SVA(req const[PTRACE_ARCH_PRCTL], pid pid, arg const[0], cmd const[ARCH_FORCE_TAGGED_SVA]) (breaks_returns)
map_shadow_stack(addr vma, size bytesize[addr], flags boolptr)
seccomp_metadata {
filter_off int64
flags const[0, int64]
}
ptrace_peeksiginfo_args {
off int64
flags flags[ptrace_peeksiginfo_flags, int32]
nr len[syscall:data, int32]
}
ptrace$peeksig(req const[PTRACE_PEEKSIGINFO], pid pid, args ptr[in, ptrace_peeksiginfo_args], data ptr[out, array[siginfo]])
capget(hdr ptr[in, cap_header], data ptr[in, cap_data])
capset(hdr ptr[in, cap_header], data ptr[in, cap_data])
resource fd_mq[fd]
mq_open(name ptr[in, string], flags flags[mq_open_flags], mode flags[open_mode], attr ptr[in, mq_attr]) fd_mq
mq_timedsend(mqd fd_mq, msg buffer[in], msglen len[msg], prio intptr, timeout ptr[in, timespec, opt])
mq_timedreceive(mqd fd_mq, msg buffer[out], msglen len[msg], prio intptr, timeout ptr[in, timespec, opt])
mq_notify(mqd fd_mq, notif ptr[in, sigevent])
mq_getsetattr(mqd fd_mq, attr ptr[in, mq_attr], oldattr ptr[out, mq_attr, opt])
mq_unlink(name ptr[in, string])
mknod(file ptr[in, filename], mode flags[mknod_mode], dev int32)
mknod$loop(file ptr[in, filename], mode flags[mknod_mode], dev proc[1792, 2])
mknodat$loop(dirfd fd_dir, file ptr[in, filename], mode flags[mknod_mode], dev proc[1792, 2])
mknodat$null(dirfd fd_dir, file ptr[in, filename], mode flags[mknod_mode], dev const[0x103])
mknodat(dirfd fd_dir, file ptr[in, filename], mode flags[mknod_mode], dev int32)
chmod(file ptr[in, filename], mode flags[open_mode])
fchmod(fd fd, mode flags[open_mode])
fchmodat(dirfd fd_dir, file ptr[in, filename], mode flags[open_mode])
chown(file ptr[in, filename], uid uid, gid gid)
lchown(file ptr[in, filename], uid uid, gid gid)
fchown(fd fd, uid uid, gid gid)
fchownat(dirfd fd_dir, file ptr[in, filename], uid uid, gid gid, flags flags[at_flags])
fallocate(fd fd, mode flags[fallocate_mode], off intptr, len intptr)
faccessat(dirfd fd_dir, pathname ptr[in, filename], mode flags[open_mode])
faccessat2(dirfd fd_dir, pathname ptr[in, filename], mode flags[open_mode], flags flags[faccessat_flags])
utime(filename ptr[in, filename], times ptr[in, utimbuf])
utimes(filename ptr[in, filename], times ptr[in, itimerval])
futimesat(dir fd_dir, pathname ptr[in, filename], times ptr[in, itimerval])
utimensat(dir fd_dir, pathname ptr[in, filename], times ptr[in, itimerval], flags flags[utimensat_flags])
# Small trick - syzkaller cannot give the proper stack pointer to clone(), but we can do it with the aid of pseudo syscalls.
syz_clone(flags flags[clone_flags], stack buffer[in], stack_len bytesize[stack], parentid ptr[out, int32], childtid ptr[out, int32], tls buffer[in]) pid (automatic_helper)
syz_clone3(args ptr[in, clone_args], size bytesize[args]) pid (automatic_helper)
# We need these disabled definitions to simplify the presence and the NR checking.
clone(flags flags[clone_flags], sp buffer[in], parentid ptr[out, int32], childtid ptr[out, int32], tls buffer[in]) (breaks_returns, disabled)
clone3(args ptr[in, clone_args], size bytesize[args]) pid (breaks_returns, disabled)
clone_args {
flags flags[clone3_flags, int64]
pidfd ptr64[out, fd_pidfd]
child_tid ptr64[out, pid]
parent_tid ptr64[out, pid]
exit_signal align64[signalno]
stack ptr64[out, array[int8]]
stack_size bytesize[stack, int64]
tls ptr64[out, array[int8]]
set_tid ptr64[in, array[pid]]
set_tid_size len[set_tid, int64]
cgroup align64[fd_cgroup]
}
resource pid[int32]: 0, -1
resource uid[int32]: 0, -1, 0xee00, 0xee01
resource gid[int32]: 0, -1, 0xee00, 0xee01
getgid() gid (automatic_helper)
getegid() gid (automatic_helper)
setuid(uid uid)
setgid(gid gid)
getuid() uid (automatic_helper)
geteuid() uid (automatic_helper)
setpgid(pid pid, pgid pid)
getpgid(pid pid) pid (automatic_helper)
getpgrp(pid pid) pid (automatic_helper)
getpid() pid (automatic_helper)
gettid() pid (automatic_helper)
setreuid(ruid uid, euid uid)
setregid(rgid gid, egid gid)
setresuid(ruid uid, euid uid, suid uid)
setresgid(rgid gid, egid gid, sgid gid)
getresuid(ruid ptr[out, uid], euid ptr[out, uid], suid ptr[out, uid])
getresgid(rgid ptr[out, gid], egid ptr[out, gid], sgid ptr[out, gid])
setfsuid(fsuid uid)
setfsgid(fsgid gid)
getgroups(size len[list], list ptr[inout, array[gid]])
setgroups(size len[list], list ptr[in, array[gid]])
personality(persona flags[personality_flags])
# Don't mess with parent (fuzzer). If we ptrace attach to it, it will hang.
# If we setrlimit for parent, it will misbehave. Killing - the same. Nothing good.
#getppid() pid
#getsid(pid pid) pid
#setsid() pid
link(old ptr[in, filename], new ptr[in, filename])
linkat(oldfd fd_dir, old ptr[in, filename], newfd fd_dir, new ptr[in, filename], flags flags[linkat_flags])
symlinkat(old ptr[in, filename], newfd fd_dir, new ptr[in, filename])
symlink(old ptr[in, filename], new ptr[in, filename])
unlink(path ptr[in, filename])
unlinkat(fd fd_dir, path ptr[in, filename], flags flags[unlinkat_flags])
readlink(path ptr[in, filename], buf buffer[out], siz len[buf])
readlinkat(fd fd_dir, path ptr[in, filename], buf buffer[out], siz len[buf])
rename(old ptr[in, filename], new ptr[in, filename])
renameat(oldfd fd_dir, old ptr[in, filename], newfd fd_dir, new ptr[in, filename])
renameat2(oldfd fd_dir, old ptr[in, filename], newfd fd_dir, new ptr[in, filename], flags flags[renameat2_flags])
mkdir(path ptr[in, filename], mode flags[open_mode])
mkdirat(fd fd_dir[opt], path ptr[in, filename], mode flags[open_mode])
rmdir(path ptr[in, filename])
truncate(file ptr[in, filename], len intptr)
ftruncate(fd fd, len intptr)
flock(fd fd, op flags[flock_op])
fsync(fd fd)
fdatasync(fd fd)
sync()
syncfs(fd fd)
sync_file_range(fd fd, off intptr, nbytes intptr, flags flags[sync_file_flags])
lookup_dcookie(cookie intptr, buf buffer[out], len len[buf])
getdents(fd fd_dir, ent buffer[out], count len[ent])
getdents64(fd fd_dir, ent buffer[out], count len[ent])
name_to_handle_at(fd fd_dir, file ptr[in, filename], handle ptr[in, file_handle], mnt ptr[out, int32], flags flags[name_to_handle_at_flags])
open_by_handle_at(mountdirfd fd, handle ptr[in, file_handle], flags flags[open_flags])
chroot(dir ptr[in, filename])
getcwd(buf buffer[out], size len[buf])
chdir(dir ptr[in, filename])
fchdir(fd fd)
pivot_root(new_root ptr[in, filename], put_old ptr[in, filename])
sysfs$1(option const[1], fsname ptr[in, string])
sysfs$2(option const[2], fsindex intptr, fsname buffer[out])
sysfs$3(option const[3])
statfs(path ptr[in, filename], buf buffer[out])
fstatfs(fd fd, buf buffer[out])
uselib(lib ptr_binfmt_file)
init_module(mod ptr[in, binfmt_elf64], len len[mod], args ptr[in, string])
finit_module(fd fd_binfmt, args ptr[in, string], flags flags[finit_module_flags])
delete_module(name ptr[in, string], flags flags[delete_module_flags])
kexec_load(entry intptr, nr_segments len[segments], segments ptr[in, array[kexec_segment]], flags flags[kexec_load_flags])
syslog(cmd flags[syslog_cmd], buf ptr[out, array[int8], opt], len len[buf])
uname(buf buffer[out])
sysinfo(info buffer[out])
ustat(dev intptr, buf ptr[out, ustat])
acct(filename ptr[in, filename, opt])
getrusage(who flags[rusage_who], usage ptr[out, rusage])
getrlimit(res flags[rlimit_type], rlim ptr[out, rlimit])
setrlimit(res flags[rlimit_type], rlim ptr[in, rlimit])
prlimit64(pid pid, res flags[rlimit_type], new ptr[in, rlimit, opt], old ptr[out, rlimit, opt])
iopl(level int8)
ioperm(from intptr, num intptr, on intptr)
ioprio_get$pid(which flags[ioprio_which_pid], who pid)
ioprio_get$uid(which flags[ioprio_which_uid], who uid)
ioprio_set$pid(which flags[ioprio_which_pid], who pid, ioprio flags[ioprio_priorities])
ioprio_set$uid(which flags[ioprio_which_uid], who uid, ioprio flags[ioprio_priorities])
# NEED: we can express the construction of integers using structs with flags
# and bitfields, which are normally obtained using a combination of bitwise
# operations with the help of macros. However, structs can't be directly passed
# as a syscall argument; therefore, such constructions can't be directly passed either.
# One example is ioprio argument for ioprio_set, where we could have expressed the
# construction less messy. For now, some subset of valid values are enumerated as
# in ioprio_priorities.
# ioprio priority values are obtained using IOPRIO_PRIO_VALUE(class, data) macro.
# the behaviour of the macro is mimicked below and some priority values are enumerated.
ioprio_priorities = IOPRIO_CLASS_NONE_PRIO, IOPRIO_CLASS_IDLE_PRIO, IOPRIO_CLASS_RT_HIGH_PRIO, IOPRIO_CLASS_BE_HIGH_PRIO, IOPRIO_CLASS_RT_MID_PRIO, IOPRIO_CLASS_BE_MID_PRIO, IOPRIO_CLASS_RT_LOW_PRIO, IOPRIO_CLASS_BE_LOW_PRIO
# The classes RT and BE take data values from the range [0:7]. Use a subset of the available
# values (0, 4, 7) to ease collisions, and to avoid redundancy. The classes NONE and IDLE
# have only one valid priority value each with data set to 0.
define IOPRIO_CLASS_NONE_PRIO (IOPRIO_CLASS_NONE << IOPRIO_CLASS_SHIFT)
define IOPRIO_CLASS_IDLE_PRIO (IOPRIO_CLASS_IDLE << IOPRIO_CLASS_SHIFT)
define IOPRIO_CLASS_RT_HIGH_PRIO (IOPRIO_CLASS_RT << IOPRIO_CLASS_SHIFT)
define IOPRIO_CLASS_BE_HIGH_PRIO (IOPRIO_CLASS_BE << IOPRIO_CLASS_SHIFT)
define IOPRIO_CLASS_RT_MID_PRIO ((IOPRIO_CLASS_RT << IOPRIO_CLASS_SHIFT) + 4)
define IOPRIO_CLASS_BE_MID_PRIO ((IOPRIO_CLASS_BE << IOPRIO_CLASS_SHIFT) + 4)
define IOPRIO_CLASS_RT_LOW_PRIO ((IOPRIO_CLASS_RT << IOPRIO_CLASS_SHIFT) + 7)
define IOPRIO_CLASS_BE_LOW_PRIO ((IOPRIO_CLASS_BE << IOPRIO_CLASS_SHIFT) + 7)
resource timerid[int32]
timer_create(id flags[clock_id], ev ptr[in, sigevent], timerid ptr[out, timerid])
timer_gettime(timerid timerid, setting ptr[out, itimerspec])
timer_getoverrun(timerid timerid)
timer_settime(timerid timerid, flags flags[timer_flags], new ptr[in, itimerspec], old ptr[out, itimerspec, opt])
timer_delete(timerid timerid)
time(t ptr[out, intptr])
clock_gettime(id flags[clock_id], tp ptr[out, timespec])
clock_settime(id flags[clock_id], tp ptr[in, timespec])
clock_adjtime(id flags[clock_id], tx ptr[in, timex])
clock_getres(id flags[clock_id], tp ptr[out, timespec])
clock_nanosleep(id flags[clock_id], flags flags[timer_flags], rqtp ptr[in, timespec], rmtp ptr[out, timespec, opt])
rt_sigaction(sig signalno, act ptr[in, sigaction], oact ptr[out, sigaction, opt], sigsetsize len[fake], fake ptr[out, sigset_t])
rt_sigprocmask(how flags[sigprocmask_how], nset ptr[in, sigset_t], oset ptr[out, sigset_t, opt], sigsetsize len[nset])
rt_sigreturn()
rt_sigpending(set ptr[out, sigset_t], sigsetsize len[set])
rt_sigtimedwait(these ptr[in, sigset_t], info ptr[out, siginfo, opt], ts ptr[in, timespec], sigsetsize len[these])
rt_sigsuspend(new ptr[in, sigset_t], sigsetsize len[new])
rt_sigqueueinfo(pid pid, sig signalno, info ptr[in, siginfo])
rt_tgsigqueueinfo(gid pid, tid pid, sig signalno, info ptr[in, siginfo])
sigaltstack(ss ptr[in, sigaltstack], oss ptr[out, sigaltstack, opt])
tgkill(gid pid, tid pid, sig signalno)
tkill(tid pid, sig signalno)
pause()
alarm(seconds intptr)
nanosleep(req ptr[in, timespec], rem ptr[out, timespec, opt])
getitimer(which flags[getitimer_which], cur ptr[out, itimerval])
setitimer(which flags[getitimer_which], new ptr[in, itimerval], old ptr[out, itimerval, opt])
exit(code intptr)
exit_group(code intptr)
waitid(which flags[waitid_which], pid pid, infop ptr[out, siginfo, opt], options flags[wait_options], ru ptr[out, rusage, opt])
waitid$P_PIDFD(which const[P_PIDFD], pidfd fd_pidfd, infop ptr[out, siginfo, opt], options flags[wait_options], ru ptr[out, rusage, opt])
wait4(pid pid, status ptr[out, int32, opt], options flags[wait_options], ru ptr[out, rusage, opt])
times(buf ptr[out, tms])
# Can send signals to all processes (pid=-1) so it's enabled only in snapshot mode.
kill(pid pid, sig signalno) (snapshot)
set_thread_area(info ptr[in, user_desc])
get_thread_area(info ptr[in, user_desc])
modify_ldt$read(func const[0], buf buffer[out], len len[buf])
modify_ldt$write(func const[1], buf ptr[in, user_desc], len len[buf])
modify_ldt$read_default(func const[2], buf buffer[out], len len[buf])
modify_ldt$write2(func const[17], buf ptr[in, user_desc], len len[buf])
process_vm_readv(pid pid, loc_vec ptr[in, array[iovec_out]], loc_vlen len[loc_vec], rem_vec ptr[in, array[iovec_out]], rem_vlen len[rem_vec], flags const[0])
process_vm_writev(pid pid, loc_vec ptr[in, array[iovec_out]], loc_vlen len[loc_vec], rem_vec ptr[in, array[iovec_out]], rem_vlen len[rem_vec], flags const[0])
set_tid_address(tidptr ptr[out, int32])
getpriority(which flags[priority_which], who pid)
setpriority(which flags[priority_which], who pid, prio intptr)
sched_getscheduler(pid pid)
sched_setscheduler(pid pid, policy flags[sched_policy], prio ptr[in, int32])
sched_rr_get_interval(pid pid, tp ptr[out, timespec])
sched_getparam(pid pid, prio ptr[out, int32])
sched_setparam(pid pid, prio ptr[in, int32])
sched_getaffinity(pid pid, cpusetsize len[mask], mask ptr[out, int64])
sched_setaffinity(pid pid, cpusetsize len[mask], mask ptr[in, int64])
sched_getattr(pid pid, attr ptr[out, sched_attr], size len[attr], flags const[0])
sched_setattr(pid pid, attr ptr[in, sched_attr], flags const[0])
sched_yield()
getrandom(buf buffer[out], len len[buf], flags flags[getrandom_flags])
reboot(magic1 const[LINUX_REBOOT_MAGIC1], magic2 const[LINUX_REBOOT_MAGIC2], cmd flags[reboot_commands], arg const[0]) (snapshot)
reboot_commands = LINUX_REBOOT_CMD_RESTART, LINUX_REBOOT_CMD_HALT, LINUX_REBOOT_CMD_CAD_ON, LINUX_REBOOT_CMD_CAD_OFF, LINUX_REBOOT_CMD_POWER_OFF, LINUX_REBOOT_CMD_RESTART2, LINUX_REBOOT_CMD_SW_SUSPEND, LINUX_REBOOT_CMD_KEXEC
swapon(specialfile ptr[in, filename], swap_flags flags[swap_flags]) (snapshot)
swapoff(specialfile ptr[in, filename]) (snapshot)
swap_flags = SWAP_FLAG_PRIO_MASK, SWAP_FLAG_PREFER, SWAP_FLAG_DISCARD, SWAP_FLAG_DISCARD_ONCE, SWAP_FLAG_DISCARD_PAGES
sethostname(name ptr[in, array[int8]], len bytesize[name]) (snapshot)
setdomainname(name ptr[in, array[int8]], len bytesize[name]) (snapshot)
gettimeofday(tv ptr[out, timeval], tz ptr[out, timezone])
settimeofday(tv ptr[out, timeval], tz ptr[out, timezone]) (snapshot)
adjtimex(txc_p ptr[in, __kernel_timex]) (snapshot)
timezone {
tz_minuteswest int32
tz_dsttime int32
}
__kernel_timex {
modes flags[adjtimex_modes, int32]
pad0 const[0, int32]
offset int64
freq int64
maxerror int64
esterror int64
status int32
pad1 const[0, int32]
constant int64
precision int64
tolerance int64
int timeval
tick int64
ppsfreq int64
jitter int64
shift int32
pad2 const[0, int32]
stabil int64
jitcnt int64
calcnt int64
errcnt int64
stbcnt int64
tai int32
pad3 array[const[0, int32], 11]
}
adjtimex_modes = ADJ_OFFSET, ADJ_FREQUENCY, ADJ_MAXERROR, ADJ_ESTERROR, ADJ_STATUS, ADJ_TIMECONST, ADJ_TAI, ADJ_SETOFFSET, ADJ_MICRO, ADJ_NANO, ADJ_TICK
membarrier(cmd flags[membarrier_cmd], flags const[0])
membarrier_cmd = MEMBARRIER_CMD_GLOBAL, MEMBARRIER_CMD_GLOBAL_EXPEDITED, MEMBARRIER_CMD_PRIVATE_EXPEDITED, MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, MEMBARRIER_CMD_QUERY, MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, MEMBARRIER_CMD_SHARED
rseq(rseq ptr[in, rseq], rseq_len bytesize[rseq], flags boolptr, sig const[0])
rseq {
cpu_id_start const[0, int32]
cpu_id const[0, int32]
rseq_cs ptr64[in, rseq_cs, opt]
flags flags[rseq_cs_flags, int32]
} [align[32]]
rseq_cs {
version const[0, int32]
flags flags[rseq_cs_flags, int32]
start_ip int64
post_commit_offset int64
abort_ip int64
} [align[32]]
rseq_cs_flags = RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT, RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL, RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE
# start/end are unused for now, no definition of SYS_RISCV_FLUSH_ICACHE_LOCAL in uapi headers.
riscv_flush_icache(start const[0], end const[0], flags bool32)
syz_open_procfs(pid pid, file ptr[in, string[procfs_proc_file]]) fd
# TODO: some of net files are only available in the init namespace (e.g. bluetooth bnep and hci).
# We could find some way to open these files in the init namespace
# esp. taking into account that we create bluetooth sockets in init namespace.
procfs_proc_file = "auxv", "cmdline", "environ", "autogroup", "cgroup", "clear_refs", "comm", "coredump_filter", "cpuset", "gid_map", "io", "limits", "loginuid", "maps", "mountinfo", "mounts", "mountstats", "numa_maps", "oom_adj", "oom_score", "oom_score_adj", "pagemap", "personality", "projid_map", "sched", "schedstat", "sessionid", "setgroups", "smaps", "smaps_rollup", "totmaps", "stack", "stat", "statm", "status", "syscall", "timers", "uid_map", "wchan", "map_files", "attr", "attr/current", "attr/exec", "attr/fscreate", "attr/keycreate", "attr/prev", "attr/sockcreate", "ns", "children", "task", "fd", "fd/3", "fd/4", "fdinfo", "fdinfo/3", "fdinfo/4", "net", "net/anycast6", "net/arp", "net/bnep", "net/connector", "net/dev", "net/dev_mcast", "net/dev_snmp6", "net/fib_trie", "net/fib_triestat", "net/hci", "net/icmp", "net/icmp6", "net/if_inet6", "net/igmp", "net/igmp6", "net/ip6_flowlabel", "net/ip6_mr_cache", "net/ip6_mr_vif", "net/ip6_tables_matches", "net/ip6_tables_names", "net/ip6_tables_targets", "net/ip_mr_cache", "net/ip_mr_vif", "net/ip_tables_matches", "net/ip_tables_names", "net/ip_tables_targets", "net/ipv6_route", "net/l2cap", "net/llc/core", "net/llc/socket", "net/mcfilter", "net/mcfilter6", "net/netfilter", "net/netlink", "net/netstat", "net/nfsfs", "net/packet", "net/protocols", "net/psched", "net/ptype", "net/raw", "net/raw6", "net/rfcomm", "net/route", "net/rpc", "net/rt6_stats", "net/rt_acct", "net/rt_cache", "net/sco", "net/sctp", "net/snmp", "net/snmp6", "net/sockstat", "net/sockstat6", "net/softnet_stat", "net/stat", "net/tcp", "net/tcp6", "net/udp", "net/udp6", "net/udplite", "net/udplite6", "net/unix", "net/wireless", "net/xfrm_stat", "net/ip_vs", "net/ip_vs_stats", "net/ip_vs_stats_percpu", "net/nf_conntrack", "net/nf_conntrack_expect", "net/vlan/config", "net/vlan/vlan0", "net/vlan/vlan1", "net/kcm", "net/psched", "timerslack_ns"
openat$procfs(fd const[AT_FDCWD], file ptr[in, string[procfs_file]], flags const[O_RDONLY], mode const[0]) fd
procfs_file = "/proc/keys", "/proc/key-users", "/proc/crypto", "/proc/consoles", "/proc/cgroups", "/proc/zoneinfo", "/proc/vmstat", "/proc/vmallocinfo", "/proc/tty/drivers", "/proc/tty/ldiscs", "/proc/timer_list", "/proc/sysvipc/sem", "/proc/sysvipc/msg", "/proc/sysvipc/shm", "/proc/stat", "/proc/slabinfo", "/proc/schedstat", "/proc/partitions", "/proc/meminfo", "/proc/mdstat", "/proc/locks", "/proc/diskstats", "/proc/cpuinfo", "/proc/consoles", "/proc/bus/input/devices", "/proc/bus/input/handlers", "/proc/asound/seq/clients", "/proc/asound/seq/clients", "/proc/asound/seq/timer", "/proc/asound/timers"
resource fd_yama_ptrace_scope[fd]
# 0 - YAMA_SCOPE_DISABLED
# 1 - YAMA_SCOPE_RELATIONAL
# 2 - YAMA_SCOPE_CAPABILITY
# 3 - YAMA_SCOPE_NO_ATTACH
yama_modes = "0", "1", "2", "3"
openat$yama_ptrace_scope(fd const[AT_FDCWD], file ptr[in, string["/proc/sys/kernel/yama/ptrace_scope"]], flags const[O_RDWR], mode const[0]) fd_yama_ptrace_scope
write$yama_ptrace_scope(fd fd_yama_ptrace_scope, data ptr[in, string[yama_modes]], count len[data])
# Write into some interesting sysct's and sysfs/procfs files.
resource fd_sysctl[fd]
openat$sysctl(fd const[AT_FDCWD], file ptr[in, string[sysctl_file]], flags const[O_WRONLY], mode const[0]) fd_sysctl
write$sysctl(fd fd_sysctl, val ptr[in, string[sysctl_value]], len len[val])
sysctl_file = "/sys/kernel/mm/ksm/run", "/proc/sys/vm/compact_memory", "/proc/sys/vm/drop_caches", "/proc/sys/net/ipv4/tcp_timestamps", "/proc/sys/net/ipv4/tcp_sack", "/proc/sys/net/ipv4/tcp_dsack", "/proc/sys/net/ipv4/tcp_window_scaling", "/proc/sys/net/ipv4/tcp_syncookies", "/proc/sys/net/ipv4/tcp_recovery", "/proc/sys/net/ipv4/tcp_mtu_probing", "/proc/sys/net/ipv4/tcp_rfc1337", "/proc/self/clear_refs"
# Most of these values are suitable for all sysctl_file files.
sysctl_value = "0", "1", "2", "3", "4", "5", "6", "7"
# Write to this file triggers khugepaged scan.
# We don't want to write small values as we only want the explicitly triggered scan.
resource fd_khugepaged_scan[fd]
openat$khugepaged_scan(fd const[AT_FDCWD], file ptr[in, string["/sys/kernel/mm/transparent_hugepage/khugepaged/scan_sleep_millisecs"]], flags const[O_WRONLY], mode const[0]) fd_khugepaged_scan
write$khugepaged_scan(fd fd_khugepaged_scan, val ptr[in, string["1000000"]], len len[val])
resource fd_tcp_congestion[fd]
openat$tcp_congestion(fd const[AT_FDCWD], file ptr[in, string["/proc/sys/net/ipv4/tcp_congestion_control"]], flags const[O_WRONLY], mode const[0]) fd_tcp_congestion
write$tcp_congestion(fd fd_tcp_congestion, val ptr[in, string[tcp_congestion]], len len[val])
tcp_congestion = "reno", "bbr", "bic", "cdg", "cubic", "dctcp", "westwood", "highspeed", "hybla", "htcp", "vegas", "nv", "veno", "scalable", "lp", "yeah", "illinois"
resource fd_tcp_mem[fd]
openat$tcp_mem(fd const[AT_FDCWD], file ptr[in, string[tcp_mem_files]], flags const[O_WRONLY], mode const[0]) fd_tcp_mem
write$tcp_mem(fd fd_tcp_mem, val ptr[in, tcp_mem_values], len len[val])
tcp_mem_files = "/proc/sys/net/ipv4/tcp_rmem", "/proc/sys/net/ipv4/tcp_wmem"
tcp_mem_values {
v0 fmt[oct, int64]
sp0 const[' ', int8]
v1 fmt[oct, int64]
sp1 const[' ', int8]
v2 fmt[oct, int64]
z const[0, int8]
} [packed]
# /proc/self/reclaim is ChromeOS-specific:
# https://chromium.googlesource.com/chromiumos/third_party/kernel/+/4c3ad28b9c913%5E%21/
resource fd_proc_reclaim[fd]
openat$proc_reclaim(fd const[AT_FDCWD], file ptr[in, string["/proc/self/reclaim"]], flags const[O_WRONLY], mode const[0]) fd_proc_reclaim
write$proc_reclaim(fd fd_proc_reclaim, val ptr[in, string[proc_reclaim_vals]], len len[val])
proc_reclaim_vals = "file", "anon", "all"
resource fd_pidfd[fd]
openat$pidfd(fd const[AT_FDCWD], file ptr[in, string["/proc/self"]], flags flags[open_flags], mode const[0]) fd_pidfd
openat$thread_pidfd(fd const[AT_FDCWD], file ptr[in, string["/proc/thread-self"]], flags flags[open_flags], mode const[0]) fd_pidfd
pidfd_send_signal(fd fd_pidfd, sig signalno, info ptr[in, siginfo], flags const[0])
# pidfd_open is dangerous, so we use syz_pidfd_open instead.
pidfd_open(pid pid, flags const[0]) fd_pidfd (disabled)
syz_pidfd_open(pid pid, flags const[0]) fd_pidfd
pidfd_getfd(pidfd fd_pidfd, fd fd, flags const[0]) fd
close_range(fd fd, max_fd fd, flags flags[close_range_flags])
# Uncomment on your own account.
#syz_open_dev$char(dev const[0xc], major intptr, minor intptr) fd
#syz_open_dev$block(dev const[0xb], major intptr, minor intptr) fd
# /dev/console known to cause problems on at least two different kernels.
# It can turn off all output or produce massive amounts of garbage on console.
# Disable it for now.
#syz_open_dev$console(dev ptr[in, string["/dev/console"]], id const[0], flags flags[open_flags]) fd
resource fd_autofs[fd]
# These devices are relatively safe (don't reboot and don't corrupt kernel memory).
# They need a more comprehensive support. But let at least open them for now,
# maybe fuzzer will be able to skrew them in a useful way.
# TODO: all these devices returning just fd need proper interface descriptions.
openat$vcs(fd const[AT_FDCWD], file ptr[in, string["/dev/vcs"]], flags flags[open_flags], mode const[0]) fd
syz_open_dev$vcsn(dev ptr[in, string["/dev/vcs#"]], id intptr, flags flags[open_flags]) fd
openat$vcsa(fd const[AT_FDCWD], file ptr[in, string["/dev/vcsa"]], flags flags[open_flags], mode const[0]) fd
syz_open_dev$vcsa(dev ptr[in, string["/dev/vcsa#"]], id intptr, flags flags[open_flags]) fd
openat$vcsu(fd const[AT_FDCWD], file ptr[in, string["/dev/vcsu"]], flags flags[open_flags], mode const[0]) fd
syz_open_dev$vcsu(dev ptr[in, string["/dev/vcsu#"]], id intptr, flags flags[open_flags]) fd
syz_open_dev$ircomm(dev ptr[in, string["/dev/ircomm#"]], id intptr, flags flags[open_flags]) fd
syz_open_dev$audion(dev ptr[in, string["/dev/audio#"]], id intptr, flags flags[open_flags]) fd
openat$null(fd const[AT_FDCWD], file ptr[in, string["/dev/null"]], flags flags[open_flags], mode const[0]) fd
openat$zero(fd const[AT_FDCWD], file ptr[in, string["/dev/zero"]], flags flags[open_flags], mode const[0]) fd
openat$full(fd const[AT_FDCWD], file ptr[in, string["/dev/full"]], flags flags[open_flags], mode const[0]) fd
openat$irnet(fd const[AT_FDCWD], file ptr[in, string["/dev/irnet"]], flags flags[open_flags], mode const[0]) fd
openat$hwrng(fd const[AT_FDCWD], file ptr[in, string["/dev/hwrng"]], flags flags[open_flags], mode const[0]) fd
openat$hpet(fd const[AT_FDCWD], file ptr[in, string["/dev/hpet"]], flags flags[open_flags], mode const[0]) fd
openat$autofs(fd const[AT_FDCWD], file ptr[in, string["/dev/autofs"]], flags flags[open_flags], mode const[0]) fd_autofs
openat$keychord(fd const[AT_FDCWD], file ptr[in, string["/dev/keychord"]], flags flags[open_flags], mode const[0]) fd
openat$zygote(fd const[AT_FDCWD], file ptr[in, string["/dev/socket/zygote"]], flags flags[open_flags], mode const[0]) fd
openat$pktcdvd(fd const[AT_FDCWD], file ptr[in, string["/dev/pktcdvd/control"]], flags flags[open_flags], mode const[0]) fd
openat$lightnvm(fd const[AT_FDCWD], file ptr[in, string["/dev/lightnvm/control"]], flags flags[open_flags], mode const[0]) fd
openat$xenevtchn(fd const[AT_FDCWD], file ptr[in, string["/dev/xen/evtchn"]], flags flags[open_flags], mode const[0]) fd
openat$dlm_control(fd const[AT_FDCWD], file ptr[in, string["/dev/dlm-control"]], flags flags[open_flags], mode const[0]) fd
openat$dlm_monitor(fd const[AT_FDCWD], file ptr[in, string["/dev/dlm-monitor"]], flags flags[open_flags], mode const[0]) fd
openat$dlm_plock(fd const[AT_FDCWD], file ptr[in, string["/dev/dlm_plock"]], flags flags[open_flags], mode const[0]) fd
openat$btrfs_control(fd const[AT_FDCWD], file ptr[in, string["/dev/btrfs-control"]], flags flags[open_flags], mode const[0]) fd
openat$ubi_ctrl(fd const[AT_FDCWD], file ptr[in, string["/dev/ubi_ctrl"]], flags flags[open_flags], mode const[0]) fd
openat$cachefiles(fd const[AT_FDCWD], file ptr[in, string["/dev/cachefiles"]], flags flags[open_flags], mode const[0]) fd
openat$ndctl0(fd const[AT_FDCWD], file ptr[in, string["/dev/ndctl0"]], flags flags[open_flags], mode const[0]) fd
openat$nmem0(fd const[AT_FDCWD], file ptr[in, string["/dev/nmem0"]], flags flags[open_flags], mode const[0]) fd
openat$nvram(fd const[AT_FDCWD], file ptr[in, string["/dev/nvram"]], flags flags[open_flags], mode const[0]) fd
openat$ocfs2_control(fd const[AT_FDCWD], file ptr[in, string["/dev/ocfs2_control"]], flags flags[open_flags], mode const[0]) fd
openat$nvme_fabrics(fd const[AT_FDCWD], file ptr[in, string["/dev/nvme-fabrics"]], flags flags[open_flags], mode const[0]) fd
pipefd {
rfd fd
wfd fd
}
type iovec[DIR, T] {
addr ptr[DIR, T]
len len[addr, intptr]
}
type iovec_in iovec[in, array[int8]]
type iovec_out iovec[out, array[int8]]
stat {
st_dev intptr
st_ino intptr
st_mode int32
st_nlink int32
st_uid uid
st_gid gid
st_rdev intptr
__pad1 const[0, intptr]
st_size intptr
st_blksize int32
__pad2 const[0, int32]
st_blocks intptr
st_atime intptr
st_atime_nsec intptr
st_mtime intptr
st_mtime_nsec intptr
st_ctime intptr
st_ctime_nsec intptr
__unused4 const[0, int32]
__unused5 const[0, int32]
}
statx {
mask int32
blksize int32
attributes int64
nlink int32
uid uid
gid gid
mode int16
__spare0 int16
ino int64
size int64
blocks int64
__spare1 int64
atime statx_timestamp
btime statx_timestamp
ctime statx_timestamp
mtime statx_timestamp
rdev_major int32
rdev_minor int32
dev_major int32
dev_minor int32
__spare2 array[int64, 14]
}
define STAT64_SIZE sizeof(struct stat64)
type stat64 array[int8, STAT64_SIZE]
pollfd {
fd fd
events flags[pollfd_events, int16]
revents const[0, int16]
}
sigset_t {
mask array[intptr, _NSIG_WORDS]
}
sigset_size {
ss ptr[inout, sigset_t]
len len[ss, intptr]
}
resource time_sec[intptr]
resource time_nsec[intptr]
resource time_usec[intptr]
# prog knowns about this struct type
timespec {
sec time_sec
nsec time_nsec
}
# prog knowns about this struct type
timeval {
sec time_sec
usec time_usec
}
statx_timestamp {
sec int64
nsec int32
__reserved int32
}
itimerspec {
interv timespec
value timespec
}
itimerval {
interv timeval
value timeval
}
utimbuf {
actime intptr
modtime intptr
}
sigevent {
val const[0, intptr]
signo signalno
notify flags[sigev_notify, int32]
u sigevent_u
} [size[SIGEVENT_SIZE]]
sigevent_u [
tid pid
thr sigevent_thread
]
define SIGEVENT_SIZE sizeof(struct sigevent)
sigevent_thread {
# NEED: this is function pointer and pthread_attr_t (?)
func buffer[in]
attr buffer[in]
}
cap_header {
var flags[cap_version, int32]
pid pid
}
cap_data {
eff0 int32
perm0 int32
inher0 int32
eff1 int32
perm1 int32
inher1 int32
}
epoll_event {
ev flags[epoll_ev, int32]
data const[0, int64]
# TODO: this packed only on amd64
} [packed]
# TODO: fd_set needs to be a separate type
fd_set {
mask0 int64
mask1 int64
mask2 int64
mask3 int64
mask4 int64
mask5 int64
mask6 int64
mask7 int64
}
sock_fprog {
len len[filter, int16]
filter ptr[in, array[sock_filter]]
}
sock_filter {
code int16
jt int8
jf int8
k int32
}
file_handle [
raw file_handle_raw
shmem file_handle_t[1, fid_shmem]
fuse file_handle_t[0x81, fid_fuse]
fuse_with_parent file_handle_t[0x82, fid_fuse_with_parent]
nfs file_handle_t[36, fid_nfs]
FILEID_INO32_GEN file_handle_t[FILEID_INO32_GEN, fid_FILEID_INO32_GEN]
FILEID_INO32_GEN_PARENT file_handle_t[FILEID_INO32_GEN_PARENT, fid_FILEID_INO32_GEN_PARENT]
FILEID_UDF_WITHOUT_PARENT file_handle_t[FILEID_UDF_WITHOUT_PARENT, fid_FILEID_UDF_WITHOUT_PARENT]
FILEID_UDF_WITH_PARENT file_handle_t[FILEID_UDF_WITH_PARENT, fid_FILEID_UDF_WITH_PARENT]
FILEID_BTRFS_WITH_PARENT file_handle_t[FILEID_BTRFS_WITH_PARENT, btrfs_fid]
FILEID_BTRFS_WITH_PARENT_ROOT file_handle_t[FILEID_BTRFS_WITH_PARENT, btrfs_fid]
FILEID_BTRFS_WITHOUT_PARENT file_handle_t[FILEID_BTRFS_WITH_PARENT, btrfs_fid]
ceph_nfs_snapfh file_handle_t[FILEID_BTRFS_WITH_PARENT, ceph_nfs_snapfh]
ceph_nfs_fh file_handle_t[FILEID_INO32_GEN, ceph_nfs_fh]
ceph_nfs_confh file_handle_t[FILEID_INO32_GEN_PARENT, ceph_nfs_confh]
GFS2_SMALL_FH_SIZE file_handle_t[GFS2_SMALL_FH_SIZE, fid_GFS2_SMALL_FH_SIZE]
GFS2_LARGE_FH_SIZE file_handle_t[GFS2_LARGE_FH_SIZE, fid_GFS2_LARGE_FH_SIZE]
OVL_FILEID_V0 file_handle_t[OVL_FILEID_V0, ovl_fb]
OVL_FILEID_V1 file_handle_t[OVL_FILEID_V1, ovl_fh]
FILEID_NILFS_WITHOUT_PARENT file_handle_t[FILEID_NILFS_WITHOUT_PARENT, nilfs_fid]
FILEID_NILFS_WITH_PARENT file_handle_t[FILEID_NILFS_WITH_PARENT, nilfs_fid]
reiserfs_2 file_handle_t[2, fid_reiserfs_2]
reiserfs_3 file_handle_t[3, fid_reiserfs_3]
reiserfs_4 file_handle_t[4, fid_reiserfs_4]
reiserfs_5 file_handle_t[5, fid_reiserfs_5]
reiserfs_6 file_handle_t[6, fid_reiserfs_6]
xfs file_handle_t[0x81, xfs_fid64]
xfs_parent file_handle_t[0x82, xfs_fid64]
orangefs file_handle_t[1, fid_orangefs]
orangefs_parent file_handle_t[2, fid_orangefs_parent]
isofs file_handle_t[1, isofs_fid]
isofs_parent file_handle_t[2, isofs_fid]
ocfs2 file_handle_t[1, fid_ocfs2]
ocfs2_parent file_handle_t[2, fid_ocfs2_parent]
] [varlen]
file_handle_raw {
handle_bytes bytesize[f_handle, int32]
handle_type flags[fid_type, int32]
f_handle align32[array[int8]]
}
type file_handle_t[TYPE, FID] {
handle_bytes bytesize[f_handle, int32]
handle_type const[TYPE, int32]
f_handle FID
}
fid_shmem {
gen int32
ino int64
} [packed]
fid_fuse {
nodeid_hi int32
nodeid_lo int32
generation int32
}
fid_fuse_with_parent {
base fid_fuse
parent_fid fid_fuse
} [packed]
fid_FILEID_INO32_GEN {
ino int32
gen int32
}
fid_FILEID_INO32_GEN_PARENT {
base fid_FILEID_INO32_GEN
parent_ino int32
parent_gen int32
}
fid_FILEID_UDF_WITHOUT_PARENT {
block int32
partref int16
parent_partref int16
generation int32
}
fid_FILEID_UDF_WITH_PARENT {
base fid_FILEID_UDF_WITHOUT_PARENT
parent_block int32
parent_generation int32
}
btrfs_fid {
objectid int64
root_objectid int64
gen int32
parent_objectid int64
parent_gen int32
parent_root_objectid int64
} [packed]
ceph_nfs_snapfh {
ino int64
snapid int64
parent_ino int64
hash int32
} [packed]
ceph_nfs_fh {
ino int64
}
ceph_nfs_confh {
ino int64
parent_ino int64
}
fid_GFS2_SMALL_FH_SIZE {
no_formal_ino_hi int32be
no_formal_ino_lo int32be
no_addr_hi int32be
no_addr_lo int32be
}
fid_GFS2_LARGE_FH_SIZE {
base fid_GFS2_SMALL_FH_SIZE
parent_fid fid_GFS2_SMALL_FH_SIZE
}
define GFS2_SMALL_FH_SIZE 4
define GFS2_LARGE_FH_SIZE 8
fid_nfs {
fileid_hi int32
fileid_lo int32
type int32
# The total size is encoded in file_handle.handle_type, so we make this const size.
size const[NFS_MAXFHSIZE, int16]
data array[int8, NFS_MAXFHSIZE]
} [align[4]]
fid_reiserfs_2 {
objectid int32
dir_id int32
}
fid_reiserfs_3 {
objectid int32
dir_id int32
generation int32
}
fid_reiserfs_4 {
objectid int32
dir_id int32
parent_objectid int32
parent_dir_id int32
}
fid_reiserfs_5 {
objectid int32
dir_id int32
generation int32
parent_objectid int32
parent_dir_id int32
}
fid_reiserfs_6 {
objectid int32
dir_id int32
generation int32
parent_objectid int32
parent_dir_id int32
parent_generation int32
}
xfs_fid64 {
ino int64
gen int32
parent_ino int64
parent_gen int32
} [align[4]]
fid_orangefs {
khandle array[int8, 16]
fs_id int32
}
fid_orangefs_parent {
base fid_orangefs
parent_fid fid_orangefs
}
nilfs_fid {
cno int64
ino int64
gen int32
parent_gen int32
parent_ino int64
} [packed]
isofs_fid {
block int32
offset int16
parent_offset int16
generation int32
parent_block int32
parent_generation int32
}
fid_ocfs2 {
blkno_hi int32
blkno_lo int32
generation int32
}
fid_ocfs2_parent {
base fid_ocfs2
parent_fid fid_ocfs2
}
fid_type = FILEID_ROOT, FILEID_INO32_GEN, FILEID_INO32_GEN_PARENT, FILEID_BTRFS_WITHOUT_PARENT, FILEID_BTRFS_WITH_PARENT, FILEID_BTRFS_WITH_PARENT_ROOT, FILEID_UDF_WITHOUT_PARENT, FILEID_UDF_WITH_PARENT, FILEID_NILFS_WITHOUT_PARENT, FILEID_NILFS_WITH_PARENT, FILEID_FAT_WITHOUT_PARENT, FILEID_FAT_WITH_PARENT, FILEID_LUSTRE, FILEID_KERNFS
mq_attr {
mq_flags intptr
mq_maxmsg intptr
mq_msgsize intptr
mq_curmsgs intptr
__reserved array[const[0, intptr], 4]
}
kexec_segment {
buf buffer[in]
sz len[buf, intptr]
# TODO: this is address in kernel
mem intptr
memsz intptr
}
rusage {
utime timeval
stime timeval
maxrss intptr
ixrss intptr
idrss intptr
isrss intptr
minflt intptr
majflt intptr
nswap intptr
inblock intptr
oublock intptr
msgsnd intptr
msgrcv intptr
signals intptr
nvcsw intptr
nivcsw intptr
}
rlimit {
soft intptr
hard intptr
}
sigaction {
sa_handler ptr[in, text[target]]
sa_flags flags[sigaction_flags, intptr]
sa_restorer ptr[in, text[target]]
sa_mask sigset_t
}
sigaltstack {
ss_sp ptr[out, array[int8]]
ss_flags flags[sigaltstack_flags, int32]
ss_size bytesize[ss_sp, intptr]
}
sigaltstack_flags = SS_ONSTACK, SS_DISABLE, SS_AUTODISARM
tms {
utime intptr
stime intptr
cutime intptr
cstime intptr
}
siginfo {
signo signalno
errno int32
code int32
} [size[SIGINFO_SIZE]]
define SIGINFO_SIZE sizeof(struct siginfo)
timex {
stuff0 intptr
stuff1 intptr
stuff2 intptr
stuff3 intptr
stuff4 intptr
stuff5 intptr
stuff6 intptr
stuff7 intptr
stuff8 intptr
stuff9 intptr
stuff10 intptr
stuff11 intptr
stuff12 intptr
stuff13 intptr
stuff14 intptr
stuff15 intptr
stuff16 intptr
stuff17 intptr
stuff18 intptr
stuff19 intptr
stuff20 intptr
stuff21 intptr
stuff22 intptr
stuff23 intptr
stuff24 intptr
stuff25 intptr
}
ustat {
f_tfree int32
f_tinode intptr
f_fname array[int8, 6]
f_fpack array[int8, 6]
}
user_desc {
entry_number int32
# Base should be vma and limit should be len[base]
# But these fields are int32, so we can't use vma.
base_addr flags[user_desc_bases, int32]
limit flags[user_desc_limits, int32]
seg_32bit int32:1
contents int32:2
read_exec_only int32:1
limit_in_pages int32:1
seg_not_present int32:1
useable int32:1
lm int32:1
}
user_desc_bases = 0, 4096, 1048576, 536870912, 536872960, 536875008, -1
user_desc_limits = 0, 1024, 4096, 8192, 16384, -1
sched_attr {
size bytesize[parent, int32]
sched_policy flags[sched_policy, int32]
sched_flags flags[sched_attr_flags, int64]
sched_nice int32
sched_priority int32
sched_runtime int64
sched_deadline int64
sched_period int64
sched_util_min int32
sched_util_max int32
}
sched_policy = SCHED_NORMAL, SCHED_FIFO, SCHED_RR, SCHED_BATCH, SCHED_IDLE, SCHED_DEADLINE
sched_attr_flags = SCHED_FLAG_RESET_ON_FORK, SCHED_FLAG_RECLAIM, SCHED_FLAG_DL_OVERRUN, SCHED_FLAG_KEEP_POLICY, SCHED_FLAG_KEEP_PARAMS, SCHED_FLAG_UTIL_CLAMP_MIN, SCHED_FLAG_UTIL_CLAMP_MAX, SCHED_FLAG_SUGOV
flock {
type flags[flock_type, int16]
whence flags[seek_whence, int16]
start intptr
len intptr
pid pid
}
f_owner_ex {
type flags[f_owner_type, int32]
pid pid
}
ucred {
pid pid
uid uid
gid gid
}
kcmp_epoll_slot {
efd fd_epoll
tfd fd
toff int32
}
open_how {
flags flags[open_flags, int64]
mode flags[open_mode, int64]
resolve flags[resolve_flags, int64]
}
# Not providing O_WRONLY means O_RDONLY.
open_flags = O_WRONLY, O_RDWR, O_APPEND, FASYNC, O_CLOEXEC, O_CREAT, O_DIRECT, O_DIRECTORY, O_EXCL, O_LARGEFILE, O_NOATIME, O_NOCTTY, O_NOFOLLOW, O_NONBLOCK, O_PATH, O_SYNC, O_TRUNC, __O_TMPFILE
open_mode = S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH
resolve_flags = RESOLVE_CACHED, RESOLVE_BENEATH, RESOLVE_IN_ROOT, RESOLVE_NO_MAGICLINKS, RESOLVE_NO_SYMLINKS, RESOLVE_NO_XDEV
madvise_flags = MADV_NORMAL, MADV_RANDOM, MADV_SEQUENTIAL, MADV_WILLNEED, MADV_DONTNEED, MADV_REMOVE, MADV_DONTFORK, MADV_DOFORK, MADV_HWPOISON, MADV_SOFT_OFFLINE, MADV_MERGEABLE, MADV_UNMERGEABLE, MADV_HUGEPAGE, MADV_NOHUGEPAGE, MADV_DONTDUMP, MADV_DODUMP, MADV_WIPEONFORK, MADV_KEEPONFORK, MADV_COLD, MADV_PAGEOUT, MADV_POPULATE_READ, MADV_POPULATE_WRITE, MADV_COLLAPSE
fadvise_flags = POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL, POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, POSIX_FADV_DONTNEED
move_pages_flags = MPOL_MF_MOVE, MPOL_MF_MOVE_ALL
msync_flags = MS_ASYNC, MS_SYNC, MS_INVALIDATE
mmap_prot = PROT_EXEC, PROT_READ, PROT_WRITE, PROT_SEM, PROT_GROWSDOWN, PROT_GROWSUP
mmap_flags = MAP_SHARED, MAP_PRIVATE, MAP_32BIT, MAP_ANONYMOUS, MAP_DENYWRITE, MAP_EXECUTABLE, MAP_FILE, MAP_FIXED, MAP_GROWSDOWN, MAP_HUGETLB, MAP_LOCKED, MAP_NONBLOCK, MAP_NORESERVE, MAP_POPULATE, MAP_STACK, MAP_UNINITIALIZED, MAP_SHARED_VALIDATE, MAP_SYNC, MAP_FIXED_NOREPLACE
mremap_flags = MREMAP_MAYMOVE, MREMAP_FIXED, MREMAP_DONTUNMAP
mbind_mode = MPOL_DEFAULT, MPOL_BIND, MPOL_INTERLEAVE, MPOL_PREFERRED, MPOL_F_STATIC_NODES, MPOL_F_RELATIVE_NODES
mbind_flags = MPOL_MF_STRICT, MPOL_MF_MOVE, MPOL_MF_MOVE_ALL
pipe_flags = O_NONBLOCK, O_CLOEXEC, O_DIRECT, O_NOTIFICATION_PIPE
mlock_flags = MLOCK_ONFAULT
mlockall_flags = MCL_CURRENT, MCL_FUTURE, MCL_ONFAULT
dup_flags = O_CLOEXEC
splice_flags = SPLICE_F_MOVE, SPLICE_F_NONBLOCK, SPLICE_F_MORE, SPLICE_F_GIFT
seek_whence = SEEK_SET, SEEK_CUR, SEEK_END, SEEK_DATA, SEEK_HOLE
signalfd_flags = SFD_NONBLOCK, SFD_CLOEXEC
eventfd_flags = EFD_CLOEXEC, EFD_NONBLOCK, EFD_SEMAPHORE
timerfd_create_flags = TFD_NONBLOCK, TFD_CLOEXEC
timerfd_settime_flags = TFD_TIMER_ABSTIME, TFD_TIMER_CANCEL_ON_SET
clock_type = CLOCK_REALTIME, CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC, CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME, CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID, CLOCK_REALTIME_ALARM, CLOCK_BOOTTIME_ALARM
sigev_notify = SIGEV_NONE, SIGEV_SIGNAL, SIGEV_THREAD, SIGEV_THREAD_ID
cap_version = _LINUX_CAPABILITY_VERSION_1, _LINUX_CAPABILITY_VERSION_2, _LINUX_CAPABILITY_VERSION_3
epoll_flags = EPOLL_CLOEXEC
epoll_ev = POLLIN, POLLOUT, POLLRDHUP, POLLPRI, POLLERR, POLLHUP, EPOLLET, EPOLLONESHOT, EPOLLEXCLUSIVE, EPOLLWAKEUP
pollfd_events = POLLIN, POLLPRI, POLLOUT, POLLERR, POLLHUP, POLLNVAL, POLLRDNORM, POLLRDBAND, POLLWRNORM, POLLWRBAND, POLLMSG, POLLREMOVE, POLLRDHUP, POLLFREE, POLL_BUSY_LOOP
mknod_mode = S_IFREG, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK, S_ISUID, S_ISGID, S_ISVTX, open_mode
at_flags = AT_EMPTY_PATH, AT_SYMLINK_NOFOLLOW, AT_SYMLINK_FOLLOW, AT_NO_AUTOMOUNT, AT_EMPTY_PATH
fallocate_mode = FALLOC_FL_KEEP_SIZE, FALLOC_FL_PUNCH_HOLE, FALLOC_FL_COLLAPSE_RANGE, FALLOC_FL_ZERO_RANGE, FALLOC_FL_INSERT_RANGE, FALLOC_FL_UNSHARE_RANGE, FALLOC_FL_NO_HIDE_STALE
linkat_flags = AT_EMPTY_PATH, AT_SYMLINK_FOLLOW
unlinkat_flags = AT_REMOVEDIR
renameat2_flags = RENAME_EXCHANGE, RENAME_NOREPLACE, RENAME_WHITEOUT
flock_op = LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB
statx_flags = AT_SYMLINK_NOFOLLOW, AT_SYMLINK_FOLLOW, AT_NO_AUTOMOUNT, AT_EMPTY_PATH, AT_STATX_SYNC_TYPE, AT_STATX_SYNC_AS_STAT, AT_STATX_FORCE_SYNC, AT_STATX_DONT_SYNC
statx_mask = STATX_TYPE, STATX_MODE, STATX_NLINK, STATX_UID, STATX_GID, STATX_ATIME, STATX_MTIME, STATX_CTIME, STATX_INO, STATX_SIZE, STATX_BLOCKS, STATX_BASIC_STATS, STATX_BTIME
name_to_handle_at_flags = AT_EMPTY_PATH, AT_SYMLINK_FOLLOW, AT_HANDLE_FID
mq_open_flags = O_WRONLY, O_RDWR, O_NONBLOCK, O_CREAT, O_EXCL, O_CREAT
finit_module_flags = MODULE_INIT_IGNORE_MODVERSIONS, MODULE_INIT_IGNORE_VERMAGIC
delete_module_flags = O_NONBLOCK, O_TRUNC
kexec_load_flags = KEXEC_ON_CRASH, KEXEC_PRESERVE_CONTEXT, KEXEC_ARCH_386, KEXEC_ARCH_X86_64, KEXEC_ARCH_PPC, KEXEC_ARCH_PPC64, KEXEC_ARCH_IA_64, KEXEC_ARCH_ARM, KEXEC_ARCH_S390, KEXEC_ARCH_SH, KEXEC_ARCH_MIPS, KEXEC_ARCH_MIPS_LE, KEXEC_ARCH_DEFAULT
faccessat_flags = AT_EACCESS, AT_SYMLINK_NOFOLLOW, AT_EMPTY_PATH
sync_file_flags = SYNC_FILE_RANGE_WAIT_BEFORE, SYNC_FILE_RANGE_WRITE, SYNC_FILE_RANGE_WAIT_AFTER
kcmp_flags = KCMP_FILE, KCMP_FILES, KCMP_FS, KCMP_IO, KCMP_SIGHAND, KCMP_SYSVSEM, KCMP_VM
rusage_who = RUSAGE_SELF, RUSAGE_CHILDREN, RUSAGE_THREAD
rlimit_type = RLIMIT_AS, RLIMIT_CORE, RLIMIT_CPU, RLIMIT_DATA, RLIMIT_FSIZE, RLIMIT_LOCKS, RLIMIT_MEMLOCK, RLIMIT_MSGQUEUE, RLIMIT_NICE, RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_RSS, RLIMIT_RTPRIO, RLIMIT_RTTIME, RLIMIT_SIGPENDING, RLIMIT_STACK
# The ones that disable console output are intentionally omitted.
syslog_cmd = SYSLOG_ACTION_CLOSE, SYSLOG_ACTION_OPEN, SYSLOG_ACTION_READ, SYSLOG_ACTION_READ_ALL, SYSLOG_ACTION_READ_CLEAR, SYSLOG_ACTION_SIZE_UNREAD, SYSLOG_ACTION_SIZE_BUFFER
ioprio_which_pid = IOPRIO_WHO_PROCESS, IOPRIO_WHO_PGRP
ioprio_which_uid = IOPRIO_WHO_USER
personality_flags = PER_LINUX, PER_SVR4, PER_SVR3, PER_OSR5, PER_WYSEV386, PER_ISCR4, PER_BSD, PER_XENIX, PER_LINUX32, PER_IRIX32, PER_IRIXN32, PER_IRIX64, PER_RISCOS, PER_SOLARIS, PER_UW7, PER_OSF4, PER_HPUX, ADDR_NO_RANDOMIZE, MMAP_PAGE_ZERO, ADDR_COMPAT_LAYOUT, READ_IMPLIES_EXEC, ADDR_LIMIT_32BIT, SHORT_INODE, WHOLE_SECONDS, STICKY_TIMEOUTS, ADDR_LIMIT_3GB
clock_id = CLOCK_REALTIME, CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC, CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME, CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID
sigprocmask_how = SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK
getitimer_which = ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF
wait_options = WNOHANG, WUNTRACED, WCONTINUED, WEXITED, WSTOPPED, WCONTINUED, WNOHANG, WNOWAIT, __WCLONE, __WALL, __WNOTHREAD
waitid_which = P_PID, P_PGID, P_ALL
sigaction_flags = SA_NOCLDSTOP, SA_NOCLDWAIT, SA_NODEFER, SA_ONSTACK, SA_RESETHAND, SA_RESTART, SA_SIGINFO
timer_flags = TIMER_ABSTIME
utimensat_flags = AT_SYMLINK_NOFOLLOW
priority_which = PRIO_PROCESS, PRIO_PGRP, PRIO_USER
mempolicy_flags = MPOL_F_MEMS_ALLOWED, MPOL_F_ADDR, MPOL_F_NODE
ptrace_req = PTRACE_LISTEN, PTRACE_KILL, PTRACE_INTERRUPT, PTRACE_ATTACH, PTRACE_DETACH
ptrace_req_peek = PTRACE_PEEKTEXT, PTRACE_PEEKDATA
ptrace_req_poke = PTRACE_POKETEXT, PTRACE_POKEDATA
ptrace_req_getregs = PTRACE_GETREGS, PTRACE_GETFPREGS
ptrace_req_setregs = PTRACE_SETREGS, PTRACE_SETFPREGS
ptrace_req_setopts = PTRACE_SETOPTIONS, PTRACE_SEIZE
ptrace_req_cont = PTRACE_CONT, PTRACE_SYSCALL, PTRACE_SINGLESTEP, PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP
pthread_regset = NT_PRSTATUS, NT_PRFPREG, NT_PRPSINFO, NT_TASKSTRUCT, NT_AUXV, NT_386_TLS, NT_386_IOPERM, NT_X86_XSTATE
ptrace_options = PTRACE_O_EXITKILL, PTRACE_O_TRACECLONE, PTRACE_O_TRACEEXEC, PTRACE_O_TRACEEXIT, PTRACE_O_TRACEFORK, PTRACE_O_TRACESYSGOOD, PTRACE_O_TRACEVFORK, PTRACE_O_TRACEVFORKDONE
fcntl_dupfd = F_DUPFD, F_DUPFD_CLOEXEC
fcntl_getflags = F_GETFD, F_GETFL, F_GETSIG, F_GETLEASE, F_GETPIPE_SZ, F_GET_SEALS
fcntl_lock = F_SETLK, F_SETLKW, F_GETLK, F_OFD_GETLK, F_OFD_SETLK, F_OFD_SETLKW
fcntl_flags = FD_CLOEXEC
fcntl_status = O_APPEND, FASYNC, O_DIRECT, O_NOATIME, O_NONBLOCK
flock_type = F_RDLCK, F_WRLCK, F_UNLCK
f_owner_type = F_OWNER_TID, F_OWNER_PID, F_OWNER_PGRP
fcntl_notify = DN_MULTISHOT, DN_ACCESS, DN_MODIFY, DN_CREATE, DN_DELETE, DN_RENAME, DN_ATTRIB
seal_types = F_SEAL_SEAL, F_SEAL_SHRINK, F_SEAL_GROW, F_SEAL_WRITE
ioctl_int_in = FIONBIO, FIOASYNC
ioctl_int_out = FIOQSIZE, FIGETBSZ
fcntl_rw_hint = RWF_WRITE_LIFE_NOT_SET, RWH_WRITE_LIFE_NONE, RWH_WRITE_LIFE_SHORT, RWH_WRITE_LIFE_MEDIUM, RWH_WRITE_LIFE_LONG, RWH_WRITE_LIFE_EXTREME
fiemap_flags = FIEMAP_FLAG_SYNC, FIEMAP_FLAG_XATTR, FIEMAP_FLAG_CACHE
fiemap_extent_flags = FIEMAP_EXTENT_LAST, FIEMAP_EXTENT_UNKNOWN, FIEMAP_EXTENT_DELALLOC, FIEMAP_EXTENT_ENCODED, FIEMAP_EXTENT_DATA_ENCRYPTED, FIEMAP_EXTENT_NOT_ALIGNED, FIEMAP_EXTENT_DATA_INLINE, FIEMAP_EXTENT_DATA_TAIL, FIEMAP_EXTENT_UNWRITTEN, FIEMAP_EXTENT_MERGED, FIEMAP_EXTENT_SHARED
getrandom_flags = GRND_NONBLOCK, GRND_RANDOM
clone_flags = CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, CLONE_PTRACE, CLONE_VFORK, CLONE_PARENT, CLONE_THREAD, CLONE_NEWNS, CLONE_SYSVSEM, CLONE_SETTLS, CLONE_PARENT_SETTID, CLONE_CHILD_CLEARTID, CLONE_UNTRACED, CLONE_CHILD_SETTID, CLONE_NEWCGROUP, CLONE_NEWUTS, CLONE_NEWIPC, CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET, CLONE_IO, CLONE_PIDFD, CLONE_NEWTIME
clone3_flags = CLONE_CLEAR_SIGHAND, CLONE_INTO_CGROUP, clone_flags
ptrace_peeksiginfo_flags = PTRACE_PEEKSIGINFO_SHARED
close_range_flags = CLOSE_RANGE_UNSHARE
# Consts for target.SpecialFileLenghts.
_ = SMB_PATH_MAX, XT_CGROUP_PATH_MAX, XENSTORE_REL_PATH_MAX
# misc
_ = KCOV_INIT_TRACE, KCOV_ENABLE, KCOV_DISABLE, KCOV_TRACE_PC, KCOV_TRACE_CMP, PTRACE_TRACEME, SYSLOG_ACTION_CONSOLE_ON, SYSLOG_ACTION_CONSOLE_OFF, SYSLOG_ACTION_CONSOLE_LEVEL, SYSLOG_ACTION_CLEAR, __NR_mmap2
# Hardcode KCOV_REMOTE_ENABLE value for amd64 until new kcov patches reach mainline.
define KCOV_REMOTE_ENABLE 1075340134
# Not yet implemented syscalls:
# umask
# vhangup
# _sysctl
# nfsservctl
# getcpu
# Probably no sense in calling these.
# Also affect system-wide state, so not reproducible anyway.
# sched_get_priority_max
# sched_get_priority_min
]
|
| 15/2 |
2026/03/10 03:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 42722
output: 143
thoughts: 162
Thoughts: **Analyzing the `readlink` System Call**
Okay, so I'm looking at how `readlink` works here. It takes a path, a buffer for the result, and a size parameter. From the looks of it, `readlink(path, buf, len)` means that `len` refers to the size of the buffer `buf`.
The original attempt, `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200), 100)`, *seems* correct, but wait a second... If `siz len[buf]` is automatically calculated by syzkaller based on buffer size, I can simplify things.
Instead of explicitly specifying the length, I should be able to just declare a buffer and let the fuzzer handle the size calculation. Therefore, I should be able to write it as `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)=""/100)`. I'm going to try this new configuration and see if it is accepted.
|
| 16/2 |
2026/03/10 03:21 |
tool |
crash-reproducer |
0m
Error:
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)=""/100)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 17/2 |
2026/03/10 03:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 43372
output: 148
thoughts: 141
Thoughts: **Decoding the `readlink` Puzzle**
Okay, hold on a second. My understanding of `readlink` is getting tripped up. I'm recalling that it expects three arguments: the path, the buffer, and the buffer size. Now, if the size parameter, `siz`, is the same as the length of the buffer, `len[buf]`, that should be something Syzkaller can infer, right? But do I *still* have to explicitly provide it? Is it redundant? Can I use `AUTO` somehow?
Right, better double-check the Syzkaller syntax to be absolutely sure. Let me see... Aha! Here's an example: `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)=""/100, 100)`. Okay, so it looks like it *is* explicitly stated. That resolves that question.
|
| 18/2 |
2026/03/10 03:22 |
tool |
crash-reproducer |
0m
Error:
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)=""/100, 100)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 19/2 |
2026/03/10 03:22 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 43961
output: 134
thoughts: 746
Thoughts: **Debugging a `readlink` Call in a Fuzzing Context**
Okay, so I'm looking at this `readlink` call and immediately hitting an argument parsing error. It's the second argument, specifically, where it's choking on `&(0x7f0000000200)=""/100`. That's clearly incorrect syntax, but it highlights the nature of how I represent memory regions in this context. I need to get the syntax right for the fuzzing engine.
Let me refresh the allowed syntax: `pointer-arg-addr = "AUTO" | "(" pointer-addr ["/" region-size] ")"`. So it looks like `&(0x7f0000000200/100)` or, more simply, `&(0x7f0000000200)`. Wait... I tried the simple one before and it failed. Maybe I'm missing something about how the arguments are interpreted.
Thinking about the `readlink` signature, it takes a path pointer, a buffer, and a buffer size. Looking at the `buf` argument, it is declared as `buffer[out]`. This means it's a pointer to a region, where the result will be written. Since `buffer[out]` means it's a pointer to an *array* I can define the size in this manner.
Okay, let me check `read` as an example from the `sys.txt` file and how it is used in syzkaller. The `read` call is similar, and uses the syntax of `read(r0, &(0x7f0000000200)=""/100, 100)` where `r0` is a previously defined file descriptor. The syntax document shows, `read(r0, &AUTO=""/4, 0x4)`. That's the correct syntax.
So, let me try the same approach to fix the `readlink` call. I'll make the second argument `&AUTO=""/100`. Let's test `readlink(&(0x7f0000000100)='link\x00', &AUTO=""/100, 100)`. This looks promising... and should solve the parsing issue and allocate a region for the `readlink` output.
|
| 20/2 |
2026/03/10 03:22 |
tool |
crash-reproducer |
0m
Error:
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &AUTO=""/100, 100)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 21/2 |
2026/03/10 03:22 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 45434
output: 147
thoughts: 211
Thoughts: **Decoding this Peculiar Syntax**
Okay, so I'm seeing this odd string, `&AUTO=""/100`, and my immediate thought is, "Wait, is this parsed as `&AUTO=""`, and then `/100` is simply ignored because it's invalid syntax?" That feels intuitively right, but the whole thing is clearly meant to be a single argument, and that can't be correct.
Then, there it is! `&AUTO=""/4` is right there in the document. Okay, so perhaps `/4` has some meaning. It looks like `&AUTO=""/4` is intended to be parsed as a `pointer-arg`. Let me see... the grammar defines a `pointer-arg` as: `pointer-arg = "&" pointer-arg-addr ["=ANY"] "=" arg`. And `pointer-arg-addr = "AUTO" | "(" pointer-addr ["/" region-size] ")"`.
So, *according* to that grammar, `&AUTO=""/4` is *not* valid. Hmm... But, hang on. I've got a line that says `read(r0, &AUTO=""/4, 0x4)`. That's an explicit use case, so it must be valid.
Okay, let's step back. Could it be that `""/4` is interpreted as a `string-arg`? No, that doesn't feel right. `""` is the string, and `/4` doesn't follow.
Let me try a similar but different example. Perhaps something like `&(0x7f0000000200/100)=""` where I've provided an address and region-size as an argument, and a string as a value.
|
| 22/2 |
2026/03/10 03:22 |
tool |
crash-reproducer |
0m
Error:
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200/100)="", 100)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 23/2 |
2026/03/10 03:22 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 46260
output: 142
thoughts: 245
Thoughts: **Debugging a `readlink` Call with Syzkaller**
Okay, so this `failed to parse argument at '1'` error is throwing me off. It looks like the first argument, `&(0x7f0000000200/100)=""`, is the one failing, which is odd because it *looks* okay. But hold on, let me double-check the arguments. The error says it's at position 1, but I need to make sure I understand which argument is which...
Alright, let's break this down. Argument 0 is `&(0x7f0000000100)='link\x00'`, which seems fine. Argument 1 is indeed the problematic one: `&(0x7f0000000200/100)=""`. And finally, argument 2 is simply `100`.
Wait a minute, wasn't there something about `readlink` and how Syzkaller infers buffer sizes in the `sys.txt` definition? Let me refresh my memory... Ah, here it is: `readlink(path ptr[in, filename], buf buffer[out], siz len[buf])`. Right, *if* `siz` is `len[buf]`, Syzkaller will infer it. I don't *need* to explicitly provide that `100` argument! That's likely the source of the parsing problem.
Okay, let's try dropping that `100` and just call `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200/100)="")`. That should get rid of that confusing argument number. Hopefully, this simple change will resolve this and prevent it from failing.
|
| 24/2 |
2026/03/10 03:22 |
tool |
crash-reproducer |
0m
Error:
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200/100)="")]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 25/2 |
2026/03/10 03:22 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 47132
output: 143
thoughts: 276
Thoughts: **Debugging a Syscall Argument**
Okay, so I'm seeing "missing syscall args," which means I do need to pass that argument. Let's try passing `100` and see what happens. Hmm, now it's failing to parse the argument at '1'. Let's see... argument 1 is `&(0x7f0000000200/100)=""`. That's odd, why can't it parse that?
Right, time to consult the documentation for `readlink` in `sys.txt`. Okay, it's `readlink(path ptr[in, filename], buf buffer[out], siz len[buf])`. Ah, right, the `buffer[out]` argument is a `ptr[out, array[int8]]`. So `buf` needs to be a pointer to an array of `int8`. Okay, the problem is that I was dividing the address. I should be able to pass `&(0x7f0000000200)=""` instead. Let's try that... So, `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)="", 100)`. Hopefully that works!
|
| 26/2 |
2026/03/10 03:22 |
tool |
crash-reproducer |
0m
Error:
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)="", 100)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 27/2 |
2026/03/10 03:22 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 47925
output: 137
thoughts: 463
Thoughts: **Debugging a `readlink` Call in Syzkaller**
Okay, so I'm looking at this error message: `failed to parse argument at '1'`. My initial thought was that it was argument 2, the `100`, that was causing trouble. But no, let's break this down. Argument 0 is correctly parsed, that's `&(0x7f0000000100)='link\x00'`. Argument 1 is `&(0x7f0000000200)=""`. And then the value `100` *is* argument 2, which is indexed at 2. So the parser is clearly off... why is it saying '1' is the issue?
Aha! Let me check the definition of `readlink` in `sys.txt`: `readlink(path ptr[in, filename], buf buffer[out], siz len[buf])`. Right, `siz` is `len[buf]`. The crucial point here is that if an argument is `len[buf]`, syzkaller automatically fills it. We *don't* define it in the syzlang program.
But then, if we *don't* pass it, it should throw a "missing syscall args" error, shouldn't it? Let me confirm the `readlink` definition in `sys.txt` again: `readlink(path ptr[in, filename], buf buffer[out], siz len[buf])`. Yes, `len[buf]` implies automatic calculation.
So, let's experiment. Let's try `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)=""/100)`. Wait, no, `""/100` isn't a valid string argument. Ok, what about `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)=ANY)`? Nope.
Okay, let's try the most basic thing, since we know `len[buf]` is computed and not passed. Let's just try `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200))`. Hopefully, this minimal call, with the implicit length, will work!
|
| 28/2 |
2026/03/10 03:22 |
tool |
crash-reproducer |
0m
Error:
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200))]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 29/2 |
2026/03/10 03:22 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 49155
output: 143
thoughts: 939
Thoughts: **Debugging a Syscall Call**
Okay, so I'm getting a "missing syscall args" error. Right, so I *do* need that third argument. But when I try to pass 100 as the third argument, I'm getting a "failed to parse argument at '1'" error. Hang on, argument 1 is `&(0x7f0000000200)`. Ah, that's a pointer! And `buf` is a `buffer[out]`, which translates to `ptr[out, array[int8]]`. So I need to pass a *pointer to an array*.
Alright, let's see, what if I try `&(0x7f0000000200)=[]`? Let's give it a shot with `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)=[], 100)`. No, it still fails to parse that argument. Wait, if argument 1 is `&(0x7f0000000200)=[]`, then the `100` becomes the second argument. Okay, let me try a different approach, `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)="", 100)`. Wait, no, `""` is a string, not an array.
Okay, let's try `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)=ANY, 100)`? Nope, that didn't work. How about `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)=""/100, 100)`? Still no good. Maybe `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)=ANY, 0x100)`? Nope. What about `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200), 0x100)`? Nope.
Wait a second, let me check the `sys.txt` definition for `readlink`: `readlink(path ptr[in, filename], buf buffer[out], siz len[buf])`. Ah, right, the `siz` argument is `len[buf]`. Syzkaller should handle filling that automatically, so I shouldn't have to specify that, right? But... if I *don't* specify it, I get "missing syscall args". So... I *do* have to provide 3 arguments!
Okay, if I provide three arguments, I get "failed to parse argument at '1' ". That means the problem lies with argument 1 (which is `buf`). Why is `&(0x7f0000000200)` failing to parse as a `buffer[out]`? Ah, because `buffer[out]` is a `ptr[out, array[int8]]`. Passing `&(0x7f0000000200)` is just the pointer; I need to specify what it points *to*! For an array, I should be able to use `""` or `[]`. But again, if I pass `&(0x7f0000000200)=""`, it still fails to parse argument 1. Let's try `readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)="", 100)` again. I'm missing something, clearly.
|
| 30/2 |
2026/03/10 03:23 |
tool |
crash-reproducer |
0m
Error:
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)="", 100)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 31/2 |
2026/03/10 03:23 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 51245
output: 144
thoughts: 225
Thoughts: **Debugging the Argument Parsing**
Okay, so I'm getting this cryptic error: "failed to parse argument at '1'." My first instinct is, argument one is the problem. But the error seems to point at "100"! What's the deal with "ERROR!!!100"? Aha! That means arguments zero and one *did* parse successfully, but argument two is the issue. And argument two is, in fact, "100".
Now, why would "100" fail to parse? Could it be that "100" isn't a valid argument for `len[buf]`? Wait a minute...isn't `len[buf]` supposed to be automatically calculated? We shouldn't *need* to pass it! But if we *don't* pass it, the system complains about missing syscall arguments. It's a classic catch-22.
So, if I *do* pass "100," it fails. Okay, let's think...the argument parsing notes say "const-arg = '0x' hex-integer." Right! "100" is *not* a valid `const-arg`! It's not prefixed with "0x"! Let me try "0x64". That should work!
|
| 32/2 |
2026/03/10 03:23 |
tool |
crash-reproducer |
0m
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)="", 0x64)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 33/2 |
2026/03/10 03:23 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 51917
output: 251
thoughts: 327
Thoughts: **Debugging a Data Race**
Okay, the parser didn't crash, which is great, but also means I need to make the race condition more likely to trigger. I need to increase the probability of it happening. Using `fail_nth` won't work here since this is a *data race* and not just a deterministic failure scenario. So, the approach here is to get it to happen, either via running the target code in a loop or by leveraging `async` with multiple threads.
Aha! I think I've spotted the race condition: it's between `unlink` and `readlink`. If the link is removed just as `readlink` is executed, it leads to a race. The program attempts to read a file that has just been unlinked. My strategy here is to add multiple calls to both `readlink` and `unlink`. So, create a symbolic link, unlink it asynchronously and then have three threads run `readlink` asynchronously at the same time. The goal is to maximize the overlap and the chance that `readlink` sees the link in the process of being removed. That should force the issue! Let's see if this works.
|
| 34/2 |
2026/03/10 03:23 |
tool |
crash-reproducer |
0m
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)="", 0x64) (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)="", 0x64) (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)="", 0x64) (async)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 35/2 |
2026/03/10 03:23 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 52767
output: 39
thoughts: 127
Thoughts: **Debugging a Persistent Issue**
Okay, still no crash, which is frustrating. I'm going through the call stack again, and I've just realized something potentially significant. Hang on, wasn't `d_make_discardable` called from `shmem_unlink`? Right, it was. Now, a thought: could this issue be related to `symlink` calls somehow creating shmem symlinks?
Hmm, yes, that's possible, especially if the current directory is a tmpfs mount. But then I'm reminded that `shmem_unlink` is also used for `unlink` operations on *any* file within tmpfs. Wait, does that mean `shmem_unlink` gets called for `unlink` on *symlinks*?
Yes! Of course, `unlink` can remove a symlink. It's not just regular files. Okay, so that means `shmem_unlink` is called for *any* file type within tmpfs, including symlinks. That might be the key to it. I need to take a closer look at the `shmem_unlink` function itself. Let's see what's going on there.
|
| 36/2 |
2026/03/10 03:23 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:mm/shmem.c IncludeLines:true Name:shmem_unlink]
Results: map[SourceCode:3994: static int shmem_unlink(struct inode *dir, struct dentry *dentry)
3995: {
3996: struct inode *inode = d_inode(dentry);
3997:
3998: if (inode->i_nlink > 1 && !S_ISDIR(inode->i_mode))
3999: shmem_free_inode(inode->i_sb, 0);
4000:
4001: simple_offset_remove(shmem_get_offset_ctx(dir), dentry);
4002:
4003: dir->i_size -= BOGO_DIRENT_SIZE;
4004: inode_inc_iversion(dir);
4005: simple_unlink(dir, dentry);
4006:
4007: /*
4008: * For now, VFS can't deal with case-insensitive negative dentries, so
4009: * we invalidate them
4010: */
4011: if (IS_ENABLED(CONFIG_UNICODE) && IS_CASEFOLDED(dir))
4012: d_invalidate(dentry);
4013:
4014: return 0;
4015: }
SourceFile:mm/shmem.c]
|
| 37/2 |
2026/03/10 03:23 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 53547
output: 38
thoughts: 15
Thoughts: Okay, here's my interpretation of those thoughts, summarized in the first person, assuming an expert-level understanding:
**Unraveling the `simple_unlink` Mystery**
Alright, so the focus is on `simple_unlink`. My initial thought is that I need to quickly grasp its role in this context. And I see it, I see that this `simple_unlink` function is calling `d_make_discardable`. It makes me wonder, given that calling this function, the link suggests that the unlink process involves making something discardable. That's a key piece of the puzzle. I'm immediately trying to connect this with the broader system design. What's being "unlinked" and *why* does it need to be made discardable? Are we talking about freeing up resources, managing cache entries, optimizing disk access, or something else entirely? The connection itself suggests this action might be very specific or related to optimization. It's that immediate next step in understanding. I need to dig deeper into the relationship to fully grasp the implication. The function `d_make_discardable` must be a function that does exactly what it says. I see a link!
|
| 38/2 |
2026/03/10 03:23 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:fs/libfs.c IncludeLines:true Name:simple_unlink]
Results: map[SourceCode: 806: int simple_unlink(struct inode *dir, struct dentry *dentry)
807: {
808: __simple_unlink(dir, dentry);
809: d_make_discardable(dentry);
810: return 0;
811: }
SourceFile:fs/libfs.c]
|
| 39/2 |
2026/03/10 03:23 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 53961
output: 1074
thoughts: 510
Thoughts: **Analyzing a Potential Data Race in tmpfs and Symlink Handling**
Okay, so I'm digging into this `unlink` behavior on a tmpfs file, and it looks like the call to `unlink` triggers `d_make_discardable`. My initial thought is that there might be a race condition between `d_make_discardable` and `do_readlinkat`. Now, `do_readlinkat` is called from `readlink`, so let's trace that. `readlink` goes through `filename_lookup` which returns a `path`. Then it checks `d_is_symlink` on the `dentry` from that path.
The crux of the matter is, if `unlink` happens concurrently with `readlink`, then `d_make_discardable` will modify `dentry->d_flags` while `readlink` is in the process of reading it. That *should* be a data race, right? But the question is, why hasn't this triggered already? Perhaps the timing window for the race is just too narrow to reliably catch.
To make the race more likely to occur, I need to force them to run concurrently, and in multiple threads. `syz_clone` is the usual approach for that. Wait, `async` already does that. Ok, let's try a loop to increase the likelihood: `symlink`, `unlink`, and `readlink`. This should repeatedly hit the conflicting code path. The problem is I can't do a loop directly in syzlang, but I can mimic it by repeating the calls several times.
Okay, here's what I'm thinking: multiple symlinks, and race them. We'll run several sequences like this:
```
symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link\x00')
unlink(&(0x7f0000000100)='link\x00') (async)
readlink(&(0x7f0000000100)='link\x00', &(0x7f0000000200)="", 0x64) (async)
symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link1\x00')
unlink(&(0x7f0000000100)='link1\x00') (async)
readlink(&(0x7f0000000100)='link1\x00', &(0x7f0000000200)="", 0x64) (async)
```
The key is that `readlink` might be executed either before or after the `unlink`, which is what I want. This should maximize the chances of exposing the race.
|
| 40/2 |
2026/03/10 03:23 |
tool |
crash-reproducer |
0m
Args: map[ReproSyz:symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000100)='link0\x00')
symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000110)='link1\x00')
symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000120)='link2\x00')
symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000130)='link3\x00')
symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000140)='link4\x00')
symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000150)='link5\x00')
symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000160)='link6\x00')
symlink(&(0x7f0000000000)='target\x00', &(0x7f0000000170)='link7\x00')
unlink(&(0x7f0000000100)='link0\x00') (async)
readlink(&(0x7f0000000100)='link0\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000110)='link1\x00') (async)
readlink(&(0x7f0000000110)='link1\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000120)='link2\x00') (async)
readlink(&(0x7f0000000120)='link2\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000130)='link3\x00') (async)
readlink(&(0x7f0000000130)='link3\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000140)='link4\x00') (async)
readlink(&(0x7f0000000140)='link4\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000150)='link5\x00') (async)
readlink(&(0x7f0000000150)='link5\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000160)='link6\x00') (async)
readlink(&(0x7f0000000160)='link6\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000170)='link7\x00') (async)
readlink(&(0x7f0000000170)='link7\x00', &(0x7f0000000200)="", 0x64) (async)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 41/2 |
2026/03/10 03:23 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 56241
output: 248
thoughts: 1008
Thoughts: **Analyzing the Race Condition in the Kernel**
Okay, still no crash, which is frustrating. Let me go back and thoroughly re-examine this bug report. It's showing a write to the memory location `0xffff888107ad6840` from task 3306 and a read from the same location by task 3001. The write is `dentry->d_flags &= ~DCACHE_PERSISTENT;` and the read is `dentry->d_flags & DCACHE_ENTRY_TYPE;`. This strongly suggests a data race. The reported stack traces point to `unlink` and `readlink` operations, specifically related to dcache and filesystem metadata.
KCSAN data-race reports can be tricky to trigger since the window for the race condition is often incredibly small. To make it happen I need to ensure the two threads are accessing the same memory location concurrently. I'm thinking, since the syzkaller executor runs programs in a loop, I might be able to simply provide a straightforward program and have syzkaller run it in its threaded mode. And yes, syzkaller automatically runs it in threaded mode if I mark the calls as `async`.
However, the executor has a limit on the number of threads (16). Let's see... If I use 8 `unlink` calls and 8 `readlink` calls, all set to `async`, they should execute concurrently, right? But it still didn't trigger!
Ah, I bet I know what it is. Maybe the symlink isn't in tmpfs? I should check and make sure that it's in a temporary file system to make sure that these concurrent operations will play nice together in the same namespace. Syzkaller's current directory is usually a tmpfs, but I want to be *certain*. So, I will explicitly mount a tmpfs and do the operation there.
Okay, let's try this. I'll first `mkdir` a directory named `tmp`. Then mount tmpfs on `tmp`. Now I create a symlink named `link` to `target` inside the `tmp` directory. Finally, I perform the `unlink` and `readlink` on that link, both `async`. That should do the trick.
```
mkdir(&(0x7f0000000000)='./tmp\x00', 0x1ff)
mount(0x0, &(0x7f0000000000)='./tmp\x00', &(0x7f0000000040)='tmpfs\x00', 0x0, 0x0)
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./tmp/link\x00')
unlink(&(0x7f00000000c0)='./tmp/link\x00') (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)
```
Hopefully this will force the race.
|
| 42/2 |
2026/03/10 03:24 |
tool |
crash-reproducer |
0m
Args: map[ReproSyz:mkdir(&(0x7f0000000000)='./tmp\x00', 0x1ff)
mount(0x0, &(0x7f0000000000)='./tmp\x00', &(0x7f0000000040)='tmpfs\x00', 0x0, 0x0)
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./tmp/link\x00')
unlink(&(0x7f00000000c0)='./tmp/link\x00') (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 43/2 |
2026/03/10 03:24 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 58253
output: 17
thoughts: 263
Thoughts: **Debugging the Persistent Non-Crash**
Okay, still no crash. That's frustrating. Let's dig into this `mount` function call within `sys.txt`. I need to understand this specific call. Okay, the function signature is `mount(source ptr[in, filename, opt], target ptr[in, filename], filesystemtype ptr[in, string], mountflags flags[mount_flags], data ptr[in, array[int8], opt])`.
Ah, here's the problematic call: `mount(0x0, &(0x7f0000000000)='./tmp\x00', &(0x7f0000000040)='tmpfs\x00', 0x0, 0x0)`. So, the `source` and `data` arguments are both `0x0`. That *should* be equivalent to `nil` for those pointers, meaning an absence of a source file/device and absence of mount-specific data, respectively.
Hold on... I'm thinking... If I use `0x0` for both of those arguments, given that it is being interpreted as a `const-arg` the `nil` will need to be passed as a `nil`? So, `0x0` should be fine, and I could even use `0`.
Hang on a second... is `mount` even defined in `sys.txt`? Let me double-check. Did I get my files mixed up? Is it in `filesystem.txt` instead? No, back to `sys.txt`, let me reconfirm its definition there.
|
| 44/2 |
2026/03/10 03:24 |
tool |
grepper |
0m
Error:
Args:
Results:
|
| 45/2 |
2026/03/10 03:24 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 58904
output: 18
thoughts: 18
Thoughts: Okay, here's the summary, rendered as your internal thought process:
**Navigating the File System**
Alright, so I'm looking for the relevant command, and it seems like the `mount` command I'm after is probably listed in `filesystem.txt`. Makes sense, considering what I know about how these things are typically organized. Let's pull that file up and get to work. I need to refresh my memory on the specific syntax and any relevant options listed there. Time to dive in and get the details.
|
| 46/2 |
2026/03/10 03:24 |
tool |
read-description |
0m
Args:
Results: map[Output:# Copyright 2018 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
include <uapi/linux/mount.h>
include <linux/fs.h>
include <linux/fcntl.h>
mount(src ptr[in, blockdev_filename], dst ptr[in, filename], type ptr[in, string[filesystem]], flags flags[mount_flags], data ptr[in, string, opt])
umount2(path ptr[in, filename], flags flags[umount_flags])
mount$bpf(src const[0], dst ptr[in, filename], type ptr[in, string["bpf"]], flags flags[mount_flags], opts ptr[in, fs_options[bpf_options]])
mount$overlay(src const[0], dst ptr[in, filename], type ptr[in, string["overlay"]], flags flags[mount_flags], opts ptr[in, fs_options[overlay_options]])
mount$binder(src const[0], dst ptr[in, filename], type ptr[in, string["binder"]], flags flags[mount_flags], opts ptr[in, fs_options[binder_options]])
mount$tmpfs(src const[0], dst ptr[in, filename], type ptr[in, string["tmpfs"]], flags flags[mount_flags], opts ptr[in, fs_options[tmpfs_options]])
mount$cgroup(src const[0], dst ptr[in, filename], type ptr[in, string["cgroup"]], flags flags[mount_flags], opts ptr[in, fs_options[cgroup_options]])
mount$cgroup2(src const[0], dst ptr[in, filename], type ptr[in, string["cgroup2"]], flags flags[mount_flags], opts ptr[in, fs_options[cgroup2_options]])
mount$afs(src ptr[in, afs_source], dst ptr[in, filename], type ptr[in, string["afs"]], flags flags[mount_flags], opts ptr[in, fs_options[afs_options]])
# A bind mount ignores the filesystem type argument, but
# pkg/host/syscalls_linux.go:isSupportedFilesystem() requires one in
# /proc/filesystems. Use a common and valid filesystem string ("pipefs") to
# pass the check.
mount$bind(src ptr[in, filename], dst ptr[in, filename], type ptr[in, string["pipefs"]], flags flags[mount_flags], data const[0])
# esdfs is ChromeOS-specific:
# https://chromium.googlesource.com/chromiumos/third_party/kernel/+/d2c1fb9fcdb53%5E%21/
mount$esdfs(src ptr[in, filename], dst ptr[in, filename], type ptr[in, string["esdfs"]], flags flags[mount_flags], opts ptr[in, fs_options[esdfs_options]])
# TODO: pvfs2 requires some device/source, but it looks unused:
# https://elixir.bootlin.com/linux/v6.1-rc6/source/fs/orangefs/super.c#L488
# Instead it sends requests to some pvfs2-req character device,
# and somebody is supposed to answer these requests with ioctls.
# But the deivce is not even created in /dev, somebody is supposed to mknod it.
# And it's major number is unknown (printed to console in debug mode only):
# https://elixir.bootlin.com/linux/v6.1-rc6/source/fs/orangefs/devorangefs-req.c#L803
# It does not look usable.
mount$pvfs2(src ptr[in, string["unused"]], dst ptr[in, filename], type ptr[in, string["pvfs2"]], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]])
# TODO: nfs source is "hostname:export_path", but we also needs to setup port,
# protocol and other options, and most importantly we need the server to reply to RPCs.
# There is something called nfsd (fs/nfsd) which may help and which we need to test as well.
mount$nfs(src ptr[in, string], dst ptr[in, filename], type ptr[in, string["nfs"]], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]])
mount$nfs4(src ptr[in, string], dst ptr[in, filename], type ptr[in, string["nfs4"]], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]])
resource fd_fscontext[fd]
fsopen(type ptr[in, string[filesystem]], flags flags[fsopen_flags]) fd_fscontext
fspick(dfd fd_dir[opt], path ptr[in, filename], flags flags[fspick_flags]) fd_fscontext
fsconfig$FSCONFIG_SET_FLAG(fd fd_fscontext, cmd const[FSCONFIG_SET_FLAG], key ptr[in, string[fsconfig_flag_params]], value const[0], aux const[0])
fsconfig$FSCONFIG_SET_STRING(fd fd_fscontext, cmd const[FSCONFIG_SET_STRING], key ptr[in, string], value ptr[in, string], aux const[0])
fsconfig$FSCONFIG_SET_BINARY(fd fd_fscontext, cmd const[FSCONFIG_SET_BINARY], key ptr[in, string], value ptr[in, array[int8]], aux bytesize[value])
fsconfig$FSCONFIG_SET_PATH(fd fd_fscontext, cmd const[FSCONFIG_SET_PATH], key ptr[in, string], value ptr[in, filename], aux fd_dir[opt])
fsconfig$FSCONFIG_SET_PATH_EMPTY(fd fd_fscontext, cmd const[FSCONFIG_SET_PATH_EMPTY], key ptr[in, string], value ptr[in, filename], aux fd_dir[opt])
fsconfig$FSCONFIG_SET_FD(fd fd_fscontext, cmd const[FSCONFIG_SET_FD], key ptr[in, string], value const[0], aux fd)
fsconfig$FSCONFIG_CMD_CREATE(fd fd_fscontext, cmd const[FSCONFIG_CMD_CREATE], key const[0], value const[0], aux const[0])
fsconfig$FSCONFIG_CMD_RECONFIGURE(fd fd_fscontext, cmd const[FSCONFIG_CMD_RECONFIGURE], key const[0], value const[0], aux const[0])
fsmount(fs_fd fd_fscontext, flags flags[fsmount_flags], attr_flags flags[fsmount_attr_flags]) fd
move_mount(from_dfd fd_dir[opt], from_pathname ptr[in, filename], to_dfd fd_dir[opt], to_pathname ptr[in, filename], flags flags[move_mount_flags])
open_tree(dfd fd_dir[opt], filename ptr[in, filename], flags flags[open_tree_flags]) fd
mount_setattr(dfd fd_dir[opt], filename ptr[in, filename], flags flags[mount_setattr_flags], args ptr[in, mount_attr], size bytesize[args])
open_tree_flags = AT_EMPTY_PATH, AT_NO_AUTOMOUNT, AT_RECURSIVE, AT_SYMLINK_NOFOLLOW, OPEN_TREE_CLONE, OPEN_TREE_CLOEXEC
mount_setattr_flags = AT_EMPTY_PATH, AT_NO_AUTOMOUNT, AT_RECURSIVE, AT_SYMLINK_NOFOLLOW
mount_attr {
attr_set flags[mount_attr_flags, int64]
attr_clr flags[mount_attr_flags, int64]
propagation flags[mount_attr_propagation_flags, int64]
userns_fd align64[fd_userns]
}
mount_attr_flags = MOUNT_ATTR_IDMAP, fsmount_attr_flags
mount_attr_propagation_flags = MS_UNBINDABLE, MS_PRIVATE, MS_SLAVE, MS_SHARED
fsmount_flags = FSMOUNT_CLOEXEC
fsopen_flags = FSOPEN_CLOEXEC
fspick_flags = FSPICK_CLOEXEC
fsmount_attr_flags = MOUNT_ATTR_RDONLY, MOUNT_ATTR_NOSUID, MOUNT_ATTR_NODEV, MOUNT_ATTR_NOEXEC, MOUNT_ATTR__ATIME, MOUNT_ATTR_NODIRATIME
move_mount_flags = MOVE_MOUNT_F_SYMLINKS, MOVE_MOUNT_F_AUTOMOUNTS, MOVE_MOUNT_F_EMPTY_PATH, MOVE_MOUNT_T_SYMLINKS, MOVE_MOUNT_T_AUTOMOUNTS, MOVE_MOUNT_T_EMPTY_PATH, MOVE_MOUNT_SET_GROUP, MOVE_MOUNT_BENEATH
fsconfig_flag_params = "dirsync", "lazytime", "mand", "posixacl", "ro", "sync", "async", "nolazytime", "nomand", "rw", "silent"
filesystem = "sysfs", "rootfs", "ramfs", "tmpfs", "devtmpfs", "debugfs", "securityfs", "sockfs", "pipefs", "anon_inodefs", "devpts", "hugetlbfs", "vfat", "ecryptfs", "fuseblk", "fuse", "rpc_pipefs", "nfs", "nfs4", "nfsd", "binfmt_misc", "autofs", "xfs", "jfs", "msdos", "ntfs", "ntfs3", "minix", "hfs", "hfsplus", "qnx4", "ufs", "btrfs", "configfs", "ncpfs", "qnx6", "exofs", "befs", "vxfs", "gfs2", "gfs2meta", "fusectl", "bfs", "nsfs", "efs", "cifs", "efivarfs", "affs", "tracefs", "bdev", "ocfs2", "ocfs2_dlmfs", "hpfs", "proc", "afs", "reiserfs", "jffs2", "romfs", "aio", "sysv", "v7", "udf", "ceph", "pstore", "adfs", "9p", "hostfs", "squashfs", "cramfs", "iso9660", "coda", "nilfs2", "logfs", "overlay", "f2fs", "omfs", "ubifs", "openpromfs", "bpf", "cgroup", "cgroup2", "cpuset", "mqueue", "aufs", "selinuxfs", "dax", "erofs", "virtiofs", "exfat", "binder", "zonefs", "pvfs2", "incremental-fs", "esdfs", "smb3", "gadgetfs", ext4_types
blockdev_filename [
filename filename
nbd nbd_filename
loop loop_filename
nullb string["/dev/nullb0"]
rnullb string["/dev/rnullb0"]
md0 string["/dev/md0"]
sg0 string["/dev/sg0"]
sr0 string["/dev/sr0"]
] [varlen]
nbd_filename {
prefix stringnoz["/dev/nbd"]
# NEED: this does not support formatting numbers larger than 9.
id proc['0', 1, int8]
z const[0, int8]
} [packed]
loop_filename {
prefix stringnoz["/dev/loop"]
# NEED: this does not support formatting numbers larger than 9.
id proc['0', 1, int8]
z const[0, int8]
} [packed]
syz_read_part_table(size len[img], img ptr[in, compressed_image]) (timeout[200], no_generate, no_minimize)
define SYZ_MOUNT_IMAGE_TIMEOUT 4000
syz_mount_image$vfat(fs ptr[in, string["vfat"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[vfat_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.vfat -n"])
syz_mount_image$msdos(fs ptr[in, string["msdos"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[msdos_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.msdos -n"])
syz_mount_image$bfs(fs ptr[in, string["bfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$xfs(fs ptr[in, string["xfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[xfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["xfs_repair -n"])
syz_mount_image$minix(fs ptr[in, string["minix"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.minix"])
syz_mount_image$reiserfs(fs ptr[in, string["reiserfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[reiserfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.reiserfs -n"])
syz_mount_image$hfs(fs ptr[in, string["hfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[hfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$hfsplus(fs ptr[in, string["hfsplus"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[hfsplus_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$iso9660(fs ptr[in, string["iso9660"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[iso9660_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$gfs2(fs ptr[in, string["gfs2"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[gfs2_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.gfs2 -n"])
syz_mount_image$jfs(fs ptr[in, string["jfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[jfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.jfs -n"])
syz_mount_image$btrfs(fs ptr[in, string["btrfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[btrfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["btrfsck --readonly"])
syz_mount_image$ntfs(fs ptr[in, string["ntfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ntfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$ntfs3(fs ptr[in, string["ntfs3"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ntfs3_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$ext4(fs ptr[in, string[ext4_types]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ext4_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.ext4 -n"])
syz_mount_image$f2fs(fs ptr[in, string["f2fs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[f2fs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.f2fs"])
syz_mount_image$ocfs2(fs ptr[in, string["ocfs2"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ocfs2_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.ocfs2 -n"])
syz_mount_image$erofs(fs ptr[in, string["erofs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[erofs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.erofs"])
syz_mount_image$exfat(fs ptr[in, string["exfat"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[exfat_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.exfat -n"])
syz_mount_image$cramfs(fs ptr[in, string["cramfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.cramfs"])
syz_mount_image$romfs(fs ptr[in, string["romfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$efs(fs ptr[in, string["efs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$jffs2(fs ptr[in, string["jffs2"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[jffs2_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$nilfs2(fs ptr[in, string["nilfs2"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[nilfs2_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$squashfs(fs ptr[in, string["squashfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[squashfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$udf(fs ptr[in, string["udf"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[udf_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$bcachefs(fs ptr[in, string["bcachefs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[bcachefs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
# TODO: zonefs needs a zoned block device:
# https://elixir.bootlin.com/linux/v6.1-rc6/source/fs/zonefs/super.c#L1768
# So currnetly the mount always fails.
# These docs say such devices can be emulated with nullb, but need special setup:
# https://zonedstorage.io/docs/getting-started/zbd-emulation
# https://btrfs.wiki.kernel.org/index.php/Zoned
syz_mount_image$zonefs(fs ptr[in, string["zonefs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[zonefs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
# TODO: ubifs needs a special ubi device:
# https://elixir.bootlin.com/linux/v6.1-rc6/source/fs/ubifs/super.c#L2063
# So currnetly the mount always fails.
syz_mount_image$ubifs(fs ptr[in, string["ubifs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ubifs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
# TODO: add mount options for the following file systems.
syz_mount_image$adfs(fs ptr[in, string["adfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[adfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$affs(fs ptr[in, string["affs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[affs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$befs(fs ptr[in, string["befs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$vxfs(fs ptr[in, string["vxfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[vxfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$omfs(fs ptr[in, string["omfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[omfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$hpfs(fs ptr[in, string["hpfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[hpfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$qnx4(fs ptr[in, string["qnx4"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$qnx6(fs ptr[in, string["qnx6"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[qnx6_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$sysv(fs ptr[in, string["sysv"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$ufs(fs ptr[in, string["ufs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ufs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$gfs2meta(fs ptr[in, string["gfs2meta"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$v7(fs ptr[in, string["v7"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
# Note: tmpfs does not need an image, but we use this in tests.
syz_mount_image$tmpfs(fs ptr[in, string["tmpfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[tmpfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
type fs_options[ELEMS] {
elems array[fs_opt_elem[ELEMS]]
common array[fs_opt_elem[fs_options_common]]
null const[0, int8]
} [packed]
type fs_opt_elem[ELEMS] {
elem ELEMS
comma const[',', int8]
} [packed]
type fs_opt[NAME, TYPE] {
name stringnoz[NAME]
eq const['=', int8]
val TYPE
} [packed]
type fs_opt_nodelim[NAME, TYPE] {
name stringnoz[NAME]
val TYPE
} [packed]
type fs_opt_str[NAME] fs_opt[NAME, stringnoz]
type fs_opt_dec[NAME, VAL] fs_opt[NAME, fmt[dec, VAL]]
type fs_opt_hex[NAME, VAL] fs_opt[NAME, fmt[hex, VAL]]
type fs_opt_oct[NAME, VAL] fs_opt[NAME, fmt[oct, VAL]]
type fs_opt_dec_suffix[NAME] fs_opt[NAME, array[flags[fs_opt_digits_suffix, int8]]]
type fs_opt_filename[NAME] fs_opt[NAME, stringnoz[filename]]
type fs_opt_codepage[NAME] fs_opt[NAME, stringnoz[codepages_names]]
type fs_opt_cp_num[NAME] fs_opt[NAME, stringnoz[codepage_nums]]
fs_opt_digits_suffix = '-', 'x', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'k', 'm', 'g', 't', 'p', 'e', '%'
fs_options_common [
flag stringnoz[fsconfig_flag_params]
# SELinux options:
context fs_opt["context", stringnoz[selinux_user_context]]
fscontext fs_opt["fscontext", stringnoz[selinux_user_context]]
rootcontext fs_opt["rootcontext", stringnoz[selinux_user_context]]
defcontext fs_opt["defcontext", stringnoz[selinux_user_context]]
seclabel stringnoz["seclabel"]
# Smack options:
smackfsdef fs_opt_str["smackfsdef"]
smackfsfloor fs_opt_str["smackfsfloor"]
smackfshat fs_opt_str["smackfshat"]
smackfsroot fs_opt_str["smackfsroot"]
smackfstransmute fs_opt_str["smackfstransmute"]
# IMA options:
measure stringnoz["measure"]
dont_measure stringnoz["dont_measure"]
appraise stringnoz["appraise"]
dont_appraise stringnoz["dont_appraise"]
audit stringnoz["audit"]
hash stringnoz["hash"]
dont_hash stringnoz["dont_hash"]
permit_directio stringnoz["permit_directio"]
obj_user fs_opt_str["obj_user"]
obj_role fs_opt_str["obj_role"]
obj_type fs_opt_str["obj_type"]
subj_user fs_opt_str["subj_user"]
subj_role fs_opt_str["subj_role"]
subj_type fs_opt_str["subj_type"]
func fs_opt["func", stringnoz[ima_funcs]]
mask fs_opt["mask", stringnoz[ima_masks]]
fsmagic fs_opt_hex["fsmagic", intptr]
fsname fs_opt_str["fsname"]
fsuuid fs_opt["fsuuid", uuid_str]
uid_eq fs_opt_dec["uid", uid]
euid_eq fs_opt_dec["euid", uid]
fowner_eq fs_opt_dec["fowner", uid]
uid_gt fs_opt_nodelim["uid>", fmt[dec, uid]]
euid_gt fs_opt_nodelim["euid>", fmt[dec, uid]]
fowner_gt fs_opt_nodelim["fowner>", fmt[dec, uid]]
uid_lt fs_opt_nodelim["uid<", fmt[dec, uid]]
euid_lt fs_opt_nodelim["euid<", fmt[dec, uid]]
fowner_lt fs_opt_nodelim["fowner<", fmt[dec, uid]]
appraise_type stringnoz["appraise_type=imasig"]
pcr fs_opt_dec["pcr", int64[0:64]]
] [varlen]
uuid_str {
p0 array[flags[hex_chars, int8], 8]
d0 const['-', int8]
p1 array[flags[hex_chars, int8], 4]
d1 const['-', int8]
p2 array[flags[hex_chars, int8], 4]
d2 const['-', int8]
p3 array[flags[hex_chars, int8], 4]
d3 const['-', int8]
p4 array[flags[hex_chars, int8], 8]
}
hex_chars = '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
ima_funcs = "FILE_CHECK", "PATH_CHECK", "MODULE_CHECK", "FIRMWARE_CHECK", "FILE_MMAP", "MMAP_CHECK", "BPRM_CHECK", "CREDS_CHECK", "KEXEC_KERNEL_CHECK", "KEXEC_INITRAMFS_CHECK", "POLICY_CHECK"
ima_masks = "MAY_EXEC", "MAY_WRITE", "MAY_READ", "MAY_APPEND", "^MAY_EXEC", "^MAY_WRITE", "^MAY_READ", "^MAY_APPEND"
msdos_options [
fat fat_options
nodots stringnoz["nodots"]
dots stringnoz["dots"]
] [varlen]
vfat_options [
fat fat_options
iocharset fs_opt_codepage["iocharset"]
rodir stringnoz["rodir"]
utf8no stringnoz["utf8=0"]
utf8 stringnoz["utf8=1"]
uni_xlateno stringnoz["uni_xlate=0"]
uni_xlate stringnoz["uni_xlate=1"]
numtail stringnoz["nonumtail=0"]
nonumtail stringnoz["nnonumtail=1"]
shortname_lower stringnoz["shortname=lower"]
shortname_win95 stringnoz["shortname=win95"]
shortname_winnt stringnoz["shortname=winnt"]
shortname_mixed stringnoz["shortname=mixed"]
] [varlen]
fat_options [
check_relaxed stringnoz["check=relaxed"]
check_strict stringnoz["check=strict"]
check_normal stringnoz["check=normal"]
usefree stringnoz["usefree"]
nocase stringnoz["nocase"]
quiet stringnoz["quiet"]
showexec stringnoz["showexec"]
debug stringnoz["debug"]
sys_immutable stringnoz["sys_immutable"]
flush stringnoz["flush"]
tz_utc stringnoz["tz=UTC"]
errors_continue stringnoz["errors=continue"]
errors_remount stringnoz["errors=remount-ro"]
discard stringnoz["discard"]
nfs stringnoz["nfs"]
nfs_nostale_ro stringnoz["nfs=nostale_ro"]
nfs_stale_rw stringnoz["nfs=stale_rw"]
dos1xfloppy stringnoz["dos1xfloppy"]
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
umask fs_opt_oct["umask", int32]
dmask fs_opt_oct["dmask", int32]
fmask fs_opt_oct["fmask", int32]
allow_utime fs_opt_oct["allow_utime", int32]
time_offset fs_opt_hex["time_offset", int32[-1440:1440]]
codepage fs_opt_cp_num["codepage"]
] [varlen]
xfs_options [
wsync stringnoz["wsync"]
noalign stringnoz["noalign"]
swalloc stringnoz["swalloc"]
nouuid stringnoz["nouuid"]
mtpt stringnoz["mtpt"]
grpid stringnoz["grpid"]
nogrpid stringnoz["nogrpid"]
bsdgroups stringnoz["bsdgroups"]
sysvgroups stringnoz["sysvgroups"]
norecovery stringnoz["norecovery"]
inode64 stringnoz["inode64"]
inode32 stringnoz["inode32"]
ikeep stringnoz["ikeep"]
noikeep stringnoz["noikeep"]
largeio stringnoz["largeio"]
nolargeio stringnoz["nolargeio"]
attr2 stringnoz["attr2"]
noattr2 stringnoz["noattr2"]
filestreams stringnoz["filestreams"]
quota stringnoz["quota"]
noquota stringnoz["noquota"]
lazytime stringnoz["lazytime"]
nolazytime stringnoz["nolazytime"]
usrquota stringnoz["usrquota"]
grpquota stringnoz["grpquota"]
prjquota stringnoz["prjquota"]
uquota stringnoz["uquota"]
gquota stringnoz["gquota"]
pquota stringnoz["pquota"]
uqnoenforce stringnoz["uqnoenforce"]
gqnoenforce stringnoz["gqnoenforce"]
pqnoenforce stringnoz["pqnoenforce"]
qnoenforce stringnoz["qnoenforce"]
discard stringnoz["discard"]
nodiscard stringnoz["nodiscard"]
dax stringnoz["dax"]
dax_inode stringnoz["dax=inode"]
dax_always stringnoz["dax=always"]
dax_never stringnoz["dax=never"]
barrier stringnoz["barrier"]
nobarrier stringnoz["nobarrier"]
logbufs fs_opt_dec["logbufs", int32[-1:8]]
biosize fs_opt_dec["biosize", int32]
sunit fs_opt_hex["sunit", int32]
swidth fs_opt_hex["swidth", int32]
logbsize fs_opt_dec_suffix["logbsize"]
allocsize fs_opt_dec_suffix["allocsize"]
logdev fs_opt_filename["logdev"]
rtdev fs_opt_filename["rtdev"]
] [varlen]
reiserfs_options [
tails_on stringnoz["tails=on"]
tails_off stringnoz["tails=off"]
tails_small stringnoz["tails=small"]
notail stringnoz["notail"]
conv stringnoz["conv"]
noattrs stringnoz["noattrs"]
expose_privroot stringnoz["expose_privroot"]
user_xattr stringnoz["user_xattr"]
nouser_xattr stringnoz["nouser_xattr"]
acl stringnoz["acl"]
noacl stringnoz["noacl"]
replayonly stringnoz["replayonly"]
nolargeio stringnoz["nolargeio"]
usrquota stringnoz["usrquota"]
grpquota stringnoz["grpquota"]
noquota stringnoz["noquota"]
usrjquota stringnoz["usrjquota"]
usrjquota_file stringnoz["usrjquota=syz"]
grpjquota stringnoz["grpjquota"]
commit fs_opt_hex["commit", int32]
resize fs_opt_hex["resize", int32]
resize_auto stringnoz["resize=auto"]
jdev fs_opt_filename["jdev"]
jqfmt_vfsold stringnoz["jqfmt=vfsold"]
jqfmt_vfsv0 stringnoz["jqfmt=vfsv0"]
hash_tea stringnoz["hash=tea"]
hash_rupasov stringnoz["hash=rupasov"]
hash_r5 stringnoz["hash=r5"]
balloc_noborder stringnoz["block-allocator=noborder"]
balloc_border stringnoz["block-allocator=border"]
balloc_no_unhash_reloc stringnoz["block-allocator=no_unhashed_relocation"]
balloc_hashed_reloc stringnoz["block-allocator=hashed_relocation"]
balloc_test4 stringnoz["block-allocator=test4"]
balloc_notest4 stringnoz["block-allocator=notest4"]
barrier_none stringnoz["barrier=none"]
barrier_flush stringnoz["barrier=flush"]
data_ordered stringnoz["data=ordered"]
data_journal stringnoz["data=journal"]
data_writeback stringnoz["data=writeback"]
errors_continue stringnoz["errors=continue"]
errors_ro_remount stringnoz["errors=ro-remount"]
] [varlen]
hfs_options [
quiet stringnoz["quiet"]
umask fs_opt_oct["umask", int32]
file_umask fs_opt_oct["file_umask", int32]
dir_umask fs_opt_oct["dir_umask", int32]
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
part fs_opt_hex["part", int32]
session fs_opt_hex["session", int32]
type fs_opt["type", array[int8, 4]]
creator fs_opt["creator", array[int8, 4]]
codepage fs_opt_codepage["codepage"]
iocharset fs_opt_codepage["iocharset"]
] [varlen]
hfsplus_options [
decompose stringnoz["decompose"]
nodecompose stringnoz["nodecompose"]
barrier stringnoz["barrier"]
nobarrier stringnoz["nobarrier"]
force stringnoz["force"]
umask fs_opt_oct["umask", int32]
type fs_opt["type", array[int8, 4]]
creator fs_opt["creator", array[int8, 4]]
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
part fs_opt_hex["part", int32]
session fs_opt_hex["session", int32]
nls fs_opt_codepage["nls"]
] [varlen]
iso9660_options [
norock stringnoz["norock"]
nojoliet stringnoz["nojoliet"]
unhide stringnoz["unhide"]
hide stringnoz["hide"]
showassoc stringnoz["showassoc"]
cruft stringnoz["cruft"]
utf8 stringnoz["utf8"]
map_acorn stringnoz["map=acorn"]
map_normal stringnoz["map=normal"]
map_off stringnoz["map=off"]
check_relaxed stringnoz["check=relaxed"]
check_strict stringnoz["check=strict"]
overriderock stringnoz["overriderockperm"]
nocompress stringnoz["nocompress"]
session fs_opt_hex["session", int32[0:98]]
sbsector fs_opt_hex["sbsector", int32]
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
mode fs_opt_hex["mode", int32]
dmode fs_opt_hex["dmode", int32]
block fs_opt_hex["block", flags[iso9660_blocks]]
iocharset fs_opt_codepage["iocharset"]
] [varlen]
iso9660_blocks = 512, 1024, 2048
# Note that the "debug" option has been omitted since it's equivalent to "errors=panic".
gfs2_options [
spectator stringnoz["spectator"]
norecovery stringnoz["norecovery"]
ignore_local_fs stringnoz["ignore_local_fs"]
localflocks stringnoz["localflocks"]
localcaching stringnoz["localcaching"]
nodebug stringnoz["nodebug"]
upgrade stringnoz["upgrade"]
acl stringnoz["acl"]
noacl stringnoz["noacl"]
quota_off stringnoz["quota=off"]
quota_account stringnoz["quota=account"]
quota_on stringnoz["quota=on"]
quota_quiet stringnoz["quota=quiet"]
quota stringnoz["quota"]
noquota stringnoz["noquota"]
suiddir stringnoz["suiddir"]
nosuiddir stringnoz["nosuiddir"]
data_writeback stringnoz["data=writeback"]
data_ordered stringnoz["data=ordered"]
meta stringnoz["meta"]
discard stringnoz["discard"]
nodiscard stringnoz["nodiscard"]
errors_withdraw stringnoz["errors=withdraw"]
barrier stringnoz["barrier"]
nobarrier stringnoz["nobarrier"]
rgrplvb stringnoz["rgrplvb"]
norgrplvb stringnoz["norgrplvb"]
loccookie stringnoz["loccookie"]
noloccookie stringnoz["noloccookie"]
commit fs_opt_hex["commit", int32]
statfs_quantum fs_opt_hex["statfs_quantum", int32]
statfs_percent fs_opt_hex["statfs_percent", int32]
quota_quantum fs_opt_hex["quota_quantum", int32]
lockproto_dlm stringnoz["lockproto=dlm"]
lockproto_nolock stringnoz["lockproto=lock_nolock"]
locktable fs_opt_str["locktable"]
hostdata fs_opt_str["hostdata"]
] [varlen]
jfs_options [
integrity stringnoz["integrity"]
nointegrity stringnoz["nointegrity"]
resize stringnoz["resize"]
noquota stringnoz["noquota"]
quota stringnoz["quota"]
usrquota stringnoz["usrquota"]
grpquota stringnoz["grpquota"]
discard stringnoz["discard"]
nodiscard stringnoz["nodiscard"]
iocharset fs_opt_codepage["iocharset"]
errors_continue stringnoz["errors=continue"]
errors_remount stringnoz["errors=remount-ro"]
resize_size fs_opt_hex["resize", int32]
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
umask fs_opt_hex["umask", int32]
discard_size fs_opt_hex["discard", int32]
] [varlen]
btrfs_options [
degraded stringnoz["degraded"]
nodatasum stringnoz["nodatasum"]
datasum stringnoz["datasum"]
nodatacow stringnoz["nodatacow"]
datacow stringnoz["datacow"]
nobarrier stringnoz["nobarrier"]
barrier stringnoz["barrier"]
compress stringnoz["compress"]
compress_force stringnoz["compress-force"]
ssd stringnoz["ssd"]
ssd_spread stringnoz["ssd_spread"]
nossd_spread stringnoz["nossd_spread"]
nossd stringnoz["nossd"]
acl stringnoz["acl"]
noacl stringnoz["noacl"]
notreelog stringnoz["notreelog"]
treelog stringnoz["treelog"]
flushoncommit stringnoz["flushoncommit"]
noflushoncommit stringnoz["noflushoncommit"]
discard stringnoz["discard"]
nodiscard stringnoz["nodiscard"]
discard_sync stringnoz["discard=sync"]
discard_async stringnoz["discard=async"]
fatal_errors_bug stringnoz["fatal_errors=bug"]
space_cache stringnoz["space_cache"]
clear_cache stringnoz["clear_cache"]
user_subvol_rm stringnoz["user_subvol_rm_allowed"]
enospc_debug stringnoz["enospc_debug"]
noenospc_debug stringnoz["noenospc_debug"]
autodefrag stringnoz["autodefrag"]
noautodefrag stringnoz["noautodefrag"]
inode_cache stringnoz["inode_cache"]
noinode_cache stringnoz["noinode_cache"]
nospace_cache stringnoz["nospace_cache"]
usebackuproot stringnoz["usebackuproot"]
skip_balance stringnoz["skip_balance"]
check_int stringnoz["check_int"]
check_int_data stringnoz["check_int_data"]
rescan_uuid_tree stringnoz["rescan_uuid_tree"]
fragment_data stringnoz["fragment=data"]
fragment_metadata stringnoz["fragment=metadata"]
fragment_all stringnoz["fragment=all"]
ref_verify stringnoz["ref_verify"]
metadata_ratio fs_opt_hex["metadata_ratio", int32]
check_int_print_mask fs_opt_hex["check_int_print_mask", int32]
commit fs_opt_hex["commit", int32]
thread_pool fs_opt_hex["thread_pool", int32]
device fs_opt_filename["device"]
subvolid fs_opt_hex["subvolid", int64]
subvol fs_opt_str["subvol"]
max_inline fs_opt_dec_suffix["max_inline"]
compress_algo fs_opt["compress", stringnoz[btrfs_compress_algos]]
compress_force_algo fs_opt["compress-force", stringnoz[btrfs_compress_algos]]
space_cache_v1 stringnoz["space_cache=v1"]
space_cache_v2 stringnoz["space_cache=v2"]
rescue fs_opt["rescue", stringnoz[btrfs_rescue_opts]]
] [varlen]
btrfs_compress_algos = "zlib", "lzo", "zstd", "no"
btrfs_rescue_opts = "usebackuproot", "nologreplay", "ignorebadroots", "ibadroots", "ignoredatacsums", "ignoremetacsums", "ignoresuperflags", "idatacsums", "imetacsums", "isuperflags", "all"
ntfs_options [
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
umask fs_opt_oct["umask", int32]
fmask fs_opt_oct["fmask", int32]
dmask fs_opt_oct["dmask", int32]
mft_zone_multiplier fs_opt_hex["mft_zone_multiplier", int32[-1:4]]
show_sys_files_no stringnoz["show_sys_files=no"]
show_sys_files_yes stringnoz["show_sys_files=yes"]
case_sensitive_no stringnoz["case_sensitive=no"]
case_sensitive_yes stringnoz["case_sensitive=yes"]
disable_sparse_no stringnoz["disable_sparse=no"]
disable_sparse_yes stringnoz["disable_sparse=yes"]
errors_remount stringnoz["errors=remount-ro"]
errors_continue stringnoz["errors=continue"]
errors_recover stringnoz["errors=recover"]
nls fs_opt_codepage["nls"]
utf8 stringnoz["utf8"]
] [varlen]
ntfs3_options [
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
umask fs_opt_oct["umask", int32]
fmask fs_opt_oct["fmask", int32]
dmask fs_opt_oct["dmask", int32]
noacsrules stringnoz["noacsrules"]
hidden stringnoz["hidden"]
nohidden stringnoz["nohidden"]
sys_immutable stringnoz["sys_immutable"]
nosys_immutable stringnoz["nosys_immutable"]
discard stringnoz["discard"]
nodiscard stringnoz["discard"]
force stringnoz["force"]
noforce stringnoz["noforce"]
sparse stringnoz["sparse"]
nosparse stringnoz["nosparse"]
hide_dot_files stringnoz["hide_dot_files"]
nohide_dot_files stringnoz["nohide_dot_files"]
windows_names stringnoz["windows_names"]
nowindows_names stringnoz["windows_names"]
showmeta stringnoz["showmeta"]
noshowmeta stringnoz["noshowmeta"]
prealloc stringnoz["prealloc"]
noprealloc stringnoz["noprealloc"]
acl stringnoz["acl"]
noacl stringnoz["noacl"]
iocharset fs_opt_codepage["iocharset"]
case stringnoz["case"]
nocase stringnoz["nocase"]
] [varlen]
ext4_options [
bsddf stringnoz["bsddf"]
minixdf stringnoz["minixdf"]
grpid stringnoz["grpid"]
bsdgroups stringnoz["bsdgroups"]
nogrpid stringnoz["nogrpid"]
sysvgroups stringnoz["sysvgroups"]
errors_continue stringnoz["errors=continue"]
errors_remount stringnoz["errors=remount-ro"]
nouid32 stringnoz["nouid32"]
debug stringnoz["debug"]
oldalloc stringnoz["oldalloc"]
orlov stringnoz["orlov"]
user_xattr stringnoz["user_xattr"]
nouser_xattr stringnoz["nouser_xattr"]
acl stringnoz["acl"]
noacl stringnoz["noacl"]
norecovery stringnoz["norecovery"]
noload stringnoz["noload"]
nobh stringnoz["nobh"]
bh stringnoz["bh"]
journal_checksum stringnoz["journal_checksum"]
nojournal_checksum stringnoz["nojournal_checksum"]
journal_async_commit stringnoz["journal_async_commit"]
abort stringnoz["abort"]
data_journal stringnoz["data=journal"]
data_ordered stringnoz["data=ordered"]
data_writeback stringnoz["data=writeback"]
data_err_abort stringnoz["data_err=abort"]
data_err_ignore stringnoz["data_err=ignore"]
usrjquota stringnoz["usrjquota="]
grpjquota stringnoz["grpjquota="]
jqfmt_vfsold stringnoz["jqfmt=vfsold"]
jqfmt_vfsv0 stringnoz["jqfmt=vfsv0"]
jqfmt_vfsv1 stringnoz["jqfmt=vfsv1"]
grpquota stringnoz["grpquota"]
noquota stringnoz["noquota"]
quota stringnoz["quota"]
usrquota stringnoz["usrquota"]
prjquota stringnoz["prjquota"]
barrier stringnoz["barrier"]
nobarrier stringnoz["nobarrier"]
i_version stringnoz["i_version"]
dax stringnoz["dax"]
dax_always stringnoz["dax=always"]
dax_inode stringnoz["dax=inode"]
dax_never stringnoz["dax=never"]
delalloc stringnoz["delalloc"]
lazytime stringnoz["lazytime"]
nolazytime stringnoz["nolazytime"]
nodelalloc stringnoz["nodelalloc"]
mblk_io_submit stringnoz["mblk_io_submit"]
nomblk_io_submit stringnoz["nomblk_io_submit"]
block_validity stringnoz["block_validity"]
noblock_validity stringnoz["noblock_validity"]
auto_da_alloc stringnoz["auto_da_alloc"]
noauto_da_alloc stringnoz["noauto_da_alloc"]
dioread_nolock stringnoz["dioread_nolock"]
nodioread_nolock stringnoz["nodioread_nolock"]
dioread_lock stringnoz["dioread_lock"]
discard stringnoz["discard"]
nodiscard stringnoz["nodiscard"]
init_itable stringnoz["init_itable"]
noinit_itable stringnoz["noinit_itable"]
test_dummy_encryption stringnoz["test_dummy_encryption"]
test_dummy_encryption_v1 stringnoz["test_dummy_encryption=v1"]
nombcache stringnoz["nombcache"]
inlinecrypt stringnoz["inlinecrypt"]
mb_optimize_scan fs_opt_hex["mb_optimize_scan", int32[0:1]]
resgid fs_opt_hex["resgid", gid]
resuid fs_opt_hex["resuid", uid]
sb fs_opt_hex["sb", int32]
commit fs_opt_hex["commit", int32]
min_batch_time fs_opt_hex["min_batch_time", int32]
max_batch_time fs_opt_hex["max_batch_time", int32]
journal_dev fs_opt_hex["journal_dev", int32]
barrier_val fs_opt_hex["barrier", int32]
stripe fs_opt_hex["stripe", int32]
debug_want_extra_isize fs_opt_hex["debug_want_extra_isize", int32]
inode_readahead_blks fs_opt_hex["inode_readahead_blks", flags[ext4_inode_readahead_blks]]
journal_ioprio fs_opt_hex["journal_ioprio", int32[0:7]]
auto_da_alloc_val fs_opt_hex["auto_da_alloc", int32]
init_itable_val fs_opt_hex["init_itable", int32]
max_dir_size_kb fs_opt_hex["max_dir_size_kb", int32]
journal_path fs_opt_filename["journal_path"]
grpjquota_path fs_opt_filename["grpjquota"]
usrjquota_path fs_opt_filename["usrjquota"]
] [varlen]
ext4_types = "ext4", "ext3", "ext2"
ext4_inode_readahead_blks = 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000
f2fs_options [
background_gc_sync stringnoz["background_gc=sync"]
background_gc_off stringnoz["background_gc=off"]
background_gc_on stringnoz["background_gc=on"]
disable_roll_forward stringnoz["disable_roll_forward"]
norecovery stringnoz["norecovery"]
discard stringnoz["discard"]
nodiscard stringnoz["nodiscard"]
noheap stringnoz["no_heap"]
heap stringnoz["heap"]
user_xattr stringnoz["user_xattr"]
nouser_xattr stringnoz["nouser_xattr"]
acl stringnoz["acl"]
noacl stringnoz["noacl"]
six_active_logs stringnoz["active_logs=6"]
four_active_logs stringnoz["active_logs=4"]
two_active_logs stringnoz["active_logs=2"]
disable_ext_identify stringnoz["disable_ext_identify"]
inline_xattr stringnoz["inline_xattr"]
noinline_xattr stringnoz["noinline_xattr"]
inline_xattr_size fs_opt_hex["inline_xattr_size", int32]
inline_data stringnoz["inline_data"]
noinline_data stringnoz["noinline_data"]
inline_dentry stringnoz["inline_dentry"]
noinline_dentry stringnoz["noinline_dentry"]
flush_merge stringnoz["flush_merge"]
noflush_merge stringnoz["noflush_merge"]
barrier stringnoz["barrier"]
nobarrier stringnoz["nobarrier"]
fastboot stringnoz["fastboot"]
extent_cache stringnoz["extent_cache"]
noextent_cache stringnoz["noextent_cache"]
data_flush stringnoz["data_flush"]
reserve_root fs_opt_dec["reserver_root", int32]
adaptive_mode stringnoz["mode=adaptive"]
lfs_mode stringnoz["mode=lfs"]
segment_mode stringnoz["mode=fragment:segment"]
block_mode stringnoz["mode=fragment:block"]
io_bits fs_opt_dec["io_bits", int32[0:256]]
fault_injection fs_opt_dec["fault_injection", int32]
fault_type fs_opt_dec["fault_type", int32]
resgid fs_opt_hex["resgid", gid]
resuid fs_opt_hex["resuid", uid]
lazytime stringnoz["lazytime"]
nolazytime stringnoz["nolazytime"]
quota stringnoz["quota"]
noquota stringnoz["noquota"]
usrquota fs_opt_str["usrquota"]
grpquota fs_opt_str["grpquota"]
prjquota fs_opt_str["prjquota"]
usrjquota fs_opt_str["usrjquota"]
grpjquota fs_opt_str["grpjquota"]
prjjquota fs_opt_str["prjjquota"]
jqfmt_vfsold stringnoz["jqfmt=vfsold"]
jqfmt_vfsv0 stringnoz["jqfmt=vfsv0"]
jqfmt_vfsv1 stringnoz["jqfmt=vfsv1"]
whint_mode_user stringnoz["whint_mode=user-based"]
whint_mode_off stringnoz["whint_mode=off"]
whint_mode_fs stringnoz["whint_mode=fs-based"]
alloc_mode_def stringnoz["alloc_mode=default"]
alloc_mode_reuse stringnoz["alloc_mode=reuse"]
fsync_mode_posix stringnoz["fsync_mode=posix"]
fsync_mode_strict stringnoz["fsync_mode=strict"]
test_dummy_encryption stringnoz["test_dummy_encryption"]
test_dummy_encryption_v1 stringnoz["test_dummy_encryption=v1"]
errors_continue stringnoz["errors=continue"]
errors_remount stringnoz["errors=remount-ro"]
inlinecrypt stringnoz["inlinecrypt"]
checkpoint_diasble stringnoz["checkpoint=disable"]
checkpoint_enable stringnoz["checkpoint=enable"]
checkpoint_merge stringnoz["checkpoint=merge"]
nocheckpoint_merge stringnoz["nocheckpoint_merge"]
compress_chksum stringnoz["compress_chksum"]
compress_cache stringnoz["compress_cache"]
atgc stringnoz["atgc"]
gc_merge stringnoz["gc_merge"]
nogc_merge stringnoz["nogc_merge"]
discard_unit_block stringnoz["discard_unit=block"]
discard_unit_segment stringnoz["discard_unit=segment"]
discard_unit_section stringnoz["discard_unit=section"]
memory_normal stringnoz["memory=normal"]
memory_low stringnoz["memory=low"]
age_extent_cache stringnoz["age_extent_cache"]
] [varlen]
ocfs2_options [
barrier fs_opt_dec["barrier", int32]
err_ro stringnoz["errors=remount-ro"]
intr stringnoz["intr"]
nointr stringnoz["nointr"]
heartbeat_none stringnoz["heartbeat=none"]
heartbeat_local stringnoz["heartbeat=local"]
heartbeat_global stringnoz["heartbeat=global"]
data_ordered stringnoz["data=ordered"]
data_writeback stringnoz["data=writeback"]
atime_quantum fs_opt_dec["atime_quantum", int32]
preferred_slot fs_opt_dec["preferred_slot", int32]
commit fs_opt_dec["commit", int32]
localalloc fs_opt_dec["localalloc", int32]
localflocks stringnoz["localflocks"]
cluster_stack stringnoz["cluster_stack=o2cb"]
user_xattr stringnoz["user_xattr"]
nouser_xattr stringnoz["nouser_xattr"]
inode64 stringnoz["inode64"]
acl stringnoz["acl"]
noacl stringnoz["noacl"]
usrquota stringnoz["usrquota"]
grpquota stringnoz["grpquota"]
coherency_buffered stringnoz["coherency=buffered"]
coherency_full stringnoz["coherency=full"]
resv_level fs_opt_dec["resv_level", int32[0:9]]
dir_resv_level fs_opt_dec["dir_resv_level", int32[0:9]]
journal_async_commit stringnoz["journal_async_commit"]
err_cont stringnoz["errors=continue"]
] [varlen]
bpf_options [
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
mode fs_opt_oct["mode", int32]
] [varlen]
overlay_options [
lowerdir fs_opt_filename["lowerdir"]
upperdir fs_opt_filename["upperdir"]
workdir fs_opt_filename["workdir"]
redirect_dir_on stringnoz["redirect_dir=on"]
redirect_dir_off stringnoz["redirect_dir=off"]
redirect_dir_follow stringnoz["redirect_dir=follow"]
redirect_dir_nofollow stringnoz["redirect_dir=nofollow"]
default_permissions stringnoz["default_permissions"]
index_on stringnoz["index=on"]
index_off stringnoz["index=off"]
uuid_on stringnoz["uuid=on"]
uuid_off stringnoz["uuid=off"]
uuid_auto stringnoz["uuid=auto"]
uuid_null stringnoz["uuid=null"]
nfs_export_on stringnoz["nfs_export=on"]
nfs_export_off stringnoz["nfs_export=off"]
userxattr stringnoz["userxattr"]
xino_on stringnoz["xino=on"]
xino_off stringnoz["xino=off"]
xino_auto stringnoz["xino=auto"]
metacopy_on stringnoz["metacopy=on"]
metacopy_off stringnoz["metacopy=off"]
verity_on stringnoz["verity=on"]
verity_off stringnoz["verity=off"]
verity_require stringnoz["verity=require"]
volatile stringnoz["volatile"]
] [varlen]
binder_options [
max fs_opt_dec["max", int32[0:4]]
stats stringnoz["stats=global"]
] [varlen]
erofs_options [
user_xattr stringnoz["user_xattr"]
nouser_xattr stringnoz["nouser_xattr"]
acl stringnoz["acl"]
noacl stringnoz["noacl"]
fault_injection fs_opt_hex["fault_injection", int32]
cache_strategy_disabled stringnoz["cache_strategy=disabled"]
cache_strategy_readahead stringnoz["cache_strategy=readahead"]
cache_strategy_readaround stringnoz["cache_strategy=readaround"]
dax stringnoz["dax"]
dax_always stringnoz["dax=always"]
dax_never stringnoz["dax=never"]
] [varlen]
exfat_options [
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
umask fs_opt_oct["umask", int32]
dmask fs_opt_oct["dmask", int32]
fmask fs_opt_oct["fmask", int32]
allow_utime fs_opt_oct["allow_utime", int32]
codepage fs_opt_codepage["codepage"]
iocharset fs_opt_codepage["iocharset"]
namecase stringnoz["namecase=1"]
errors_remount stringnoz["errors=remount-ro"]
errors_continue stringnoz["errors=continue"]
utf8 stringnoz["utf8"]
discard stringnoz["discard"]
keep_last_dots stringnoz["keep_last_dots"]
sys_tz stringnoz["sys_tz"]
time_offset fs_opt_hex["time_offset", int32]
zero_size_dir stringnoz["zero_size_dir"]
] [varlen]
# TODO: afs should be configured via /proc/fs/afs/{cells,servers} (see fs/afs/proc.c).
# Without that mounting of afs will fail.
afs_source [
none string["none"]
cell afs_cell_source
] [varlen]
afs_cell_source {
prefix flags[afs_cell_prefix, int8]
cell stringnoz[afs_cells]
volname stringnoz[afs_volnames]
suffix stringnoz[afs_suffixes]
z const[0, int8]
} [packed]
afs_cell_prefix = '%', '#'
afs_cells = "", "syz0:", "syz1:"
afs_volnames = "syz0", "syz1"
afs_suffixes = "", ".readonly", ".backup"
afs_options [
autocell stringnoz["autocell"]
dyn stringnoz["dyn"]
flock_local stringnoz["flock=local"]
flock_openafs stringnoz["flock=openafs"]
flock_strict stringnoz["flock=strict"]
flock_write stringnoz["flock=write"]
] [varlen]
tmpfs_options [
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
mode fs_opt_oct["mode", int32]
nr_blocks fs_opt_dec_suffix["nr_blocks"]
nr_inodes fs_opt_dec_suffix["nr_inodes"]
size fs_opt_dec_suffix["size"]
huge_never stringnoz["huge=never"]
huge_always stringnoz["huge=always"]
huge_within_size stringnoz["huge=within_size"]
huge_advise stringnoz["huge=advise"]
mpol fs_opt["mpol", tmpfs_mpol]
inode32 stringnoz["inode32"]
inode64 stringnoz["indo64"]
noswap stringnoz["noswap"]
quota stringnoz["quota"]
usrquota stringnoz["usrquota"]
grpquota stringnoz["grpquota"]
usrquota_block_hardlimit fs_opt_dec_suffix["usrquota_block_hardlimit"]
usrquota_inode_hardlimit fs_opt_dec_suffix["usrquota_inode_hardlimit"]
grpquota_block_hardlimit fs_opt_dec_suffix["grpquota_block_hardlimit"]
grpquota_inode_hardlimit fs_opt_dec_suffix["grpquota_inode_hardlimit"]
] [varlen]
tmpfs_mpol {
policy stringnoz[tmpfs_mpol_policy]
flags stringnoz[tmpfs_mpol_flags]
nodes optional[tmpfs_mpol_nodes]
} [packed]
tmpfs_mpol_nodes {
colon const[':', int8]
nodes array[flags[tmpfs_mpol_node_chars, int8]]
}
tmpfs_mpol_policy = "default", "prefer", "bind", "interleave", "local"
tmpfs_mpol_flags = "", "=static", "=relative"
tmpfs_mpol_node_chars = '-', ':', '/', ',', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
zonefs_options [
errors_remount_ro stringnoz["errors=remount-ro"]
errors_zone_ro stringnoz["errors=zone-ro"]
errors_zone_offline stringnoz["errors=zone-offline"]
errors_repair stringnoz["errors=repair"]
explicit_open stringnoz["explicit-open"]
] [varlen]
jffs2_options [
compr_none stringnoz["compr=none"]
compr_lzo stringnoz["compr=lzo"]
compr_zlib stringnoz["compr=zlib"]
rp_size fs_opt_dec["rp_size", int32]
] [varlen]
nilfs2_options [
barrier stringnoz["barrier"]
nobarrier stringnoz["nobarrier"]
norecovery stringnoz["norecovery"]
discard stringnoz["discard"]
nodiscard stringnoz["nodiscard"]
snapshot fs_opt_hex["cp", int32[0:3]]
order_relaxed stringnoz["order=relaxed"]
order_strict stringnoz["order=strict"]
errors_continue stringnoz["errors=continue"]
errors_remount_ro stringnoz["errors=remount-ro"]
] [varlen]
squashfs_options [
errors stringnoz["errors=continue"]
threads_str fs_opt["threads", stringnoz[squashfs_thread]]
threads_num fs_opt_dec["threads", int32]
] [varlen]
squashfs_thread = "single", "multi", "percpu"
ubifs_options [
fast_unmount stringnoz["fast_unmount"]
norm_unmount stringnoz["norm_unmount"]
bulk_read stringnoz["bulk_read"]
no_bulk_read stringnoz["no_bulk_read"]
chk_data_crc stringnoz["chk_data_crc"]
no_chk_data_crc stringnoz["no_chk_data_crc"]
compr_none stringnoz["compr=none"]
compr_lzo stringnoz["compr=lzo"]
compr_zlib stringnoz["compr=zlib"]
compr_zstd stringnoz["compr=zstd"]
auth_key fs_opt_str["auth_key"]
auth_hash_name fs_opt["auth_hash_name", stringnoz[ubifs_auth_hash_name]]
] [varlen]
adfs_options [
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
ownmask fs_opt_oct["ownmask", int32]
othmask fs_opt_oct["othmask", int32]
ftsuffix fs_opt_dec["ftsuffix", int32]
] [varlen]
affs_options [
bs fs_opt_hex["bs", flags[affs_bs]]
mode fs_opt_oct["mode", int32]
mufs stringnoz["mufs"]
notruncate stringnoz["nofilenametruncate"]
protect stringnoz["protect"]
reserved fs_opt_dec["reserved", int32]
root fs_opt_dec["root", int32]
setuid fs_opt_hex["setuid", uid]
setgid fs_opt_hex["setgid", gid]
verbose stringnoz["verbose"]
] [varlen]
affs_bs = 512, 1024, 2048, 4096
vxfs_options [
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
iocharset fs_opt_codepage["iocharset"]
debug stringnoz["debug"]
] [varlen]
omfs_options [
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
umask fs_opt_oct["umask", int32]
dmask fs_opt_oct["dmask", int32]
fmask fs_opt_oct["fmask", int32]
] [varlen]
hpfs_options [
help stringnoz["help"]
uid fs_opt_hex["uid", uid]
gid fs_opt_hex["gid", gid]
umask fs_opt_oct["umask", int32]
case_lower stringnoz["case=lower"]
case_asis stringnoz["case=asis"]
check_none stringnoz["check=none"]
check_normal stringnoz["check=normal"]
check_strict stringnoz["check=strict"]
err_cont stringnoz["errors=continue"]
err_ro stringnoz["errors=remount-ro"]
eas_no stringnoz["eas=no"]
eas_ro stringnoz["ear=ro"]
eas_rw stringnoz["eas=rw"]
chkdsk_no stringnoz["chkdsk=no"]
chkdsk_errors stringnoz["chkdsk=errors"]
chkdsk_always stringnoz["chkdsk=always"]
timeshift fs_opt_dec["timeshift", int32]
] [varlen]
qnx6_options [
mmi_fs stringnoz["mmi_fs"]
] [varlen]
# We could use more hash names, but the problem is that alg_hash_name is 0-terminated.
ubifs_auth_hash_name = "crc32", "ghash", "md5", "sha1"
udf_options [
novrs stringnoz["novrs"]
nostrict stringnoz["nostrict"]
unhide stringnoz["unhide"]
undelete stringnoz["undelete"]
noadinicb stringnoz["noadinicb"]
adinicb stringnoz["adinicb"]
shortad stringnoz["shortad"]
longad stringnoz["longad"]
utf8 stringnoz["utf8"]
iocharset fs_opt_codepage["iocharset"]
uid_forget stringnoz["uid=forget"]
uid_ignore stringnoz["uid=ignore"]
gid_forget stringnoz["gid=forget"]
gid_ignore stringnoz["gid=ignore"]
gid fs_opt_dec["gid", gid]
uid fs_opt_dec["uid", uid]
umask fs_opt_oct["umask", int32]
mode fs_opt_oct["mode", int32]
dmode fs_opt_oct["dmode", int32]
bs fs_opt_dec["bs", int32]
session fs_opt_dec["session", int32]
lastblock fs_opt_dec["lastblock", int32]
anchor fs_opt_dec["anchor", int32]
volume fs_opt_dec["volume", int32]
partition fs_opt_dec["partition", int32]
fileset fs_opt_dec["fileset", int32]
rootdir fs_opt_dec["rootdir", int32]
] [varlen]
esdfs_options [
lower fs_opt_str["lower"]
upper fs_opt_str["upper"]
derive fs_opt["derive", stringnoz[esdfs_derive]]
confine stringnoz["confine"]
noconfine stringnoz["noconfine"]
derive_gid stringnoz["derive_gid"]
default_normal stringnoz["default_normal"]
dl_loc fs_opt_str["dl_loc"]
dl_uid fs_opt_oct["dl_uid", uid]
dl_gid fs_opt_oct["dl_gid", gid]
ns_fd fs_opt_oct["ns_fd", fd_namespace]
fsuid fs_opt_oct["fsuid", uid]
fsgid fs_opt_oct["fsgid", gid]
gid fs_opt_oct["gid", gid]
mask fs_opt_oct["mask", int32]
userid fs_opt_oct["userid", uid]
multiuser stringnoz["multiuser"]
] [varlen]
esdfs_derive = "none", "legacy", "unified", "multi", "public"
bcachefs_options [
metadata_checksum fs_opt["metadata_checksum", stringnoz[bcachefs_checksum]]
data_checksum fs_opt["data_checksum", stringnoz[bcachefs_checksum]]
compression fs_opt["compression", stringnoz[bcachefs_compression]]
background_compression fs_opt["background_compression", stringnoz[bcachefs_compression]]
str_hash fs_opt["str_hash", stringnoz[bcachefs_str_hash]]
nocow stringnoz["nocow"]
errors_continue stringnoz["errors=continue"]
errors_fix_safe stringnoz["errors=fix_safe"]
errors_ro stringnoz["error=ro"]
metadata_replicas fs_opt_hex["metadata_replicas", int32[1:4]]
data_replicas fs_opt_hex["data_replicas", int32[1:4]]
metadata_replicas_required fs_opt_hex["metadata_replicas_required", int32[1:4]]
data_replicas_required fs_opt_hex["data_replicas_required", int32[1:4]]
erasure_code stringnoz["erasure_code"]
inodes_32bit stringnoz["inodes_32bit"]
shared_inode_numbers stringnoz["shard_inode_numbers"]
inodes_use_key_cache stringnoz["inodes_use_key_cache"]
btree_node_mem_ptr_optimization stringnoz["btree_node_mem_ptr_optimization"]
gc_reserve_percent fs_opt_hex["gc_reserve_percent", int32[5:21]]
gc_reserve_bytes fs_opt_hex["gc_reserve_bytes", int32]
root_reserve_percent fs_opt_hex["root_reserve_percent", int32[0:100]]
wide_macs stringnoz["wide_macs"]
inline_data stringnoz["inline_data"]
acl stringnoz["acl"]
usrquota stringnoz["usrquota"]
grpquota stringnoz["grpquota"]
prjquota stringnoz["prjquota"]
degraded stringnoz["degraded"]
very_degraded stringnoz["very_degraded"]
no_splitbrain_check stringnoz["no_splitbrain_check"]
discard stringnoz["discard"]
verbose stringnoz["verbose"]
journal_flush_delay fs_opt_hex["journal_flush_delay", int32]
journal_flush_disabled stringnoz["journal_flush_disabled"]
journal_reclaim_delay fs_opt_hex["journal_reclaim_delay", int32]
move_bytes_in_flight fs_opt_hex["move_bytes_in_flight", int32]
move_ios_in_flight fs_opt_hex["move_ios_in_flight", int32[1:1024]]
fsck stringnoz["fsck"]
fsck_memory_usage_percent fs_opt_hex["fsck_memory_usage_percent", int32[20:70]]
fix_errors fs_opt["fix_errors", stringnoz[bcachefs_fix_errors]]
ratelimit_errors stringnoz["ratelimit_errors"]
nochanges stringnoz["nochanges"]
norecovery stringnoz["norecovery"]
recovery_pass_last fs_opt["recovery_pass_last", stringnoz[bcachefs_recovery_pass_last]]
journal_transaction_names stringnoz["journal_transaction_names"]
allocator_stuck_timeout fs_opt_hex["allocator_stuck_timeout", int16]
noexcl stringnoz["noexcl"]
direct_io stringnoz["direct_io"]
sb fs_opt_hex["sb", int32]
read_only stringnoz["read_only"]
reconstruct_alloc stringnoz["reconstruct_alloc"]
version_upgrade fs_opt["version_upgrade", stringnoz[bcachefs_version_upgrade]]
nocow_enabled stringnoz["nocow_enabled"]
no_data_io stringnoz["no_data_io"]
btree_node_prefetch stringnoz["btree_node_prefetch"]
] [varlen]
bcachefs_checksum = "none", "crc32c", "crc64", "xxhash"
bcachefs_compression = "none", "lz4", "gzip", "zstd"
bcachefs_str_hash = "crc32c", "crc64", "siphash"
bcachefs_fix_errors = "exit", "yes", "no", "ask"
bcachefs_version_upgrade = "compatible", "incompatible", "none"
bcachefs_recovery_pass_last = "scan_for_btree_nodes", "check_topology", "accounting_read", "alloc_read", "stripes_read", "initialize_subvolumes", "snapshots_read", "check_allocations", "trans_mark_dev_sbs", "fs_journal_alloc", "set_may_go_rw", "journal_replay", "check_alloc_info", "check_lrus", "check_btree_backpointers", "check_backpointers_to_extents", "check_extents_to_backpointers", "check_alloc_to_lru_refs", "fs_freespace_init", "bucket_gens_init", "reconstruct_snapshots", "check_snapshot_trees", "check_snapshots", "check_subvols", "check_subvol_children", "delete_dead_snapshots", "fs_upgrade_for_subvolumes", "check_inodes", "check_extents", "check_indirect_extents", "check_dirents", "check_xattrs", "check_root", "check_subvolume_structure", "check_directory_structure", "check_nlinks", "resume_logged_ops", "delete_dead_inodes", "fix_reflink_p", "set_fs_needs_rebalance"
cgroup_options [
all stringnoz["all"]
clone_children stringnoz["clone_children"]
cpuset_v2_mode stringnoz["cpuset_v2_mode"]
name fs_opt_str["name"]
none stringnoz["none"]
noprefix stringnoz["noprefix"]
release_agent fs_opt_filename["release_agent"]
xattr stringnoz["xattr"]
favordynmods stringnoz["favordynmods"]
nofavordynmods stringnoz["nofavordynmods"]
subsystem stringnoz[cgroup_subsystems]
] [varlen]
cgroup2_options [
nsdelegate stringnoz["nsdelegate"]
favordynmods stringnoz["favordynmods"]
memory_localevents stringnoz["memory_localevents"]
memory_recursiveprot stringnoz["memory_recursiveprot"]
memory_hugetlb_accounting stringnoz["memory_hugetlb_accounting"]
pids_localevents stringnoz["pids_localevents"]
subsystem stringnoz[cgroup_subsystems]
] [varlen]
ufs_options [
type fs_opt["type", stringnoz[ufs_type]]
onerror fs_opt["onerror", stringnoz[ufs_onerror]]
] [varlen]
ufs_type = "old", "sunx86", "sun", "sunos", "44bsd", "ufs2", "5xbsd", "hp", "nextstep-cd", "nextstep", "openstep"
ufs_onerror = "lock", "umount", "repair"
codepage_nums = "1250", "1251", "1255", "437", "737", "775", "850", "852", "855", "857", "860", "861", "862", "863", "864", "865", "866", "869", "874", "932", "936", "949", "950"
codepages_names = "macceltic", "maccenteuro", "maccroatian", "maccyrillic", "macgaelic", "macgreek", "maciceland", "macinuit", "macroman", "macromanian", "macturkish", "ascii", "default", "cp1250", "cp1251", "cp1255", "cp437", "cp737", "cp775", "cp850", "cp852", "cp855", "cp857", "cp860", "cp861", "cp862", "cp863", "cp864", "cp865", "cp866", "cp869", "cp874", "cp932", "cp936", "cp949", "cp950", "euc-jp", "iso8859-13", "iso8859-14", "iso8859-15", "iso8859-1", "iso8859-2", "iso8859-3", "iso8859-4", "iso8859-5", "iso8859-6", "iso8859-7", "iso8859-9", "koi8-r", "koi8-ru", "koi8-u", "utf8", "none"
mount_flags = MS_BIND, MS_DIRSYNC, MS_MANDLOCK, MS_MOVE, MS_NOATIME, MS_NODEV, MS_NODIRATIME, MS_NOEXEC, MS_NOSUID, MS_RDONLY, MS_RELATIME, MS_REMOUNT, MS_SILENT, MS_STRICTATIME, MS_SYNCHRONOUS, MS_REC, MS_POSIXACL, MS_UNBINDABLE, MS_PRIVATE, MS_SLAVE, MS_SHARED, MS_I_VERSION, MS_LAZYTIME
umount_flags = MNT_FORCE, MNT_DETACH, MNT_EXPIRE, UMOUNT_NOFOLLOW
file_getattr(dfd fd_dir[opt], filename ptr[in, filename], ufattr ptr[out, file_attr], usize len[ufattr], flags flags[at_flags])
file_setattr(dfd fd_dir[opt], filename ptr[in, filename], ufattr ptr[in, file_attr], usize len[ufattr], flags flags[at_flags])
file_attr {
fa_xflags flags[file_attr_flags, int64]
fa_extsize int32
fa_nextents int32
fa_projid int32
fa_cowextsize int32
}
file_attr_flags = FS_XFLAG_REALTIME, FS_XFLAG_PREALLOC, FS_XFLAG_IMMUTABLE, FS_XFLAG_APPEND, FS_XFLAG_SYNC, FS_XFLAG_NOATIME, FS_XFLAG_NODUMP, FS_XFLAG_RTINHERIT, FS_XFLAG_PROJINHERIT, FS_XFLAG_NOSYMLINKS, FS_XFLAG_EXTSIZE, FS_XFLAG_EXTSZINHERIT, FS_XFLAG_NODEFRAG, FS_XFLAG_FILESTREAM, FS_XFLAG_DAX, FS_XFLAG_COWEXTSIZE, FS_XFLAG_HASATTR
]
|
| 47/2 |
2026/03/10 03:24 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 82775
output: 251
thoughts: 141
Thoughts: **Analyzing the `mount$tmpfs` Function**
Okay, so I've found the `mount$tmpfs` function definition nestled within `filesystem.txt`. Looking at the signature, it's clear how this function is structured. It takes a source argument that is likely `0` in this case, a destination path which I can see being set to something like `./tmp`, which appears to be a pointer to a filename, a type set to "tmpfs", flags (likely represented as `mount_flags`), and options specific to the `tmpfs` filesystem (represented as `fs_options[tmpfs_options]`).
Given this, I should be able to make a direct call using `mount$tmpfs`. Specifically, if I feed `0` as the source, use a memory address such as `0x7f0000000000` to represent the destination path "./tmp", `tmpfs` at `0x7f0000000040` for the filesystem type and zero for both the flags and options, then I should have a basic tmpfs mount. Let's give it a shot using that exact configuration.
|
| 48/2 |
2026/03/10 03:24 |
tool |
crash-reproducer |
0m
Args: map[ReproSyz:mkdir(&(0x7f0000000000)='./tmp\x00', 0x1ff)
mount$tmpfs(0x0, &(0x7f0000000000)='./tmp\x00', &(0x7f0000000040)='tmpfs\x00', 0x0, 0x0)
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./tmp/link\x00')
unlink(&(0x7f00000000c0)='./tmp/link\x00') (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 49/2 |
2026/03/10 03:24 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 83445
output: 467
thoughts: 941
Thoughts: **The Race Condition in dentry->d_flags**
Okay, still no crash, which is odd. Let's retrace the calls and see if we can find the vulnerability. So, `d_make_discardable` is called from `simple_unlink`, which is called by `shmem_unlink`, which in turn is called by `vfs_unlink`, and finally by `filename_unlinkat` and ultimately `unlink`. Now, the other path, `do_readlinkat`, is called from `readlink`. It seems the race revolves around the `dentry->d_flags`.
`d_make_discardable` is setting `dentry->d_flags &= ~DCACHE_PERSISTENT;`, while `do_readlinkat` is calling `d_is_symlink(path.dentry)` and reading from the same flag. But `d_is_symlink` is called *after* `filename_lookup`. If the `unlink` happens before `filename_lookup`, the lookup fails with `-ENOENT`. If the `unlink` happens after, then `d_is_symlink` will try to read the now-modified `dentry->d_flags`.
`d_make_discardable` is definitely in `simple_unlink`, which is called by `shmem_unlink`. Here, hold on, `shmem_unlink` is called with `dir->i_rwsem` held. Does `filename_lookup` take that same lock? No, `filename_lookup` uses RCU lookups first. It only takes the lock if the lookup *fails*. Ah, that's the key. So `filename_lookup` can run concurrently with `shmem_unlink`.
To trigger the race condition, we need `readlink` to do `filename_lookup` and get the dentry, then `unlink` to call `d_make_discardable` on the *same* dentry, while `readlink` is in the `d_is_symlink` part. The race window is incredibly small: between `filename_lookup` returning and `d_is_symlink` being called. We need to maximize the chances of this happening. Multiple `readlink` and `unlink` pairs should increase the probability.
Let's try this execution pattern, which will increase the chance of catching the race:
```
mkdir(&(0x7f0000000000)='./tmp\x00', 0x1ff)
mount$tmpfs(0x0, &(0x7f0000000000)='./tmp\x00', &(0x7f0000000040)='tmpfs\x00', 0x0, 0x0)
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./tmp/link\x00')
unlink(&(0x7f00000000c0)='./tmp/link\x00') (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)
```
Fingers crossed, this should expose the race.
|
| 50/2 |
2026/03/10 03:24 |
tool |
crash-reproducer |
0m
Args: map[ReproSyz:mkdir(&(0x7f0000000000)='./tmp\x00', 0x1ff)
mount$tmpfs(0x0, &(0x7f0000000000)='./tmp\x00', &(0x7f0000000040)='tmpfs\x00', 0x0, 0x0)
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./tmp/link\x00')
unlink(&(0x7f00000000c0)='./tmp/link\x00') (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)
readlink(&(0x7f00000000c0)='./tmp/link\x00', &(0x7f0000000200)="", 0x64) (async)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 51/2 |
2026/03/10 03:24 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 85849
output: 546
thoughts: 1183
Thoughts: **Analyzing a Potential tmpfs Race Condition**
Okay, still no crash, which means the initial approach didn't work. Let's re-examine the reported call stacks. I see `d_make_discardable` is called from `simple_unlink`. Does `simple_unlink` apply to `tmpfs`? Yes, `shmem_unlink` calls `simple_unlink`, and based on the crash report, we see the issue is with `shmem_unlink`. The read is happening in `do_readlinkat`. So it's a race between `unlink` and `readlink` on a tmpfs symlink. Why isn't this consistently reproducible?
The race window must be tiny. How do we increase the probability of hitting it? We could use something like `syz_clone` to run them concurrently in multiple threads. But, wait, `async` already runs those calls in separate threads, so `syz_clone` is unnecessary. However, `async` calls are executed only once. To increase the probability further, a loop might be needed. Unfortunately, syzkaller's syzlang doesn't directly support loops.
But wait a minute! The syzkaller executor *itself* runs the entire program in a loop! If I just provide the program, syzkaller will repeatedly execute it. But there's a problem: if the `unlink` succeeds, the symlink is gone. The next iteration will fail because the link is gone. Ah, but the syzkaller executor runs each program in a *separate process*, right? And cleans up the filesystem between iterations either by a new mount namespace or by deleting everything. Okay, that means it's running a new process, setting up the links, unlinking and reading. If `unlink` executes before `readlink`, `readlink` fails with `ENOENT`. If `readlink` happens before `unlink`, it succeeds. Only if they are perfectly concurrent, will we catch this race.
To increase our chances, let's create *multiple* symlinks and race all of them. So, the strategy is:
1. Create several symlinks (e.g., link0, link1, link2, link3) pointing to a target.
2. Then, concurrently, `unlink` and `readlink` each symlink with async calls.
That should provide a better shot at triggering the race condition, and I'll see if that works.
|
| 52/2 |
2026/03/10 03:25 |
tool |
crash-reproducer |
0m
Args: map[ReproSyz:symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./link0\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000d0)='./link1\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000e0)='./link2\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000f0)='./link3\x00')
unlink(&(0x7f00000000c0)='./link0\x00') (async)
readlink(&(0x7f00000000c0)='./link0\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000d0)='./link1\x00') (async)
readlink(&(0x7f00000000d0)='./link1\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000e0)='./link2\x00') (async)
readlink(&(0x7f00000000e0)='./link2\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000f0)='./link3\x00') (async)
readlink(&(0x7f00000000f0)='./link3\x00', &(0x7f0000000200)="", 0x64) (async)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 53/2 |
2026/03/10 03:25 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 88125
output: 49
thoughts: 121
Thoughts: **Debugging a Persistent Issue: No Crash (Yet)**
Okay, so still no crash, which is... frustrating. I need to rethink my approach. I keep looking at the same areas but I must be missing something. Let's see, what else can trigger `d_make_discardable`? I've been focusing on the obvious path, but perhaps there's a more obscure entry point I'm not considering.
Right, I know that `d_make_discardable` gets called from `simple_unlink`. And `simple_unlink` calls into `shmem_unlink`. Now I remember: `shmem_unlink` is called by `vfs_unlink`. Hmmm... and `vfs_unlink` is called from `filename_unlinkat`. But could there be any other file systems which might be calling `d_make_discardable` directly? Or indirectly, through similar means? I need to broaden my search. Time to check all the references. It's time to follow the trail again.
|
| 54/2 |
2026/03/10 03:25 |
tool |
codesearch-find-references |
0m
Args: map[ContextFile:fs/dcache.c IncludeSnippetLines:0 Name:d_make_discardable SourceTreePrefix:]
Results: map[References:[map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:__simple_recursive_removal SourceFile:fs/libfs.c SourceLine:627] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:autofs_dir_rmdir SourceFile:fs/autofs/root.c SourceLine:719] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:autofs_dir_unlink SourceFile:fs/autofs/root.c SourceLine:637] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:devpts_pty_kill SourceFile:fs/devpts/inode.c SourceLine:561] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:eventfs_remove_events_dir SourceFile:fs/tracefs/event_inode.c SourceLine:913] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:simple_rmdir SourceFile:fs/libfs.c SourceLine:820] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:simple_unlink SourceFile:fs/libfs.c SourceLine:809]] TruncatedOutput:false]
|
| 55/2 |
2026/03/10 03:25 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 88884
output: 1074
thoughts: 1799
Thoughts: **Analyzing a Data Race in the Filesystem**
Okay, so I'm looking at this KCSAN report. It seems pretty clear that the issue lies with how `dentry->d_flags` is being handled. I can see that `simple_unlink` is the key, called by `shmem_unlink`, and given the bug report, `shmem_unlink` seems to be the culprit. Specifically, the problem arises because `d_make_discardable` calls `dentry->d_flags &= ~DCACHE_PERSISTENT;`, which is the write. Meanwhile, `do_readlinkat` calls `d_is_symlink(path.dentry)`, which reads `dentry->d_flags`.
The read uses `d_is_symlink`, which is checking against `DCACHE_ENTRY_TYPE`. The key here is that both `DCACHE_PERSISTENT` and `DCACHE_ENTRY_TYPE` are different bits within the same 32-bit `d_flags` integer. KCSAN is flagging a data race because one thread is modifying the flags while another is reading them concurrently, without any synchronization.
Since these are read-modify-write operations on the same memory location, a data race is definitely possible. But these races can be hard to reproduce because the window of opportunity is so tiny. To make it reliably reproducible, I'm thinking we'll need to run `unlink` and `readlink` concurrently and repeat them many times.
I was considering if we could slow down the file path walk in `filename_lookup` somehow, but then I realized that the actual read happens *immediately* after that call returns. The critical window is very small – it's just the time between `filename_lookup` finishing and `d_is_symlink` being called.
So, the trick to reproducing this seems to be to make `unlink` and `readlink` happen at the same time. The `async` calls can create concurrent threads, but the current implementation only creates threads once per program. I'll need to repeat the calls, let's say ten times, to increase the likelihood of hitting the race condition. Here's what that looks like:
```
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./link0\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000d0)='./link1\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000e0)='./link2\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000f0)='./link3\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000100)='./link4\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000110)='./link5\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000120)='./link6\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000130)='./link7\x00')
unlink(&(0x7f00000000c0)='./link0\x00') (async)
readlink(&(0x7f00000000c0)='./link0\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000d0)='./link1\x00') (async)
readlink(&(0x7f00000000d0)='./link1\x00', &(0x7f000000020
|
| 56/2 |
2026/03/10 03:25 |
tool |
crash-reproducer |
0m
Args: map[ReproSyz:symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./link0\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000d0)='./link1\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000e0)='./link2\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000f0)='./link3\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000100)='./link4\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000110)='./link5\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000120)='./link6\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000130)='./link7\x00')
unlink(&(0x7f00000000c0)='./link0\x00') (async)
readlink(&(0x7f00000000c0)='./link0\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000d0)='./link1\x00') (async)
readlink(&(0x7f00000000d0)='./link1\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000e0)='./link2\x00') (async)
readlink(&(0x7f00000000e0)='./link2\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f00000000f0)='./link3\x00') (async)
readlink(&(0x7f00000000f0)='./link3\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000100)='./link4\x00') (async)
readlink(&(0x7f0000000100)='./link4\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000110)='./link5\x00') (async)
readlink(&(0x7f0000000110)='./link5\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000120)='./link6\x00') (async)
readlink(&(0x7f0000000120)='./link6\x00', &(0x7f0000000200)="", 0x64) (async)
unlink(&(0x7f0000000130)='./link7\x00') (async)
readlink(&(0x7f0000000130)='./link7\x00', &(0x7f0000000200)="", 0x64) (async)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 57/2 |
2026/03/10 03:25 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 92807
output: 938
thoughts: 2462
Thoughts: **Analyzing the Race Condition in `d_flags` Access**
Okay, so the initial focus is still on reproducing this KCSAN data race. I'm trying to figure out the right path to trigger `d_make_discardable` in conjunction with a `readlink` operation. The bug report points to `shmem_unlink`. Tracing that back, it involves `simple_unlink`, then `shmem_unlink`, leading to `vfs_unlink` and finally `filename_unlinkat`. I checked other filesystems, like `ramfs`, `bpf` and `tracefs`, but `shmem` seems to be the explicit target here.
The key is that `d_make_discardable` modifies `dentry->d_flags` by clearing `DCACHE_PERSISTENT`, and the race is with `d_is_symlink`, which *reads* the same `dentry->d_flags` to check `DCACHE_ENTRY_TYPE`. Thankfully, the bits are distinct, so we're not dealing with bitwise aliasing. The problem is a classic read-modify-write data race. The read happens immediately after the return of `filename_lookup`. So the read window is very small.
To make the race reproducible, I need concurrent calls to `unlink` and `readlink`. I initially thought about using `syz_clone` to spawn many threads, but since `async` calls do the trick, I'll just repeat the `unlink` and `readlink` calls multiple times. I tried this, but it didn't trigger, so I need to find another way.
My next idea is using `rename`, but it won't help. The correct path is going to be `unlink`. What about `rmdir`? The call to `shmem_rmdir` calls `simple_rmdir` which in turns calls `d_make_discardable`. `rmdir` is for directories, but let's consider this. `readlink` on a directory won't read it as a symlink, so it'll get to the `-EINVAL` path but reads `dentry->d_flags` on the way. Bingo! I'll try `rmdir` and `readlink` on a directory concurrently! Let's see if that works.
|
| 58/2 |
2026/03/10 03:26 |
tool |
crash-reproducer |
0m
Args: map[ReproSyz:mkdir(&(0x7f00000000c0)='./dir0\x00', 0x1ff)
mkdir(&(0x7f00000000d0)='./dir1\x00', 0x1ff)
mkdir(&(0x7f00000000e0)='./dir2\x00', 0x1ff)
mkdir(&(0x7f00000000f0)='./dir3\x00', 0x1ff)
mkdir(&(0x7f0000000100)='./dir4\x00', 0x1ff)
mkdir(&(0x7f0000000110)='./dir5\x00', 0x1ff)
mkdir(&(0x7f0000000120)='./dir6\x00', 0x1ff)
mkdir(&(0x7f0000000130)='./dir7\x00', 0x1ff)
rmdir(&(0x7f00000000c0)='./dir0\x00') (async)
readlink(&(0x7f00000000c0)='./dir0\x00', &(0x7f0000000200)="", 0x64) (async)
rmdir(&(0x7f00000000d0)='./dir1\x00') (async)
readlink(&(0x7f00000000d0)='./dir1\x00', &(0x7f0000000200)="", 0x64) (async)
rmdir(&(0x7f00000000e0)='./dir2\x00') (async)
readlink(&(0x7f00000000e0)='./dir2\x00', &(0x7f0000000200)="", 0x64) (async)
rmdir(&(0x7f00000000f0)='./dir3\x00') (async)
readlink(&(0x7f00000000f0)='./dir3\x00', &(0x7f0000000200)="", 0x64) (async)
rmdir(&(0x7f0000000100)='./dir4\x00') (async)
readlink(&(0x7f0000000100)='./dir4\x00', &(0x7f0000000200)="", 0x64) (async)
rmdir(&(0x7f0000000110)='./dir5\x00') (async)
readlink(&(0x7f0000000110)='./dir5\x00', &(0x7f0000000200)="", 0x64) (async)
rmdir(&(0x7f0000000120)='./dir6\x00') (async)
readlink(&(0x7f0000000120)='./dir6\x00', &(0x7f0000000200)="", 0x64) (async)
rmdir(&(0x7f0000000130)='./dir7\x00') (async)
readlink(&(0x7f0000000130)='./dir7\x00', &(0x7f0000000200)="", 0x64) (async)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 59/2 |
2026/03/10 03:26 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 96727
output: 842
thoughts: 1626
Thoughts: **Analyzing the Reproducer and Debugging the Race Condition**
Okay, still no crash. I need to figure out how to trigger `d_make_discardable` reliably. I know `d_make_discardable` is called from `simple_unlink`, which in turn is called by `shmem_unlink`, which is called by `vfs_unlink`, and finally by `filename_unlinkat`. Are there any other filesystems that call `d_make_discardable`? Let me quickly check the references to `d_make_discardable`. `simple_unlink` is also used by `ramfs`, `bpffs`, and `tracefs` among others, but the bug report explicitly points to `shmem_unlink`, so that's the path I should focus on.
Wait, instead of `unlink`, what if I try `rename`? `shmem_rename` uses `simple_rename`, which calls `simple_unlink` on the target if it already exists. Yes, `simple_rename` does call `simple_unlink` if the target exists, which is important here. So, `shmem_unlink` is used for `unlink`. What about `rmdir`? `shmem_rmdir` utilizes `simple_rmdir` that calls `d_make_discardable`. But `rmdir` is for directories, and `readlink` on a directory should fail with an error. No, `readlink` will succeed in `filename_lookup`, but then `d_is_symlink` will be false, and it will return `-EINVAL`. So, `readlink` on a directory will also read the `dentry->d_flags`! I've already tried that, and it didn't help.
Let's revisit the bug report. It clearly shows the memory access pattern: `d_make_discardable` writing and `readlink` reading the same memory location. The report is exactly what I'm trying to reproduce, but it isn't triggering. Hmm, is KCSAN enabled in the reproducer environment? The `crash-reproducer` should enable KCSAN if the bug report says `KCSAN: data-race`. Yes, it *does* say `KCSAN: data-race`. Maybe the race window is too small, making it unreliable? To increase the chances, I could use a loop or just repeat the calls many times. Wait, syzkaller runs the program in a loop, doesn't it? If I just provide `unlink` and `readlink`, it will run them in a loop. But, `unlink` will delete the file. So, the next iteration will fail with `ENOENT`. I need to recreate the file in each iteration! Wait, syzkaller cleans up the filesystem between iterations? No, it runs in a new mount namespace or deletes everything after each program. So, syzkaller will execute the `symlink`, then the `unlink` and `readlink`. If `unlink` happens before `readlink`, the readlink fails with `ENOENT`. If `readlink` happens first, it succeeds, and then `unlink` succeeds. The race only happens if they happen simultaneously. To increase the race probability, I can create multiple symlinks and race them all. Is there a way to run them in a loop using `syz_clone`? No.
Wait, what about using `rename` to constantly overwrite the symlink?
```
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./link0\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000d0)='./link1\x00')
rename(&(0x7f00000000c0)='./link0\x00', &(0x7f00000000d0)='./link1\x00') (async)
readlink(&(0x7f00000000d0)='./link1\x00', &(0x7f0000000200)="", 0x64) (async)
```
`rename` calls `simple_unlink` on the target if it exists. So, `rename` will call `d_make_discardable` on `./link1`. And `readlink` will read `./link1`. This is the same race, but `rename` might be a little bit slower, making the race window larger? Let me try this approach.
|
| 60/2 |
2026/03/10 03:26 |
tool |
crash-reproducer |
0m
Args: map[ReproSyz:symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000c0)='./link0\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000d0)='./link1\x00')
rename(&(0x7f00000000c0)='./link0\x00', &(0x7f00000000d0)='./link1\x00') (async)
readlink(&(0x7f00000000d0)='./link1\x00', &(0x7f0000000200)="", 0x64) (async)
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000e0)='./link2\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f00000000f0)='./link3\x00')
rename(&(0x7f00000000e0)='./link2\x00', &(0x7f00000000f0)='./link3\x00') (async)
readlink(&(0x7f00000000f0)='./link3\x00', &(0x7f0000000200)="", 0x64) (async)
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000100)='./link4\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000110)='./link5\x00')
rename(&(0x7f0000000100)='./link4\x00', &(0x7f0000000110)='./link5\x00') (async)
readlink(&(0x7f0000000110)='./link5\x00', &(0x7f0000000200)="", 0x64) (async)
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000120)='./link6\x00')
symlink(&(0x7f0000000080)='target\x00', &(0x7f0000000130)='./link7\x00')
rename(&(0x7f0000000120)='./link6\x00', &(0x7f0000000130)='./link7\x00') (async)
readlink(&(0x7f0000000130)='./link7\x00', &(0x7f0000000200)="", 0x64) (async)]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 61/2 |
2026/03/10 03:26 |
llm |
crash-repro-finder |
7m
Model:
Tokens:
input: 100242
output: 19
thoughts: 62912
|
| 62/2 |
2026/03/10 03:34 |
tool |
set-results |
0m
Args:
Results:
|
| 63/2 |
2026/03/10 03:34 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 163190
output: 1059
thoughts: 19
Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience:
**Analyzing the Compilation Process**
Alright, I've got the reproduction environment configured with the `-threaded` flag set. This immediately tells me we're dealing with a multi-threaded scenario, which means potential concurrency issues are definitely on the table for debugging. Given that setting, I anticipate that the next step is the actual compilation output. I'm already mentally running through a checklist: checking the build logs for any threading-related warnings, thinking about the implications for memory management, and anticipating that this build might take a little longer than a single-threaded execution. I'll need to pay close attention to the generated code and look for data races, deadlocks, and other common threading pitfalls. Ultimately, I'm expecting this output to provide the groundwork I need to either reproduce a threading bug or get closer to understanding the root cause. Let's see what we've got.
|