| 0/0 |
2026/03/11 07:56 |
flow |
repro |
37m
Results: map[ReproOpts: ReproSyz:r0 = socket$nl_route(0x10, 0x3, 0x0)
setsockopt$sock_int(r0, 0x1, 0x10, &(0x7f0000000000)=0x1, 0x4)
sendmsg$nl_route(r0, &(0x7f0000000040)={&(0x7f0000000080)={0x10, 0x0, 0x0, 0x0}, 0xc, &(0x7f00000000c0)={&(0x7f0000000100)=@getlink={AUTO, 0x12, 0x5, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, []}, AUTO}, 0x1, 0x0, 0x0, 0x0}, 0x0)
recvmsg(r0, &(0x7f0000000140)={0x0, 0x0, &(0x7f0000000180)=[{&(0x7f00000001c0)=""/1024, 0x400}], 0x1, &(0x7f00000005c0)=""/1024, 0x400, 0x0}, 0x0) SyzkallerCommit:86914af9098a80da53c3c5d46be980c572ee29f8]
|
| 1/1 |
2026/03/11 07:56 |
action |
kernel-checkouter |
0m
Results: map[KernelSrc:/usr/local/google/home/dvyukov/syzkaller/agent/workdir/cache/src/1244da8713a7b9651347df1a6951d3bcf4225f5a]
|
| 2/1 |
2026/03/11 07:56 |
action |
kernel-builder |
6m
Results: map[KernelObj:/usr/local/google/home/dvyukov/syzkaller/agent/workdir/cache/build/7fe8d8f2f8f27097cad5945f5eed62da0be9141d]
|
| 3/1 |
2026/03/11 08:02 |
action |
codesearch-prepare |
5m
Results: map[Index:codesearch-index]
|
| 4/1 |
2026/03/11 08:07 |
agent |
crash-repro-finder |
26m
Model:
Results: map[ReproOpts: ReproSyz:r0 = socket$nl_route(0x10, 0x3, 0x0)
setsockopt$sock_int(r0, 0x1, 0x10, &(0x7f0000000000)=0x1, 0x4)
sendmsg$nl_route(r0, &(0x7f0000000040)={&(0x7f0000000080)={0x10, 0x0, 0x0, 0x0}, 0xc, &(0x7f00000000c0)={&(0x7f0000000100)=@getlink={AUTO, 0x12, 0x5, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, []}, AUTO}, 0x1, 0x0, 0x0, 0x0}, 0x0)
recvmsg(r0, &(0x7f0000000140)={0x0, 0x0, &(0x7f0000000180)=[{&(0x7f00000001c0)=""/1024, 0x400}], 0x1, &(0x7f00000005c0)=""/1024, 0x400, 0x0}, 0x0)]
Instruction:
You are an expert in the Linux kernel fuzzing. Your goal is to write a syzkaller program to trigger a specific bug.
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 = 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 = integer
region-size = integer
integer = dec-integer | oct-integer | "0x" 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: KMSAN: uninit-value in put_cmsg
The bug report to reproduce:
=====================================================
BUG: KMSAN: uninit-value in put_cmsg+0x534/0xbc0 net/core/scm.c:280
put_cmsg+0x534/0xbc0 net/core/scm.c:280
__scm_recv_common+0x2fb/0x910 net/core/scm.c:517
scm_recv+0x55/0xe0 net/core/scm.c:531
netlink_recvmsg+0xd45/0xfe0 net/netlink/af_netlink.c:1983
sock_recvmsg_nosec net/socket.c:1078 [inline]
sock_recvmsg+0x27b/0x310 net/socket.c:1100
____sys_recvmsg+0x193/0x620 net/socket.c:2812
___sys_recvmsg+0x20b/0x850 net/socket.c:2854
__sys_recvmsg net/socket.c:2887 [inline]
__do_sys_recvmsg net/socket.c:2893 [inline]
__se_sys_recvmsg net/socket.c:2890 [inline]
__x64_sys_recvmsg+0x20e/0x3d0 net/socket.c:2890
x64_sys_call+0x35cc/0x3ea0 arch/x86/include/generated/asm/syscalls_64.h:48
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x134/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Local variable ucreds created at:
__scm_recv_common+0x1bb/0x910 net/core/scm.c:511
scm_recv+0x55/0xe0 net/core/scm.c:531
CPU: 0 UID: 0 PID: 10460 Comm: udevd Not tainted syzkaller #0 PREEMPT(full)
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_nilfs2.txt
fs_ioctl_ocfs2.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
|
| 5/2 |
2026/03/11 08:07 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 12952
output: 42
thoughts: 393
Thoughts: **Debugging a KMSAN Uninitialized Value in SCM Receive**
Okay, so I've got this bug report, a KMSAN uninit-value error, specifically in `put_cmsg`. The stack trace points to `net/core/scm.c` at line 280, and it looks like the issue is related to the `__scm_recv_common` function. It seems this error cascades up through the `scm_recv`, `netlink_recvmsg`, and standard socket receive functions, right down to the system call level. The bug is triggered in `net/core/scm.c`, then it’s used from `net/netlink/af_netlink.c`, which leads me to suspect a flaw in how SCM credentials are being handled during a receive operation. The trace highlights the local variable `ucreds` being created in `__scm_recv_common`. That function call is responsible for handling the "send control message" features of the Socket Control Message (SCM) protocol. Time to dive into those two files and see what's going on! This should be straightforward, though I know how these sorts of intermittent issues can be.
|
| 6/2 |
2026/03/11 08:07 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/scm.c IncludeLines:true Name:__scm_recv_common]
Results: map[SourceCode: 497: static bool __scm_recv_common(struct sock *sk, struct msghdr *msg,
498: struct scm_cookie *scm, int flags)
499: {
500: if (!msg->msg_control) {
501: if (sk->sk_scm_credentials || sk->sk_scm_pidfd ||
502: scm->fp || scm_has_secdata(sk))
503: msg->msg_flags |= MSG_CTRUNC;
504:
505: scm_destroy(scm);
506: return false;
507: }
508:
509: if (sk->sk_scm_credentials) {
510: struct user_namespace *current_ns = current_user_ns();
511: struct ucred ucreds = {
512: .pid = scm->creds.pid,
513: .uid = from_kuid_munged(current_ns, scm->creds.uid),
514: .gid = from_kgid_munged(current_ns, scm->creds.gid),
515: };
516:
517: put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
518: }
519:
520: scm_passec(sk, msg, scm);
521:
522: if (scm->fp)
523: scm_detach_fds(msg, scm);
524:
525: return true;
526: }
SourceFile:net/core/scm.c]
|
| 7/2 |
2026/03/11 08:07 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 14132
output: 38
thoughts: 144
Thoughts: **Uninitialized Value Bug in `put_cmsg` for `ucreds`**
Okay, so I've pinpointed the bug: it looks like an uninitialized value issue in the `put_cmsg` function, specifically related to the `ucreds` struct. The code shows the initialization:
```c
struct ucred ucreds = {
.pid = scm->creds.pid,
.uid = from_kuid_munged(current_ns, scm->creds.uid),
.gid = from_kgid_munged(current_ns, scm->creds.gid),
};
```
Wait a second...I need to double-check something. Is `struct ucred` defined in `include/uapi/linux/socket.h`? Let me quickly cross-reference its layout and members. I need to make sure I haven't missed something fundamental about its structure that might be relevant here. Let's see...
|
| 8/2 |
2026/03/11 08:08 |
tool |
codesearch-struct-layout |
0m
Args: map[ContextFile:net/core/scm.c FieldOffset:<nil> Name:ucred]
Results: map[Fields:[map[Name:pid OffsetBits:0 SizeBits:32] map[Name:uid OffsetBits:32 SizeBits:32] map[Name:gid OffsetBits:64 SizeBits:32]]]
|
| 9/2 |
2026/03/11 08:08 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 14602
output: 39
thoughts: 124
Thoughts: **Analyzing the Credential Structure**
Okay, so I'm looking at this `struct ucred`, and immediately my expert brain starts running through the implications. I see that it holds `pid`, `uid`, and `gid`, which all are core process identity and security attributes. It's a total of 96 bits, or 12 bytes. My immediate thought is, "Is there any padding going on here?" We're dealing with memory, so alignment concerns always spring to mind.
Let's break it down. `pid` is 32 bits, `uid` is 32 bits, and `gid` is also 32 bits. That, yes, comes out to the expected 12 bytes total. So, no apparent padding is in play here.
Now, a red flag pops up, and I ask myself: "Why would there be an *uninitialized* value at all?" This makes me think about potential security vulnerabilities. Is it possible that `scm->creds.pid` might be uninitialized? Or perhaps the `uid` or `gid` fields are being used without proper initialization, which could be a source of problems.
Time to shift gears and delve deeper. I'm going to consult the definition of `struct scm_cookie` to get more context and understand how these credentials are being handled. I need to understand the full picture here.
|
| 10/2 |
2026/03/11 08:08 |
tool |
codesearch-struct-layout |
0m
Args: map[ContextFile:net/core/scm.c FieldOffset:<nil> Name:scm_cookie]
Results: map[Fields:[map[Name:pid OffsetBits:0 SizeBits:64] map[Name:fp OffsetBits:64 SizeBits:64] map[Name:creds OffsetBits:128 SizeBits:96] map[Name:secid OffsetBits:224 SizeBits:32]]]
|
| 11/2 |
2026/03/11 08:08 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 15148
output: 40
thoughts: 28
Thoughts: Here's my thought process, as if I were considering this myself:
**Diving into SCM Credentials**
Okay, so I see `scm->creds`. My initial assumption is that this is likely a `struct scm_creds`. Given my experience with socket control messages and security contexts, it's a pretty reasonable leap. But assumptions can bite, so let's verify that quickly. I'll need to pull up the definition of `struct scm_creds` and make sure it aligns with what I expect – typically, things like user IDs, group IDs, process IDs, and maybe even security attributes, depending on the system and kernel version. I need to confirm the structure layout and its members before I can confidently understand how `scm->creds` is being used and what potential security implications might be at play here. This is a critical first step for any further analysis.
|
| 12/2 |
2026/03/11 08:08 |
tool |
codesearch-struct-layout |
0m
Args: map[ContextFile:net/core/scm.c FieldOffset:<nil> Name:scm_creds]
Results: map[Fields:[map[Name:pid OffsetBits:0 SizeBits:32] map[Name:uid OffsetBits:32 SizeBits:32] map[Name:gid OffsetBits:64 SizeBits:32]]]
|
| 13/2 |
2026/03/11 08:08 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 15471
output: 45
thoughts: 70
Thoughts: Here's my summary, as the expert:
**Investigating Netlink Message Reception**
Okay, so I'm digging into this `scm_cookie` structure, and the offset of its `creds` member is tripping me up. It looks like it's at offset 128, which translates to 16 bytes. That seems unusual, and I need to figure out *why* it's so far in.
My first thought is where this `scm_cookie` is initialized. Let me quickly check the code where it's populated. I think it is in `netlink_recvmsg`... Yes, that is right!
Now, the natural next step is to examine `netlink_recvmsg` itself. Let me navigate to `net/netlink/af_netlink.c` and take a closer look at the function, and see how the structure is being used, and if I can glean why `creds` is located where it is. Hopefully, the context will give me some clues as to what's happening.
|
| 14/2 |
2026/03/11 08:08 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_recvmsg]
Results: map[SourceCode:1901: static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1902: int flags)
1903: {
1904: struct scm_cookie scm;
1905: struct sock *sk = sock->sk;
1906: struct netlink_sock *nlk = nlk_sk(sk);
1907: size_t copied, max_recvmsg_len;
1908: struct sk_buff *skb, *data_skb;
1909: int err, ret;
1910:
1911: if (flags & MSG_OOB)
1912: return -EOPNOTSUPP;
1913:
1914: copied = 0;
1915:
1916: skb = skb_recv_datagram(sk, flags, &err);
1917: if (skb == NULL)
1918: goto out;
1919:
1920: data_skb = skb;
1921:
1922: #ifdef CONFIG_COMPAT_NETLINK_MESSAGES
1923: if (unlikely(skb_shinfo(skb)->frag_list)) {
1924: /*
1925: * If this skb has a frag_list, then here that means that we
1926: * will have to use the frag_list skb's data for compat tasks
1927: * and the regular skb's data for normal (non-compat) tasks.
1928: *
1929: * If we need to send the compat skb, assign it to the
1930: * 'data_skb' variable so that it will be used below for data
1931: * copying. We keep 'skb' for everything else, including
1932: * freeing both later.
1933: */
1934: if (flags & MSG_CMSG_COMPAT)
1935: data_skb = skb_shinfo(skb)->frag_list;
1936: }
1937: #endif
1938:
1939: /* Record the max length of recvmsg() calls for future allocations */
1940: max_recvmsg_len = max(READ_ONCE(nlk->max_recvmsg_len), len);
1941: max_recvmsg_len = min_t(size_t, max_recvmsg_len,
1942: SKB_WITH_OVERHEAD(32768));
1943: WRITE_ONCE(nlk->max_recvmsg_len, max_recvmsg_len);
1944:
1945: copied = data_skb->len;
1946: if (len < copied) {
1947: msg->msg_flags |= MSG_TRUNC;
1948: copied = len;
1949: }
1950:
1951: err = skb_copy_datagram_msg(data_skb, 0, msg, copied);
1952:
1953: if (msg->msg_name) {
1954: DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name);
1955: addr->nl_family = AF_NETLINK;
1956: addr->nl_pad = 0;
1957: addr->nl_pid = NETLINK_CB(skb).portid;
1958: addr->nl_groups = netlink_group_mask(NETLINK_CB(skb).dst_group);
1959: msg->msg_namelen = sizeof(*addr);
1960: }
1961:
1962: if (nlk_test_bit(RECV_PKTINFO, sk))
1963: netlink_cmsg_recv_pktinfo(msg, skb);
1964: if (nlk_test_bit(LISTEN_ALL_NSID, sk))
1965: netlink_cmsg_listen_all_nsid(sk, msg, skb);
1966:
1967: memset(&scm, 0, sizeof(scm));
1968: scm.creds = *NETLINK_CREDS(skb);
1969: if (flags & MSG_TRUNC)
1970: copied = data_skb->len;
1971:
1972: skb_free_datagram(sk, skb);
1973:
1974: if (READ_ONCE(nlk->cb_running) &&
1975: atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
1976: ret = netlink_dump(sk, false);
1977: if (ret) {
1978: WRITE_ONCE(sk->sk_err, -ret);
1979: sk_error_report(sk);
1980: }
1981: }
1982:
1983: scm_recv(sock, msg, &scm, flags);
1984: out:
1985: netlink_rcv_wake(sk);
1986: return err ? : copied;
1987: }
SourceFile:net/netlink/af_netlink.c]
|
| 15/2 |
2026/03/11 08:08 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 17279
output: 45
thoughts: 81
Thoughts: Here's my summary, as the expert:
**Diving into `netlink_recvmsg`**
Okay, I'm tracing through `netlink_recvmsg` here. The first thing that jumps out is the initialization of the `scm` structure with `memset` followed by the assignment `scm.creds = *NETLINK_CREDS(skb);`. Right away, the line that involves `NETLINK_CREDS(skb)` causes a small pause. I'm assuming that it is getting some kind of credentials from the socket buffer and is returning a pointer to a struct. But what exactly is `NETLINK_CREDS` doing? I need to quickly verify that `NETLINK_CREDS` does in fact return a pointer to a `struct scm_creds`. Need to check its definition right away to confirm my understanding.
|
| 16/2 |
2026/03/11 08:08 |
tool |
codesearch-definition-source |
0m
Error:
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:NETLINK_CREDS]
Results: map[SourceCode: SourceFile:]
|
| 17/2 |
2026/03/11 08:08 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 17608
output: 21
thoughts: 12
Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience:
**Diving into NETLINK_CREDS**
Okay, so I need to understand something related to credentials, and my initial hunch tells me that `NETLINK_CREDS` might be a relevant keyword to start with. Given my experience, I'm thinking this likely relates to how credentials are handled within the Netlink framework. I want to quickly explore the code base for mentions of `NETLINK_CREDS`, hoping to uncover where this constant is defined, used, and what context it provides. This grep should quickly reveal the relevant code locations and allow me to determine, at a low level, where the system is interacting with the credential information. I'm focusing on the low level interaction points because I know there can be some nuance in how credentials are represented on the wire.
|
| 18/2 |
2026/03/11 08:08 |
tool |
grepper |
0m
Args: map[Expression:#define NETLINK_CREDS]
Results: map[Output:include/linux/netlink.h=25=struct netlink_skb_parms {
--
include/linux/netlink.h-35-#define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb))
include/linux/netlink.h:36:#define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds)
include/linux/netlink.h-37-#define NETLINK_CTX_SIZE 48
]
|
| 19/2 |
2026/03/11 08:08 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 17956
output: 45
thoughts: 63
Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience:
**Diving into Netlink Credential Handling**
Right, so I'm looking at how Netlink credentials are being managed here, and the first thing that jumps out is `NETLINK_CB(skb).creds`. This is the familiar `struct scm_creds` which represents the security credentials. Hold on a second, that's not quite right. Thinking more deeply, `NETLINK_CB(skb)` actually resolves to `struct netlink_skb_parms`. I'd best verify how these structures interrelate before I go further and make any assumptions. Let me quickly refresh my memory on the details within the `struct netlink_skb_parms` itself. Always important to confirm the basics!
|
| 20/2 |
2026/03/11 08:08 |
tool |
codesearch-struct-layout |
0m
Args: map[ContextFile:include/linux/netlink.h FieldOffset:<nil> Name:netlink_skb_parms]
Results: map[Fields:[map[Name:creds OffsetBits:0 SizeBits:96] map[Name:portid OffsetBits:96 SizeBits:32] map[Name:dst_group OffsetBits:128 SizeBits:32] map[Name:flags OffsetBits:160 SizeBits:32] map[Name:sk OffsetBits:192 SizeBits:64] map[Name:nsid_is_set OffsetBits:256 SizeBits:8] map[Name:nsid OffsetBits:288 SizeBits:32]]]
|
| 21/2 |
2026/03/11 08:08 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 18393
output: 45
thoughts: 154
Thoughts: **Uninitialized Credentials: A Potential Security Concern**
Okay, so I'm looking at this `creds` structure, and it's starting at offset zero with a size of 96 bits, or 12 bytes. Hmm, the code snippet `scm.creds = *NETLINK_CREDS(skb);` is making a direct copy of 12 bytes. That's fine, *if* `NETLINK_CREDS(skb)` is properly initialized. But what if it *isn't* initialized? Then `scm.creds` ends up with uninitialized data. That's a classic source of problems, and frankly, a potential security vulnerability.
I need to understand under what circumstances `NETLINK_CREDS(skb)` could be uninitialized. Ah, `skb->cb` is an array of 48 bytes. Okay, so that's where this data lives. Now, when an `skb` is first allocated, I believe the `cb` array isn't necessarily initialized by default, right?
So, where is this `cb` array being set? The key is to see where `NETLINK_CB(skb)` is initialized. I think in `netlink_sendmsg`, that's where it's populated. Let me go check that out... I'm going to track down the initialization flow of that `skb->cb` array in `netlink_sendmsg` and see if the initialization path is always followed correctly. That's where I need to focus my analysis.
|
| 22/2 |
2026/03/11 08:08 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_sendmsg]
Results: map[SourceCode:1812: static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
1813: {
1814: struct sock *sk = sock->sk;
1815: struct netlink_sock *nlk = nlk_sk(sk);
1816: DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name);
1817: u32 dst_portid;
1818: u32 dst_group;
1819: struct sk_buff *skb;
1820: int err;
1821: struct scm_cookie scm;
1822: u32 netlink_skb_flags = 0;
1823:
1824: if (msg->msg_flags & MSG_OOB)
1825: return -EOPNOTSUPP;
1826:
1827: if (len == 0) {
1828: pr_warn_once("Zero length message leads to an empty skb\n");
1829: return -ENODATA;
1830: }
1831:
1832: err = scm_send(sock, msg, &scm, true);
1833: if (err < 0)
1834: return err;
1835:
1836: if (msg->msg_namelen) {
1837: err = -EINVAL;
1838: if (msg->msg_namelen < sizeof(struct sockaddr_nl))
1839: goto out;
1840: if (addr->nl_family != AF_NETLINK)
1841: goto out;
1842: dst_portid = addr->nl_pid;
1843: dst_group = ffs(addr->nl_groups);
1844: err = -EPERM;
1845: if ((dst_group || dst_portid) &&
1846: !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
1847: goto out;
1848: netlink_skb_flags |= NETLINK_SKB_DST;
1849: } else {
1850: /* Paired with WRITE_ONCE() in netlink_connect() */
1851: dst_portid = READ_ONCE(nlk->dst_portid);
1852: dst_group = READ_ONCE(nlk->dst_group);
1853: }
1854:
1855: /* Paired with WRITE_ONCE() in netlink_insert() */
1856: if (!READ_ONCE(nlk->bound)) {
1857: err = netlink_autobind(sock);
1858: if (err)
1859: goto out;
1860: } else {
1861: /* Ensure nlk is hashed and visible. */
1862: smp_rmb();
1863: }
1864:
1865: err = -EMSGSIZE;
1866: if (len > sk->sk_sndbuf - 32)
1867: goto out;
1868: err = -ENOBUFS;
1869: skb = netlink_alloc_large_skb(len, dst_group);
1870: if (skb == NULL)
1871: goto out;
1872:
1873: NETLINK_CB(skb).portid = nlk->portid;
1874: NETLINK_CB(skb).dst_group = dst_group;
1875: NETLINK_CB(skb).creds = scm.creds;
1876: NETLINK_CB(skb).flags = netlink_skb_flags;
1877:
1878: err = -EFAULT;
1879: if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
1880: kfree_skb(skb);
1881: goto out;
1882: }
1883:
1884: err = security_netlink_send(sk, skb);
1885: if (err) {
1886: kfree_skb(skb);
1887: goto out;
1888: }
1889:
1890: if (dst_group) {
1891: refcount_inc(&skb->users);
1892: netlink_broadcast(sk, skb, dst_portid, dst_group, GFP_KERNEL);
1893: }
1894: err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags & MSG_DONTWAIT);
1895:
1896: out:
1897: scm_destroy(&scm);
1898: return err;
1899: }
SourceFile:net/netlink/af_netlink.c]
|
| 23/2 |
2026/03/11 08:08 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 20316
output: 43
thoughts: 54
Thoughts: Okay, here's my breakdown of what's going on, thinking through this code:
**Diving into Netlink Message Credentials**
Alright, I'm tracing through this `netlink_sendmsg` function. I see this line: `NETLINK_CB(skb).creds = scm.creds;` Immediately, my expert antennae go up. I'm thinking, "Hang on a second… Where did `scm.creds` get populated?" It's clear that the credentials for the socket buffer (`skb`) are being set from something called `scm.creds`. This isn't immediately obvious, I need to understand this.
So, the next logical step is to dive into the call that seems to initialize that `scm` structure. It's likely this `scm_send` function I need to look into. Let's see how `scm.creds` is set there. I'm betting that's where the magic, or potential vulnerability, lies in establishing the credentials context.
|
| 24/2 |
2026/03/11 08:08 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:scm_send]
Results: map[SourceCode: 91: static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
92: struct scm_cookie *scm, bool forcecreds)
93: {
94: memset(scm, 0, sizeof(*scm));
95: scm->creds.uid = INVALID_UID;
96: scm->creds.gid = INVALID_GID;
97: if (forcecreds)
98: scm_set_cred(scm, task_tgid(current), current_uid(), current_gid());
99: unix_get_peersec_dgram(sock, scm);
100: if (msg->msg_controllen <= 0)
101: return 0;
102: return __scm_send(sock, msg, scm);
103: }
SourceFile:include/net/scm.h]
|
| 25/2 |
2026/03/11 08:08 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 20888
output: 44
thoughts: 144
Thoughts: **My Concerns Regarding Credential Handling in Netlink Communication**
Okay, so I'm looking at `scm_send` and immediately see that `memset` clearing the `scm` struct. Specifically, `scm->creds` gets zeroed out. That's good, it ensures a clean slate, a fully initialized `scm->creds`. Then, it's assigned to `NETLINK_CB(skb).creds`. But hang on a second... what if this `skb` *isn't* being sent through the usual `netlink_sendmsg` path?
My immediate concern is: what if someone uses `netlink_unicast` directly? Or, and this is a big one, what about `netlink_recvmsg` receiving an `skb` that wasn't allocated here? What if it's an `skb` that came from some other kernel function? I'm thinking of functions like `netlink_ack` or even `netlink_broadcast`. If the `skb` originated somewhere else, the `scm->creds` zeroing won't have occurred. The credential information is going to be garbage, right?
I need to dig into `netlink_ack` to see how it allocates and handles its `skb` structures. This could be a significant security vulnerability if credentials from an unintended source are being relied upon. This could mean credential information being leaked, or allowing an attacker to spoof source information. I need to figure out the flow. I need to investigate how those packets are built and if that initialization is happening in those other pathways. It's a potential risk, and I need to verify how these other paths initialize their creds.
|
| 26/2 |
2026/03/11 08:08 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_ack]
Results: map[SourceCode:2463: void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
2464: const struct netlink_ext_ack *extack)
2465: {
2466: struct sk_buff *skb;
2467: struct nlmsghdr *rep;
2468: struct nlmsgerr *errmsg;
2469: size_t payload = sizeof(*errmsg);
2470: struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk);
2471: unsigned int flags = 0;
2472: size_t tlvlen;
2473:
2474: /* Error messages get the original request appended, unless the user
2475: * requests to cap the error message, and get extra error data if
2476: * requested.
2477: */
2478: if (err && !test_bit(NETLINK_F_CAP_ACK, &nlk->flags))
2479: payload += nlmsg_len(nlh);
2480: else
2481: flags |= NLM_F_CAPPED;
2482:
2483: tlvlen = netlink_ack_tlv_len(nlk, err, extack);
2484: if (tlvlen)
2485: flags |= NLM_F_ACK_TLVS;
2486:
2487: skb = nlmsg_new(payload + tlvlen, GFP_KERNEL);
2488: if (!skb)
2489: goto err_skb;
2490:
2491: rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
2492: NLMSG_ERROR, sizeof(*errmsg), flags);
2493: if (!rep)
2494: goto err_bad_put;
2495: errmsg = nlmsg_data(rep);
2496: errmsg->error = err;
2497: errmsg->msg = *nlh;
2498:
2499: if (!(flags & NLM_F_CAPPED)) {
2500: if (!nlmsg_append(skb, nlmsg_len(nlh)))
2501: goto err_bad_put;
2502:
2503: memcpy(nlmsg_data(&errmsg->msg), nlmsg_data(nlh),
2504: nlmsg_len(nlh));
2505: }
2506:
2507: if (tlvlen)
2508: netlink_ack_tlv_fill(skb, nlh, err, extack);
2509:
2510: nlmsg_end(skb, rep);
2511:
2512: nlmsg_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid);
2513:
2514: return;
2515:
2516: err_bad_put:
2517: nlmsg_free(skb);
2518: err_skb:
2519: WRITE_ONCE(NETLINK_CB(in_skb).sk->sk_err, ENOBUFS);
2520: sk_error_report(NETLINK_CB(in_skb).sk);
2521: }
SourceFile:net/netlink/af_netlink.c]
|
| 27/2 |
2026/03/11 08:08 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 22421
output: 44
thoughts: 102
Thoughts: **Netlink ACK Deep Dive**
Okay, so I'm tracing through this `netlink_ack` function, and the first thing that jumps out is the allocation of the socket buffer, `skb = nlmsg_new(...)`. Right, `nlmsg_new` calls `alloc_skb`, that's standard practice. Then it moves on to calling `nlmsg_unicast`. Hang on a second, that's not quite right in my head. I know I've seen that before. Yes, `nlmsg_unicast` then calls `netlink_unicast`.
Now I'm thinking about the control block, specifically `NETLINK_CB(skb)`. Does `nlmsg_new` initialize that correctly? I need to quickly refresh my memory on the interactions of these functions. Looks like I'll be revisiting `nlmsg_new` and `nlmsg_unicast`. I'll go check the code to be certain. I want to be 100% sure this sequence is correct.
|
| 28/2 |
2026/03/11 08:09 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:nlmsg_new]
Results: map[SourceCode:1045: /**
1046: * nlmsg_new - Allocate a new netlink message
1047: * @payload: size of the message payload
1048: * @flags: the type of memory to allocate.
1049: *
1050: * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known
1051: * and a good default is needed.
1052: */
1053: static inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags)
1054: {
1055: return alloc_skb(nlmsg_total_size(payload), flags);
1056: }
SourceFile:include/net/netlink.h]
|
| 29/2 |
2026/03/11 08:09 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 23007
output: 45
thoughts: 27
Thoughts: Here's a summary of my thought process, as requested:
**Network Socket Buffer Allocation Concerns**
Okay, so I'm digging into this code and immediately something pops out. The `alloc_skb` function, as I recall, doesn't zero out the `skb->cb` field in the socket buffer. That's a potential vulnerability, a lurking bug waiting to bite us if we're not careful. I need to make sure this isn't causing unexpected behavior or security issues down the line.
Let's shift focus to `nlmsg_unicast` for a moment. I need to understand how this function utilizes socket buffers. Knowing whether it assumes `skb->cb` is initialized, or if it explicitly sets it, is crucial here. Understanding this can help me identify possible risks stemming from the uninitialized `skb->cb` in `alloc_skb`. This seems like the logical next step in my investigation.
|
| 30/2 |
2026/03/11 08:09 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:nlmsg_unicast]
Results: map[SourceCode:1188: /**
1189: * nlmsg_unicast - unicast a netlink message
1190: * @sk: netlink socket to spread message to
1191: * @skb: netlink message as socket buffer
1192: * @portid: netlink portid of the destination socket
1193: */
1194: static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 portid)
1195: {
1196: int err;
1197:
1198: err = netlink_unicast(sk, skb, portid, MSG_DONTWAIT);
1199: if (err > 0)
1200: err = 0;
1201:
1202: return err;
1203: }
SourceFile:include/net/netlink.h]
|
| 31/2 |
2026/03/11 08:09 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 23541
output: 45
thoughts: 38
Thoughts: Okay, here's my interpretation of those thoughts, tailored for an expert audience, presented in the first person:
**Decoding the Netlink Unicast Path**
Alright, let me just run that thought through again... *netlink_unicast* sends the Socket Buffer (skb) *directly*. Right, no detour, no extra copies. It's a key function in getting messages to their destination. But... does it handle initializing `NETLINK_CB(skb).creds`? That's what I really need to confirm. It's crucial for the security context and the eventual authorization checks. If `netlink_unicast` isn't setting the credentials correctly, that represents a potentially serious vulnerability; allowing someone to inject a message pretending to have higher privileges. Now to drill down into the kernel code and check it.
|
| 32/2 |
2026/03/11 08:09 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_unicast]
Results: map[SourceCode:1327: int netlink_unicast(struct sock *ssk, struct sk_buff *skb,
1328: u32 portid, int nonblock)
1329: {
1330: struct sock *sk;
1331: int err;
1332: long timeo;
1333:
1334: skb = netlink_trim(skb, gfp_any());
1335:
1336: timeo = sock_sndtimeo(ssk, nonblock);
1337: retry:
1338: sk = netlink_getsockbyportid(ssk, portid);
1339: if (IS_ERR(sk)) {
1340: kfree_skb(skb);
1341: return PTR_ERR(sk);
1342: }
1343: if (netlink_is_kernel(sk))
1344: return netlink_unicast_kernel(sk, skb, ssk);
1345:
1346: if (sk_filter(sk, skb)) {
1347: err = skb->len;
1348: kfree_skb(skb);
1349: sock_put(sk);
1350: return err;
1351: }
1352:
1353: err = netlink_attachskb(sk, skb, &timeo, ssk);
1354: if (err == 1)
1355: goto retry;
1356: if (err)
1357: return err;
1358:
1359: return netlink_sendskb(sk, skb);
1360: }
SourceFile:net/netlink/af_netlink.c]
|
| 33/2 |
2026/03/11 08:09 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 24308
output: 48
thoughts: 151
Thoughts: **Uninitialized Memory in Netlink Communication**
Okay, so I'm digging into this `netlink` code, and I've hit a potential problem. It seems like if `netlink_unicast` doesn't explicitly initialize `NETLINK_CB(skb).creds`, then we're going to have an issue when `netlink_recvmsg` tries to access that data. It's essentially reading uninitialized memory, which is a big no-no.
Now, wait a minute... I'm remembering that `netlink_ack` sends an acknowledgement message back to user space. The critical question here is whether `netlink_ack` handles initializing `NETLINK_CB(skb).creds`. If it doesn't, that just exacerbates the problem.
And after a quick review, it's pretty clear... `netlink_ack` doesn't initialize the structure. Hmm, that's not good.
But, `netlink_ack` is called by `netlink_rcv_skb`, and that's when `NLM_F_ACK` is set, or in case of an error. So, the crucial place to look is `netlink_rcv_skb` to be sure what's going on. Let's dig deeper into the code there.
|
| 34/2 |
2026/03/11 08:09 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_rcv_skb]
Results: map[SourceCode:2524: int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
2525: struct nlmsghdr *,
2526: struct netlink_ext_ack *))
2527: {
2528: struct netlink_ext_ack extack;
2529: struct nlmsghdr *nlh;
2530: int err;
2531:
2532: while (skb->len >= nlmsg_total_size(0)) {
2533: int msglen;
2534:
2535: memset(&extack, 0, sizeof(extack));
2536: nlh = nlmsg_hdr(skb);
2537: err = 0;
2538:
2539: if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len)
2540: return 0;
2541:
2542: /* Only requests are handled by the kernel */
2543: if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
2544: goto ack;
2545:
2546: /* Skip control messages */
2547: if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
2548: goto ack;
2549:
2550: err = cb(skb, nlh, &extack);
2551: if (err == -EINTR)
2552: goto skip;
2553:
2554: ack:
2555: if (nlh->nlmsg_flags & NLM_F_ACK || err)
2556: netlink_ack(skb, nlh, err, &extack);
2557:
2558: skip:
2559: msglen = NLMSG_ALIGN(nlh->nlmsg_len);
2560: if (msglen > skb->len)
2561: msglen = skb->len;
2562: skb_pull(skb, msglen);
2563: }
2564:
2565: return 0;
2566: }
SourceFile:net/netlink/af_netlink.c]
|
| 35/2 |
2026/03/11 08:09 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 25447
output: 44
thoughts: 96
Thoughts: Okay, let me think this through.
**Analyzing Netlink Acknowledgement and Credentials Handling**
Right, so `netlink_ack` is sending an `skb` back to the socket. That's the key. Now, if the socket has `sk->sk_scm_credentials` set, then `netlink_recvmsg` is supposed to pull the credentials from `scm.creds` and store them in `ucreds`. But hang on a second... `netlink_ack` *should* be setting `NETLINK_CB(skb).creds`, right? Because if it doesn't, we're going to have a gap in the credential propagation. I need to go back and double-check `netlink_ack`. Something feels off here, and I need to make sure I haven't missed a crucial detail in the flow. This could be a significant security concern if the credentials aren't properly passed along with the acknowledgement. Let me re-examine that code path.
|
| 36/2 |
2026/03/11 08:09 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_ack]
Results: map[SourceCode:2463: void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
2464: const struct netlink_ext_ack *extack)
2465: {
2466: struct sk_buff *skb;
2467: struct nlmsghdr *rep;
2468: struct nlmsgerr *errmsg;
2469: size_t payload = sizeof(*errmsg);
2470: struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk);
2471: unsigned int flags = 0;
2472: size_t tlvlen;
2473:
2474: /* Error messages get the original request appended, unless the user
2475: * requests to cap the error message, and get extra error data if
2476: * requested.
2477: */
2478: if (err && !test_bit(NETLINK_F_CAP_ACK, &nlk->flags))
2479: payload += nlmsg_len(nlh);
2480: else
2481: flags |= NLM_F_CAPPED;
2482:
2483: tlvlen = netlink_ack_tlv_len(nlk, err, extack);
2484: if (tlvlen)
2485: flags |= NLM_F_ACK_TLVS;
2486:
2487: skb = nlmsg_new(payload + tlvlen, GFP_KERNEL);
2488: if (!skb)
2489: goto err_skb;
2490:
2491: rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
2492: NLMSG_ERROR, sizeof(*errmsg), flags);
2493: if (!rep)
2494: goto err_bad_put;
2495: errmsg = nlmsg_data(rep);
2496: errmsg->error = err;
2497: errmsg->msg = *nlh;
2498:
2499: if (!(flags & NLM_F_CAPPED)) {
2500: if (!nlmsg_append(skb, nlmsg_len(nlh)))
2501: goto err_bad_put;
2502:
2503: memcpy(nlmsg_data(&errmsg->msg), nlmsg_data(nlh),
2504: nlmsg_len(nlh));
2505: }
2506:
2507: if (tlvlen)
2508: netlink_ack_tlv_fill(skb, nlh, err, extack);
2509:
2510: nlmsg_end(skb, rep);
2511:
2512: nlmsg_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid);
2513:
2514: return;
2515:
2516: err_bad_put:
2517: nlmsg_free(skb);
2518: err_skb:
2519: WRITE_ONCE(NETLINK_CB(in_skb).sk->sk_err, ENOBUFS);
2520: sk_error_report(NETLINK_CB(in_skb).sk);
2521: }
SourceFile:net/netlink/af_netlink.c]
|
| 37/2 |
2026/03/11 08:09 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 26785
output: 21
thoughts: 696
Thoughts: **Uninitialized Credentials in Netlink ACK Messages**
Okay, so I've been digging into this Netlink issue, and it looks like there's a problem with uninitialized credentials. Specifically, the `NETLINK_CB(skb).creds` field within the `skb` is not getting initialized in the ACK flow. Let me walk through this.
It all starts with `nlmsg_new`, which allocates an `skb`. Then, `nlmsg_put` calls `__nlmsg_put`. `nlmsg_unicast` then calls `netlink_unicast`. The problem is that none of these functions initialize the `creds` field within the Control Block (`NETLINK_CB`) of the `skb`. And to my surprise, `netlink_unicast` doesn't do it either. That means `NETLINK_CB(skb).creds` remains uninitialized.
This uninitialized data then causes a problem down the line. When `netlink_recvmsg` receives the `skb`, it copies the uninitialized `NETLINK_CB(skb).creds` into `scm.creds`. Then, it calls `scm_recv`, which calls `__scm_recv_common`. Here's the kicker: If `sk->sk_scm_credentials` is set to true (i.e. we enable `SO_PASSCRED`), `__scm_recv_common` reads the uninitialized `scm.creds` and puts it into `ucreds`. After that, `put_cmsg` is called with `ucreds`, which triggers KMSAN's uninit-value!
So, the issue is how these credentials are being handled when an ACK is sent. I can reproduce this vulnerability by creating a Netlink socket, enabling `SO_PASSCRED`, and then sending a message that will trigger an ACK from the kernel (like an invalid message with the `NLM_F_ACK` flag set). I then use `recvmsg` to receive the ACK message. That's the vector.
Now I need to test this hypothesis. I'll write a program to reproduce the issue, and that's when it hit me that a syzkaller program is the right way to approach this. Let me quickly sketch this out in syzlang.
Essentially, I create a Netlink route socket, enable `SO_PASSCRED`, send a message, and then receive the ACK. Let me review `socket.txt` for `setsockopt$sock_int` to make sure I get the level and optname correct for `SO_PASSCRED`, which is `SOL_SOCKET` and `SO_PASSCRED`. I know what level and optname values to use when setting this option.
|
| 38/2 |
2026/03/11 08:09 |
tool |
grepper |
0m
Error:
Args: map[Expression:setsockopt\$sock_int]
Results:
|
| 39/2 |
2026/03/11 08:09 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 28108
output: 17
thoughts: 15
Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience:
**Investigating `setsockopt` within `socket.txt`**
Okay, time to dive into `setsockopt`. I'm going to start by reviewing its usage and purpose as it's implemented in `socket.txt`. My gut feeling is that something specific is being configured here, but it's important to not assume anything before checking. I need to understand exactly which socket options are being manipulated, and in what context. Are we dealing with buffering, timeouts, connection state, or something more specialized? I'll need to pay close attention to the levels (SOL_SOCKET, IPPROTO_TCP, etc.) to grasp the scope of these settings. Context matters immensely, so I'll be keeping an eye out for how this configuration ties into the broader socket workflow of the application or system. Analyzing `setsockopt` will tell me a lot about this implementation.
|
| 40/2 |
2026/03/11 08:09 |
tool |
grepper |
0m
Args: map[Expression:setsockopt]
Results: map[Output:
Full output is too long, showing 500 out of 9455 lines.
Use more precise expression if possible.
[Documentation/admin-guide/sysctl/net.rst=420=Controls default hash rethink behaviour on socket when SO_TXREHASH option is set
Documentation/admin-guide/sysctl/net.rst:421:to SOCK_TXREHASH_DEFAULT (i. e. not overridden by setsockopt).
Documentation/admin-guide/sysctl/net.rst-422-
--
Documentation/bpf/libbpf/program_types.rst=18=described in more detail in the footnotes.
--
Documentation/bpf/libbpf/program_types.rst-33-+ +----------------------------------------+----------------------------------+-----------+
Documentation/bpf/libbpf/program_types.rst:34:| | ``BPF_CGROUP_SETSOCKOPT`` | ``cgroup/setsockopt`` | |
Documentation/bpf/libbpf/program_types.rst-35-+-------------------------------------------+----------------------------------------+----------------------------------+-----------+
--
Documentation/bpf/prog_cgroup_sockopt.rst=8=cgroup hooks:
--
Documentation/bpf/prog_cgroup_sockopt.rst-11- system call.
Documentation/bpf/prog_cgroup_sockopt.rst:12:* ``BPF_CGROUP_SETSOCKOPT`` - called every time process executes ``setsockopt``
Documentation/bpf/prog_cgroup_sockopt.rst-13- system call.
--
Documentation/bpf/prog_cgroup_sockopt.rst=27=back to the userspace after all other BPF programs in the cgroup
Documentation/bpf/prog_cgroup_sockopt.rst:28:chain finish (i.e. kernel ``setsockopt`` handling will *not* be executed).
Documentation/bpf/prog_cgroup_sockopt.rst-29-
--
Documentation/bpf/prog_cgroup_sockopt.rst=85=then the next program in the chain (A) will see those changes,
Documentation/bpf/prog_cgroup_sockopt.rst:86:*not* the original input ``setsockopt`` arguments. The potentially
Documentation/bpf/prog_cgroup_sockopt.rst-87-modified values will be then passed down to the kernel.
--
Documentation/bpf/prog_cgroup_sockopt.rst=108=Recommended way to handle BPF programs is as follows:
--
Documentation/bpf/prog_cgroup_sockopt.rst-137-
Documentation/bpf/prog_cgroup_sockopt.rst:138: SEC("cgroup/setsockopt")
Documentation/bpf/prog_cgroup_sockopt.rst:139: int setsockopt(struct bpf_sockopt *ctx)
Documentation/bpf/prog_cgroup_sockopt.rst-140- {
--
Documentation/crypto/userspace-if.rst=42=The interface is provided via socket type using the type AF_ALG. In
Documentation/crypto/userspace-if.rst:43:addition, the setsockopt option type is SOL_ALG. In case the user space
Documentation/crypto/userspace-if.rst-44-header files do not export these flags yet, use the following macros:
--
Documentation/crypto/userspace-if.rst=116=digests. Though, a keyed message digest is referenced by the appropriate
Documentation/crypto/userspace-if.rst:117:salg_name. Please see below for the setsockopt interface that explains
Documentation/crypto/userspace-if.rst-118-how the key can be set for a keyed message digest.
--
Documentation/crypto/userspace-if.rst=133=In order to set a message digest key, the calling application must use
Documentation/crypto/userspace-if.rst:134:the setsockopt() option of ALG_SET_KEY or ALG_SET_KEY_BY_KEY_SERIAL. If the
Documentation/crypto/userspace-if.rst-135-key is not set the HMAC operation is performed without the initial HMAC state
--
Documentation/crypto/userspace-if.rst=155=family, the consumer must set the key. The key setting is described with
Documentation/crypto/userspace-if.rst:156:the setsockopt invocation below.
Documentation/crypto/userspace-if.rst-157-
--
Documentation/crypto/userspace-if.rst=209=family, the consumer must set the key. The key setting is described with
Documentation/crypto/userspace-if.rst:210:the setsockopt invocation below.
Documentation/crypto/userspace-if.rst-211-
--
Documentation/crypto/userspace-if.rst=213=system call family, the consumer must set the authentication tag size.
Documentation/crypto/userspace-if.rst:214:To set the authentication tag size, the caller must use the setsockopt
Documentation/crypto/userspace-if.rst-215-invocation described below.
--
Documentation/crypto/userspace-if.rst=269=The sizes of the AAD and the authentication tag are provided with the
Documentation/crypto/userspace-if.rst:270:sendmsg and setsockopt calls (see there). As the kernel knows the size
Documentation/crypto/userspace-if.rst-271-of the entire data stream, the kernel is now able to calculate the right
--
Documentation/crypto/userspace-if.rst=304=Depending on the RNG type, the RNG must be seeded. The seed is provided
Documentation/crypto/userspace-if.rst:305:using the setsockopt interface to set the key. The SP800-90A DRBGs do
Documentation/crypto/userspace-if.rst-306-not require a seed, but may be seeded. The seed is also known as a
--
Documentation/crypto/userspace-if.rst=318=CRYPTO_USER_API_RNG_CAVP option:
--
Documentation/crypto/userspace-if.rst-320-- the concatenation of *Entropy* and *Nonce* can be provided to the RNG via
Documentation/crypto/userspace-if.rst:321: ALG_SET_DRBG_ENTROPY setsockopt interface. Setting the entropy requires
Documentation/crypto/userspace-if.rst-322- CAP_SYS_ADMIN permission.
--
Documentation/crypto/userspace-if.rst=364=to set the additional information for the cipher operation. This
Documentation/crypto/userspace-if.rst:365:additional information is set using the setsockopt system call that must
Documentation/crypto/userspace-if.rst-366-be invoked with the file descriptor of the open cipher (i.e. the file
Documentation/crypto/userspace-if.rst=367=descriptor returned by the accept system call).
Documentation/crypto/userspace-if.rst-368-
Documentation/crypto/userspace-if.rst:369:Each setsockopt invocation must use the level SOL_ALG.
Documentation/crypto/userspace-if.rst-370-
Documentation/crypto/userspace-if.rst:371:The setsockopt interface allows setting the following data using the
Documentation/crypto/userspace-if.rst-372-mentioned optname:
--
Documentation/driver-api/connector.rst=115=that group first. It can be achieved by the following pseudocode::
--
Documentation/driver-api/connector.rst-130- int on = l_local.nl_groups;
Documentation/driver-api/connector.rst:131: setsockopt(s, 270, 1, &on, sizeof(on));
Documentation/driver-api/connector.rst-132- }
--
Documentation/kernel-hacking/locking.rst=152=Example: ``net/netfilter/nf_sockopt.c`` allows registration of new
Documentation/kernel-hacking/locking.rst:153:setsockopt() and getsockopt() calls, with
Documentation/kernel-hacking/locking.rst-154-nf_register_sockopt(). Registration and de-registration
--
Documentation/kernel-hacking/locking.rst=156=no concurrency), and the list of registrations is only consulted for an
Documentation/kernel-hacking/locking.rst:157:unknown setsockopt() or getsockopt() system
Documentation/kernel-hacking/locking.rst-158-call. The ``nf_sockopt_mutex`` is perfect to protect this, especially
Documentation/kernel-hacking/locking.rst:159:since the setsockopt and getsockopt calls may well sleep.
Documentation/kernel-hacking/locking.rst-160-
--
Documentation/networking/af_xdp.rst=26=packets on the TX ring. These rings are registered and sized with the
Documentation/networking/af_xdp.rst:27:setsockopts XDP_RX_RING and XDP_TX_RING, respectively. It is mandatory
Documentation/networking/af_xdp.rst-28-to have at least one of these rings for each socket. An RX or TX
--
Documentation/networking/af_xdp.rst=40=appropriate (malloc, mmap, huge pages, etc). This memory area is then
Documentation/networking/af_xdp.rst:41:registered with the kernel using the new setsockopt XDP_UMEM_REG. The
Documentation/networking/af_xdp.rst-42-UMEM also has two rings: the FILL ring and the COMPLETION ring. The
--
Documentation/networking/af_xdp.rst=110=queue id of that netdev. It is created and configured (chunk size,
Documentation/networking/af_xdp.rst:111:headroom, start address and size) by using the XDP_UMEM_REG setsockopt
Documentation/networking/af_xdp.rst-112-system call. A UMEM is bound to a netdev and queue id, via the bind()
--
Documentation/networking/af_xdp.rst=142=member, and increasing the consumer index.
Documentation/networking/af_xdp.rst-143-
Documentation/networking/af_xdp.rst:144:The rings are configured and created via the _RING setsockopt system
Documentation/networking/af_xdp.rst-145-calls and mmapped to user-space using the appropriate offset to mmap()
--
Documentation/networking/af_xdp.rst=386=syscalls needed for the TX path.
Documentation/networking/af_xdp.rst-387-
Documentation/networking/af_xdp.rst:388:XDP_{RX|TX|UMEM_FILL|UMEM_COMPLETION}_RING setsockopts
Documentation/networking/af_xdp.rst-389-------------------------------------------------------
Documentation/networking/af_xdp.rst-390-
Documentation/networking/af_xdp.rst:391:These setsockopts sets the number of descriptors that the RX, TX,
Documentation/networking/af_xdp.rst-392-FILL, and COMPLETION rings respectively should have. It is mandatory
--
Documentation/networking/af_xdp.rst=412=negatively impact performance.
Documentation/networking/af_xdp.rst-413-
Documentation/networking/af_xdp.rst:414:XDP_UMEM_REG setsockopt
Documentation/networking/af_xdp.rst-415------------------------
Documentation/networking/af_xdp.rst-416-
Documentation/networking/af_xdp.rst:417:This setsockopt registers a UMEM to a socket. This is the area that
Documentation/networking/af_xdp.rst-418-contain all the buffers that packet can reside in. The call takes a
--
Documentation/networking/af_xdp.rst=430=be dealt with in separate sections for each UMEM flag.
Documentation/networking/af_xdp.rst-431-
Documentation/networking/af_xdp.rst:432:SO_BINDTODEVICE setsockopt
Documentation/networking/af_xdp.rst-433---------------------------
--
Documentation/networking/af_xdp.rst=439=to a different interface. Updating the value requires CAP_NET_RAW.
Documentation/networking/af_xdp.rst-440-
Documentation/networking/af_xdp.rst:441:XDP_MAX_TX_SKB_BUDGET setsockopt
Documentation/networking/af_xdp.rst-442---------------------------------
Documentation/networking/af_xdp.rst-443-
Documentation/networking/af_xdp.rst:444:This setsockopt sets the maximum number of descriptors that can be handled
Documentation/networking/af_xdp.rst-445-and passed to the driver at one send syscall. It is applied in the copy
--
Documentation/networking/can.rst=512=receive filters for each open socket separately:
--
Documentation/networking/can.rst-522-
Documentation/networking/can.rst:523: setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
Documentation/networking/can.rst-524-
Documentation/networking/can.rst=525=To disable the reception of CAN frames on the selected CAN_RAW socket:
--
Documentation/networking/can.rst-528-
Documentation/networking/can.rst:529: setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
Documentation/networking/can.rst-530-
--
Documentation/networking/can.rst=563=filter has to be defined in this way to benefit from the optimized filters:
--
Documentation/networking/can.rst-573-
Documentation/networking/can.rst:574: setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
Documentation/networking/can.rst-575-
--
Documentation/networking/can.rst=586=The values for the error mask are defined in linux/can/error.h:
--
Documentation/networking/can.rst-591-
Documentation/networking/can.rst:592: setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
Documentation/networking/can.rst-593- &err_mask, sizeof(err_mask));
--
Documentation/networking/can.rst=602=functionality can be disabled (separately for each socket):
--
Documentation/networking/can.rst-607-
Documentation/networking/can.rst:608: setsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback));
Documentation/networking/can.rst-609-
--
Documentation/networking/can.rst=620=demand:
--
Documentation/networking/can.rst-625-
Documentation/networking/can.rst:626: setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
Documentation/networking/can.rst-627- &recv_own_msgs, sizeof(recv_own_msgs));
--
Documentation/networking/devmem.rst=219=SO_DEVMEM_DONTNEED::
Documentation/networking/devmem.rst-220-
Documentation/networking/devmem.rst:221: ret = setsockopt(client_fd, SOL_SOCKET, SO_DEVMEM_DONTNEED, &token,
Documentation/networking/devmem.rst-222- sizeof(token));
--
Documentation/networking/devmem.rst=285=to the semantics of MSG_ZEROCOPY::
Documentation/networking/devmem.rst-286-
Documentation/networking/devmem.rst:287: setsockopt(socket_fd, SOL_SOCKET, SO_ZEROCOPY, &opt, sizeof(opt));
Documentation/networking/devmem.rst-288-
--
Documentation/networking/devmem.rst=290=the dma-buf has been bound to via SO_BINDTODEVICE::
Documentation/networking/devmem.rst-291-
Documentation/networking/devmem.rst:292: setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname) + 1);
Documentation/networking/devmem.rst-293-
--
Documentation/networking/filter.rst=92=For socket filtering, a pointer to this structure (as shown in
Documentation/networking/filter.rst:93:follow-up example) is being passed to the kernel through setsockopt(2).
Documentation/networking/filter.rst-94-
Documentation/networking/filter.rst=95=Example
--
Documentation/networking/filter.rst-142-
Documentation/networking/filter.rst:143: ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
Documentation/networking/filter.rst-144- if (ret < 0)
--
Documentation/networking/filter.rst=152=be dropped for this socket.
Documentation/networking/filter.rst-153-
Documentation/networking/filter.rst:154:The setsockopt(2) call to SO_DETACH_FILTER doesn't need any arguments
Documentation/networking/filter.rst-155-and SO_LOCK_FILTER for preventing the filter to be detached, takes an
--
Documentation/networking/filter.rst=161=Summary of system calls:
Documentation/networking/filter.rst-162-
Documentation/networking/filter.rst:163: * setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_FILTER, &val, sizeof(val));
Documentation/networking/filter.rst:164: * setsockopt(sockfd, SOL_SOCKET, SO_DETACH_FILTER, &val, sizeof(val));
Documentation/networking/filter.rst:165: * setsockopt(sockfd, SOL_SOCKET, SO_LOCK_FILTER, &val, sizeof(val));
Documentation/networking/filter.rst-166-
--
Documentation/networking/ip-sysctl.rst=412=tcp_congestion_control - STRING
--
Documentation/networking/ip-sysctl.rst-419-
Documentation/networking/ip-sysctl.rst:420: [see setsockopt(listenfd, SOL_TCP, TCP_CONGESTION, "name" ...) ]
Documentation/networking/ip-sysctl.rst-421-
--
Documentation/networking/ip-sysctl.rst=537=tcp_fwmark_accept - BOOLEAN
--
Documentation/networking/ip-sysctl.rst-542- listening socket's mark is unchanged. Listening sockets that already
Documentation/networking/ip-sysctl.rst:543: have a fwmark set via setsockopt(SOL_SOCKET, SO_MARK, ...) are
Documentation/networking/ip-sysctl.rst-544- unaffected.
--
Documentation/networking/ip-sysctl.rst=840=tcp_rmem - vector of 3 INTEGERs: min, default, max
--
Documentation/networking/ip-sysctl.rst-853- selected receiver buffers for TCP socket.
Documentation/networking/ip-sysctl.rst:854: Calling setsockopt() with SO_RCVBUF disables
Documentation/networking/ip-sysctl.rst-855- automatic tuning of that socket's receive buffer size, in which
--
Documentation/networking/ip-sysctl.rst=1041=tcp_fastopen_key - list of comma separated 32-digit hexadecimal INTEGERs
--
Documentation/networking/ip-sysctl.rst-1048- the tcp_fastopen sysctl is set to 0x400 (see above), or if the
Documentation/networking/ip-sysctl.rst:1049: TCP_FASTOPEN setsockopt() optname is set and a key has not been
Documentation/networking/ip-sysctl.rst-1050- previously configured via sysctl. If keys are configured via
Documentation/networking/ip-sysctl.rst:1051: setsockopt() by using the TCP_FASTOPEN_KEY optname, then those
Documentation/networking/ip-sysctl.rst-1052- per-socket keys will be used instead of any keys that are specified via
--
Documentation/networking/ip-sysctl.rst=1202=tcp_wmem - vector of 3 INTEGERs: min, default, max
--
Documentation/networking/ip-sysctl.rst-1216- send buffers for TCP sockets. This value does not override
Documentation/networking/ip-sysctl.rst:1217: net.core.wmem_max. Calling setsockopt() with SO_SNDBUF disables
Documentation/networking/ip-sysctl.rst-1218- automatic tuning of that socket's send buffer size, in which case
--
Documentation/networking/ip-sysctl.rst=3688=encap_port - INTEGER
--
Documentation/networking/ip-sysctl.rst-3692- outgoing UDP-encapsulated SCTP packets by default. Users can also
Documentation/networking/ip-sysctl.rst:3693: change the value for each sock/asoc/transport by using setsockopt.
Documentation/networking/ip-sysctl.rst-3694- For further information, please refer to RFC6951.
--
Documentation/networking/iso15765-2.rst=130=When creating an ISO-TP socket, reasonable defaults are set. Some options can
Documentation/networking/iso15765-2.rst:131:be modified with ``setsockopt(2)`` and/or read back with ``getsockopt(2)``.
Documentation/networking/iso15765-2.rst-132-
--
Documentation/networking/iso15765-2.rst=136=General socket options can be passed using the ``CAN_ISOTP_OPTS`` optname:
--
Documentation/networking/iso15765-2.rst-140- struct can_isotp_options opts;
Documentation/networking/iso15765-2.rst:141: ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts))
Documentation/networking/iso15765-2.rst-142-
--
Documentation/networking/iso15765-2.rst=227=to provide the communication parameters for receiving ISO-TP PDUs.
--
Documentation/networking/iso15765-2.rst-231- struct can_isotp_fc_options fc_opts;
Documentation/networking/iso15765-2.rst:232: ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_RECV_FC, &fc_opts, sizeof(fc_opts));
Documentation/networking/iso15765-2.rst-233-
--
Documentation/networking/iso15765-2.rst=258=Link Layer (LL) options can be passed using the ``CAN_ISOTP_LL_OPTS`` optname:
--
Documentation/networking/iso15765-2.rst-262- struct can_isotp_ll_options ll_opts;
Documentation/networking/iso15765-2.rst:263: ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_LL_OPTS, &ll_opts, sizeof(ll_opts));
Documentation/networking/iso15765-2.rst-264-
--
Documentation/networking/iso15765-2.rst=291=flow control frames:
--
Documentation/networking/iso15765-2.rst-295- uint32_t stmin;
Documentation/networking/iso15765-2.rst:296: ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_TX_STMIN, &stmin, sizeof(stmin));
Documentation/networking/iso15765-2.rst-297-
--
Documentation/networking/iso15765-2.rst=304=differ less than this value will be ignored:
--
Documentation/networking/iso15765-2.rst-308- uint32_t stmin;
Documentation/networking/iso15765-2.rst:309: ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_RX_STMIN, &stmin, sizeof(stmin));
Documentation/networking/iso15765-2.rst-310-
--
Documentation/networking/j1939.rst=336=When creating a socket, reasonable defaults are set. Some options can be
Documentation/networking/j1939.rst:337:modified with ``setsockopt(2)`` & ``getsockopt(2)``.
Documentation/networking/j1939.rst-338-
--
Documentation/networking/j1939.rst=345=receiving broadcast packets use the socket option ``SO_BROADCAST``:
--
Documentation/networking/j1939.rst-349- int value = 1;
Documentation/networking/j1939.rst:350: setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
Documentation/networking/j1939.rst-351-
--
Documentation/networking/j1939.rst=403=with ``cmsg_level == SOL_J1939 && cmsg_type == SCM_J1939_DEST_ADDR``,
--
Documentation/networking/j1939.rst-424-
Documentation/networking/j1939.rst:425:setsockopt(2)
Documentation/networking/j1939.rst-426-^^^^^^^^^^^^^
Documentation/networking/j1939.rst-427-
Documentation/networking/j1939.rst:428:The ``setsockopt(2)`` function is used to configure various socket-level
Documentation/networking/j1939.rst-429-options for J1939 communication. The following options are supported:
--
Documentation/networking/j1939.rst=469=To remove existing filters, you can pass ``optval == NULL`` or ``optlen == 0``
Documentation/networking/j1939.rst:470:to ``setsockopt(2)``. This will clear all currently set filters. If you want to
Documentation/networking/j1939.rst-471-**update** the set of filters, you must pass the updated filter set to
Documentation/networking/j1939.rst:472:``setsockopt(2)``, as the new filter set will **replace** the old one entirely.
Documentation/networking/j1939.rst-473-This behavior ensures that any previous filter configuration is discarded and
--
Documentation/networking/j1939.rst=476=Example of removing all filters:
--
Documentation/networking/j1939.rst-479-
Documentation/networking/j1939.rst:480: setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, NULL, 0);
Documentation/networking/j1939.rst-481-
--
Documentation/networking/j1939.rst=493=Example:
--
Documentation/networking/j1939.rst-508- };
Documentation/networking/j1939.rst:509: setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, &filt, sizeof(filt));
Documentation/networking/j1939.rst-510-
--
Documentation/networking/j1939.rst=540=Example:
--
Documentation/networking/j1939.rst-544- int value = 1;
Documentation/networking/j1939.rst:545: setsockopt(sock, SOL_CAN_J1939, SO_J1939_PROMISC, &value, sizeof(value));
Documentation/networking/j1939.rst-546-
--
Documentation/networking/j1939.rst=571=Example:
--
Documentation/networking/j1939.rst-575- int value = 1;
Documentation/networking/j1939.rst:576: setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
Documentation/networking/j1939.rst-577-
--
Documentation/networking/j1939.rst=599=Example:
--
Documentation/networking/j1939.rst-603- int prio = 3; // Priority value between 0 (highest) and 7 (lowest)
Documentation/networking/j1939.rst:604: setsockopt(sock, SOL_CAN_J1939, SO_J1939_SEND_PRIO, &prio, sizeof(prio));
Documentation/networking/j1939.rst-605-
--
Documentation/networking/j1939.rst=653=Example:
--
Documentation/networking/j1939.rst-657- int enable = 1; // Enable error queue reception
Documentation/networking/j1939.rst:658: setsockopt(sock, SOL_CAN_J1939, SO_J1939_ERRQUEUE, &enable, sizeof(enable));
Documentation/networking/j1939.rst-659-
--
Documentation/networking/j1939.rst-663- SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_OPT_CMSG;
Documentation/networking/j1939.rst:664: setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, ×tamping,
Documentation/networking/j1939.rst-665- sizeof(timestamping));
--
Documentation/networking/j1939.rst=862=Example:
--
Documentation/networking/j1939.rst-873-
Documentation/networking/j1939.rst:874: setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &sock_opt, sizeof(sock_opt));
Documentation/networking/j1939.rst-875-
--
Documentation/networking/j1939.rst=891=To claim an address following code example can be used:
--
Documentation/networking/j1939.rst-908- int value = 1;
Documentation/networking/j1939.rst:909: setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
Documentation/networking/j1939.rst-910-
--
Documentation/networking/j1939.rst-924-
Documentation/networking/j1939.rst:925: setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, &filt, sizeof(filt));
Documentation/networking/j1939.rst-926-
--
Documentation/networking/j1939.rst=1005=codes and those derived from protocol-specific abort codes.
--
Documentation/networking/j1939.rst-1067-- ``ENOPROTOOPT``: Protocol not available. This can occur when using
Documentation/networking/j1939.rst:1068: ``getsockopt(2)`` or ``setsockopt(2)`` if the requested socket option is not
Documentation/networking/j1939.rst-1069- available.
--
Documentation/networking/kcm.rst=189=Disabling receive on KCM socket
--
Documentation/networking/kcm.rst-191-
Documentation/networking/kcm.rst:192:A setsockopt is used to disable or enable receiving on a KCM socket.
Documentation/networking/kcm.rst-193-When receive is disabled, any pending messages in the socket's
--
Documentation/networking/kcm.rst=197=while. Example use::
--
Documentation/networking/kcm.rst-200-
Documentation/networking/kcm.rst:201: setsockopt(kcmfd, SOL_KCM, KCM_RECV_DISABLE, &val, sizeof(val))
Documentation/networking/kcm.rst-202-
--
Documentation/networking/l2tp.rst=366=Userspace may control behavior of the tunnel or session using
Documentation/networking/l2tp.rst:367:setsockopt and ioctl on the PPPoX socket. The following socket
Documentation/networking/l2tp.rst-368-options are supported:-
--
Documentation/networking/l2tp.rst=547=being created by a separate netlink request:
--
Documentation/networking/l2tp.rst-556- socket is connected to a non-zero session id. Session parameters
Documentation/networking/l2tp.rst:557: are set using setsockopt. The L2TP session instance is destroyed
Documentation/networking/l2tp.rst-558- when the socket is closed.
--
Documentation/networking/mptcp.rst=125=Generally, the same value is propagated to all subflows, including the ones
Documentation/networking/mptcp.rst:126:created after the calls to ``setsockopt()``. eBPF can be used to set different
Documentation/networking/mptcp.rst-127-values per subflow.
--
Documentation/networking/msg_zerocopy.rst=69=this flag, a process must first signal intent by setting a socket option:
--
Documentation/networking/msg_zerocopy.rst-72-
Documentation/networking/msg_zerocopy.rst:73: if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one)))
Documentation/networking/msg_zerocopy.rst:74: error(1, errno, "setsockopt zerocopy");
Documentation/networking/msg_zerocopy.rst-75-
--
Documentation/networking/net_cachelines/inet_connection_sock.rst=27=u8:1 icsk_ca_initialized read_write tcp_init_transfer,tcp_init_congestion_control,tcp_init_transfer,tcp_finish_connect,tcp_connect
Documentation/networking/net_cachelines/inet_connection_sock.rst:28:u8:1 icsk_ca_setsockopt
Documentation/networking/net_cachelines/inet_connection_sock.rst-29-u8:1 icsk_ca_dst_locked write_mostly tcp_ca_dst_init,tcp_connect_init,tcp_connect
--
Documentation/networking/packet_mmap.rst=64=the following process::
--
Documentation/networking/packet_mmap.rst-67- [setup] socket() -------> creation of the capture socket
Documentation/networking/packet_mmap.rst:68: setsockopt() ---> allocation of the circular buffer (ring)
Documentation/networking/packet_mmap.rst-69- option: PACKET_RX_RING
--
Documentation/networking/packet_mmap.rst=105=Transmission process is similar to capture as shown below::
--
Documentation/networking/packet_mmap.rst-107- [setup] socket() -------> creation of the transmission socket
Documentation/networking/packet_mmap.rst:108: setsockopt() ---> allocation of the circular buffer (ring)
Documentation/networking/packet_mmap.rst-109- option: PACKET_TX_RING
--
Documentation/networking/packet_mmap.rst=183=can set tp_net (with SOCK_DGRAM) or tp_mac (with SOCK_RAW). In order
Documentation/networking/packet_mmap.rst:184:to make this work it must be enabled previously with setsockopt()
Documentation/networking/packet_mmap.rst-185-and the PACKET_TX_HAS_OFF option.
--
Documentation/networking/packet_mmap.rst=190=To setup PACKET_MMAP from user level code is done with a call like
--
Documentation/networking/packet_mmap.rst-193-
Documentation/networking/packet_mmap.rst:194: setsockopt(fd, SOL_PACKET, PACKET_RX_RING, (void *) &req, sizeof(req))
Documentation/networking/packet_mmap.rst-195-
--
Documentation/networking/packet_mmap.rst-197-
Documentation/networking/packet_mmap.rst:198: setsockopt(fd, SOL_PACKET, PACKET_TX_RING, (void *) &req, sizeof(req))
Documentation/networking/packet_mmap.rst-199-
--
Documentation/networking/packet_mmap.rst=420=RX and TX buffer ring has to be done with one call to mmap::
--
Documentation/networking/packet_mmap.rst-422- ...
Documentation/networking/packet_mmap.rst:423: setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &foo, sizeof(foo));
Documentation/networking/packet_mmap.rst:424: setsockopt(fd, SOL_PACKET, PACKET_TX_RING, &bar, sizeof(bar));
Documentation/networking/packet_mmap.rst-425- ...
--
Documentation/networking/packet_mmap.rst=448=TP_STATUS_COPY This flag indicates that the frame (and associated
--
Documentation/networking/packet_mmap.rst-453- In order to make this work it must to be
Documentation/networking/packet_mmap.rst:454: enabled previously with setsockopt() and
Documentation/networking/packet_mmap.rst-455- the PACKET_COPY_THRESH option.
--
Documentation/networking/packet_mmap.rst=541=What TPACKET versions are available and when to use them?
--
Documentation/networking/packet_mmap.rst-546- int val = tpacket_version;
Documentation/networking/packet_mmap.rst:547: setsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
Documentation/networking/packet_mmap.rst-548- getsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
--
Documentation/networking/packet_mmap.rst=552=TPACKET_V1:
Documentation/networking/packet_mmap.rst:553: - Default if not otherwise specified by setsockopt(2)
Documentation/networking/packet_mmap.rst-554- - RX_RING, TX_RING available
--
Documentation/networking/packet_mmap.rst=614=Minimal example code by David S. Miller (try things like "./test eth0 hash",
--
Documentation/networking/packet_mmap.rst-673- fanout_arg = (fanout_id | (fanout_type << 16));
Documentation/networking/packet_mmap.rst:674: err = setsockopt(fd, SOL_PACKET, PACKET_FANOUT,
Documentation/networking/packet_mmap.rst-675- &fanout_arg, sizeof(fanout_arg));
Documentation/networking/packet_mmap.rst-676- if (err) {
Documentation/networking/packet_mmap.rst:677: perror("setsockopt");
Documentation/networking/packet_mmap.rst-678- return EXIT_FAILURE;
--
Documentation/networking/packet_mmap.rst=773=it with gcc -Wall -O2 blob.c, and try things like "./a.out eth0", etc.)::
--
Documentation/networking/packet_mmap.rst-838-
Documentation/networking/packet_mmap.rst:839: err = setsockopt(fd, SOL_PACKET, PACKET_VERSION, &v, sizeof(v));
Documentation/networking/packet_mmap.rst-840- if (err < 0) {
Documentation/networking/packet_mmap.rst:841: perror("setsockopt");
Documentation/networking/packet_mmap.rst-842- exit(1);
--
Documentation/networking/packet_mmap.rst-852-
Documentation/networking/packet_mmap.rst:853: err = setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &ring->req,
Documentation/networking/packet_mmap.rst-854- sizeof(ring->req));
Documentation/networking/packet_mmap.rst-855- if (err < 0) {
Documentation/networking/packet_mmap.rst:856: perror("setsockopt");
Documentation/networking/packet_mmap.rst-857- exit(1);
--
Documentation/networking/packet_mmap.rst=1010=creation::
--
Documentation/networking/packet_mmap.rst-1012- int one = 1;
Documentation/networking/packet_mmap.rst:1013: setsockopt(fd, SOL_PACKET, PACKET_QDISC_BYPASS, &one, sizeof(one));
Documentation/networking/packet_mmap.rst-1014-
--
Documentation/networking/packet_mmap.rst=1035=PACKET_TIMESTAMP accepts the same integer bit field as SO_TIMESTAMPING::
--
Documentation/networking/packet_mmap.rst-1037- int req = SOF_TIMESTAMPING_RAW_HARDWARE;
Documentation/networking/packet_mmap.rst:1038: setsockopt(fd, SOL_PACKET, PACKET_TIMESTAMP, (void *) &req, sizeof(req))
Documentation/networking/packet_mmap.rst-1039-
--
Documentation/networking/rds.rst=29=The high-level semantics of RDS from the application's point of view are
--
Documentation/networking/rds.rst-52- control messages, while other extensions use the getsockopt/
Documentation/networking/rds.rst:53: setsockopt calls.
Documentation/networking/rds.rst-54-
--
Documentation/networking/rds.rst=67=Socket Interface
]
]
|
| 41/2 |
2026/03/11 08:09 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 38911
output: 18
thoughts: 42
Thoughts: Okay, here's my interpretation of that thought process, from an expert's perspective:
**Socket Option Optimization**
Right, a lightbulb just went off. Instead of reinventing the wheel or digging through obscure manuals, I can probably streamline this socket configuration. If I recall correctly, there's a good chance `setsockopt$sock_int` (or a similar construct) is defined in the `socket.txt` file. It's a fundamental part of socket programming, so it makes sense that the relevant documentation would be there, and `setsockopt` is a pretty ubiquitous function. Time to check `socket.txt` and confirm if it’s there, because if it *is* defined, then I can use it directly to handle those integer socket options. That’s far quicker and more reliable than any alternative approach I'm currently considering.
|
| 42/2 |
2026/03/11 08:09 |
tool |
grepper |
0m
Error:
Args: map[Expression:setsockopt\$]
Results:
|
| 43/2 |
2026/03/11 08:09 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 39167
output: 18
thoughts: 15
Thoughts: Here's my thought process, summarized as if I were considering this myself:
**Investigating `setsockopt` in `sys.txt`**
Okay, so I need to find the definition or usage of `setsockopt`. My first step, and really the most logical given what I know about system calls and file system structures, is to check `sys.txt`. It's highly probable that information related to `setsockopt` – its arguments, return values, any associated flags or constants – would be documented there, likely alongside other socket-related system calls. That file is generally the place to start when I need to figure out system call behavior. Makes perfect sense to dig in there.
|
| 44/2 |
2026/03/11 08:09 |
tool |
grepper |
0m
Args: map[Expression:setsockopt\(]
Results: map[Output:
Full output is too long, showing 500 out of 6282 lines.
Use more precise expression if possible.
[Documentation/bpf/prog_cgroup_sockopt.rst=108=Recommended way to handle BPF programs is as follows:
--
Documentation/bpf/prog_cgroup_sockopt.rst-138- SEC("cgroup/setsockopt")
Documentation/bpf/prog_cgroup_sockopt.rst:139: int setsockopt(struct bpf_sockopt *ctx)
Documentation/bpf/prog_cgroup_sockopt.rst-140- {
--
Documentation/crypto/userspace-if.rst=133=In order to set a message digest key, the calling application must use
Documentation/crypto/userspace-if.rst:134:the setsockopt() option of ALG_SET_KEY or ALG_SET_KEY_BY_KEY_SERIAL. If the
Documentation/crypto/userspace-if.rst-135-key is not set the HMAC operation is performed without the initial HMAC state
--
Documentation/driver-api/connector.rst=115=that group first. It can be achieved by the following pseudocode::
--
Documentation/driver-api/connector.rst-130- int on = l_local.nl_groups;
Documentation/driver-api/connector.rst:131: setsockopt(s, 270, 1, &on, sizeof(on));
Documentation/driver-api/connector.rst-132- }
--
Documentation/kernel-hacking/locking.rst=152=Example: ``net/netfilter/nf_sockopt.c`` allows registration of new
Documentation/kernel-hacking/locking.rst:153:setsockopt() and getsockopt() calls, with
Documentation/kernel-hacking/locking.rst-154-nf_register_sockopt(). Registration and de-registration
--
Documentation/kernel-hacking/locking.rst=156=no concurrency), and the list of registrations is only consulted for an
Documentation/kernel-hacking/locking.rst:157:unknown setsockopt() or getsockopt() system
Documentation/kernel-hacking/locking.rst-158-call. The ``nf_sockopt_mutex`` is perfect to protect this, especially
--
Documentation/networking/can.rst=512=receive filters for each open socket separately:
--
Documentation/networking/can.rst-522-
Documentation/networking/can.rst:523: setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
Documentation/networking/can.rst-524-
Documentation/networking/can.rst=525=To disable the reception of CAN frames on the selected CAN_RAW socket:
--
Documentation/networking/can.rst-528-
Documentation/networking/can.rst:529: setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
Documentation/networking/can.rst-530-
--
Documentation/networking/can.rst=563=filter has to be defined in this way to benefit from the optimized filters:
--
Documentation/networking/can.rst-573-
Documentation/networking/can.rst:574: setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
Documentation/networking/can.rst-575-
--
Documentation/networking/can.rst=586=The values for the error mask are defined in linux/can/error.h:
--
Documentation/networking/can.rst-591-
Documentation/networking/can.rst:592: setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
Documentation/networking/can.rst-593- &err_mask, sizeof(err_mask));
--
Documentation/networking/can.rst=602=functionality can be disabled (separately for each socket):
--
Documentation/networking/can.rst-607-
Documentation/networking/can.rst:608: setsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback));
Documentation/networking/can.rst-609-
--
Documentation/networking/can.rst=620=demand:
--
Documentation/networking/can.rst-625-
Documentation/networking/can.rst:626: setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
Documentation/networking/can.rst-627- &recv_own_msgs, sizeof(recv_own_msgs));
--
Documentation/networking/devmem.rst=219=SO_DEVMEM_DONTNEED::
Documentation/networking/devmem.rst-220-
Documentation/networking/devmem.rst:221: ret = setsockopt(client_fd, SOL_SOCKET, SO_DEVMEM_DONTNEED, &token,
Documentation/networking/devmem.rst-222- sizeof(token));
--
Documentation/networking/devmem.rst=285=to the semantics of MSG_ZEROCOPY::
Documentation/networking/devmem.rst-286-
Documentation/networking/devmem.rst:287: setsockopt(socket_fd, SOL_SOCKET, SO_ZEROCOPY, &opt, sizeof(opt));
Documentation/networking/devmem.rst-288-
--
Documentation/networking/devmem.rst=290=the dma-buf has been bound to via SO_BINDTODEVICE::
Documentation/networking/devmem.rst-291-
Documentation/networking/devmem.rst:292: setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname) + 1);
Documentation/networking/devmem.rst-293-
--
Documentation/networking/filter.rst=92=For socket filtering, a pointer to this structure (as shown in
Documentation/networking/filter.rst:93:follow-up example) is being passed to the kernel through setsockopt(2).
Documentation/networking/filter.rst-94-
Documentation/networking/filter.rst=95=Example
--
Documentation/networking/filter.rst-142-
Documentation/networking/filter.rst:143: ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
Documentation/networking/filter.rst-144- if (ret < 0)
--
Documentation/networking/filter.rst=152=be dropped for this socket.
Documentation/networking/filter.rst-153-
Documentation/networking/filter.rst:154:The setsockopt(2) call to SO_DETACH_FILTER doesn't need any arguments
Documentation/networking/filter.rst-155-and SO_LOCK_FILTER for preventing the filter to be detached, takes an
--
Documentation/networking/filter.rst=161=Summary of system calls:
Documentation/networking/filter.rst-162-
Documentation/networking/filter.rst:163: * setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_FILTER, &val, sizeof(val));
Documentation/networking/filter.rst:164: * setsockopt(sockfd, SOL_SOCKET, SO_DETACH_FILTER, &val, sizeof(val));
Documentation/networking/filter.rst:165: * setsockopt(sockfd, SOL_SOCKET, SO_LOCK_FILTER, &val, sizeof(val));
Documentation/networking/filter.rst-166-
--
Documentation/networking/ip-sysctl.rst=412=tcp_congestion_control - STRING
--
Documentation/networking/ip-sysctl.rst-419-
Documentation/networking/ip-sysctl.rst:420: [see setsockopt(listenfd, SOL_TCP, TCP_CONGESTION, "name" ...) ]
Documentation/networking/ip-sysctl.rst-421-
--
Documentation/networking/ip-sysctl.rst=537=tcp_fwmark_accept - BOOLEAN
--
Documentation/networking/ip-sysctl.rst-542- listening socket's mark is unchanged. Listening sockets that already
Documentation/networking/ip-sysctl.rst:543: have a fwmark set via setsockopt(SOL_SOCKET, SO_MARK, ...) are
Documentation/networking/ip-sysctl.rst-544- unaffected.
--
Documentation/networking/ip-sysctl.rst=840=tcp_rmem - vector of 3 INTEGERs: min, default, max
--
Documentation/networking/ip-sysctl.rst-853- selected receiver buffers for TCP socket.
Documentation/networking/ip-sysctl.rst:854: Calling setsockopt() with SO_RCVBUF disables
Documentation/networking/ip-sysctl.rst-855- automatic tuning of that socket's receive buffer size, in which
--
Documentation/networking/ip-sysctl.rst=1041=tcp_fastopen_key - list of comma separated 32-digit hexadecimal INTEGERs
--
Documentation/networking/ip-sysctl.rst-1048- the tcp_fastopen sysctl is set to 0x400 (see above), or if the
Documentation/networking/ip-sysctl.rst:1049: TCP_FASTOPEN setsockopt() optname is set and a key has not been
Documentation/networking/ip-sysctl.rst-1050- previously configured via sysctl. If keys are configured via
Documentation/networking/ip-sysctl.rst:1051: setsockopt() by using the TCP_FASTOPEN_KEY optname, then those
Documentation/networking/ip-sysctl.rst-1052- per-socket keys will be used instead of any keys that are specified via
--
Documentation/networking/ip-sysctl.rst=1202=tcp_wmem - vector of 3 INTEGERs: min, default, max
--
Documentation/networking/ip-sysctl.rst-1216- send buffers for TCP sockets. This value does not override
Documentation/networking/ip-sysctl.rst:1217: net.core.wmem_max. Calling setsockopt() with SO_SNDBUF disables
Documentation/networking/ip-sysctl.rst-1218- automatic tuning of that socket's send buffer size, in which case
--
Documentation/networking/iso15765-2.rst=130=When creating an ISO-TP socket, reasonable defaults are set. Some options can
Documentation/networking/iso15765-2.rst:131:be modified with ``setsockopt(2)`` and/or read back with ``getsockopt(2)``.
Documentation/networking/iso15765-2.rst-132-
--
Documentation/networking/iso15765-2.rst=136=General socket options can be passed using the ``CAN_ISOTP_OPTS`` optname:
--
Documentation/networking/iso15765-2.rst-140- struct can_isotp_options opts;
Documentation/networking/iso15765-2.rst:141: ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts))
Documentation/networking/iso15765-2.rst-142-
--
Documentation/networking/iso15765-2.rst=227=to provide the communication parameters for receiving ISO-TP PDUs.
--
Documentation/networking/iso15765-2.rst-231- struct can_isotp_fc_options fc_opts;
Documentation/networking/iso15765-2.rst:232: ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_RECV_FC, &fc_opts, sizeof(fc_opts));
Documentation/networking/iso15765-2.rst-233-
--
Documentation/networking/iso15765-2.rst=258=Link Layer (LL) options can be passed using the ``CAN_ISOTP_LL_OPTS`` optname:
--
Documentation/networking/iso15765-2.rst-262- struct can_isotp_ll_options ll_opts;
Documentation/networking/iso15765-2.rst:263: ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_LL_OPTS, &ll_opts, sizeof(ll_opts));
Documentation/networking/iso15765-2.rst-264-
--
Documentation/networking/iso15765-2.rst=291=flow control frames:
--
Documentation/networking/iso15765-2.rst-295- uint32_t stmin;
Documentation/networking/iso15765-2.rst:296: ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_TX_STMIN, &stmin, sizeof(stmin));
Documentation/networking/iso15765-2.rst-297-
--
Documentation/networking/iso15765-2.rst=304=differ less than this value will be ignored:
--
Documentation/networking/iso15765-2.rst-308- uint32_t stmin;
Documentation/networking/iso15765-2.rst:309: ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_RX_STMIN, &stmin, sizeof(stmin));
Documentation/networking/iso15765-2.rst-310-
--
Documentation/networking/j1939.rst=336=When creating a socket, reasonable defaults are set. Some options can be
Documentation/networking/j1939.rst:337:modified with ``setsockopt(2)`` & ``getsockopt(2)``.
Documentation/networking/j1939.rst-338-
--
Documentation/networking/j1939.rst=345=receiving broadcast packets use the socket option ``SO_BROADCAST``:
--
Documentation/networking/j1939.rst-349- int value = 1;
Documentation/networking/j1939.rst:350: setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
Documentation/networking/j1939.rst-351-
--
Documentation/networking/j1939.rst=403=with ``cmsg_level == SOL_J1939 && cmsg_type == SCM_J1939_DEST_ADDR``,
--
Documentation/networking/j1939.rst-424-
Documentation/networking/j1939.rst:425:setsockopt(2)
Documentation/networking/j1939.rst-426-^^^^^^^^^^^^^
Documentation/networking/j1939.rst-427-
Documentation/networking/j1939.rst:428:The ``setsockopt(2)`` function is used to configure various socket-level
Documentation/networking/j1939.rst-429-options for J1939 communication. The following options are supported:
--
Documentation/networking/j1939.rst=469=To remove existing filters, you can pass ``optval == NULL`` or ``optlen == 0``
Documentation/networking/j1939.rst:470:to ``setsockopt(2)``. This will clear all currently set filters. If you want to
Documentation/networking/j1939.rst-471-**update** the set of filters, you must pass the updated filter set to
Documentation/networking/j1939.rst:472:``setsockopt(2)``, as the new filter set will **replace** the old one entirely.
Documentation/networking/j1939.rst-473-This behavior ensures that any previous filter configuration is discarded and
--
Documentation/networking/j1939.rst=476=Example of removing all filters:
--
Documentation/networking/j1939.rst-479-
Documentation/networking/j1939.rst:480: setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, NULL, 0);
Documentation/networking/j1939.rst-481-
--
Documentation/networking/j1939.rst=493=Example:
--
Documentation/networking/j1939.rst-508- };
Documentation/networking/j1939.rst:509: setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, &filt, sizeof(filt));
Documentation/networking/j1939.rst-510-
--
Documentation/networking/j1939.rst=540=Example:
--
Documentation/networking/j1939.rst-544- int value = 1;
Documentation/networking/j1939.rst:545: setsockopt(sock, SOL_CAN_J1939, SO_J1939_PROMISC, &value, sizeof(value));
Documentation/networking/j1939.rst-546-
--
Documentation/networking/j1939.rst=571=Example:
--
Documentation/networking/j1939.rst-575- int value = 1;
Documentation/networking/j1939.rst:576: setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
Documentation/networking/j1939.rst-577-
--
Documentation/networking/j1939.rst=599=Example:
--
Documentation/networking/j1939.rst-603- int prio = 3; // Priority value between 0 (highest) and 7 (lowest)
Documentation/networking/j1939.rst:604: setsockopt(sock, SOL_CAN_J1939, SO_J1939_SEND_PRIO, &prio, sizeof(prio));
Documentation/networking/j1939.rst-605-
--
Documentation/networking/j1939.rst=653=Example:
--
Documentation/networking/j1939.rst-657- int enable = 1; // Enable error queue reception
Documentation/networking/j1939.rst:658: setsockopt(sock, SOL_CAN_J1939, SO_J1939_ERRQUEUE, &enable, sizeof(enable));
Documentation/networking/j1939.rst-659-
--
Documentation/networking/j1939.rst-663- SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_OPT_CMSG;
Documentation/networking/j1939.rst:664: setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, ×tamping,
Documentation/networking/j1939.rst-665- sizeof(timestamping));
--
Documentation/networking/j1939.rst=862=Example:
--
Documentation/networking/j1939.rst-873-
Documentation/networking/j1939.rst:874: setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &sock_opt, sizeof(sock_opt));
Documentation/networking/j1939.rst-875-
--
Documentation/networking/j1939.rst=891=To claim an address following code example can be used:
--
Documentation/networking/j1939.rst-908- int value = 1;
Documentation/networking/j1939.rst:909: setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
Documentation/networking/j1939.rst-910-
--
Documentation/networking/j1939.rst-924-
Documentation/networking/j1939.rst:925: setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, &filt, sizeof(filt));
Documentation/networking/j1939.rst-926-
--
Documentation/networking/j1939.rst=1005=codes and those derived from protocol-specific abort codes.
--
Documentation/networking/j1939.rst-1067-- ``ENOPROTOOPT``: Protocol not available. This can occur when using
Documentation/networking/j1939.rst:1068: ``getsockopt(2)`` or ``setsockopt(2)`` if the requested socket option is not
Documentation/networking/j1939.rst-1069- available.
--
Documentation/networking/kcm.rst=197=while. Example use::
--
Documentation/networking/kcm.rst-200-
Documentation/networking/kcm.rst:201: setsockopt(kcmfd, SOL_KCM, KCM_RECV_DISABLE, &val, sizeof(val))
Documentation/networking/kcm.rst-202-
--
Documentation/networking/mptcp.rst=125=Generally, the same value is propagated to all subflows, including the ones
Documentation/networking/mptcp.rst:126:created after the calls to ``setsockopt()``. eBPF can be used to set different
Documentation/networking/mptcp.rst-127-values per subflow.
--
Documentation/networking/msg_zerocopy.rst=69=this flag, a process must first signal intent by setting a socket option:
--
Documentation/networking/msg_zerocopy.rst-72-
Documentation/networking/msg_zerocopy.rst:73: if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one)))
Documentation/networking/msg_zerocopy.rst-74- error(1, errno, "setsockopt zerocopy");
--
Documentation/networking/packet_mmap.rst=64=the following process::
--
Documentation/networking/packet_mmap.rst-67- [setup] socket() -------> creation of the capture socket
Documentation/networking/packet_mmap.rst:68: setsockopt() ---> allocation of the circular buffer (ring)
Documentation/networking/packet_mmap.rst-69- option: PACKET_RX_RING
--
Documentation/networking/packet_mmap.rst=105=Transmission process is similar to capture as shown below::
--
Documentation/networking/packet_mmap.rst-107- [setup] socket() -------> creation of the transmission socket
Documentation/networking/packet_mmap.rst:108: setsockopt() ---> allocation of the circular buffer (ring)
Documentation/networking/packet_mmap.rst-109- option: PACKET_TX_RING
--
Documentation/networking/packet_mmap.rst=183=can set tp_net (with SOCK_DGRAM) or tp_mac (with SOCK_RAW). In order
Documentation/networking/packet_mmap.rst:184:to make this work it must be enabled previously with setsockopt()
Documentation/networking/packet_mmap.rst-185-and the PACKET_TX_HAS_OFF option.
--
Documentation/networking/packet_mmap.rst=190=To setup PACKET_MMAP from user level code is done with a call like
--
Documentation/networking/packet_mmap.rst-193-
Documentation/networking/packet_mmap.rst:194: setsockopt(fd, SOL_PACKET, PACKET_RX_RING, (void *) &req, sizeof(req))
Documentation/networking/packet_mmap.rst-195-
--
Documentation/networking/packet_mmap.rst-197-
Documentation/networking/packet_mmap.rst:198: setsockopt(fd, SOL_PACKET, PACKET_TX_RING, (void *) &req, sizeof(req))
Documentation/networking/packet_mmap.rst-199-
--
Documentation/networking/packet_mmap.rst=420=RX and TX buffer ring has to be done with one call to mmap::
--
Documentation/networking/packet_mmap.rst-422- ...
Documentation/networking/packet_mmap.rst:423: setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &foo, sizeof(foo));
Documentation/networking/packet_mmap.rst:424: setsockopt(fd, SOL_PACKET, PACKET_TX_RING, &bar, sizeof(bar));
Documentation/networking/packet_mmap.rst-425- ...
--
Documentation/networking/packet_mmap.rst=448=TP_STATUS_COPY This flag indicates that the frame (and associated
--
Documentation/networking/packet_mmap.rst-453- In order to make this work it must to be
Documentation/networking/packet_mmap.rst:454: enabled previously with setsockopt() and
Documentation/networking/packet_mmap.rst-455- the PACKET_COPY_THRESH option.
--
Documentation/networking/packet_mmap.rst=541=What TPACKET versions are available and when to use them?
--
Documentation/networking/packet_mmap.rst-546- int val = tpacket_version;
Documentation/networking/packet_mmap.rst:547: setsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
Documentation/networking/packet_mmap.rst-548- getsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
--
Documentation/networking/packet_mmap.rst=552=TPACKET_V1:
Documentation/networking/packet_mmap.rst:553: - Default if not otherwise specified by setsockopt(2)
Documentation/networking/packet_mmap.rst-554- - RX_RING, TX_RING available
--
Documentation/networking/packet_mmap.rst=614=Minimal example code by David S. Miller (try things like "./test eth0 hash",
--
Documentation/networking/packet_mmap.rst-673- fanout_arg = (fanout_id | (fanout_type << 16));
Documentation/networking/packet_mmap.rst:674: err = setsockopt(fd, SOL_PACKET, PACKET_FANOUT,
Documentation/networking/packet_mmap.rst-675- &fanout_arg, sizeof(fanout_arg));
--
Documentation/networking/packet_mmap.rst=773=it with gcc -Wall -O2 blob.c, and try things like "./a.out eth0", etc.)::
--
Documentation/networking/packet_mmap.rst-838-
Documentation/networking/packet_mmap.rst:839: err = setsockopt(fd, SOL_PACKET, PACKET_VERSION, &v, sizeof(v));
Documentation/networking/packet_mmap.rst-840- if (err < 0) {
--
Documentation/networking/packet_mmap.rst-852-
Documentation/networking/packet_mmap.rst:853: err = setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &ring->req,
Documentation/networking/packet_mmap.rst-854- sizeof(ring->req));
--
Documentation/networking/packet_mmap.rst=1010=creation::
--
Documentation/networking/packet_mmap.rst-1012- int one = 1;
Documentation/networking/packet_mmap.rst:1013: setsockopt(fd, SOL_PACKET, PACKET_QDISC_BYPASS, &one, sizeof(one));
Documentation/networking/packet_mmap.rst-1014-
--
Documentation/networking/packet_mmap.rst=1035=PACKET_TIMESTAMP accepts the same integer bit field as SO_TIMESTAMPING::
--
Documentation/networking/packet_mmap.rst-1037- int req = SOF_TIMESTAMPING_RAW_HARDWARE;
Documentation/networking/packet_mmap.rst:1038: setsockopt(fd, SOL_PACKET, PACKET_TIMESTAMP, (void *) &req, sizeof(req))
Documentation/networking/packet_mmap.rst-1039-
--
Documentation/networking/rds.rst=67=Socket Interface
--
Documentation/networking/rds.rst-72- to create RDS sockets. SOL_RDS is the socket-level to be used
Documentation/networking/rds.rst:73: with setsockopt(2) and getsockopt(2) for RDS specific socket
Documentation/networking/rds.rst-74- options.
--
Documentation/networking/rds.rst-78-
Documentation/networking/rds.rst:79: setsockopt(SOL_SOCKET): send and receive buffer size
Documentation/networking/rds.rst-80- RDS honors the send and receive buffer size socket options.
--
Documentation/networking/rds.rst-146-
Documentation/networking/rds.rst:147: setsockopt(SOL_RDS, RDS_CANCEL_SENT_TO, &sockaddr_in)
Documentation/networking/rds.rst-148- This allows the application to discard all messages queued to a
--
Documentation/networking/rds.rst-157-
Documentation/networking/rds.rst:158: ``setsockopt(fd, SOL_RDS, SO_RDS_TRANSPORT, (int *)&transport ..), getsockopt(fd, SOL_RDS, SO_RDS_TRANSPORT, (int *)&transport ..)``
Documentation/networking/rds.rst-159- Set or read an integer defining the underlying
--
Documentation/networking/rxrpc.rst=544=A client would issue an operation by:
--
Documentation/networking/rxrpc.rst-572- const char *key = "AFS:cambridge.redhat.com";
Documentation/networking/rxrpc.rst:573: setsockopt(client, SOL_RXRPC, RXRPC_SECURITY_KEY, key, strlen(key));
Documentation/networking/rxrpc.rst-574-
--
Documentation/networking/rxrpc.rst-578- unsigned int sec = RXRPC_SECURITY_ENCRYPT;
Documentation/networking/rxrpc.rst:579: setsockopt(client, SOL_RXRPC, RXRPC_MIN_SECURITY_LEVEL,
Documentation/networking/rxrpc.rst-580- &sec, sizeof(sec));
--
Documentation/networking/rxrpc.rst=640=A server would be set up to accept operations in the following manner:
--
Documentation/networking/rxrpc.rst-658-
Documentation/networking/rxrpc.rst:659: setsockopt(server, SOL_RXRPC, RXRPC_SECURITY_KEYRING, "AFSkeys", 7);
Documentation/networking/rxrpc.rst-660-
--
Documentation/networking/rxrpc.rst-683- unsigned short service_ids[2] = { from_ID, to_ID };
Documentation/networking/rxrpc.rst:684: setsockopt(server, SOL_RXRPC, RXRPC_UPGRADEABLE_SERVICE,
Documentation/networking/rxrpc.rst-685- service_ids, sizeof(service_ids));
--
Documentation/networking/snmp_counter.rst=951=net.core.somaxconn. For example:
Documentation/networking/snmp_counter.rst-952-
Documentation/networking/snmp_counter.rst:953:setsockopt(sfd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
Documentation/networking/snmp_counter.rst-954-
--
Documentation/networking/snmp_counter.rst=1412=The client side code::
--
Documentation/networking/snmp_counter.rst-1421- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Documentation/networking/snmp_counter.rst:1422: s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 10))
Documentation/networking/snmp_counter.rst:1423: s.setsockopt(socket.SOL_TCP, socket.TCP_LINGER2, struct.pack('i', -1))
Documentation/networking/snmp_counter.rst-1424- s.connect((server, port))
--
Documentation/networking/tcp_ao.rst=239=re-establishing the TCP connection.
--
Documentation/networking/tcp_ao.rst-243-
Documentation/networking/tcp_ao.rst:244:Linux TCP-AO support is implemented using ``setsockopt()s``, in a similar way
Documentation/networking/tcp_ao.rst-245-to TCP-MD5. It means that a userspace application that wants to use TCP-AO
Documentation/networking/tcp_ao.rst:246:should perform ``setsockopt()`` on a TCP socket when it wants to add,
Documentation/networking/tcp_ao.rst-247-remove or rotate MKTs. This approach moves the key management responsibility
--
Documentation/networking/tcp_ao.rst=254=no transparency is really needed and modern BGP daemons already have
Documentation/networking/tcp_ao.rst:255:``setsockopt()s`` for TCP-MD5 support.
Documentation/networking/tcp_ao.rst-256-
--
Documentation/networking/tcp_ao.rst-259- +----------------------+------------------------+-----------------------+
Documentation/networking/tcp_ao.rst:260: | | ``setsockopt()`` | in-kernel DB |
Documentation/networking/tcp_ao.rst-261- +======================+========================+=======================+
Documentation/networking/tcp_ao.rst:262: | Extendability | ``setsockopt()`` | Netlink messages are |
Documentation/networking/tcp_ao.rst-263- | | commands should be | simple and extendable |
--
Documentation/networking/tcp_ao.rst-268- | | to perform | something like |
Documentation/networking/tcp_ao.rst:269: | | ``setsockopt()s`` | ``ip tcpao add key`` |
Documentation/networking/tcp_ao.rst-270- | | and do key management | (delete/show/rotate) |
--
Documentation/networking/tcp_ao.rst-292-
Documentation/networking/tcp_ao.rst:293:Linux provides a set of ``setsockopt()s`` and ``getsockopt()s`` that let
Documentation/networking/tcp_ao.rst-294-userspace manage TCP-AO on a per-socket basis. In order to add/delete MKTs
--
Documentation/networking/tcp_ao.rst=297=as well as to remove the last key from TCP-AO connection.
Documentation/networking/tcp_ao.rst-298-
Documentation/networking/tcp_ao.rst:299:``setsockopt(TCP_AO_DEL_KEY)`` command may specify ``tcp_ao_del::current_key``
Documentation/networking/tcp_ao.rst-300-+ ``tcp_ao_del::set_current`` and/or ``tcp_ao_del::rnext``
--
Documentation/networking/tcp_ao.rst=306=the TCP-AO connection.
Documentation/networking/tcp_ao.rst-307-
Documentation/networking/tcp_ao.rst:308:The usual/normal key-rotation can be performed with ``setsockopt(TCP_AO_INFO)``.
Documentation/networking/tcp_ao.rst-309-It also provides a uAPI to change per-socket TCP-AO settings, such as
--
Documentation/networking/tcp_ao.rst=316=peer and/or sndid/rcvid, VRF L3 interface or get current_key/rnext_key.
Documentation/networking/tcp_ao.rst-317-
Documentation/networking/tcp_ao.rst:318:To repair TCP-AO connections ``setsockopt(TCP_AO_REPAIR)`` is available,
Documentation/networking/tcp_ao.rst-319-provided that the user previously has checkpointed/dumped the socket with
--
Documentation/networking/tcp_ao.rst=323=keys, is: use filters in ``getsockopt(TCP_AO_GET_KEYS)`` and asynchronous
Documentation/networking/tcp_ao.rst:324:delete with ``setsockopt(TCP_AO_DEL_KEY)``.
Documentation/networking/tcp_ao.rst-325-
--
Documentation/networking/tcp_ao.rst=359=not implemented.
Documentation/networking/tcp_ao.rst-360-
Documentation/networking/tcp_ao.rst:361:4. ``setsockopt()`` vs ``accept()`` race
Documentation/networking/tcp_ao.rst-362-========================================
--
Documentation/networking/tcp_ao.rst=380=At this moment, the resolution for the two races:
Documentation/networking/tcp_ao.rst:381:``setsockopt(TCP_AO_ADD_KEY)`` vs ``accept()``
Documentation/networking/tcp_ao.rst:382:and ``setsockopt(TCP_AO_DEL_KEY)`` vs ``accept()`` is delegated to userspace.
Documentation/networking/tcp_ao.rst-383-This means that it's expected that userspace would check the MKTs on the socket
--
Documentation/networking/timestamping.rst=75=socket option takes a bitmap of flags, not a boolean. In::
Documentation/networking/timestamping.rst-76-
Documentation/networking/timestamping.rst:77: err = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &val, sizeof(val));
Documentation/networking/timestamping.rst-78-
--
Documentation/networking/timestamping.rst=344=setsockopt to receive timestamps::
--
Documentation/networking/timestamping.rst-347- SOF_TIMESTAMPING_OPT_ID /* or any other flag */;
Documentation/networking/timestamping.rst:348: err = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &val, sizeof(val));
Documentation/networking/timestamping.rst-349-
--
Documentation/networking/tls.rst=20=TLS ULP.
--
Documentation/networking/tls.rst-25- connect(sock, addr, addrlen);
Documentation/networking/tls.rst:26: setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));
Documentation/networking/tls.rst-27-
--
Documentation/networking/tls.rst=32=the transmit and the receive into the kernel.
--
Documentation/networking/tls.rst-60-
Documentation/networking/tls.rst:61: setsockopt(sock, SOL_TLS, TLS_TX, &crypto_info, sizeof(crypto_info));
Documentation/networking/tls.rst-62-
--
Documentation/networking/tls.rst=250=or may impact correctness, hence they require an opt-in.
Documentation/networking/tls.rst:251:All options are set per-socket using setsockopt(), and their
Documentation/networking/tls.rst-252-state can be checked using getsockopt() and via socket diag (``ss``).
--
Documentation/networking/tproxy.rst=39=option before calling bind::
--
Documentation/networking/tproxy.rst-43- int value = 1;
Documentation/networking/tproxy.rst:44: setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value));
Documentation/networking/tproxy.rst-45- /* - 8< -*/
--
Documentation/networking/udplite.rst=4=The UDP-Lite protocol (RFC 3828)
--
Documentation/networking/udplite.rst-67- int val = 20;
Documentation/networking/udplite.rst:68: setsockopt(s, SOL_UDPLITE, UDPLITE_SEND_CSCOV, &val, sizeof(int));
Documentation/networking/udplite.rst-69-
--
Documentation/networking/udplite.rst-85- int min = 20;
Documentation/networking/udplite.rst:86: setsockopt(s, SOL_UDPLITE, UDPLITE_RECV_CSCOV, &min, sizeof(int));
Documentation/networking/udplite.rst-87-
--
Documentation/networking/udplite.rst-147-
Documentation/networking/udplite.rst:148: setsockopt(sockfd, SOL_SOCKET, SO_NO_CHECK, ... );
Documentation/networking/udplite.rst-149-
--
Documentation/networking/vrf.rst=114=VRF device::
Documentation/networking/vrf.rst-115-
Documentation/networking/vrf.rst:116: setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, dev, strlen(dev)+1);
Documentation/networking/vrf.rst-117-
--
Documentation/translations/it_IT/kernel-hacking/locking.rst=163=Per esempio: ``net/netfilter/nf_sockopt.c`` permette la registrazione
Documentation/translations/it_IT/kernel-hacking/locking.rst:164:di nuove chiamate per setsockopt() e getsockopt()
]
]
|
| 45/2 |
2026/03/11 08:09 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 49704
output: 18
thoughts: 15
Thoughts: Here's my thought process, summarized as if I were considering this myself:
**Investigating `setsockopt` in `sys.txt`**
Okay, so I need to find the definition or usage of `setsockopt`. My first step, and really the most logical given what I know about system calls and file system structures, is to check `sys.txt`. It's highly probable that information related to `setsockopt` – its arguments, return values, any associated flags or constants – would be documented there, likely alongside other socket-related system calls. That file is generally the place to start when I need to figure out system call behavior. Makes perfect sense to dig in there.
|
| 46/2 |
2026/03/11 08:10 |
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]]
type iovec_inout iovec[inout, 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
]
|
| 47/2 |
2026/03/11 08:10 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 75866
output: 18
thoughts: 23
Thoughts: Here's my thought process, as it went down:
**Investigating a Missing Socket Option**
Okay, so `sys.txt` doesn't seem to contain the information I was expecting. Specifically, I was looking for the `setsockopt` function and it's just not there. Given that, the next logical step is to check `socket.txt`. It's highly probable that `setsockopt`, being a fundamental socket-related operation, would reside there. It's the most likely place based on my experience. I'll need to confirm that and then proceed accordingly.
|
| 48/2 |
2026/03/11 08:10 |
tool |
read-description |
0m
Args:
Results: map[Output:# Copyright 2017 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 <asm/ioctls.h>
include <linux/if_tun.h>
include <linux/if_bridge.h>
include <linux/net.h>
include <linux/net_tstamp.h>
include <linux/route.h>
include <linux/socket.h>
include <uapi/linux/in.h>
include <uapi/linux/ethtool.h>
include <uapi/linux/if_ether.h>
include <uapi/linux/if_vlan.h>
include <uapi/asm-generic/socket.h>
resource sock[fd]
type sock_port int16be[20000:20004]
# TODO: describe socketcall syscall
socket(domain flags[socket_domain], type flags[socket_type], proto int32) sock (automatic_helper)
socketpair(domain flags[socket_domain], type flags[socket_type], proto int32, fds ptr[out, sock_pair])
bind(fd sock, addr ptr[in, sockaddr_storage], addrlen len[addr])
connect(fd sock, addr ptr[in, sockaddr_storage], addrlen len[addr])
accept(fd sock, peer ptr[out, sockaddr_storage, opt], peerlen ptr[inout, len[peer, int32]]) sock
accept4(fd sock, peer ptr[out, sockaddr_storage, opt], peerlen ptr[inout, len[peer, int32]], flags flags[accept_flags]) sock
sendto(fd sock, buf buffer[in], len len[buf], f flags[send_flags], addr ptr[in, sockaddr_storage, opt], addrlen len[addr])
recvfrom(fd sock, buf buffer[out], len len[buf], f flags[recv_flags], addr ptr[in, sockaddr_storage, opt], addrlen len[addr])
getsockname(fd sock, addr ptr[out, sockaddr_storage], addrlen ptr[inout, len[addr, int32]])
getpeername(fd sock, peer ptr[out, sockaddr_storage], peerlen ptr[inout, len[peer, int32]])
sendmsg(fd sock, msg ptr[in, send_msghdr], f flags[send_flags])
sendmmsg(fd sock, mmsg ptr[in, array[send_mmsghdr]], vlen len[mmsg], f flags[send_flags])
recvmsg(fd sock, msg ptr[inout, recv_msghdr], f flags[recv_flags])
recvmmsg(fd sock, mmsg ptr[in, array[recv_mmsghdr]], vlen len[mmsg], f flags[recv_flags], timeout ptr[in, timespec, opt])
listen(fd sock, backlog int32)
shutdown(fd sock, how flags[shutdown_flags])
getsockopt(fd sock, level int32, optname int32, optval buffer[out], optlen ptr[inout, len[optval, int32]])
setsockopt(fd sock, level int32, optname int32, optval buffer[in], optlen len[optval])
socket_domain = AF_UNIX, AF_INET, AF_INET6, AF_NETLINK, AF_X25, AF_AX25, AF_ATMPVC, AF_APPLETALK, AF_PACKET, AF_VSOCK, AF_XDP, AF_TIPC, AF_RXRPC, AF_PPPOX, AF_RDS, AF_ROSE, AF_PHONET, AF_NFC, AF_NETROM, AF_KEY, AF_KCM, AF_ISDN, AF_SMC, AF_CAN, AF_CAIF, AF_BLUETOOTH, AF_LLC, AF_ALG, AF_QIPCRTR
socket_type = SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_DCCP, SOCK_PACKET, SOCK_NONBLOCK, SOCK_CLOEXEC
accept_flags = SOCK_NONBLOCK, SOCK_CLOEXEC
shutdown_flags = SHUT_RD, SHUT_WR
send_flags = MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, MSG_EOR, MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PROBE, MSG_BATCH, MSG_FASTOPEN, MSG_ZEROCOPY
recv_flags = MSG_CMSG_CLOEXEC, MSG_DONTWAIT, MSG_ERRQUEUE, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, MSG_WAITFORONE
cmsg_levels = SOL_SOCKET, IPPROTO_ICMP, SOL_IP, SOL_TCP, SOL_UDP, SOL_IPV6, SOL_ICMPV6, SOL_SCTP, SOL_UDPLITE, SOL_RAW, SOL_AX25, SOL_ATALK, SOL_NETROM, SOL_ROSE, SOL_PACKET, SOL_ATM, SOL_AAL, SOL_IRDA, SOL_NETBEUI, SOL_LLC, SOL_DCCP, SOL_NETLINK, SOL_TIPC, SOL_RXRPC, SOL_PPPOL2TP, SOL_BLUETOOTH, SOL_PNPIPE, SOL_RDS, SOL_IUCV, SOL_CAIF, SOL_ALG, SOL_NFC, SOL_KCM
sock_pair {
fd0 sock
fd1 sock
}
# This sockaddr type corresponds to the struct sockaddr and is 16 bytes or less.
# TODO: add AF_APPLETALK, AF_ATMPVC, AF_ROSE, AF_ATMSVC, AF_IRDA, AF_IB, AF_IUCV
# Note: AF_UNIX, AF_INET6, AF_PACKET, AF_ALG, AF_PPPOX sockaddr is bigger than 16 bytes
# Note: AF_NETROM sockaddr is the same as AF_AX25
sockaddr [
in sockaddr_in
ax25 sockaddr_ax25
nl sockaddr_nl
llc sockaddr_llc
can sockaddr_can
sco sockaddr_sco
l2 sockaddr_l2
hci sockaddr_hci
rc sockaddr_rc
nfc sockaddr_nfc
vsock sockaddr_vm
xdp sockaddr_xdp
tipc sockaddr_tipc
isdn sockaddr_mISDN
l2tp sockaddr_l2tpip
phonet sockaddr_pn
ethernet sockaddr_ethernet
qipcrtr sockaddr_qrtr
generic sockaddr_generic
] [size[SOCKADDR_SIZE]]
# This sockaddr type corresponds to the sockaddr_storage type and is 128 bytes size.
sockaddr_storage [
un sockaddr_un
in sockaddr_in
x25 sockaddr_x25
ax25 full_sockaddr_ax25
in6 sockaddr_in6
nl sockaddr_nl
ll sockaddr_ll
pppoe sockaddr_pppoe
pppol2tp sockaddr_pppol2tp
pppol2tpin6 sockaddr_pppol2tpin6
pppol2tpv3 sockaddr_pppol2tpv3
pppol2tpv3in6 sockaddr_pppol2tpv3in6
pptp sockaddr_pptp
l2tp sockaddr_l2tpip
l2tp6 sockaddr_l2tpip6
llc sockaddr_llc
can sockaddr_can
sco sockaddr_sco
l2 sockaddr_l2
hci sockaddr_hci
rc sockaddr_rc
alg sockaddr_alg
nfc sockaddr_nfc
nfc_llcp sockaddr_nfc_llcp
vsock sockaddr_vm
xdp sockaddr_xdp
tipc sockaddr_tipc
caif sockaddr_caif
isdn sockaddr_mISDN
rxrpc sockaddr_rxrpc
phonet sockaddr_pn
ethernet sockaddr_ethernet
qipcrtr sockaddr_qrtr
ieee802154 sockaddr_ieee802154
generic sockaddr_storage_generic
] [size[SOCKADDR_STORAGE_SIZE]]
define SOCKADDR_SIZE sizeof(struct sockaddr)
define SOCKADDR_STORAGE_SIZE sizeof(struct sockaddr_storage)
sockaddr_generic {
sa_family flags[socket_domain, int16]
sa_data array[int8, 14]
}
sockaddr_storage_generic {
sa_family flags[socket_domain, int16]
sa_data array[int8, 126]
}
send_msghdr {
msg_name ptr[in, sockaddr_storage, opt]
msg_namelen len[msg_name, int32]
msg_iov ptr[in, array[iovec_in]]
msg_iovlen len[msg_iov, intptr]
msg_control ptr[in, array[cmsghdr], opt]
msg_controllen bytesize[msg_control, intptr]
msg_flags const[0, int32]
}
msghdr_sock {
msg_name ptr[in, sockaddr_storage, opt]
msg_namelen len[msg_name, int32]
msg_iov ptr[in, array[iovec_in]]
msg_iovlen len[msg_iov, intptr]
msg_control ptr[in, array[cmsghdr_sock], opt]
msg_controllen bytesize[msg_control, intptr]
msg_flags const[0, int32]
}
send_mmsghdr {
msg_hdr send_msghdr
msg_len const[0, int32]
}
mmsghdr_sock {
msg_hdr msghdr_sock
msg_len const[0, int32]
}
recv_msghdr {
msg_name ptr[out, sockaddr_storage, opt]
msg_namelen len[msg_name, int32]
msg_iov ptr[in, array[iovec_out]]
msg_iovlen len[msg_iov, intptr]
msg_control ptr[out, array[int8], opt]
msg_controllen bytesize[msg_control, intptr]
msg_flags const[0, int32]
}
recv_mmsghdr {
msg_hdr recv_msghdr
msg_len int32
}
cmsghdr {
cmsg_len len[parent, intptr]
cmsg_level flags[cmsg_levels, int32]
cmsg_type int32
data array[int8]
} [align[PTR_SIZE]]
type cmsghdr_t[SOL, TYP, DATA] {
unaligned cmsghdr_unaligned[SOL, TYP, DATA]
} [align[PTR_SIZE]]
type cmsghdr_unaligned[SOL, TYP, DATA] {
cmsg_len len[parent, intptr]
cmsg_level const[SOL, int32]
cmsg_type const[TYP, int32]
data DATA
} [packed]
# For __sock_cmsg_send
cmsghdr_sock [
mark cmsghdr_t[SOL_SOCKET, SO_MARK, int32]
timestamping cmsghdr_t[SOL_SOCKET, SO_TIMESTAMPING_OLD, int32]
txtime cmsghdr_t[SOL_SOCKET, SCM_TXTIME, int64]
] [varlen]
# Socket options
# http://lxr.free-electrons.com/source/include/uapi/asm-generic/socket.h
setsockopt$sock_void(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_void], optval const[0], optlen const[0])
getsockopt$sock_int(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_int], optval ptr[out, int32], optlen ptr[inout, len[optval, int32]])
setsockopt$sock_int(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_int], optval ptr[in, int32], optlen len[optval])
getsockopt$sock_linger(fd sock, level const[SOL_SOCKET], optname const[SO_LINGER], optval ptr[out, linger], optlen ptr[inout, len[optval, int32]])
setsockopt$sock_linger(fd sock, level const[SOL_SOCKET], optname const[SO_LINGER], optval ptr[in, linger], optlen len[optval])
getsockopt$sock_cred(fd sock, level const[SOL_SOCKET], optname const[SO_PEERCRED], optval ptr[out, ucred], optlen ptr[inout, len[optval, int32]])
setsockopt$sock_cred(fd sock, level const[SOL_SOCKET], optname const[SO_PEERCRED], optval ptr[in, ucred], optlen len[optval])
getsockopt$sock_timeval(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_timeval], optval ptr[out, timeval], optlen ptr[inout, len[optval, int32]])
setsockopt$sock_timeval(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_timeval], optval ptr[in, timeval], optlen len[optval])
setsockopt$sock_attach_bpf(fd sock, level const[SOL_SOCKET], optname const[SO_ATTACH_BPF], optval ptr[in, fd_bpf_prog], optlen len[optval])
setsockopt$SO_TIMESTAMP(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_timestamp], optval ptr[in, int32], optlen len[optval])
getsockopt$SO_TIMESTAMP(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_timestamp], optval ptr[out, int32], optlen ptr[inout, len[optval, int32]])
setsockopt$SO_TIMESTAMPING(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_timestamping], optval ptr[in, flags[sockopt_so_timestamping, int32]], optlen len[optval])
getsockopt$SO_TIMESTAMPING(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_timestamping], optval ptr[out, int32], optlen ptr[inout, len[optval, int32]])
setsockopt$SO_ATTACH_FILTER(fd sock, level const[SOL_SOCKET], optname const[SO_ATTACH_FILTER], optval ptr[in, sock_fprog], optlen len[optval])
setsockopt$SO_BINDTODEVICE(fd sock, level const[SOL_SOCKET], optname const[SO_BINDTODEVICE], optval ptr[in, devname], optlen len[optval])
getsockopt$SO_BINDTODEVICE(fd sock, level const[SOL_SOCKET], optname const[SO_BINDTODEVICE], optval ptr[out, devname], optlen len[optval])
getsockopt$sock_buf(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_buf], optval buffer[out], optlen ptr[inout, len[optval, int32]])
getsockopt$SO_COOKIE(fd sock, level const[SOL_SOCKET], optname const[SO_COOKIE], optval ptr[out, int64], optlen ptr[inout, len[optval, int32]])
linger {
onoff bool32
linger int32
}
sockopt_opt_sock_void = SO_DETACH_FILTER, SO_MARK
sockopt_opt_sock_int = SO_ACCEPTCONN, SO_BROADCAST, SO_DEBUG, SO_DOMAIN, SO_ERROR, SO_DONTROUTE, SO_KEEPALIVE, SO_PEEK_OFF, SO_PRIORITY, SO_PROTOCOL, SO_RCVBUF, SO_RCVBUFFORCE, SO_RCVLOWAT, SO_SNDLOWAT, SO_REUSEADDR, SO_SNDBUF, SO_SNDBUFFORCE, SO_TIMESTAMP_OLD, SO_TYPE, SO_REUSEPORT, SO_OOBINLINE, SO_NO_CHECK, SO_PASSCRED, SO_TIMESTAMPNS_OLD, SO_LOCK_FILTER, SO_PASSSEC, SO_RXQ_OVFL, SO_WIFI_STATUS, SO_NOFCS, SO_SELECT_ERR_QUEUE, SO_BUSY_POLL, SO_MAX_PACING_RATE, SO_ZEROCOPY
sockopt_opt_sock_timeval = SO_RCVTIMEO_OLD, SO_RCVTIMEO_NEW, SO_SNDTIMEO_OLD, SO_SNDTIMEO_NEW
sockopt_opt_sock_timestamp = SO_TIMESTAMP_OLD, SO_TIMESTAMP_NEW, SO_TIMESTAMPNS_OLD, SO_TIMESTAMPNS_NEW
sockopt_opt_sock_timestamping = SO_TIMESTAMPING_OLD, SO_TIMESTAMPING_NEW
sockopt_opt_sock_buf = SO_PEERNAME, SO_PEERSEC, SO_GET_FILTER, SO_MEMINFO, SO_PEERGROUPS, SO_TXTIME
sockopt_so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE, SOF_TIMESTAMPING_TX_SOFTWARE, SOF_TIMESTAMPING_RX_HARDWARE, SOF_TIMESTAMPING_RX_SOFTWARE, SOF_TIMESTAMPING_SOFTWARE, SOF_TIMESTAMPING_SYS_HARDWARE, SOF_TIMESTAMPING_RAW_HARDWARE, SOF_TIMESTAMPING_OPT_ID, SOF_TIMESTAMPING_TX_SCHED, SOF_TIMESTAMPING_TX_ACK, SOF_TIMESTAMPING_OPT_CMSG, SOF_TIMESTAMPING_OPT_TSONLY, SOF_TIMESTAMPING_OPT_STATS, SOF_TIMESTAMPING_OPT_PKTINFO, SOF_TIMESTAMPING_OPT_TX_SWHW
# Socket ioctls
# Since some socket ioctls are forwarded to the network device, adding device ioctls here as well.
# http://lxr.free-electrons.com/linux/latest/source/include/uapi/linux/sockios.h
# http://lxr.free-electrons.com/linux/latest/source/include/uapi/asm-generic/sockios.h
ioctl$sock_SIOCADDRT(fd sock, cmd const[SIOCADDRT], arg ptr[inout, rtentry])
ioctl$sock_SIOCDELRT(fd sock, cmd const[SIOCDELRT], arg ptr[inout, rtentry])
ioctl$sock_SIOCGIFVLAN_SET_VLAN_INGRESS_PRIORITY_CMD(fd sock, cmd const[SIOCGIFVLAN], arg ptr[in, vlan_args[SET_VLAN_INGRESS_PRIORITY_CMD, int32]])
ioctl$sock_SIOCGIFVLAN_SET_VLAN_EGRESS_PRIORITY_CMD(fd sock, cmd const[SIOCGIFVLAN], arg ptr[in, vlan_args[SET_VLAN_EGRESS_PRIORITY_CMD, int32]])
ioctl$sock_SIOCGIFVLAN_SET_VLAN_FLAG_CMD(fd sock, cmd const[SIOCGIFVLAN], arg ptr[in, vlan_args[SET_VLAN_FLAG_CMD, int32]])
ioctl$sock_SIOCGIFVLAN_SET_VLAN_NAME_TYPE_CMD(fd sock, cmd const[SIOCGIFVLAN], arg ptr[in, vlan_args[SET_VLAN_NAME_TYPE_CMD, int32]])
ioctl$sock_SIOCGIFVLAN_ADD_VLAN_CMD(fd sock, cmd const[SIOCGIFVLAN], arg ptr[in, vlan_args[ADD_VLAN_CMD, int32[0:4]]])
ioctl$sock_SIOCGIFVLAN_DEL_VLAN_CMD(fd sock, cmd const[SIOCGIFVLAN], arg ptr[in, vlan_args[DEL_VLAN_CMD, const[0, int32]]])
ioctl$sock_SIOCGIFVLAN_GET_VLAN_REALDEV_NAME_CMD(fd sock, cmd const[SIOCGIFVLAN], arg ptr[inout, vlan_args[GET_VLAN_REALDEV_NAME_CMD, string[devnames, 24]]])
ioctl$sock_SIOCGIFVLAN_GET_VLAN_VID_CMD(fd sock, cmd const[SIOCGIFVLAN], arg ptr[out, vlan_args[GET_VLAN_VID_CMD, int32]])
ioctl$sock_SIOCGIFVLAN_GET_VLAN_INGRESS_PRIORITY_CMD(fd sock, cmd const[SIOCGIFVLAN], arg ptr[out, vlan_args[GET_VLAN_INGRESS_PRIORITY_CMD, const[0, int32]]])
ioctl$sock_SIOCGIFVLAN_GET_VLAN_EGRESS_PRIORITY_CMD(fd sock, cmd const[SIOCGIFVLAN], arg ptr[out, vlan_args[GET_VLAN_EGRESS_PRIORITY_CMD, const[0, int32]]])
ioctl$sock_SIOCSIFVLAN_SET_VLAN_INGRESS_PRIORITY_CMD(fd sock, cmd const[SIOCSIFVLAN], arg ptr[in, vlan_args[SET_VLAN_INGRESS_PRIORITY_CMD, int32]])
ioctl$sock_SIOCSIFVLAN_SET_VLAN_EGRESS_PRIORITY_CMD(fd sock, cmd const[SIOCSIFVLAN], arg ptr[in, vlan_args[SET_VLAN_EGRESS_PRIORITY_CMD, int32]])
ioctl$sock_SIOCSIFVLAN_SET_VLAN_FLAG_CMD(fd sock, cmd const[SIOCSIFVLAN], arg ptr[in, vlan_args[SET_VLAN_FLAG_CMD, int32]])
ioctl$sock_SIOCSIFVLAN_SET_VLAN_NAME_TYPE_CMD(fd sock, cmd const[SIOCSIFVLAN], arg ptr[in, vlan_args[SET_VLAN_NAME_TYPE_CMD, int32]])
ioctl$sock_SIOCSIFVLAN_ADD_VLAN_CMD(fd sock, cmd const[SIOCSIFVLAN], arg ptr[in, vlan_args[ADD_VLAN_CMD, int32[0:4]]])
ioctl$sock_SIOCSIFVLAN_DEL_VLAN_CMD(fd sock, cmd const[SIOCSIFVLAN], arg ptr[in, vlan_args[DEL_VLAN_CMD, const[0, int32]]])
ioctl$sock_SIOCSIFVLAN_GET_VLAN_REALDEV_NAME_CMD(fd sock, cmd const[SIOCSIFVLAN], arg ptr[inout, vlan_args[GET_VLAN_REALDEV_NAME_CMD, string[devnames, 24]]])
ioctl$sock_SIOCSIFVLAN_GET_VLAN_VID_CMD(fd sock, cmd const[SIOCSIFVLAN], arg ptr[out, vlan_args[GET_VLAN_VID_CMD, int32]])
ioctl$sock_SIOCSIFVLAN_GET_VLAN_INGRESS_PRIORITY_CMD(fd sock, cmd const[SIOCSIFVLAN], arg ptr[out, vlan_args[GET_VLAN_INGRESS_PRIORITY_CMD, const[0, int32]]])
ioctl$sock_SIOCSIFVLAN_GET_VLAN_EGRESS_PRIORITY_CMD(fd sock, cmd const[SIOCSIFVLAN], arg ptr[out, vlan_args[GET_VLAN_EGRESS_PRIORITY_CMD, const[0, int32]]])
ioctl$sock_SIOCETHTOOL(fd sock, cmd const[SIOCETHTOOL], arg ptr[inout, ifreq_t[ptr[inout, ethtool_cmd_u]]])
ioctl$sock_SIOCOUTQ(fd sock, cmd const[SIOCOUTQ], arg ptr[out, int32])
ioctl$sock_SIOCINQ(fd sock, cmd const[SIOCINQ], arg ptr[out, int32])
ioctl$sock_SIOCGIFCONF(fd sock, cmd const[SIOCGIFCONF], arg ptr[inout, ifconf])
ifreq_ioctls = SIOCGIFNAME, SIOCSIFLINK, SIOCGIFFLAGS, SIOCSIFFLAGS, SIOCGIFADDR, SIOCSIFADDR, SIOCGIFDSTADDR, SIOCSIFDSTADDR, SIOCGIFBRDADDR, SIOCSIFBRDADDR, SIOCGIFNETMASK, SIOCSIFNETMASK, SIOCGIFMETRIC, SIOCSIFMETRIC, SIOCGIFMEM, SIOCSIFMEM, SIOCGIFMTU, SIOCSIFMTU, SIOCSIFNAME, SIOCSIFHWADDR, SIOCGIFENCAP, SIOCSIFENCAP, SIOCGIFHWADDR, SIOCGIFSLAVE, SIOCSIFSLAVE, SIOCADDMULTI, SIOCDELMULTI, SIOCGIFINDEX, SIOCSIFPFLAGS, SIOCGIFPFLAGS, SIOCDIFADDR, SIOCSIFHWBROADCAST, SIOCGIFCOUNT, SIOCGIFTXQLEN, SIOCSIFTXQLEN, SIOCETHTOOL, SIOCGMIIPHY, SIOCGMIIREG, SIOCSMIIREG, SIOCWANDEV, SIOCGIFMAP, SIOCSIFMAP, SIOCBONDENSLAVE, SIOCBONDRELEASE, SIOCBONDSETHWADDR, SIOCBONDSLAVEINFOQUERY, SIOCBONDINFOQUERY, SIOCBONDCHANGEACTIVE, SIOCBRADDIF, SIOCBRDELIF, SIOCSHWTSTAMP, SIOCGHWTSTAMP
ioctl$sock_ifreq(fd sock, cmd flags[ifreq_ioctls], arg ptr[inout, ifreq])
ioctl$sock_SIOCGIFINDEX(fd sock, cmd const[SIOCGIFINDEX], arg ptr[out, ifreq_t[ifindex]]) (automatic_helper)
ioctl$sock_SIOCGIFBR(fd sock, cmd const[SIOCGIFBR], arg ptr[inout, brctl_arg])
ioctl$sock_SIOCSIFBR(fd sock, cmd const[SIOCSIFBR], arg ptr[inout, brctl_arg])
ioctl$sock_SIOCOUTQNSD(fd sock, cmd const[SIOCOUTQNSD], arg ptr[out, int32])
ioctl$sock_SIOCGSKNS(fd sock, cmd const[SIOCGSKNS], arg ptr[inout, int32])
ioctl$sock_SIOCADDDLCI(fd sock, cmd const[SIOCADDDLCI], arg ptr[inout, dlci_add])
ioctl$sock_SIOCDELDLCI(fd sock, cmd const[SIOCDELDLCI], arg ptr[in, dlci_add])
ioctl$sock_SIOCBRADDBR(fd sock, cmd const[SIOCBRADDBR], arg ptr[in, devname])
ioctl$sock_SIOCBRDELBR(fd sock, cmd const[SIOCBRDELBR], arg ptr[in, devname])
define SIOCDEVPRIVATE_BEG (SIOCDEVPRIVATE)
define SIOCDEVPRIVATE_END (SIOCDEVPRIVATE + 15)
define SIOCPROTOPRIVATE_BEG (SIOCPROTOPRIVATE)
define SIOCPROTOPRIVATE_END (SIOCPROTOPRIVATE + 15)
ioctl$sock_netdev_private(fd sock, cmd int32[SIOCDEVPRIVATE_BEG:SIOCDEVPRIVATE_END], arg ptr[in, array[int8]])
ioctl$sock_proto_private(fd sock, cmd int32[SIOCPROTOPRIVATE_BEG:SIOCPROTOPRIVATE_END], arg ptr[in, array[int8]])
ioctl$sock_FIOSETOWN(fd sock, cmd const[FIOSETOWN], arg ptr[in, pid])
ioctl$sock_SIOCSPGRP(fd sock, cmd const[SIOCSPGRP], arg ptr[in, pid])
ioctl$sock_FIOGETOWN(fd sock, cmd const[FIOGETOWN], arg ptr[out, pid])
ioctl$sock_SIOCGPGRP(fd sock, cmd const[SIOCGPGRP], arg ptr[out, pid])
ioctl$sock_TIOCOUTQ(fd sock, cmd const[TIOCOUTQ], arg ptr[out, int32])
ioctl$sock_TIOCINQ(fd sock, cmd const[TIOCINQ], arg ptr[out, int32])
ioctl$SIOCGSTAMP(fd sock, cmd const[SIOCGSTAMP], arg ptr[out, timeval])
ioctl$SIOCGSTAMPNS(fd sock, cmd const[SIOCGSTAMPNS], arg ptr[out, timespec])
# Socket sendmsg
sendmsg$sock(fd sock, msg ptr[in, msghdr_sock], f flags[send_flags])
sendmmsg$sock(fd sock, mmsg ptr[in, array[mmsghdr_sock]], vlen len[mmsg], f flags[send_flags])
resource ifindex[int32]
type ifreq_dev_t[DEVNAME, ELEM] {
ifr_ifrn string[DEVNAME, IFNAMSIZ] (in)
elem ELEM
} [size[IFREQ_SIZE]]
type ifreq_t[ELEM] ifreq_dev_t[devnames, ELEM]
type ifreq ifreq_t[ifr_ifru]
ifr_ifru [
ifru_addrs sockaddr
ifru_hwaddr mac_addr
ifru_flags flags[ifru_flags, int16]
ifru_ivalue int32
ifru_mtu int32
ifru_map ifmap
ifru_names devname
ifru_data ptr[in, array[int8, 32]]
ifru_settings if_settings
]
define IFREQ_SIZE sizeof(struct ifreq)
# https://elixir.bootlin.com/linux/v5.3.11/source/include/uapi/linux/if_vlan.h
type vlan_args[CMD, DATA] {
cmd const[CMD, int32]
device1 string[devnames, 24]
u vlan_args_u[DATA]
vlan_qos int16
}
type vlan_args_u[DATA] {
datadata DATA
} [size[24]]
# https://elixir.bootlin.com/linux/v5.3.12/source/include/uapi/linux/route.h#L31
rtentry {
rt_pad1 const[0, intptr]
rt_dst sockaddr
rt_gateway sockaddr
rt_genmask sockaddr
rt_flags int16
rt_pad2 const[0, int16]
rt_pad3 const[0, intptr]
rt_pad4 const[0, intptr]
rt_metric int16
rt_dev ptr[in, devname, opt]
rt_mtu intptr
rt_window intptr
rt_irtt int16
}
# We could add "eth0" to this list as well, but this will affect the connection
# between fuzzer and manager and produce lots of "no output" crashes
# (actually, this is not true now since all testing is done in a separate
# network namespace, but we still don't mess with eth0).
# Note: lapb0, bpq0 and hwsim0 are only present in init namespace.
# Note: for roseN and nrN we should use proc type, but for simplicity we currently use N=0.
# Note: netdevsim0 and netpci0 are renamed in initialize_devlink_ports()
devnames = "", "lo", "tunl0", "gre0", "gretap0", "ip_vti0", "ip6_vti0", "sit0", "ip6tnl0", "ip6gre0", "ip6gretap0", "bond0", "dummy0", "nr0", "rose0", "erspan0", "vlan0", "bridge0", "vcan0", "team0", "syz_tun", "veth0", "veth1", "veth0_to_bridge", "veth1_to_bridge", "veth0_to_bond", "veth1_to_bond", "veth0_to_team", "veth1_to_team", "bridge_slave_0", "bridge_slave_1", "bond_slave_0", "bond_slave_1", "team_slave_0", "team_slave_1", "syzkaller0", "syzkaller1", "veth0_to_hsr", "veth1_to_hsr", "hsr0", "ip6erspan0", "vxcan1", "caif0", "batadv0", "veth0_to_batadv", "veth1_to_batadv", "batadv_slave_0", "batadv_slave_1", "netdevsim0", "netpci0", "nicvf0", "xfrm0", "veth0_virt_wifi", "veth1_virt_wifi", "virt_wifi0", "veth0_vlan", "veth1_vlan", "vlan0", "vlan1", "macvlan0", "macvlan1", "ipvlan0", "ipvlan1", "veth0_macvtap", "veth1_macvtap", "macvtap0", "macsec0", "geneve0", "geneve1", "wg0", "wg1", "wg2", "wlan0", "wlan1", "dvmrp0", "dvmrp1", "pimreg", "pimreg0", "pimreg1", "pim6reg", "pim6reg0", "pim6reg1"
type devname string[devnames, IFNAMSIZ]
devname_mask {
lo flags[devname_mask_values, int8]
} [size[IFNAMSIZ]]
devname_mask_values = 0, 0xff
ifru_flags = IFF_TUN, IFF_TAP, IFF_NO_PI, IFF_ONE_QUEUE, IFF_VNET_HDR, IFF_TUN_EXCL, IFF_MULTI_QUEUE, IFF_ATTACH_QUEUE, IFF_DETACH_QUEUE, IFF_PERSIST, IFF_NOFILTER
ifmap {
mem_start intptr
mem_end intptr
base_addr int16
irq int8
dma int8
port int8
}
if_settings {
type int32
size int32
ifs_ifsu ifs_ifsu
}
ifs_ifsu [
raw_hdlc ptr[in, raw_hdlc_proto]
cisco ptr[in, cisco_proto]
fr ptr[in, fr_proto]
fr_pvc ptr[in, fr_proto_pvc]
fr_pvc_info ptr[in, fr_proto_pvc_info]
sync ptr[in, sync_serial_settings]
te1 ptr[in, te1_settings]
]
raw_hdlc_proto {
encode int16
parity int16
}
cisco_proto {
val int32
timeout int32
}
fr_proto {
t391 int32
t392 int32
n391 int32
n392 int32
n393 int32
lmi int16
dce int16
}
fr_proto_pvc {
dlcl int32
}
fr_proto_pvc_info {
dlci int32
master devname
}
sync_serial_settings {
rate int32
type int32
loop int16
}
te1_settings {
rate int32
type int32
loop int16
slot int32
}
ifconf [
req ifconf_req
buf ifconf_buf
]
ifconf_buf {
ifc_len len[ifcu_buf, int32]
ifcu_buf ptr[inout, array[int8], opt]
}
ifconf_req {
ifc_len len[ifcu_req, int32]
ifcu_req ptr[inout, ifreq, opt]
}
brctl_cmds = BRCTL_GET_VERSION, BRCTL_GET_BRIDGES, BRCTL_ADD_BRIDGE, BRCTL_DEL_BRIDGE
brctl_arg [
get brctl_arg_get
add_del brctl_arg_add_del
generic brctl_arg_generic
]
brctl_arg_get {
cmd const[BRCTL_GET_BRIDGES, int64]
buf ptr[out, array[int8]]
indices int64
}
brctl_arg_add_del {
cmd const[BRCTL_ADD_BRIDGE, int64]
devname ptr[in, devname]
pad const[0, int64]
}
brctl_arg_generic {
a0 flags[brctl_cmds, int64]
a1 int64
a2 int64
}
dlci_add {
devname devname
dlci int16
}
# ETHTOOL declaration part
# http://elixir.free-electrons.com/linux/latest/source/include/uapi/linux/ethtool.h
ethtool_cmd_u [
ethtool_cmd ethtool_cmd
ethtool_drvinfo ethtool_drvinfo
ethtool_wolinfo ethtool_wolinfo
ethtool_regs ethtool_regs
ethtool_eeprom ethtool_eeprom
ethtool_eee ethtool_eee
ethtool_modinfo ethtool_modinfo
ethtool_coalesce ethtool_coalesce
ethtool_ringparam ethtool_ringparam
ethtool_channels ethtool_channels
ethtool_pauseparam ethtool_pauseparam
ethtool_gstrings ethtool_gstrings
ethtool_sset_info ethtool_sset_info
ethtool_test ethtool_test
ethtool_stats ethtool_stats
ethtool_perm_addr ethtool_perm_addr
ethtool_rxnfc ethtool_rxnfc
ethtool_rxfh_indir ethtool_rxfh_indir
ethtool_rxfh ethtool_rxfh
ethtool_rx_ntuple ethtool_rx_ntuple
ethtool_flash ethtool_flash
ethtool_dump ethtool_dump
ethtool_gfeatures ethtool_gfeatures
ethtool_sfeatures ethtool_sfeatures
ethtool_ts_info ethtool_ts_info
ethtool_per_queue_op ethtool_per_queue_op
ethtool_link_settings ethtool_link_settings
] [varlen]
ethtool_cmd {
cmd flags[ethtool_cmd_flags, int32]
supported int32
advertising int32
speed int16
duplex int8
port int8
phy_address int8
transceiver int8
autoneg int8
mdio_support int8
maxtxpkt int32
maxrxpkt int32
speed_hi int16
eth_tp_mdix int8
eth_tp_mdix_ctrl int8
lp_advertising int32
reserved array[int32, 2]
}
ethtool_cmd_flags = ETHTOOL_GSET, ETHTOOL_SSET, ETHTOOL_GDRVINFO, ETHTOOL_GREGS, ETHTOOL_GWOL, ETHTOOL_SWOL, ETHTOOL_GMSGLVL, ETHTOOL_SMSGLVL, ETHTOOL_NWAY_RST, ETHTOOL_GLINK, ETHTOOL_GCOALESCE, ETHTOOL_SCOALESCE, ETHTOOL_GRINGPARAM, ETHTOOL_SRINGPARAM, ETHTOOL_GPAUSEPARAM, ETHTOOL_SPAUSEPARAM, ETHTOOL_GRXCSUM, ETHTOOL_SRXCSUM, ETHTOOL_GTXCSUM, ETHTOOL_STXCSUM, ETHTOOL_GSG, ETHTOOL_SSG, ETHTOOL_TEST, ETHTOOL_PHYS_ID, ETHTOOL_GSTATS, ETHTOOL_GTSO, ETHTOOL_STSO, ETHTOOL_GPERMADDR, ETHTOOL_GUFO, ETHTOOL_SUFO, ETHTOOL_GGSO, ETHTOOL_SGSO, ETHTOOL_GFLAGS, ETHTOOL_SFLAGS, ETHTOOL_GPFLAGS, ETHTOOL_SPFLAGS, ETHTOOL_GGRO, ETHTOOL_SGRO, ETHTOOL_RESET, ETHTOOL_SRXNTUPLE, ETHTOOL_GRXNTUPLE, ETHTOOL_GSSET_INFO, ETHTOOL_GRXFHINDIR, ETHTOOL_SRXFHINDIR, ETHTOOL_GFEATURES, ETHTOOL_SFEATURES, ETHTOOL_GCHANNELS, ETHTOOL_SCHANNELS, ETHTOOL_GET_TS_INFO, ETHTOOL_GEEE, ETHTOOL_SEEE, ETHTOOL_GRSSH, ETHTOOL_SRSSH, ETHTOOL_GTUNABLE, ETHTOOL_STUNABLE, ETHTOOL_GPHYSTATS, ETHTOOL_PERQUEUE, ETHTOOL_GLINKSETTINGS, ETHTOOL_SLINKSETTINGS, ETHTOOL_PHY_GTUNABLE, ETHTOOL_PHY_STUNABLE, ethtool_eeprom_cmd_flags, ethtool_rxnfc_cmd_flags, ethtool_dump_cmd_flags
ethtool_drvinfo {
cmd const[ETHTOOL_GDRVINFO, int32]
driver array[int8, 32]
version array[int8, 32]
fw_version array[int8, ETHTOOL_FWVERS_LEN]
bus_info array[int8, ETHTOOL_BUSINFO_LEN]
erom_version array[int8, ETHTOOL_EROMVERS_LEN]
reserved2 array[int8, 12]
n_priv_flags int32
n_stats int32
testinfo_len int32
eedump_len int32
regdump_len int32
}
ethtool_wolinfo_cmd_flags = ETHTOOL_GWOL, ETHTOOL_SWOL
ethtool_wolinfo {
cmd flags[ethtool_wolinfo_cmd_flags, int32]
supported int32
wolopts int32
sopass array[int8, SOPASS_MAX]
}
ethtool_regs {
cmd const[ETHTOOL_GREGS, int32]
version int32
len len[data, int32]
data array[int8]
}
ethtool_eeprom_cmd_flags = ETHTOOL_GEEPROM, ETHTOOL_GMODULEEEPROM, ETHTOOL_SEEPROM
ethtool_eeprom {
cmd flags[ethtool_eeprom_cmd_flags, int32]
magic int32
offset int32
len len[data, int32]
data array[int8]
}
ethtool_eee_cmd_flags = ETHTOOL_GEEE, ETHTOOL_SEEE
ethtool_eee {
cmd flags[ethtool_eee_cmd_flags, int32]
supported int32
advertised int32
lp_advertised int32
eee_active int32
eee_enabled int32
tx_lpi_enabled int32
tx_lpi_timer int32
reserved array[int32, 2]
}
ethtool_modinfo {
cmd const[ETHTOOL_GMODULEINFO, int32]
type int32
eeprom_len int32
reserved array[const[0, int32], 8]
}
ethtool_coalesce_cmd_flags = ETHTOOL_GCOALESCE, ETHTOOL_SCOALESCE
ethtool_coalesce {
cmd flags[ethtool_coalesce_cmd_flags, int32]
rx_coalesce_usecs int32
rx_max_coalesced_frames int32
rx_coalesce_usecs_irq int32
rx_max_coalesced_frames_irq int32
tx_coalesce_usecs int32
tx_max_coalesced_frames int32
tx_coalesce_usecs_irq int32
tx_max_coalesced_frames_irq int32
stats_block_coalesce_usecs int32
use_adaptive_rx_coalesce int32
use_adaptive_tx_coalesce int32
pkt_rate_low int32
rx_coalesce_usecs_low int32
rx_max_coalesced_frames_low int32
tx_coalesce_usecs_low int32
tx_max_coalesced_frames_low int32
pkt_rate_high int32
rx_coalesce_usecs_high int32
rx_max_coalesced_frames_high int32
tx_coalesce_usecs_high int32
tx_max_coalesced_frames_high int32
rate_sample_interval int32
}
ethtool_ringparam_cmd_flags = ETHTOOL_GRINGPARAM, ETHTOOL_SRINGPARAM
ethtool_ringparam {
cmd flags[ethtool_ringparam_cmd_flags, int32]
rx_max_pending int32
rx_mini_max_pending int32
rx_jumbo_max_pending int32
tx_max_pending int32
rx_pending int32
rx_mini_pending int32
rx_jumbo_pending int32
tx_pending int32
}
ethtool_channels_cmd_flags = ETHTOOL_GCHANNELS, ETHTOOL_SCHANNELS
ethtool_channels {
cmd flags[ethtool_channels_cmd_flags, int32]
max_rx int32
max_tx int32
max_other int32
max_combined int32
rx_count int32
tx_count int32
other_count int32
combined_count int32
}
ethtool_pauseparam_cmd_flags = ETHTOOL_GPAUSEPARAM, ETHTOOL_SPAUSEPARAM
ethtool_pauseparam {
cmd flags[ethtool_pauseparam_cmd_flags, int32]
autoneg int32
rx_pause int32
tx_pause int32
}
ethtool_gstrings {
cmd const[ETHTOOL_GSTRINGS, int32]
string_set flags[ethtool_stringset, int32]
len len[data, int32]
data array[int8]
}
ethtool_stringset = ETH_SS_TEST, ETH_SS_STATS, ETH_SS_PRIV_FLAGS, ETH_SS_NTUPLE_FILTERS, ETH_SS_FEATURES, ETH_SS_RSS_HASH_FUNCS, ETH_SS_TUNABLES, ETH_SS_PHY_STATS, ETH_SS_PHY_TUNABLES
ethtool_sset_info {
cmd const[ETHTOOL_GSSET_INFO, int32]
reserved int32
sset_mask int64
data array[int32]
}
ethtool_test {
cmd const[ETHTOOL_TEST, int32]
flags int32
reserved int32
len len[data, int32]
data array[int64]
}
ethtool_stats {
cmd const[ETHTOOL_GSTATS, int32]
n_stats len[data, int32]
data array[int64]
}
ethtool_perm_addr {
cmd const[ETHTOOL_GPERMADDR, int32]
size len[data, int32]
data array[int8]
}
# http://elixir.free-electrons.com/linux/latest/source/include/uapi/linux/ethtool.h#L1565
traffic_flow_types = TCP_V4_FLOW, UDP_V4_FLOW, SCTP_V4_FLOW, AH_ESP_V4_FLOW, TCP_V6_FLOW, UDP_V6_FLOW, SCTP_V6_FLOW, AH_ESP_V6_FLOW, AH_V4_FLOW, ESP_V4_FLOW, AH_V6_FLOW, ESP_V6_FLOW, IPV4_USER_FLOW, IP_USER_FLOW, IPV6_USER_FLOW, IPV4_FLOW, IPV6_FLOW, ETHER_FLOW
ethtool_rxnfc_cmd_flags = ETHTOOL_GRXFH, ETHTOOL_SRXFH, ETHTOOL_GRXRINGS, ETHTOOL_GRXCLSRLCNT, ETHTOOL_GRXCLSRULE, ETHTOOL_GRXCLSRLALL, ETHTOOL_SRXCLSRLDEL, ETHTOOL_SRXCLSRLINS
ethtool_rxnfc {
cmd flags[ethtool_rxnfc_cmd_flags, int32]
flow_type flags[traffic_flow_types, int32]
data int64
fs ethtool_rx_flow_spec
rule_cnt len[rule_locs, int32]
rule_locs array[int32]
}
ethtool_rx_flow_spec {
flow_type flags[traffic_flow_types, int32]
h_u ethtool_flow_union
h_ext ethtool_flow_ext
m_u ethtool_flow_union
m_ext ethtool_flow_ext
ring_cookie int64
location int32
}
ethtool_flow_union [
tcp_ip4_spec ethtool_tcpip4_spec
udp_ip4_spec ethtool_tcpip4_spec
sctp_ip4_spec ethtool_tcpip4_spec
ah_ip4_spec ethtool_ah_espip4_spec
esp_ip4_spec ethtool_ah_espip4_spec
usr_ip4_spec ethtool_usrip4_spec
tcp_ip6_spec ethtool_tcpip6_spec
udp_ip6_spec ethtool_tcpip6_spec
sctp_ip6_spec ethtool_tcpip6_spec
ah_ip6_spec ethtool_ah_espip6_spec
esp_ip6_spec ethtool_ah_espip6_spec
usr_ip6_spec ethtool_usrip6_spec
ether_spec ethhdr
hdata array[int8, 52]
]
ethtool_flow_ext {
padding const[0, int16]
h_dest mac_addr
vlan_etype int16be
vlan_tci int16be
data array[int32be, 2]
}
ethtool_tcpip4_spec {
ip4src ipv4_addr
ip4dst ipv4_addr
psrc sock_port
pdst sock_port
tos int8
}
ethtool_ah_espip4_spec {
ip4src ipv4_addr
ip4dst ipv4_addr
spi int32be
tos int8
}
ethtool_usrip4_spec {
ip4src ipv4_addr
ip4dst ipv4_addr
l4_4_bytes int32be
tos int8
ip_ver const[ETH_RX_NFC_IP4, int8]
proto int8
}
ethtool_tcpip6_spec {
ip6src ipv6_addr
ip6dst ipv6_addr
psrc sock_port
pdst sock_port
tclass int8
}
ethtool_ah_espip6_spec {
ip6src ipv6_addr
ip6dst ipv6_addr
spi int32be
tclass int8
}
ethtool_usrip6_spec {
ip6src ipv6_addr
ip6dst ipv6_addr
l4_4_bytes int32be
tclass int8
l4_proto int8
}
ethhdr {
h_dest mac_addr
h_source mac_addr
h_proto int16be
} [packed]
ethtool_rxfh_indir_flags = ETHTOOL_GRXFHINDIR, ETHTOOL_SRXFHINDIR
ethtool_rxfh_indir {
cmd flags[ethtool_rxfh_indir_flags, int32]
size len[ring_index, int32]
ring_index array[int32]
}
ethtool_rxfh_cmd_flags = ETHTOOL_GRSSH, ETHTOOL_SRSSH
ethtool_rxfh {
cmd flags[ethtool_rxfh_cmd_flags, int32]
rss_context int32
indir_size int32
key_size int32
hfunc int8
rsvd8 array[int8, 3]
rsvd32 int32
rss_config array[int32]
}
ethtool_rx_ntuple {
cmd const[ETHTOOL_SRXNTUPLE, int32]
fs ethtool_rx_ntuple_flow_spec
}
ethtool_rx_ntuple_flow_spec_action_flags = ETHTOOL_RXNTUPLE_ACTION_DROP, ETHTOOL_RXNTUPLE_ACTION_CLEAR
ethtool_rx_ntuple_flow_spec {
flow_type flags[traffic_flow_types, int32]
h_u ethtool_rx_ntuple_flow_spec_union
m_u ethtool_rx_ntuple_flow_spec_union
vlan_tag int16
vlan_tag_mask int16
data int64
data_mask int64
action flags[ethtool_rx_ntuple_flow_spec_action_flags, int32]
}
ethtool_rx_ntuple_flow_spec_union [
tcp_ip4_spec ethtool_tcpip4_spec
udp_ip4_spec ethtool_tcpip4_spec
sctp_ip4_spec ethtool_tcpip4_spec
ah_ip4_spec ethtool_ah_espip4_spec
esp_ip4_spec ethtool_ah_espip4_spec
usr_ip4_spec ethtool_usrip4_spec
ether_spec ethhdr
hdata array[int8, 72]
]
ethtool_flash {
cmd const[ETHTOOL_FLASHDEV, int32]
region int32
data string[filename, ETHTOOL_FLASH_MAX_FILENAME]
}
ethtool_dump_cmd_flags = ETHTOOL_GET_DUMP_FLAG, ETHTOOL_GET_DUMP_DATA, ETHTOOL_SET_DUMP
ethtool_dump {
cmd flags[ethtool_dump_cmd_flags, int32]
version int32
flag int32
len len[data, int32]
data array[int8]
}
ethtool_gfeatures {
cmd const[ETHTOOL_GFEATURES, int32]
size len[features, int32]
features array[ethtool_get_features_block]
}
ethtool_get_features_block {
available const[0, int32]
requested const[0, int32]
active const[0, int32]
never_changed const[0, int32]
}
ethtool_sfeatures {
cmd const[ETHTOOL_SFEATURES, int32]
size len[features, int32]
features array[ethtool_set_features_block]
}
ethtool_set_features_block {
valid int32
requested int32
}
ethtool_ts_info {
cmd const[ETHTOOL_GET_TS_INFO, int32]
so_timestamping const[0, int32]
phc_index const[0, int32]
tx_types const[0, int32]
tx_reserved array[const[0, int32], 3]
rx_filters const[0, int32]
rx_reserved array[const[0, int32], 3]
}
ethtool_per_queue_op {
cmd const[ETHTOOL_PERQUEUE, int32]
sub_command flags[ethtool_per_queue_sub_cmd, int32]
queue_mask array[int32, ethtool_per_queue_op_size]
data array[int8]
}
ethtool_per_queue_sub_cmd = ETHTOOL_GCOALESCE, ETHTOOL_SCOALESCE
define ethtool_per_queue_op_size __KERNEL_DIV_ROUND_UP(MAX_NUM_QUEUE, 32)
ethtool_link_settings_cmd_flags = ETHTOOL_GLINKSETTINGS, ETHTOOL_SLINKSETTINGS
ethtool_link_settings {
cmd flags[ethtool_link_settings_cmd_flags, int32]
speed int32
duplex int8
port int8
phy_address int8
autoneg int8
mdio_support int8
eth_tp_mdix int8
eth_tp_mdix_ctrl int8
link_mode_masks_nwords int8
reserved array[int32, 8]
link_mode_masks array[int32]
}
]
|
| 49/2 |
2026/03/11 08:10 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 90818
output: 20
thoughts: 304
Thoughts: **My Analysis of Netlink Socket Options**
Okay, let's break this down. My initial thought was, "Right, I need to manipulate some socket options, probably related to credential passing." I quickly remembered that `setsockopt$sock_int` is where I'd find what I'm looking for, and confirmed that in `socket.txt`. The signature looks right, `setsockopt$sock_int(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_int], optval ptr[in, int32], optlen len[optval])`. Specifically, `sockopt_opt_sock_int` seems like the key here, and I noted it includes `SO_PASSCRED`.
So my initial code snippet:
```
r0 = socket$nl_route(0x10, 0x3, 0x0)
setsockopt$sock_int(r0, 0x1, 0x10, &(0x7f0000000000)=0x1, 0x4)
```
My reasoning: This looks like a reasonable call. I'm creating a netlink route socket and then setting the `SO_PASSCRED` option. But I needed to double-check that `SO_PASSCRED` was 16. I can't completely rely on memory! A quick check back in `socket.txt` confirmed it. "Yes, `SO_PASSCRED` is in `sockopt_opt_sock_int`. And `SOL_SOCKET` is 1," I said to myself, happy with that verification.
Now, to make sure this works I have to send a netlink message that triggers an ACK. The obvious choices are `sendto$nl_route` or `sendmsg$sock`. "Wait, `sendto$nl_route` isn't defined?" I queried my mental database. "Let's check `socket_netlink_route.txt`." Time to dig into the details.
|
| 50/2 |
2026/03/11 08:10 |
tool |
grepper |
0m
Error:
Args: map[Expression:sendto\$nl_route]
Results:
|
| 51/2 |
2026/03/11 08:10 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 91604
output: 20
thoughts: 12
Thoughts: Here's my take on those thoughts, tailored for an expert audience:
**Examining `sendmsg$nl_route`**
Okay, so I'm diving into `sendmsg$nl_route`. My first instinct is to see how this function handles netlink routing messages. I need to quickly recall the typical usage: This likely handles the construction and sending of routing messages over the netlink socket. I'll need to confirm if it has the necessary argument parsing and error handling for common routing operations – adding, deleting, getting, and updating routes. I will need to check how it deals with the various attributes, and the packing of the `nlmsghdr` and any associated route attributes (`rta`). I also need to ensure there is support for different address families.
I must not overlook the interaction with the underlying netlink socket and ensure proper error handling across all these stages. Performance is key. I'll be looking for any potential bottlenecks or areas that could benefit from optimization, especially around buffer management or redundant data copies. My key areas of interest are: socket usage and resource management, attribute handling, and error conditions and handling.
|
| 52/2 |
2026/03/11 08:10 |
tool |
grepper |
0m
Error:
Args: map[Expression:sendmsg\$nl_route]
Results:
|
| 53/2 |
2026/03/11 08:10 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 91887
output: 16
thoughts: 19
Thoughts: Okay, here's my summary, taking the perspective of someone deeply familiar with networking code and specifically Netlink sockets:
**Checking `sendmsg` in `socket_netlink_route.txt`**
Alright, time to get to it. Let's dig into this `sendmsg` call within the context of the Netlink routing subsystem. I need to refresh my memory on the specific implementation details, especially considering the file context. I know this area like the back of my hand, but with so many layers of abstraction, it's easy to get lost in the weeds. I want to see exactly how the data is being constructed, how the message flags are being set, and what error checking is in place. Specifically, I'm thinking about the potential for fragmentation issues, resource allocation problems, and maybe even race conditions if we're dealing with multiple threads or processes. I need to understand the interaction with the routing table lookup. Time to look it up and make sure I know what I am talking about. Let's do it!
|
| 54/2 |
2026/03/11 08:10 |
tool |
grepper |
0m
Args:
Results: map[Output:
Full output is too long, showing 500 out of 6285 lines.
Use more precise expression if possible.
[Documentation/bpf/libbpf/program_types.rst=18=described in more detail in the footnotes.
--
Documentation/bpf/libbpf/program_types.rst-53-+ +----------------------------------------+----------------------------------+-----------+
Documentation/bpf/libbpf/program_types.rst:54:| | ``BPF_CGROUP_UDP4_SENDMSG`` | ``cgroup/sendmsg4`` | |
Documentation/bpf/libbpf/program_types.rst-55-+ +----------------------------------------+----------------------------------+-----------+
--
Documentation/bpf/libbpf/program_types.rst-57-+ +----------------------------------------+----------------------------------+-----------+
Documentation/bpf/libbpf/program_types.rst:58:| | ``BPF_CGROUP_UDP6_SENDMSG`` | ``cgroup/sendmsg6`` | |
Documentation/bpf/libbpf/program_types.rst-59-| +----------------------------------------+----------------------------------+-----------+
--
Documentation/bpf/libbpf/program_types.rst-61-| +----------------------------------------+----------------------------------+-----------+
Documentation/bpf/libbpf/program_types.rst:62:| | ``BPF_CGROUP_UNIX_SENDMSG`` | ``cgroup/sendmsg_unix`` | |
Documentation/bpf/libbpf/program_types.rst-63-| +----------------------------------------+----------------------------------+-----------+
--
Documentation/bpf/map_sockmap.rst=203=following cases:
Documentation/bpf/map_sockmap.rst-204-
Documentation/bpf/map_sockmap.rst:205:- A single ``sendmsg()`` or ``sendfile()`` system call contains multiple
Documentation/bpf/map_sockmap.rst-206- logical messages that the BPF program is supposed to read and for which it
--
Documentation/bpf/map_sockmap.rst=224=This can be used when one needs a specific number of bytes before a verdict can
Documentation/bpf/map_sockmap.rst:225:be assigned, even if the data spans multiple ``sendmsg()`` or ``sendfile()``
Documentation/bpf/map_sockmap.rst-226-calls.
--
Documentation/bpf/map_sockmap.rst=241=parse data that the (``data``, ``data_end``) pointers have already consumed.
Documentation/bpf/map_sockmap.rst:242:For ``sendmsg()`` hooks this is likely the first scatterlist element. But for
Documentation/bpf/map_sockmap.rst-243-calls relying on MSG_SPLICE_PAGES (e.g., ``sendfile()``) this will be the
--
Documentation/crypto/userspace-if.rst=156=the setsockopt invocation below.
Documentation/crypto/userspace-if.rst-157-
Documentation/crypto/userspace-if.rst:158:Using the sendmsg() system call, the application provides the data that
Documentation/crypto/userspace-if.rst-159-should be processed for encryption or decryption. In addition, the IV is
Documentation/crypto/userspace-if.rst:160:specified with the data structure provided by the sendmsg() system call.
Documentation/crypto/userspace-if.rst-161-
Documentation/crypto/userspace-if.rst:162:The sendmsg system call parameter of struct msghdr is embedded into the
Documentation/crypto/userspace-if.rst-163-struct cmsghdr data structure. See recv(2) and cmsg(3) for more
--
Documentation/crypto/userspace-if.rst=215=invocation described below.
Documentation/crypto/userspace-if.rst-216-
Documentation/crypto/userspace-if.rst:217:Using the sendmsg() system call, the application provides the data that
Documentation/crypto/userspace-if.rst-218-should be processed for encryption or decryption. In addition, the IV is
Documentation/crypto/userspace-if.rst:219:specified with the data structure provided by the sendmsg() system call.
Documentation/crypto/userspace-if.rst-220-
Documentation/crypto/userspace-if.rst:221:The sendmsg system call parameter of struct msghdr is embedded into the
Documentation/crypto/userspace-if.rst-222-struct cmsghdr data structure. See recv(2) and cmsg(3) for more
--
Documentation/crypto/userspace-if.rst=269=The sizes of the AAD and the authentication tag are provided with the
Documentation/crypto/userspace-if.rst:270:sendmsg and setsockopt calls (see there). As the kernel knows the size
Documentation/crypto/userspace-if.rst-271-of the entire data stream, the kernel is now able to calculate the right
--
Documentation/crypto/userspace-if.rst=318=CRYPTO_USER_API_RNG_CAVP option:
--
Documentation/crypto/userspace-if.rst-323-
Documentation/crypto/userspace-if.rst:324:- *Additional Data* can be provided using the send()/sendmsg() system calls,
Documentation/crypto/userspace-if.rst-325- but only after the entropy has been set.
--
Documentation/filesystems/coda.rst=26=kernel support.
--
Documentation/filesystems/coda.rst-247- At some later point the FS driver receives a message from Venus,
Documentation/filesystems/coda.rst:248: namely when Venus calls sendmsg_to_kernel. At this moment the Coda FS
Documentation/filesystems/coda.rst-249- driver looks at the contents of the message and decides if:
--
Documentation/filesystems/coda.rst-254- WRITTEN. Finally, the FS driver unblocks P (still in the kernel
Documentation/filesystems/coda.rst:255: mode context of Venus) and the sendmsg_to_kernel call returns to
Documentation/filesystems/coda.rst-256- Venus. The process P will be scheduled at some point and continues
--
Documentation/filesystems/coda.rst-262- (usually a cache eviction or replacement) and when it finishes
Documentation/filesystems/coda.rst:263: sendmsg_to_kernel returns.
Documentation/filesystems/coda.rst-264-
--
Documentation/filesystems/coda.rst-268- attempt to terminate P) or as is normally the case by Venus in its
Documentation/filesystems/coda.rst:269: sendmsg_to_kernel call. In the normal case, the upcall routine will
Documentation/filesystems/coda.rst-270- deallocate the message structure and return. The FS routine can proceed
--
Documentation/filesystems/coda.rst-301- call is used. The DeviceIoControl call is designed to copy buffers
Documentation/filesystems/coda.rst:302: from user memory to kernel memory with OPCODES. The sendmsg_to_kernel
Documentation/filesystems/coda.rst-303- is issued as a synchronous call, while the getmsg_from_kernel call is
--
Documentation/networking/af_xdp.rst=199=filled (index, length and offset) and passed into the ring.
Documentation/networking/af_xdp.rst-200-
Documentation/networking/af_xdp.rst:201:To start the transfer a sendmsg() system call is required. This might
Documentation/networking/af_xdp.rst-202-be relaxed in the future.
--
Documentation/networking/can.rst=226=the socket, you can read(2) and write(2) from/to the socket or use
Documentation/networking/can.rst:227:send(2), sendto(2), sendmsg(2) and the recv* counterpart operations
Documentation/networking/can.rst-228-on the socket as usual. There are also CAN specific socket options
--
Documentation/networking/devmem.rst=308=from offset 2000 into the dmabuf. The dmabuf to send from is tx_dmabuf_id::
--
Documentation/networking/devmem.rst-335-
Documentation/networking/devmem.rst:336: sendmsg(socket_fd, &msg, MSG_ZEROCOPY);
Documentation/networking/devmem.rst-337-
--
Documentation/networking/devmem.rst=348=using MSG_ERRQUEUE::
--
Documentation/networking/devmem.rst-375-
Documentation/networking/devmem.rst:376:After the associated sendmsg has been completed, the dmabuf can be reused by
Documentation/networking/devmem.rst-377-the userspace.
--
Documentation/networking/ip-sysctl.rst=371=tcp_autocorking - BOOLEAN
Documentation/networking/ip-sysctl.rst-372- Enable TCP auto corking :
Documentation/networking/ip-sysctl.rst:373: When applications do consecutive small write()/sendmsg() system calls,
Documentation/networking/ip-sysctl.rst-374- we try to coalesce these small writes as much as possible, to lower
--
Documentation/networking/ip-sysctl.rst=999=tcp_fastopen - INTEGER
--
Documentation/networking/ip-sysctl.rst-1003- The client support is enabled by flag 0x1 (on by default). The client
Documentation/networking/ip-sysctl.rst:1004: then must use sendmsg() or sendto() with the MSG_FASTOPEN flag,
Documentation/networking/ip-sysctl.rst-1005- rather than connect() to send data in SYN.
--
Documentation/networking/ip-sysctl.rst=1223=tcp_notsent_lowat - UNSIGNED INTEGER
--
Documentation/networking/ip-sysctl.rst-1226- reports POLLOUT events if the amount of unsent bytes is below a per
Documentation/networking/ip-sysctl.rst:1227: socket value, and if the write queue is not full. sendmsg() will
Documentation/networking/ip-sysctl.rst-1228- also not add new buffers if the limit is hit.
--
Documentation/networking/iso15765-2.rst=96=the usual ``read(2)`` and ``write(2)`` system calls, as well as ``send(2)``,
Documentation/networking/iso15765-2.rst:97:``sendmsg(2)``, ``recv(2)`` and ``recvmsg(2)``.
Documentation/networking/iso15765-2.rst-98-Unlike the CAN_RAW socket API, only the ISO-TP data field (the actual payload)
--
Documentation/networking/j1939.rst=270=binding and/or connecting the socket, you can ``read(2)`` and ``write(2)`` from/to the
Documentation/networking/j1939.rst:271:socket or use ``send(2)``, ``sendto(2)``, ``sendmsg(2)`` and the ``recv*()`` counterpart
Documentation/networking/j1939.rst-272-operations on the socket as usual. There are also J1939 specific socket options
--
Documentation/networking/j1939.rst=388=Message Flags during send() and Related System Calls
--
Documentation/networking/j1939.rst-390-
Documentation/networking/j1939.rst:391:``send(2)``, ``sendto(2)`` and ``sendmsg(2)`` take a 'flags' argument. Currently
Documentation/networking/j1939.rst-392-supported flags are:
--
Documentation/networking/j1939.rst=981=Now, the socket 'sock' is bound to the SA 0x20. Since no ``connect(2)`` was called,
Documentation/networking/j1939.rst:982:at this point we can use only ``sendto(2)`` or ``sendmsg(2)``.
Documentation/networking/j1939.rst-983-
--
Documentation/networking/kcm.rst=256=messages on a KCM socket.
--
Documentation/networking/kcm.rst-258- 1) Send multiple messages in a single sendmmsg.
Documentation/networking/kcm.rst:259: 2) Send a group of messages each with a sendmsg call, where all messages
Documentation/networking/kcm.rst:260: except the last have MSG_BATCH in the flags of sendmsg call.
Documentation/networking/kcm.rst-261- 3) Create "super message" composed of multiple messages and send this
Documentation/networking/kcm.rst:262: with a single sendmsg.
Documentation/networking/kcm.rst-263-
--
Documentation/networking/mctp.rst=121=receiving packets with and without a message integrity check footer.
Documentation/networking/mctp.rst-122-
Documentation/networking/mctp.rst:123:``sendto()``, ``sendmsg()``, ``send()`` : transmit an MCTP message
Documentation/networking/mctp.rst-124-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Documentation/networking/mctp.rst-125-
Documentation/networking/mctp.rst:126:An MCTP message is transmitted using one of the ``sendto()``, ``sendmsg()`` or
Documentation/networking/mctp.rst-127-``send()`` syscalls. Using ``sendto()`` as the primary example:
--
Documentation/networking/mctp.rst=159=buffer, and the most-significant bit of the message type byte must be 1.
Documentation/networking/mctp.rst-160-
Documentation/networking/mctp.rst:161:The ``sendmsg()`` system call allows a more compact argument interface, and the
Documentation/networking/mctp.rst-162-message buffer to be specified as a scatter-gather list. At present no ancillary
Documentation/networking/mctp.rst:163:message types (used for the ``msg_control`` data passed to ``sendmsg()``) are
Documentation/networking/mctp.rst-164-defined.
--
Documentation/networking/mctp.rst=218=These tags give applications more control over MCTP message tags, by allocating
Documentation/networking/mctp.rst-219-(and dropping) tag values explicitly, rather than the kernel automatically
Documentation/networking/mctp.rst:220:allocating a per-message tag at ``sendmsg()`` time.
Documentation/networking/mctp.rst-221-
--
Documentation/networking/mctp.rst=228=Both ioctls are passed a pointer to a ``struct mctp_ioc_tag_ctl``:
--
Documentation/networking/mctp.rst-238-``SIOCMCTPALLOCTAG`` allocates a tag for a specific peer, which an application
Documentation/networking/mctp.rst:239:can use in future ``sendmsg()`` calls. The application populates the
Documentation/networking/mctp.rst-240-``peer_addr`` member with the remote EID. Other fields must be zero.
--
Documentation/networking/mctp.rst=243=The allocated tag will have the following tag bits set:
--
Documentation/networking/mctp.rst-247-
Documentation/networking/mctp.rst:248: - ``MCTP_TAG_PREALLOC``: to indicate to ``sendmsg()`` that this is a
Documentation/networking/mctp.rst-249- preallocated tag.
--
Documentation/networking/mctp.rst=266=There are a few possible packet flows in the MCTP stack:
--
Documentation/networking/mctp.rst-269-
Documentation/networking/mctp.rst:270: sendmsg()
Documentation/networking/mctp.rst-271- -> mctp_local_output()
--
Documentation/networking/mctp.rst-277-
Documentation/networking/mctp.rst:278: sendmsg()
Documentation/networking/mctp.rst-279- -> mctp_local_output()
--
Documentation/networking/msg_zerocopy.rst=44=the excellent reporting over at LWN.net or read the original code.
--
Documentation/networking/msg_zerocopy.rst-52- patchset
Documentation/networking/msg_zerocopy.rst:53: [PATCH net-next v4 0/9] socket sendmsg MSG_ZEROCOPY
Documentation/networking/msg_zerocopy.rst-54- https://lore.kernel.org/netdev/20170803202945.70750-1-willemdebruijn.kernel@gmail.com
--
Documentation/networking/msg_zerocopy.rst=76=Transmission
--
Documentation/networking/msg_zerocopy.rst-78-
Documentation/networking/msg_zerocopy.rst:79:The change to send (or sendto, sendmsg, sendmmsg) itself is trivial.
Documentation/networking/msg_zerocopy.rst-80-Pass the new flag.
--
Documentation/networking/net_cachelines/inet_sock.rst=12=struct ipv6_pinfo* pinet6
Documentation/networking/net_cachelines/inet_sock.rst:13:struct ipv6_fl_socklist* ipv6_fl_list read_mostly tcp_v6_connect,__ip6_datagram_connect,udpv6_sendmsg,rawv6_sendmsg
Documentation/networking/net_cachelines/inet_sock.rst-14-be16 inet_sport read_mostly __tcp_transmit_skb
--
Documentation/networking/net_cachelines/inet_sock.rst=37=u8:1 recverr_rfc4884
Documentation/networking/net_cachelines/inet_sock.rst:38:u8:1 defer_connect read_mostly tcp_sendmsg_fastopen
Documentation/networking/net_cachelines/inet_sock.rst-39-u8 rcv_tos
--
Documentation/networking/net_cachelines/netns_ipv4_sysctl.rst=118=int sysctl_tcp_pacing_ca_ratio default_cong_cont(tcp_update_pacing_rate)
Documentation/networking/net_cachelines/netns_ipv4_sysctl.rst:119:int sysctl_tcp_wmem[3] read_mostly tcp_wmem_schedule(sendmsg/sendpage)
Documentation/networking/net_cachelines/netns_ipv4_sysctl.rst-120-int sysctl_tcp_rmem[3] read_mostly __tcp_grow_window(tx),tcp_rcv_space_adjust(rx)
--
Documentation/networking/net_cachelines/snmp.rst=13=unsigned_long LINUX_MIB_DELAYEDACKLOCKED write_mostly tcp_delack_timer_handler,tcp_delack_timer
Documentation/networking/net_cachelines/snmp.rst:14:unsigned_long LINUX_MIB_TCPAUTOCORKING write_mostly tcp_push,tcp_sendmsg_locked
Documentation/networking/net_cachelines/snmp.rst-15-unsigned_long LINUX_MIB_TCPFROMZEROWINDOWADV write_mostly tcp_select_window,tcp_transmit-skb
--
Documentation/networking/rds.rst=67=Socket Interface
--
Documentation/networking/rds.rst-81- You are not allowed to queue more than SO_SNDSIZE bytes to
Documentation/networking/rds.rst:82: a socket. A message is queued when sendmsg is called, and
Documentation/networking/rds.rst-83- it leaves the queue when the remote system acknowledges
--
Documentation/networking/rds.rst-98-
Documentation/networking/rds.rst:99: sendmsg(fd, ...)
Documentation/networking/rds.rst-100- Sends a message to the indicated recipient. The kernel will
--
Documentation/networking/rds.rst-144- this - by using congestion notifications, and by checking for
Documentation/networking/rds.rst:145: ENOBUFS errors returned by sendmsg.
Documentation/networking/rds.rst-146-
--
Documentation/networking/rds.rst=336=The send path
--
Documentation/networking/rds.rst-338-
Documentation/networking/rds.rst:339: rds_sendmsg()
Documentation/networking/rds.rst-340- - struct rds_message built from incoming data
--
Documentation/networking/rds.rst=393=Multipath RDS (mprds)
--
Documentation/networking/rds.rst-421- t_mp_capable bit during registration with the rds core module. When the
Documentation/networking/rds.rst:422: transport is multipath-capable, rds_sendmsg() hashes outgoing traffic
Documentation/networking/rds.rst-423- across multiple paths. The outgoing hash is computed based on the
--
Documentation/networking/rds.rst-431- first data packet. The control packet exchange must have completed
Documentation/networking/rds.rst:432: prior to outgoing hash completion in rds_sendmsg() when the transport
Documentation/networking/rds.rst-433- is multipath capable.
--
Documentation/networking/rxrpc.rst=8=that can be used to perform RxRPC remote operations. This is done over sockets
Documentation/networking/rxrpc.rst:9:of AF_RXRPC family, using sendmsg() and recvmsg() with control data to send and
Documentation/networking/rxrpc.rst-10-receive data, aborts and errors.
--
Documentation/networking/rxrpc.rst=206=Interaction with the user of the RxRPC socket:
--
Documentation/networking/rxrpc.rst-210-
Documentation/networking/rxrpc.rst:211: (#) In the client, sending a request is achieved with one or more sendmsgs,
Documentation/networking/rxrpc.rst-212- followed by the reply being received with one or more recvmsgs.
Documentation/networking/rxrpc.rst-213-
Documentation/networking/rxrpc.rst:214: (#) The first sendmsg for a request to be sent from a client contains a tag to
Documentation/networking/rxrpc.rst:215: be used in all other sendmsgs or recvmsgs associated with that call. The
Documentation/networking/rxrpc.rst-216- tag is carried in the control data.
--
Documentation/networking/rxrpc.rst-219- socket. This may be overridden by supplying an alternate address to the
Documentation/networking/rxrpc.rst:220: first sendmsg() of a call (struct msghdr::msg_name).
Documentation/networking/rxrpc.rst-221-
--
Documentation/networking/rxrpc.rst-225- (#) A server socket may also be used to make client calls. To do this, the
Documentation/networking/rxrpc.rst:226: first sendmsg() of the call must specify the target address. The server's
Documentation/networking/rxrpc.rst-227- transport endpoint is used to send the packets.
--
Documentation/networking/rxrpc.rst-234- (#) In the server, a request is received with one or more recvmsgs, then the
Documentation/networking/rxrpc.rst:235: the reply is transmitted with one or more sendmsgs, and then the final ACK
Documentation/networking/rxrpc.rst-236- is received with a last recvmsg.
Documentation/networking/rxrpc.rst-237-
Documentation/networking/rxrpc.rst:238: (#) When sending data for a call, sendmsg is given MSG_MORE if there's more
Documentation/networking/rxrpc.rst-239- data to come on that call.
--
Documentation/networking/rxrpc.rst-267- its acceptance [recvmsg reports a special control message]. The server
Documentation/networking/rxrpc.rst:268: application then uses sendmsg to assign a tag to the new call. Once that
Documentation/networking/rxrpc.rst-269- is done, the first part of the request data will be delivered by recvmsg.
--
Documentation/networking/rxrpc.rst-281-
Documentation/networking/rxrpc.rst:282:Notes on sendmsg:
Documentation/networking/rxrpc.rst-283-
Documentation/networking/rxrpc.rst:284: (#) MSG_WAITALL can be set to tell sendmsg to ignore signals if the peer is
Documentation/networking/rxrpc.rst-285- making progress at accepting packets within a reasonable time such that we
--
Documentation/networking/rxrpc.rst-288-
Documentation/networking/rxrpc.rst:289: If this isn't set, sendmsg() will return immediately, either returning
Documentation/networking/rxrpc.rst-290- EINTR/ERESTARTSYS if nothing was consumed or returning the amount of data
--
Documentation/networking/rxrpc.rst=322=Control Messages
--
Documentation/networking/rxrpc.rst-324-
Documentation/networking/rxrpc.rst:325:AF_RXRPC makes use of control messages in sendmsg() and recvmsg() to multiplex
Documentation/networking/rxrpc.rst-326-calls, to invoke certain actions and to report certain conditions. These are:
--
Documentation/networking/rxrpc.rst-356- This is can be used by an application to abort a call by passing it to
Documentation/networking/rxrpc.rst:357: sendmsg, or it can be delivered by recvmsg to indicate a remote abort was
Documentation/networking/rxrpc.rst-358- received. Either way, it must be associated with an RXRPC_USER_CALL_ID to
--
Documentation/networking/rxrpc.rst-400- to indicate the user ID to be assigned. If there is no call to be
Documentation/networking/rxrpc.rst:401: accepted (it may have timed out, been aborted, etc.), then sendmsg will
Documentation/networking/rxrpc.rst-402- return error ENODATA. If the user ID is already in use by another call,
--
Documentation/networking/rxrpc.rst-428- the buffer and then encrypting in place. This may only be given with the
Documentation/networking/rxrpc.rst:429: first sendmsg() providing data for a call. EMSGSIZE will be generated if
Documentation/networking/rxrpc.rst-430- the amount of data actually given is different.
--
Documentation/networking/rxrpc.rst=544=A client would issue an operation by:
--
Documentation/networking/rxrpc.rst-582- (4) The server to be contacted can then be specified (alternatively this can
Documentation/networking/rxrpc.rst:583: be done through sendmsg)::
Documentation/networking/rxrpc.rst-584-
--
Documentation/networking/rxrpc.rst-595- (5) The request data should then be posted to the server socket using a series
Documentation/networking/rxrpc.rst:596: of sendmsg() calls, each with the following control message attached:
Documentation/networking/rxrpc.rst-597-
--
Documentation/networking/rxrpc.rst-605- An RXRPC_TX_LENGTH control message can also be specified on the first
Documentation/networking/rxrpc.rst:606: sendmsg() call.
Documentation/networking/rxrpc.rst-607-
--
Documentation/networking/rxrpc.rst=626=better service if one is available by supplying RXRPC_UPGRADE_SERVICE on the
Documentation/networking/rxrpc.rst:627:first sendmsg() of a call. The client should then check srx_service in the
Documentation/networking/rxrpc.rst-628-msg_name filled in by recvmsg() when collecting the result. srx_service will
Documentation/networking/rxrpc.rst:629:hold the same value as given to sendmsg() if the upgrade request was ignored by
Documentation/networking/rxrpc.rst-630-the service - otherwise it will be altered to indicate the service ID the
--
Documentation/networking/rxrpc.rst=640=A server would be set up to accept operations in the following manner:
--
Documentation/networking/rxrpc.rst-706-
Documentation/networking/rxrpc.rst:707: (7) The server then accepts the new call by issuing a sendmsg() with two
Documentation/networking/rxrpc.rst-708- pieces of control data and no actual data:
--
Documentation/networking/rxrpc.rst-730- (9) The reply data should then be posted to the server socket using a series
Documentation/networking/rxrpc.rst:731: of sendmsg() calls, each with the following control messages attached:
Documentation/networking/rxrpc.rst-732-
--
Documentation/networking/rxrpc.rst-752-(11) Up to the point the final packet of reply data is sent, the call can be
Documentation/networking/rxrpc.rst:753: aborted by calling sendmsg() with a dataless message with the following
Documentation/networking/rxrpc.rst-754- control messages attached:
--
Documentation/networking/rxrpc.rst=764=Note that all the communications for a particular service take place through
Documentation/networking/rxrpc.rst:765:the one server socket, using control messages on sendmsg() and recvmsg() to
Documentation/networking/rxrpc.rst-766-determine the call affected.
--
Documentation/networking/rxrpc.rst=795=The kernel interface functions are as follows:
--
Documentation/networking/rxrpc.rst-820-
Documentation/networking/rxrpc.rst:821: The user_call_ID is equivalent to that supplied to sendmsg() in the
Documentation/networking/rxrpc.rst-822- control data buffer. It is entirely feasible to use this to point to a
--
Documentation/networking/rxrpc.rst=1150=API Function Reference
--
Documentation/networking/rxrpc.rst-1160-.. kernel-doc:: net/rxrpc/rxkad.c
Documentation/networking/rxrpc.rst:1161:.. kernel-doc:: net/rxrpc/sendmsg.c
Documentation/networking/rxrpc.rst-1162-.. kernel-doc:: net/rxrpc/server_key.c
--
Documentation/networking/scaling.rst=339=Each table value is a CPU index that is updated during calls to recvmsg
Documentation/networking/scaling.rst:340:and sendmsg (specifically, inet_recvmsg(), inet_sendmsg() and
Documentation/networking/scaling.rst-341-tcp_splice_read()).
--
Documentation/networking/smc-sysctl.rst=10=autocorking_size - INTEGER
--
Documentation/networking/smc-sysctl.rst-13- perspective of view. When applications do consecutive small
Documentation/networking/smc-sysctl.rst:14: write()/sendmsg() system calls, we try to coalesce these small writes
Documentation/networking/smc-sysctl.rst-15- as much as possible, to lower total amount of CDC and RDMA Write been
--
Documentation/networking/timestamping.rst=84=queue (1.3.2) and options (1.3.3). Timestamp generation can also
Documentation/networking/timestamping.rst:85:be enabled for individual sendmsg calls using cmsg (1.3.4).
Documentation/networking/timestamping.rst-86-
--
Documentation/networking/timestamping.rst=178=SOF_TIMESTAMPING_OPT_ID:
--
Documentation/networking/timestamping.rst-215- *((__u32 *) CMSG_DATA(cmsg)) = opt_id;
Documentation/networking/timestamping.rst:216: err = sendmsg(fd, msg, 0);
Documentation/networking/timestamping.rst-217-
--
Documentation/networking/timestamping.rst=324=per write via cmsg, only for SOF_TIMESTAMPING_TX_* (see Section 1.3.1).
Documentation/networking/timestamping.rst:325:Using this feature, applications can sample timestamps per sendmsg()
Documentation/networking/timestamping.rst-326-without paying the overhead of enabling and disabling timestamps via
Documentation/networking/timestamping.rst=327=setsockopt::
--
Documentation/networking/timestamping.rst-337- SOF_TIMESTAMPING_TX_ACK;
Documentation/networking/timestamping.rst:338: err = sendmsg(fd, msg, 0);
Documentation/networking/timestamping.rst-339-
--
Documentation/networking/timestamping.rst=400=autocork. After linux-4.7, a better way to prevent coalescing is
Documentation/networking/timestamping.rst:401:to use MSG_EOR flag at sendmsg() time.
Documentation/networking/timestamping.rst-402-
--
Documentation/networking/tls.rst=132=using a record of type @record_type.
--
Documentation/networking/tls.rst-159-
Documentation/networking/tls.rst:160: return sendmsg(sock, &msg, 0);
Documentation/networking/tls.rst-161- }
--
Documentation/security/SCTP.rst=68=A summary of the ``@optname`` entries is as follows::
--
Documentation/security/SCTP.rst-83- SCTP_SENDMSG_CONNECT - Initiate a connection that is generated by a
Documentation/security/SCTP.rst:84: sendmsg(2) or sctp_sendmsg(3) on a new association.
Documentation/security/SCTP.rst-85-
--
Documentation/security/SCTP.rst=136=establishing an association.
--
Documentation/security/SCTP.rst-143- by a connect(2), sctp_connectx(3),
Documentation/security/SCTP.rst:144: sendmsg(2) or sctp_sendmsg(3).
Documentation/security/SCTP.rst-145- These will result in a call to
--
Documentation/trace/histogram.rst=5=Documentation written by Tom Zanussi
--
Documentation/trace/histogram.rst-1113- udp_send_skb+0x173/0x2a0
Documentation/trace/histogram.rst:1114: udp_sendmsg+0x2bf/0x9f0
Documentation/trace/histogram.rst:1115: inet_sendmsg+0x64/0xa0
Documentation/trace/histogram.rst:1116: sock_sendmsg+0x3d/0x50
Documentation/trace/histogram.rst-1117- } hitcount: 115 len: 13030
--
Documentation/trace/histogram.rst-1538- udp_send_skb+0x13e/0x270
Documentation/trace/histogram.rst:1539: udp_sendmsg+0x2bf/0x980
Documentation/trace/histogram.rst:1540: inet_sendmsg+0x67/0xa0
Documentation/trace/histogram.rst:1541: sock_sendmsg+0x38/0x50
Documentation/trace/histogram.rst-1542- SYSC_sendto+0xef/0x170
--
Documentation/trace/histogram.rst-1558- udp_send_skb+0x16d/0x270
Documentation/trace/histogram.rst:1559: udp_sendmsg+0x2bf/0x980
Documentation/trace/histogram.rst:1560: inet_sendmsg+0x67/0xa0
Documentation/trace/histogram.rst:1561: sock_sendmsg+0x38/0x50
Documentation/trace/histogram.rst:1562: ___sys_sendmsg+0x14e/0x270
Documentation/trace/histogram.rst-1563- } hitcount: 76
--
Documentation/trace/histogram.rst-1576- udp_send_skb+0x16d/0x270
Documentation/trace/histogram.rst:1577: udp_sendmsg+0x2bf/0x980
Documentation/trace/histogram.rst:1578: inet_sendmsg+0x67/0xa0
Documentation/trace/histogram.rst:1579: sock_sendmsg+0x38/0x50
Documentation/trace/histogram.rst:1580: ___sys_sendmsg+0x269/0x270
Documentation/trace/histogram.rst-1581- } hitcount: 77
--
Documentation/trace/histogram.rst-1594- udp_send_skb+0x16d/0x270
Documentation/trace/histogram.rst:1595: udp_sendmsg+0x2bf/0x980
Documentation/trace/histogram.rst:1596: inet_sendmsg+0x67/0xa0
Documentation/trace/histogram.rst:1597: sock_sendmsg+0x38/0x50
Documentation/trace/histogram.rst-1598- SYSC_sendto+0xef/0x170
--
Documentation/translations/zh_CN/networking/msg_zerocopy.rst=41=MSG_ZEROCOPY 并非总是像简单地传递该标志那样容易。
--
Documentation/translations/zh_CN/networking/msg_zerocopy.rst-55- 补丁集:
Documentation/translations/zh_CN/networking/msg_zerocopy.rst:56: [PATCH net-next v4 0/9] socket sendmsg MSG_ZEROCOPY
Documentation/translations/zh_CN/networking/msg_zerocopy.rst-57- https://lore.kernel.org/netdev/20170803202945.70750-1-willemdebruijn.kernel@gmail.com
--
Documentation/translations/zh_CN/networking/msg_zerocopy.rst-78-
Documentation/translations/zh_CN/networking/msg_zerocopy.rst:79:对 send(或 sendto、sendmsg、sendmmsg)本身的改动非常简单。只需传递新的标志即可。
Documentation/translations/zh_CN/networking/msg_zerocopy.rst-80-
--
Documentation/translations/zh_CN/networking/timestamping.rst=77=val 是一个整数,设置了以下任何位。设置其他位将返回 EINVAL 且不更改当前状态。
--
Documentation/translations/zh_CN/networking/timestamping.rst-82-配置相关选项(1.3.3);
Documentation/translations/zh_CN/networking/timestamping.rst:83:也可以通过 cmsg 为单个 sendmsg 调用启用时间戳生成(1.3.4)。
Documentation/translations/zh_CN/networking/timestamping.rst-84-
--
Documentation/translations/zh_CN/networking/timestamping.rst=155=SOF_TIMESTAMPING_OPT_ID:
--
Documentation/translations/zh_CN/networking/timestamping.rst-183- *((__u32 *) CMSG_DATA(cmsg)) = opt_id;
Documentation/translations/zh_CN/networking/timestamping.rst:184: err = sendmsg(fd, msg, 0);
Documentation/translations/zh_CN/networking/timestamping.rst-185-
--
Documentation/translations/zh_CN/networking/timestamping.rst=265=SOF_TIMESTAMPING_TX_*(见第 1.3.1 节)。使用此功能,应用程序可以无需启用和
Documentation/translations/zh_CN/networking/timestamping.rst:266:禁用时间戳即可采样每个 sendmsg() 的时间戳::
Documentation/translations/zh_CN/networking/timestamping.rst-267-
--
Documentation/translations/zh_CN/networking/timestamping.rst-276- SOF_TIMESTAMPING_TX_ACK;
Documentation/translations/zh_CN/networking/timestamping.rst:277: err = sendmsg(fd, msg, 0);
Documentation/translations/zh_CN/networking/timestamping.rst-278-
--
Documentation/translations/zh_CN/networking/timestamping.rst=318=TCP_CORK和 autocork。在 linux-4.7 之后,更好的预防合并方法是使用 MSG_EOR
Documentation/translations/zh_CN/networking/timestamping.rst:319:标志在sendmsg()时。
Documentation/translations/zh_CN/networking/timestamping.rst-320-
--
Documentation/translations/zh_CN/security/SCTP.rst=39=security_sctp_bind_connect()
--
Documentation/translations/zh_CN/security/SCTP.rst-80-
Documentation/translations/zh_CN/security/SCTP.rst:81: SCTP_SENDMSG_CONNECT - 通过sendmsg(2)或sctp_sendmsg(3)在新关联上
Documentation/translations/zh_CN/security/SCTP.rst-82- 发起连接。
--
Documentation/translations/zh_CN/security/SCTP.rst=118=security_sctp_assoc_established()
--
Documentation/translations/zh_CN/security/SCTP.rst-137- 关联的设置可以通过connect(2),
Documentation/translations/zh_CN/security/SCTP.rst:138: sctp_connectx(3),sendmsg(2)
Documentation/translations/zh_CN/security/SCTP.rst:139: or sctp_sendmsg(3)来发起。
Documentation/translations/zh_CN/security/SCTP.rst-140- 这将导致调用security_sctp_bind_connect()
--
arch/alpha/kernel/syscalls/syscall.tbl-37-27 common osf_nrecvmsg sys_ni_syscall
arch/alpha/kernel/syscalls/syscall.tbl:38:28 common osf_nsendmsg sys_ni_syscall
arch/alpha/kernel/syscalls/syscall.tbl-39-29 common osf_nrecvfrom sys_ni_syscall
--
arch/alpha/kernel/syscalls/syscall.tbl-122-113 common recvmsg sys_recvmsg
arch/alpha/kernel/syscalls/syscall.tbl:123:114 common sendmsg sys_sendmsg
arch/alpha/kernel/syscalls/syscall.tbl-124-115 common osf_old_vtrace sys_ni_syscall
--
arch/arm/include/asm/syscalls.h=47=struct user_msghdr;
arch/arm/include/asm/syscalls.h:48:asmlinkage long sys_oabi_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags);
arch/arm/include/asm/syscalls.h-49-asmlinkage long sys_oabi_socketcall(int call, unsigned long __user *args);
--
arch/arm/kernel/sys_oabi-compat.c-64- * sys_connect:
arch/arm/kernel/sys_oabi-compat.c:65: * sys_sendmsg:
arch/arm/kernel/sys_oabi-compat.c-66- * sys_sendto:
]
]
|
| 55/2 |
2026/03/11 08:10 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 103066
output: 23
thoughts: 384
Thoughts: **Analyzing Netlink Socket Communication**
Okay, let's dive into this. First, I need to confirm the availability and structure of the `sendmsg$sock` function. Let me look at the definition in `socket.txt`. Ah, yes, there it is: `sendmsg$sock(fd sock, msg ptr[in, msghdr_sock], f flags[send_flags])`. Confirmed, it's defined. Now I need to understand the `msghdr_sock` structure. The definition shows `msghdr_sock { msg_name ptr[in, sockaddr_storage, opt] ... }`. Excellent.
Now, hold on. `sendmsg$sock` takes `sock`, which, as I see, is an alias for the file descriptor, `fd`. Meaning I can definitely use this with a netlink socket. The question now becomes, how do I craft a message that will reliably trigger an ACK from the kernel? It looks like I'll need a netlink message, which is based on the `nlmsghdr` structure.
```
nlmsghdr {
nlmsg_len len[parent, int32]
nlmsg_type flags[nlmsg_types, int16]
nlmsg_flags flags[nlmsg_flags, int16]
nlmsg_seq int32
nlmsg_pid int32
}
```
However, I'm second-guessing myself a bit. Using `sendto$nl_route` or a similarly specialized function might simplify the process of constructing the specific netlink message and sending it. I think I'll go ahead and check `socket_netlink_route.txt` to see if there's a more streamlined way to send a message.
|
| 56/2 |
2026/03/11 08:10 |
tool |
read-description |
0m
Args: map[File:socket_netlink_route.txt]
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.
# AF_NETLINK/NETLINK_ROUTE support.
include <linux/net.h>
include <linux/netdevice.h>
include <uapi/linux/if.h>
include <uapi/linux/ip.h>
include <uapi/linux/if_link.h>
include <uapi/linux/if_addr.h>
include <uapi/linux/if_addrlabel.h>
include <uapi/linux/if_bridge.h>
include <uapi/linux/if_vlan.h>
include <uapi/linux/netlink.h>
include <uapi/linux/netconf.h>
include <uapi/linux/rtnetlink.h>
include <uapi/linux/lwtunnel.h>
include <uapi/linux/neighbour.h>
include <uapi/linux/nexthop.h>
include <uapi/linux/fib_rules.h>
include <uapi/linux/if_tunnel.h>
include <uapi/linux/net_namespace.h>
include <uapi/linux/veth.h>
include <uapi/linux/can/gw.h>
include <uapi/linux/can/vxcan.h>
include <uapi/linux/mpls_iptunnel.h>
include <uapi/linux/ila.h>
include <uapi/linux/seg6_iptunnel.h>
include <uapi/linux/seg6_local.h>
include <uapi/linux/rpl_iptunnel.h>
include <uapi/linux/batman_adv.h>
resource sock_nl_route[sock_netlink]
type netns_id int32[0:4]
socket$nl_route(domain const[AF_NETLINK], type const[SOCK_RAW], proto const[NETLINK_ROUTE]) sock_nl_route
sendmsg$nl_route(fd sock_nl_route, msg ptr[in, msghdr_netlink[netlink_msg_route]], f flags[send_flags])
netlink_msg_route [
newlink netlink_msg[RTM_NEWLINK, ifinfomsg[AF_UNSPEC], ifla_policy]
getlink netlink_msg[RTM_GETLINK, ifinfomsg[AF_UNSPEC], ifla_policy]
setlink netlink_msg[RTM_SETLINK, ifinfomsg[AF_UNSPEC], ifla_policy]
dellink netlink_msg[RTM_DELLINK, ifinfomsg[AF_UNSPEC], ifla_policy]
getaddr netlink_msg[RTM_GETADDR, rtgenmsg[AF_UNSPEC], void]
getroute netlink_msg[RTM_GETROUTE, rtgenmsg[AF_UNSPEC], void]
getrule netlink_msg[RTM_GETRULE, rtgenmsg[AF_UNSPEC], void]
getnetconf netlink_msg[RTM_GETNETCONF, rtgenmsg[AF_UNSPEC], void]
getstats netlink_msg[RTM_GETSTATS, if_stats_msg[AF_UNSPEC], void]
newneigh netlink_msg[RTM_NEWNEIGH, ndmsg, nda_policy]
delneigh netlink_msg[RTM_DELNEIGH, ndmsg, nda_policy]
getneigh netlink_msg[RTM_GETNEIGH, rtgenmsg[AF_UNSPEC], void]
getneightbl netlink_msg[RTM_GETNEIGHTBL, rtgenmsg[AF_UNSPEC], void]
setneightbl netlink_msg[RTM_SETNEIGHTBL, ndtmsg, nl_neightbl_policy]
newlinkprop netlink_msg[RTM_NEWLINKPROP, ifinfomsg[AF_UNSPEC], ifla_policy]
# RTM_GETLINKPROP is currently not used by the kernel.
dellinkprop netlink_msg[RTM_DELLINKPROP, ifinfomsg[AF_UNSPEC], ifla_policy]
newnexthop netlink_msg[RTM_NEWNEXTHOP, nhmsg_new[AF_UNSPEC], rtm_nh_policy_new]
delnexthop netlink_msg[RTM_DELNEXTHOP, nhmsg_get_del[AF_UNSPEC], rtm_nh_policy_del]
getnexthop netlink_msg[RTM_GETNEXTHOP, nhmsg_get_del[AF_UNSPEC], rtm_nh_policy_get]
ipv4_newaddr netlink_msg[RTM_NEWADDR, ifaddrmsg[AF_INET], ifa_ipv4_policy]
ipv4_deladdr netlink_msg[RTM_DELADDR, ifaddrmsg[AF_INET], ifa_ipv4_policy]
ipv4_getaddr netlink_msg[RTM_GETADDR, ifaddrmsg[AF_INET], ifa_ipv4_policy]
ipv4_newroute netlink_msg[RTM_NEWROUTE, rtmsg[AF_INET], rtm_ipv4_policy]
ipv4_delroute netlink_msg[RTM_DELROUTE, rtmsg[AF_INET], rtm_ipv4_policy]
ipv4_getroute netlink_msg[RTM_GETROUTE, rtmsg[AF_INET], void]
ipv4_getnetconf netlink_msg[RTM_GETNETCONF, netconfmsg[AF_INET], devconf_ipv4_policy]
ipv4_newrule netlink_msg[RTM_NEWRULE, fib_rule_hdr[AF_INET], fib4_rule_policy]
ipv4_delrule netlink_msg[RTM_DELRULE, fib_rule_hdr[AF_INET], fib4_rule_policy]
ipv4_getrule netlink_msg[RTM_GETRULE, fib_rule_hdr[AF_INET], void]
ipv4_newnexthop netlink_msg[RTM_NEWNEXTHOP, nhmsg_new[AF_INET], rtm_nh_policy_new]
ipv4_getnexthop netlink_msg[RTM_GETNEXTHOP, nhmsg_get_del[AF_INET], rtm_nh_policy_get]
ipv6_newaddr netlink_msg[RTM_NEWADDR, ifaddrmsg[AF_INET6], ifa_ipv6_policy]
ipv6_deladdr netlink_msg[RTM_DELADDR, ifaddrmsg[AF_INET6], ifa_ipv6_policy]
ipv6_getaddr netlink_msg[RTM_GETADDR, ifaddrmsg[AF_INET6], ifa_ipv6_policy]
ipv6_newroute netlink_msg[RTM_NEWROUTE, rtmsg[AF_INET6], rtm_ipv6_policy]
ipv6_delroute netlink_msg[RTM_DELROUTE, rtmsg[AF_INET6], rtm_ipv6_policy]
ipv6_getroute netlink_msg[RTM_GETROUTE, rtmsg[AF_INET6], rtm_ipv6_policy]
ipv6_getmulticast netlink_msg[RTM_GETMULTICAST, rtgenmsg[AF_INET6], void]
ipv6_getanyicast netlink_msg[RTM_GETANYCAST, rtgenmsg[AF_INET6], void]
ipv6_getnetconf netlink_msg[RTM_GETNETCONF, netconfmsg[AF_INET6], devconf_ipv4_policy]
ipv6_newrule netlink_msg[RTM_NEWRULE, fib_rule_hdr[AF_INET6], fib6_rule_policy]
ipv6_delrule netlink_msg[RTM_DELRULE, fib_rule_hdr[AF_INET6], fib6_rule_policy]
ipv6_getrule netlink_msg[RTM_GETRULE, fib_rule_hdr[AF_INET6], void]
ipv6_newaddrlabel netlink_msg[RTM_NEWADDRLABEL, ifaddrlblmsg[AF_INET6], ifal_policy]
ipv6_deladdrlabel netlink_msg[RTM_DELADDRLABEL, ifaddrlblmsg[AF_INET6], ifal_policy]
ipv6_getaddrlabel netlink_msg[RTM_GETADDRLABEL, ifaddrlblmsg[AF_INET6], ifal_policy]
ipv6_newnexthop netlink_msg[RTM_NEWNEXTHOP, nhmsg_new[AF_INET6], rtm_nh_policy_new]
ipv6_getnexthop netlink_msg[RTM_GETNEXTHOP, nhmsg_get_del[AF_INET6], rtm_nh_policy_get]
ipmr_newroute netlink_msg[RTM_NEWROUTE, rtmsg[RTNL_FAMILY_IPMR], rtm_ipv4_policy]
ipmr_delroute netlink_msg[RTM_DELROUTE, rtmsg[RTNL_FAMILY_IPMR], rtm_ipv4_policy]
ipmr_getroute netlink_msg[RTM_GETROUTE, rtmsg[RTNL_FAMILY_IPMR], void]
mpls_newroute netlink_msg[RTM_NEWROUTE, rtmsg[AF_MPLS], rtm_mpls_policy]
mpls_delroute netlink_msg[RTM_DELROUTE, rtmsg[AF_MPLS], rtm_mpls_policy]
mpls_getroute netlink_msg[RTM_GETROUTE, rtmsg[AF_MPLS], rtm_mpls_policy]
mpls_getnetconf netlink_msg[RTM_GETNETCONF, netconfmsg[AF_MPLS], devconf_mpls_policy]
bridge_newneigh netlink_msg[RTM_NEWNEIGH, ndmsg, nda_policy]
bridge_delneigh netlink_msg[RTM_DELNEIGH, ndmsg, nda_policy]
bridge_getneigh netlink_msg[RTM_GETNEIGH, ifinfomsg[AF_BRIDGE], ifla_policy]
bridge_getlink netlink_msg[RTM_GETLINK, ifinfomsg[AF_BRIDGE], ifla_policy]
bridge_setlink netlink_msg[RTM_SETLINK, ifinfomsg[AF_BRIDGE], ifla_policy]
bridge_dellink netlink_msg[RTM_DELLINK, ifinfomsg[AF_BRIDGE], ifla_policy]
bridge_getvlan netlink_msg[RTM_GETVLAN, br_vlan_msg[AF_BRIDGE], br_vlan_db_dump_pol]
bridge_newvlan netlink_msg[RTM_NEWVLAN, br_vlan_msg[AF_BRIDGE], br_vlan_db_policy$container]
bridge_delvlan netlink_msg[RTM_DELVLAN, br_vlan_msg[AF_BRIDGE], br_vlan_db_policy$container]
RTM_GETMDB netlink_msg[RTM_GETMDB, br_port_msg[AF_BRIDGE], void]
RTM_NEWMDB netlink_msg[RTM_NEWMDB, br_port_msg[AF_BRIDGE], br_mdb_policy]
RTM_DELMDB netlink_msg[RTM_DELMDB, br_port_msg[AF_BRIDGE], br_mdb_policy]
RTM_NEWNSID netlink_msg[RTM_NEWNSID, rtgenmsg[AF_UNSPEC], rtnl_net_policy]
RTM_GETNSID netlink_msg[RTM_GETNSID, rtgenmsg[AF_UNSPEC], rtnl_net_policy]
can_newroute netlink_msg[RTM_NEWROUTE, rtcanmsg, cgw_policy]
can_delroute netlink_msg[RTM_DELROUTE, rtcanmsg, cgw_policy]
] [varlen]
type rtgenmsg[FAMILY] {
rtgen_family const[FAMILY, int8]
}
type netconfmsg[FAMILY] {
ncm_family const[FAMILY, int8]
}
type ifinfomsg[FAMILY] {
ifi_family const[FAMILY, int8]
__ifi_pad const[0, int8]
ifi_type const[0, int16]
ifi_index ifindex[opt]
ifi_flags flags[net_device_flags, int32]
ifi_change flags[net_device_flags, int32]
}
type ifaddrmsg[FAMILY] {
ifa_family const[FAMILY, int8]
ifa_prefixlen flags[ifa_prefixlen, int8]
ifa_flags flags[ifa_flags8, int8]
ifa_scope flags[rt_scope_t, int8]
ifa_index ifindex
}
type ifaddrlblmsg[FAMILY] {
ifal_family const[FAMILY, int8]
__ifal_reserved const[0, int8]
ifal_prefixlen flags[ifa_prefixlen, int8]
ifal_flags const[0, int8]
ifal_index ifindex
ifal_seq int32
}
type br_vlan_msg[FAMILY] {
family const[FAMILY, int8]
reserved1 const[0, int8]
reserved2 const[0, int16]
ifindex ifindex
}
type br_port_msg[FAMILY] {
family const[FAMILY, int8]
ifindex ifindex
}
type rtmsg[FAMILY] {
rtm_family const[FAMILY, int8]
rtm_dst_len flags[rtm_addr_len, int8]
rtmsrcdst_len flags[rtm_addr_len, int8]
rtm_tos int8
rtm_table flags[rt_table_types, int8]
rtm_protocol flags[rtm_protocol, int8]
rtm_scope flags[rt_scope_t, int8]
rtm_type flags[rtm_type, int8]
rtm_flags flags[rtm_flags, int32]
}
ndmsg {
ndm_family flags[rtnl_af, int8]
ndm_pad1 const[0, int8]
ndm_pad2 const[0, int16]
ndm_ifindex ifindex
ndm_state flags[ndm_state, int16]
ndm_flags flags[ndm_flags, int8]
ndm_type flags[rtm_type, int8]
}
ndtmsg {
ndm_family flags[rtnl_af, int8]
ndm_pad1 const[0, int8]
ndm_pad2 const[0, int16]
}
type if_stats_msg[FAMILY] {
family const[FAMILY, int8]
pad1 const[0, int8]
pad2 const[0, int16]
ifindex ifindex
filter_mask flags[filter_mask, int32]
}
type nhmsg_get_del[FAMILY] nhmsg[FAMILY, const[0, int8], const[0, int32]]
type nhmsg_new[FAMILY] nhmsg[FAMILY, flags[rtm_protocol, int8], flags[rtnh_flags, int32]]
type nhmsg[FAMILY, PROTOCOL, FLAGS] {
nh_family const[FAMILY, int8]
nh_scope const[0, int8]
nh_protocol PROTOCOL
resvd const[0, int8]
nh_flags FLAGS
}
ifla_policy [
IFLA_IFNAME nlattr[IFLA_IFNAME, devname]
IFLA_ADDRESS nlattr[IFLA_ADDRESS, mac_addr]
IFLA_BROADCAST nlattr[IFLA_BROADCAST, mac_addr]
IFLA_MAP nlattr[IFLA_MAP, rtnl_link_ifmap]
IFLA_MTU nlattr[IFLA_MTU, int32]
IFLA_LINK nlattr[IFLA_LINK, ifindex]
IFLA_MASTER nlattr[IFLA_MASTER, ifindex]
IFLA_CARRIER nlattr[IFLA_CARRIER, int8]
IFLA_TXQLEN nlattr[IFLA_TXQLEN, int32]
IFLA_WEIGHT nlattr[IFLA_WEIGHT, int32]
IFLA_OPERSTATE nlattr[IFLA_OPERSTATE, int8]
IFLA_LINKMODE nlattr[IFLA_LINKMODE, int8]
IFLA_LINKINFO nlnest[IFLA_LINKINFO, ifla_info_policy]
IFLA_NET_NS_PID nlattr[IFLA_NET_NS_PID, pid]
IFLA_NET_NS_FD nlattr[IFLA_NET_NS_FD, fd_namespace]
IFLA_IFALIAS nlattr[IFLA_IFALIAS, devname]
IFLA_IFALIASn nlattr[IFLA_IFALIAS, void]
IFLA_VFINFO_LIST nlnest[IFLA_VFINFO_LIST, array[nlnest[IFLA_VF_INFO, array[ifla_vf_policy]]]]
IFLA_VF_PORTS nlnest[IFLA_VF_PORTS, array[nlnest[IFLA_VF_PORT, array[ifla_port_policy]]]]
IFLA_PORT_SELF nlnest[IFLA_PORT_SELF, array[ifla_port_policy]]
IFLA_AF_SPEC nlnest[IFLA_AF_SPEC, array[ifla_af_spec_policy]]
IFLA_EXT_MASK nlattr[IFLA_EXT_MASK, int32]
IFLA_PROMISCUITY nlattr[IFLA_PROMISCUITY, int32]
IFLA_NUM_TX_QUEUES nlattr[IFLA_NUM_TX_QUEUES, int32]
IFLA_NUM_RX_QUEUES nlattr[IFLA_NUM_RX_QUEUES, int32]
IFLA_PHYS_PORT_ID nlattr[IFLA_PHYS_PORT_ID, array[int8, 0:MAX_PHYS_ITEM_ID_LEN]]
IFLA_CARRIER_CHANGES nlattr[IFLA_CARRIER_CHANGES, int32]
IFLA_PHYS_SWITCH_ID nlattr[IFLA_PHYS_SWITCH_ID, array[int8, 0:MAX_PHYS_ITEM_ID_LEN]]
IFLA_LINK_NETNSID nlattr[IFLA_LINK_NETNSID, netns_id]
IFLA_PROTO_DOWN nlattr[IFLA_PROTO_DOWN, int8]
IFLA_XDP nlnest[IFLA_XDP, array[ifla_xdp_policy]]
IFLA_EVENT nlattr[IFLA_EVENT, int32]
IFLA_GROUP nlattr[IFLA_GROUP, int32]
IFLA_TARGET_NETNSID nlattr[IFLA_TARGET_NETNSID, netns_id]
IFLA_PROP_LIST nlnest[IFLA_PROP_LIST, array[nlattr[IFLA_ALT_IFNAME, devname]]]
IFLA_ALT_IFNAME nlattr[IFLA_ALT_IFNAME, devname]
IFLA_GSO_MAX_SEGS nlattr[IFLA_GSO_MAX_SEGS, int32[0:GSO_MAX_SEGS]]
IFLA_GSO_MAX_SIZE nlattr[IFLA_GSO_MAX_SIZE, int32[0:GSO_MAX_SIZE]]
] [varlen]
ifla_af_spec_policy [
AF_INET nlnest[AF_INET, nlnest[IFLA_INET_CONF, array[nlattr_tt[int16:14[0:IPV4_DEVCONF_MAX], 0, 0, int32]]]]
AF_INET6 nlnest[AF_INET6, array[inet6_af_policy]]
AF_BRIDGE nlattr[AF_BRIDGE, void]
AF_MPLS nlattr[AF_MPLS, void]
] [varlen]
inet6_af_policy [
IFLA_INET6_ADDR_GEN_MODE nlattr[IFLA_INET6_ADDR_GEN_MODE, int8]
IFLA_INET6_TOKEN nlattr[IFLA_INET6_TOKEN, ipv6_addr]
] [varlen]
ifal_policy [
IFAL_ADDRESS nlattr[IFAL_ADDRESS, ipv6_addr]
IFAL_LABEL nlattr[IFAL_LABEL, flags[ifal_labels, int32]]
] [varlen]
type ifla_info_policy$t[TYPE, DATA_TYPE, DATA] {
IFLA_INFO_KIND nlattr[IFLA_INFO_KIND, string[TYPE]]
IFLA_INFO_DATA nlnest[DATA_TYPE, DATA]
}
# TODO: can, dummy, geneve, ifb, netdevsim, nlmon, vrf, vxlan
ifla_info_policy [
bond ifla_info_policy$t["bond", IFLA_INFO_DATA, array[bond_policy]]
bond_slave ifla_info_policy$t["bond_slave", IFLA_INFO_SLAVE_DATA, bond_slave_policy]
bridge ifla_info_policy$t["bridge", IFLA_INFO_DATA, array[br_policy]]
bridge_slave ifla_info_policy$t["bridge_slave", IFLA_INFO_SLAVE_DATA, array[br_port_policy]]
gre ifla_info_policy$t["gre", IFLA_INFO_DATA, array[ipgre_policy]]
gretap ifla_info_policy$t["gretap", IFLA_INFO_DATA, array[ipgre_policy]]
erspan ifla_info_policy$t["erspan", IFLA_INFO_DATA, array[ipgre_policy]]
ip6gre ifla_info_policy$t["ip6gre", IFLA_INFO_DATA, array[ip6gre_policy]]
ip6gretap ifla_info_policy$t["ip6gretap", IFLA_INFO_DATA, array[ip6gre_policy]]
ip6erspan ifla_info_policy$t["ip6erspan", IFLA_INFO_DATA, array[ip6gre_policy]]
ipip ifla_info_policy$t["ipip", IFLA_INFO_DATA, array[ipip_policy]]
ipip6 ifla_info_policy$t["ip6tnl", IFLA_INFO_DATA, array[ip6_tnl_policy]]
sit ifla_info_policy$t["sit", IFLA_INFO_DATA, array[ipip6_policy]]
veth ifla_info_policy$t["veth", IFLA_INFO_DATA, optional[veth_policy]]
vti ifla_info_policy$t["vti", IFLA_INFO_DATA, array[vti_policy]]
ip6vti ifla_info_policy$t["ip6vti", IFLA_INFO_DATA, array[vti6_policy]]
# TODO: this should be a net device fd. How does one even obtain these?
ppp ifla_info_policy$t["ppp", IFLA_INFO_DATA, nlattr[IFLA_PPP_DEV_FD, fd]]
gtp ifla_info_policy$t["gtp", IFLA_INFO_DATA, array[gtp_policy]]
hsr ifla_info_policy$t["hsr", IFLA_INFO_DATA, array[hsr_policy]]
xfrm ifla_info_policy$t["xfrm", IFLA_INFO_DATA, array[xfrmi_policy]]
vcan ifla_info_policy$t["vcan", IFLA_INFO_DATA, void]
vxcan ifla_info_policy$t["vxcan", IFLA_INFO_DATA, optional[nlattr[VXCAN_INFO_PEER, peer_info]]]
vlan ifla_info_policy$t["vlan", IFLA_INFO_DATA, array[vlan_policy]]
ipvlan ifla_info_policy$t["ipvlan", IFLA_INFO_DATA, array[ipvlan_nl_policy]]
macvlan ifla_info_policy$t["macvlan", IFLA_INFO_DATA, array[macvlan_policy]]
macvtap ifla_info_policy$t["macvtap", IFLA_INFO_DATA, void]
macsec ifla_info_policy$t["macsec", IFLA_INFO_DATA, array[macsec_rtnl_policy]]
lowpan ifla_info_policy$t["lowpan", IFLA_INFO_DATA, void]
ipoib ifla_info_policy$t["ipoib", IFLA_INFO_DATA, array[ipoib_policy]]
geneve ifla_info_policy$t["geneve", IFLA_INFO_DATA, array[geneve_policy]]
wireguard ifla_info_policy$t["wireguard", IFLA_INFO_DATA, void]
batadv ifla_info_policy$t["batadv", IFLA_INFO_DATA, array[batadv_policy]]
] [varlen]
batadv_policy [
IFLA_BATADV_ALGO_NAME nlattr[IFLA_BATADV_ALGO_NAME, stringnoz[batadv_algo]]
] [varlen]
# See batadv_algo_ops/batadv_algo_register.
batadv_algo = "BATMAN_V", "BATMAN_IV"
geneve_policy [
IFLA_GENEVE_ID nlattr[IFLA_GENEVE_ID, int32[0:4]]
IFLA_GENEVE_REMOTE nlattr[IFLA_GENEVE_REMOTE, ipv4_addr]
IFLA_GENEVE_REMOTE6 nlattr[IFLA_GENEVE_REMOTE6, ipv6_addr]
IFLA_GENEVE_TTL nlattr[IFLA_GENEVE_TTL, int8]
IFLA_GENEVE_TOS nlattr[IFLA_GENEVE_TOS, int8]
IFLA_GENEVE_LABEL nlnetw[IFLA_GENEVE_LABEL, int32be]
IFLA_GENEVE_PORT nlattr[IFLA_GENEVE_PORT, sock_port]
IFLA_GENEVE_COLLECT_METADATA nlattr[IFLA_GENEVE_COLLECT_METADATA, void]
IFLA_GENEVE_UDP_CSUM nlattr[IFLA_GENEVE_UDP_CSUM, bool8]
IFLA_GENEVE_UDP_ZERO_CSUM6_TX nlattr[IFLA_GENEVE_UDP_ZERO_CSUM6_TX, bool8]
IFLA_GENEVE_UDP_ZERO_CSUM6_RX nlattr[IFLA_GENEVE_UDP_ZERO_CSUM6_RX, bool8]
IFLA_GENEVE_TTL_INHERIT nlattr[IFLA_GENEVE_TTL_INHERIT, bool8]
IFLA_GENEVE_DF nlattr[IFLA_GENEVE_DF, int8]
] [varlen]
ipoib_policy [
IFLA_IPOIB_PKEY nlattr[IFLA_IPOIB_PKEY, int16]
IFLA_IPOIB_MODE nlattr[IFLA_IPOIB_MODE, bool16]
IFLA_IPOIB_UMCAST nlattr[IFLA_IPOIB_UMCAST, bool16]
] [varlen]
macsec_rtnl_policy [
# TODO: all of these need better types.
IFLA_MACSEC_SCI nlattr[IFLA_MACSEC_SCI, int64]
IFLA_MACSEC_PORT nlnetw[IFLA_MACSEC_PORT, sock_port]
IFLA_MACSEC_ICV_LEN nlattr[IFLA_MACSEC_ICV_LEN, int8]
IFLA_MACSEC_CIPHER_SUITE nlattr[IFLA_MACSEC_CIPHER_SUITE, int64]
IFLA_MACSEC_WINDOW nlattr[IFLA_MACSEC_WINDOW, int32]
IFLA_MACSEC_ENCODING_SA nlattr[IFLA_MACSEC_ENCODING_SA, int8]
IFLA_MACSEC_ENCRYPT nlattr[IFLA_MACSEC_ENCRYPT, int8]
IFLA_MACSEC_PROTECT nlattr[IFLA_MACSEC_PROTECT, int8]
IFLA_MACSEC_INC_SCI nlattr[IFLA_MACSEC_INC_SCI, int8]
IFLA_MACSEC_ES nlattr[IFLA_MACSEC_ES, int8]
IFLA_MACSEC_SCB nlattr[IFLA_MACSEC_SCB, int8]
IFLA_MACSEC_REPLAY_PROTECT nlattr[IFLA_MACSEC_REPLAY_PROTECT, int8]
IFLA_MACSEC_VALIDATION nlattr[IFLA_MACSEC_VALIDATION, int8]
] [varlen]
ipvlan_nl_policy [
IFLA_IPVLAN_MODE nlattr[IFLA_IPVLAN_MODE, flags[ipvlan_mode, int16]]
IFLA_IPVLAN_FLAGS nlattr[IFLA_IPVLAN_FLAGS, flags[ipvlan_flags, int16]]
] [varlen]
ipvlan_mode = IPVLAN_MODE_L2, IPVLAN_MODE_L3, IPVLAN_MODE_L3S
ipvlan_flags = IPVLAN_F_PRIVATE, IPVLAN_F_VEPA
macvlan_policy [
IFLA_MACVLAN_MODE nlattr[IFLA_MACVLAN_MODE, flags[macvlan_mode, int32]]
IFLA_MACVLAN_FLAGS nlattr[IFLA_MACVLAN_FLAGS, bool16]
IFLA_MACVLAN_MACADDR_MODE nlattr[IFLA_MACVLAN_MACADDR_MODE, flags[macvlan_macaddr_mode, int32]]
IFLA_MACVLAN_MACADDR nlattr[IFLA_MACVLAN_MACADDR, mac_addr]
IFLA_MACVLAN_MACADDR_DATA nlnest[IFLA_MACVLAN_MACADDR_DATA, array[nlattr[IFLA_MACVLAN_MACADDR, mac_addr]]]
IFLA_MACVLAN_BC_QUEUE_LEN nlattr[IFLA_MACVLAN_BC_QUEUE_LEN, int32]
] [varlen]
macvlan_mode = MACVLAN_MODE_PRIVATE, MACVLAN_MODE_VEPA, MACVLAN_MODE_BRIDGE, MACVLAN_MODE_PASSTHRU, MACVLAN_MODE_SOURCE
macvlan_macaddr_mode = MACVLAN_MACADDR_ADD, MACVLAN_MACADDR_DEL, MACVLAN_MACADDR_FLUSH, MACVLAN_MACADDR_SET
vlan_policy [
IFLA_VLAN_ID nlattr[IFLA_VLAN_ID, int16[0:4]]
IFLA_VLAN_FLAGS nlattr[IFLA_VLAN_FLAGS, ifla_vlan_flags]
IFLA_VLAN_EGRESS_QOS nlnest[IFLA_VLAN_EGRESS_QOS, array[vlan_map_policy]]
IFLA_VLAN_INGRESS_QOS nlnest[IFLA_VLAN_INGRESS_QOS, array[vlan_map_policy]]
IFLA_VLAN_PROTOCOL nlattr[IFLA_VLAN_PROTOCOL, flags[vlan_proto, int16be]]
] [varlen]
ifla_vlan_flags {
flags flags[ifla_vlan_flags, int32]
mask flags[ifla_vlan_flags, int32]
}
ifla_vlan_flags = VLAN_FLAG_REORDER_HDR, VLAN_FLAG_GVRP, VLAN_FLAG_LOOSE_BINDING, VLAN_FLAG_MVRP, VLAN_FLAG_BRIDGE_BINDING
vlan_map_policy [
IFLA_VLAN_QOS_MAPPING nlattr[IFLA_VLAN_QOS_MAPPING, ifla_vlan_qos_mapping]
] [varlen]
ifla_vlan_qos_mapping {
from int32
to int32
}
xfrmi_policy [
IFLA_XFRM_LINK nlattr[IFLA_XFRM_LINK, int32[0:4]]
IFLA_XFRM_IF_ID nlattr[IFLA_XFRM_IF_ID, xfrm_if_id]
] [varlen]
hsr_policy [
IFLA_HSR_SLAVE1 nlattr[IFLA_HSR_SLAVE1, ifindex]
IFLA_HSR_SLAVE2 nlattr[IFLA_HSR_SLAVE2, ifindex]
IFLA_HSR_MULTICAST_SPEC nlattr[IFLA_HSR_MULTICAST_SPEC, int8]
IFLA_HSR_VERSION nlattr[IFLA_HSR_VERSION, int8]
IFLA_HSR_SUPERVISION_ADDR nlattr[IFLA_HSR_SUPERVISION_ADDR, mac_addr]
IFLA_HSR_SEQ_NR nlattr[IFLA_HSR_SEQ_NR, int16]
IFLA_HSR_PROTOCOL nlattr[IFLA_HSR_PROTOCOL, int8[0:HSR_PROTOCOL_MAX]]
] [varlen]
bond_policy [
IFLA_BOND_MODE nlattr[IFLA_BOND_MODE, int8[0:6]]
IFLA_BOND_ACTIVE_SLAVE nlattr[IFLA_BOND_ACTIVE_SLAVE, ifindex]
IFLA_BOND_MIIMON nlattr[IFLA_BOND_MIIMON, int32]
IFLA_BOND_UPDELAY nlattr[IFLA_BOND_UPDELAY, int32]
IFLA_BOND_DOWNDELAY nlattr[IFLA_BOND_DOWNDELAY, int32]
IFLA_BOND_USE_CARRIER nlattr[IFLA_BOND_USE_CARRIER, int8]
IFLA_BOND_ARP_INTERVAL nlattr[IFLA_BOND_ARP_INTERVAL, int32]
IFLA_BOND_ARP_IP_TARGET nlnest[IFLA_BOND_ARP_IP_TARGET, array[ipv4_addr]]
IFLA_BOND_ARP_VALIDATE nlattr[IFLA_BOND_ARP_VALIDATE, int32[0:3]]
IFLA_BOND_ARP_ALL_TARGETS nlattr[IFLA_BOND_ARP_ALL_TARGETS, int32[0:1]]
IFLA_BOND_PRIMARY nlattr[IFLA_BOND_PRIMARY, ifindex]
IFLA_BOND_PRIMARY_RESELECT nlattr[IFLA_BOND_PRIMARY_RESELECT, int8[0:2]]
IFLA_BOND_FAIL_OVER_MAC nlattr[IFLA_BOND_FAIL_OVER_MAC, int8[0:2]]
IFLA_BOND_XMIT_HASH_POLICY nlattr[IFLA_BOND_XMIT_HASH_POLICY, int8[0:4]]
IFLA_BOND_RESEND_IGMP nlattr[IFLA_BOND_RESEND_IGMP, int32]
IFLA_BOND_NUM_PEER_NOTIF nlattr[IFLA_BOND_NUM_PEER_NOTIF, int8]
IFLA_BOND_ALL_SLAVES_ACTIVE nlattr[IFLA_BOND_ALL_SLAVES_ACTIVE, int8]
IFLA_BOND_MIN_LINKS nlattr[IFLA_BOND_MIN_LINKS, int32]
IFLA_BOND_LP_INTERVAL nlattr[IFLA_BOND_LP_INTERVAL, int32]
IFLA_BOND_PACKETS_PER_SLAVE nlattr[IFLA_BOND_PACKETS_PER_SLAVE, int32]
IFLA_BOND_AD_LACP_RATE nlattr[IFLA_BOND_AD_LACP_RATE, int8[0:1]]
IFLA_BOND_AD_SELECT nlattr[IFLA_BOND_AD_SELECT, int8[0:2]]
IFLA_BOND_AD_ACTOR_SYS_PRIO nlattr[IFLA_BOND_AD_ACTOR_SYS_PRIO, int16]
IFLA_BOND_AD_USER_PORT_KEY nlattr[IFLA_BOND_AD_USER_PORT_KEY, int16]
IFLA_BOND_AD_ACTOR_SYSTEM nlattr[IFLA_BOND_AD_ACTOR_SYSTEM, ipv4_addr]
IFLA_BOND_TLB_DYNAMIC_LB nlattr[IFLA_BOND_TLB_DYNAMIC_LB, int8]
IFLA_BOND_PEER_NOTIF_DELAY nlattr[IFLA_BOND_PEER_NOTIF_DELAY, int32]
IFLA_BOND_AD_LACP_ACTIVE nlattr[IFLA_BOND_AD_LACP_ACTIVE, int8]
] [varlen]
bond_slave_policy [
IFLA_BOND_SLAVE_QUEUE_ID nlattr[IFLA_BOND_SLAVE_QUEUE_ID, int16]
] [varlen]
br_policy [
IFLA_BR_FORWARD_DELAY nlattr[IFLA_BR_FORWARD_DELAY, int32[2:30]]
IFLA_BR_HELLO_TIME nlattr[IFLA_BR_HELLO_TIME, int32[1:10]]
IFLA_BR_MAX_AGE nlattr[IFLA_BR_MAX_AGE, int32[6:40]]
IFLA_BR_AGEING_TIME nlattr[IFLA_BR_AGEING_TIME, int32]
IFLA_BR_STP_STATE nlattr[IFLA_BR_STP_STATE, int32[0:1]]
IFLA_BR_PRIORITY nlattr[IFLA_BR_PRIORITY, int16]
IFLA_BR_VLAN_FILTERING nlattr[IFLA_BR_VLAN_FILTERING, int8]
IFLA_BR_VLAN_PROTOCOL nlattr[IFLA_BR_VLAN_PROTOCOL, flags[vlan_proto, int16]]
IFLA_BR_GROUP_FWD_MASK nlattr[IFLA_BR_GROUP_FWD_MASK, int16]
IFLA_BR_GROUP_ADDR nlattr[IFLA_BR_GROUP_ADDR, mac_addr]
IFLA_BR_MCAST_ROUTER nlattr[IFLA_BR_MCAST_ROUTER, bool8]
IFLA_BR_MCAST_SNOOPING nlattr[IFLA_BR_MCAST_SNOOPING, bool8]
IFLA_BR_MCAST_QUERY_USE_IFADDR nlattr[IFLA_BR_MCAST_QUERY_USE_IFADDR, bool8]
IFLA_BR_MCAST_QUERIER nlattr[IFLA_BR_MCAST_QUERIER, int8]
IFLA_BR_MCAST_HASH_ELASTICITY nlattr[IFLA_BR_MCAST_HASH_ELASTICITY, int32]
IFLA_BR_MCAST_HASH_MAX nlattr[IFLA_BR_MCAST_HASH_MAX, int32]
IFLA_BR_MCAST_LAST_MEMBER_CNT nlattr[IFLA_BR_MCAST_LAST_MEMBER_CNT, int32]
IFLA_BR_MCAST_STARTUP_QUERY_CNT nlattr[IFLA_BR_MCAST_STARTUP_QUERY_CNT, int32]
IFLA_BR_MCAST_LAST_MEMBER_INTVL nlattr[IFLA_BR_MCAST_LAST_MEMBER_INTVL, int64]
IFLA_BR_MCAST_MEMBERSHIP_INTVL nlattr[IFLA_BR_MCAST_MEMBERSHIP_INTVL, int64]
IFLA_BR_MCAST_QUERIER_INTVL nlattr[IFLA_BR_MCAST_QUERIER_INTVL, int64]
IFLA_BR_MCAST_QUERY_INTVL nlattr[IFLA_BR_MCAST_QUERY_INTVL, int64]
IFLA_BR_MCAST_QUERY_RESPONSE_INTVL nlattr[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL, int64]
IFLA_BR_MCAST_STARTUP_QUERY_INTVL nlattr[IFLA_BR_MCAST_STARTUP_QUERY_INTVL, int64]
IFLA_BR_NF_CALL_IPTABLES nlattr[IFLA_BR_NF_CALL_IPTABLES, bool8]
IFLA_BR_NF_CALL_IP6TABLES nlattr[IFLA_BR_NF_CALL_IP6TABLES, bool8]
IFLA_BR_NF_CALL_ARPTABLES nlattr[IFLA_BR_NF_CALL_ARPTABLES, bool8]
IFLA_BR_VLAN_DEFAULT_PVID nlattr[IFLA_BR_VLAN_DEFAULT_PVID, int16]
IFLA_BR_VLAN_STATS_ENABLED nlattr[IFLA_BR_VLAN_STATS_ENABLED, bool8]
IFLA_BR_MCAST_STATS_ENABLED nlattr[IFLA_BR_MCAST_STATS_ENABLED, bool8]
IFLA_BR_MCAST_IGMP_VERSION nlattr[IFLA_BR_MCAST_IGMP_VERSION, int8]
IFLA_BR_MCAST_MLD_VERSION nlattr[IFLA_BR_MCAST_MLD_VERSION, int8]
IFLA_BR_VLAN_STATS_PER_PORT nlattr[IFLA_BR_VLAN_STATS_PER_PORT, bool8]
IFLA_BR_MULTI_BOOLOPT nlattr[IFLA_BR_MULTI_BOOLOPT, br_boolopt_multi]
] [varlen]
br_boolopt_multi {
optval flags[br_boolopt_id, int32]
optmask flags[br_boolopt_id, int32]
}
br_boolopt_id = BR_BOOLOPT_NO_LL_LEARN, BR_BOOLOPT_MCAST_VLAN_SNOOPING
br_port_policy [
IFLA_BRPORT_STATE nlattr[IFLA_BRPORT_STATE, int8[0:4]]
IFLA_BRPORT_COST nlattr[IFLA_BRPORT_COST, int32]
IFLA_BRPORT_PRIORITY nlattr[IFLA_BRPORT_PRIORITY, int16]
IFLA_BRPORT_MODE nlattr[IFLA_BRPORT_MODE, int8[0:1]]
IFLA_BRPORT_GUARD nlattr[IFLA_BRPORT_GUARD, int8[0:1]]
IFLA_BRPORT_PROTECT nlattr[IFLA_BRPORT_PROTECT, int8[0:1]]
IFLA_BRPORT_FAST_LEAVE nlattr[IFLA_BRPORT_FAST_LEAVE, int8[0:1]]
IFLA_BRPORT_LEARNING nlattr[IFLA_BRPORT_LEARNING, int8[0:1]]
IFLA_BRPORT_UNICAST_FLOOD nlattr[IFLA_BRPORT_UNICAST_FLOOD, int8[0:1]]
IFLA_BRPORT_PROXYARP nlattr[IFLA_BRPORT_PROXYARP, int8[0:1]]
IFLA_BRPORT_PROXYARP_WIFI nlattr[IFLA_BRPORT_PROXYARP_WIFI, int8[0:1]]
IFLA_BRPORT_MULTICAST_ROUTER nlattr[IFLA_BRPORT_MULTICAST_ROUTER, int8[0:3]]
IFLA_BRPORT_MCAST_TO_UCAST nlattr[IFLA_BRPORT_MCAST_TO_UCAST, int8[0:1]]
IFLA_BRPORT_MCAST_FLOOD nlattr[IFLA_BRPORT_MCAST_FLOOD, int8[0:1]]
IFLA_BRPORT_BCAST_FLOOD nlattr[IFLA_BRPORT_BCAST_FLOOD, int8[0:1]]
IFLA_BRPORT_VLAN_TUNNEL nlattr[IFLA_BRPORT_VLAN_TUNNEL, int8[0:1]]
IFLA_BRPORT_GROUP_FWD_MASK nlattr[IFLA_BRPORT_GROUP_FWD_MASK, int16]
IFLA_BRPORT_NEIGH_SUPPRESS nlattr[IFLA_BRPORT_NEIGH_SUPPRESS, int8[0:1]]
IFLA_BRPORT_ISOLATED nlattr[IFLA_BRPORT_ISOLATED, int8[0:1]]
IFLA_BRPORT_FLUSH nlattr[IFLA_BRPORT_FLUSH, void]
IFLA_BRPORT_BACKUP_PORT nlattr[IFLA_BRPORT_BACKUP_PORT, ifindex]
IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT nlattr[IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT, int32]
] [varlen]
ipgre_policy [
IFLA_GRE_LINK nlattr[IFLA_GRE_LINK, ifindex]
IFLA_GRE_IFLAGS nlattr[IFLA_GRE_IFLAGS, int16]
IFLA_GRE_OFLAGS nlattr[IFLA_GRE_OFLAGS, int16]
IFLA_GRE_IKEY nlattr[IFLA_GRE_IKEY, int32]
IFLA_GRE_OKEY nlattr[IFLA_GRE_OKEY, int32]
IFLA_GRE_LOCAL nlattr[IFLA_GRE_LOCAL, ipv4_addr]
IFLA_GRE_REMOTE nlattr[IFLA_GRE_REMOTE, ipv4_addr]
IFLA_GRE_TTL nlattr[IFLA_GRE_TTL, int8]
IFLA_GRE_TOS nlattr[IFLA_GRE_TOS, int8]
IFLA_GRE_PMTUDISC nlattr[IFLA_GRE_PMTUDISC, int8[0:1]]
IFLA_GRE_ENCAP_TYPE nlattr[IFLA_GRE_ENCAP_TYPE, flags[tunnel_encap_types, int16]]
IFLA_GRE_ENCAP_FLAGS nlattr[IFLA_GRE_ENCAP_FLAGS, int16]
IFLA_GRE_ENCAP_SPORT nlattr[IFLA_GRE_ENCAP_SPORT, sock_port]
IFLA_GRE_ENCAP_DPORT nlattr[IFLA_GRE_ENCAP_DPORT, sock_port]
IFLA_GRE_COLLECT_METADATA nlattr[IFLA_GRE_COLLECT_METADATA, void]
IFLA_GRE_IGNORE_DF nlattr[IFLA_GRE_IGNORE_DF, int8[0:1]]
IFLA_GRE_FWMARK nlattr[IFLA_GRE_FWMARK, int32]
IFLA_GRE_ERSPAN_INDEX nlattr[IFLA_GRE_ERSPAN_INDEX, int32[1:0xfffff]]
IFLA_GRE_ERSPAN_VER nlattr[IFLA_GRE_ERSPAN_VER, int8[1:2]]
IFLA_GRE_ERSPAN_DIR nlattr[IFLA_GRE_ERSPAN_DIR, int8[0:1]]
IFLA_GRE_ERSPAN_HWID nlattr[IFLA_GRE_ERSPAN_HWID, int16]
] [varlen]
ip6gre_policy [
IFLA_GRE_LINK nlattr[IFLA_GRE_LINK, ifindex]
IFLA_GRE_IFLAGS nlattr[IFLA_GRE_IFLAGS, int16]
IFLA_GRE_OFLAGS nlattr[IFLA_GRE_OFLAGS, int16]
IFLA_GRE_IKEY nlattr[IFLA_GRE_IKEY, int32]
IFLA_GRE_OKEY nlattr[IFLA_GRE_OKEY, int32]
IFLA_GRE_LOCAL nlattr[IFLA_GRE_LOCAL, ipv6_addr]
IFLA_GRE_REMOTE nlattr[IFLA_GRE_REMOTE, ipv6_addr]
IFLA_GRE_TTL nlattr[IFLA_GRE_TTL, int8]
IFLA_GRE_ENCAP_LIMIT nlattr[IFLA_GRE_ENCAP_LIMIT, int8]
IFLA_GRE_FLOWINFO nlattr[IFLA_GRE_FLOWINFO, int32]
IFLA_GRE_FLAGS nlattr[IFLA_GRE_FLAGS, int32]
IFLA_GRE_ENCAP_TYPE nlattr[IFLA_GRE_ENCAP_TYPE, flags[tunnel_encap_types, int16]]
IFLA_GRE_ENCAP_FLAGS nlattr[IFLA_GRE_ENCAP_FLAGS, int16]
IFLA_GRE_ENCAP_SPORT nlattr[IFLA_GRE_ENCAP_SPORT, sock_port]
IFLA_GRE_ENCAP_DPORT nlattr[IFLA_GRE_ENCAP_DPORT, sock_port]
IFLA_GRE_COLLECT_METADATA nlattr[IFLA_GRE_COLLECT_METADATA, void]
IFLA_GRE_FWMARK nlattr[IFLA_GRE_FWMARK, int32]
IFLA_GRE_ERSPAN_INDEX nlattr[IFLA_GRE_ERSPAN_INDEX, int32[1:0xfffff]]
IFLA_GRE_ERSPAN_VER nlattr[IFLA_GRE_ERSPAN_VER, int8[1:2]]
IFLA_GRE_ERSPAN_DIR nlattr[IFLA_GRE_ERSPAN_DIR, int8[0:1]]
IFLA_GRE_ERSPAN_HWID nlattr[IFLA_GRE_ERSPAN_HWID, int16]
] [varlen]
veth_policy [
VETH_INFO_PEER nlattr[VETH_INFO_PEER, peer_info]
] [varlen]
peer_info {
hdr ifinfomsg[AF_UNSPEC]
# This may be followed by ifla_policy for the peer, but adding it causes recursion.
# policy optional[ifla_policy]
}
vti_policy$common [
IFLA_VTI_LINK nlattr[IFLA_VTI_LINK, ifindex]
IFLA_VTI_IKEY nlattr[IFLA_VTI_IKEY, int32]
IFLA_VTI_OKEY nlattr[IFLA_VTI_OKEY, int32]
IFLA_VTI_FWMARK nlattr[IFLA_VTI_FWMARK, int32]
] [varlen]
vti_policy [
IFLA_VTI_LOCAL nlattr[IFLA_VTI_LOCAL, ipv4_addr]
IFLA_VTI_REMOTE nlattr[IFLA_VTI_REMOTE, ipv4_addr]
vti_common_policy array[vti_policy$common]
] [varlen]
vti6_policy [
IFLA_VTI_LOCAL nlattr[IFLA_VTI_LOCAL, ipv6_addr]
IFLA_VTI_REMOTE nlattr[IFLA_VTI_REMOTE, ipv6_addr]
vti_common_policy array[vti_policy$common]
] [varlen]
ipip_policy [
IFLA_IPTUN_LINK nlattr[IFLA_IPTUN_LINK, ifindex]
IFLA_IPTUN_LOCAL nlattr[IFLA_IPTUN_LOCAL, ipv4_addr]
IFLA_IPTUN_REMOTE nlattr[IFLA_IPTUN_REMOTE, ipv4_addr]
IFLA_IPTUN_TTL nlattr[IFLA_IPTUN_TTL, int8]
IFLA_IPTUN_TOS nlattr[IFLA_IPTUN_TOS, int8]
IFLA_IPTUN_PROTO nlattr[IFLA_IPTUN_PROTO, flags[ipip6_ip_proto, int8]]
IFLA_IPTUN_PMTUDISC nlattr[IFLA_IPTUN_PMTUDISC, int8[0:1]]
IFLA_IPTUN_ENCAP_TYPE nlattr[IFLA_IPTUN_ENCAP_TYPE, flags[tunnel_encap_types, int16]]
IFLA_IPTUN_ENCAP_FLAGS nlattr[IFLA_IPTUN_ENCAP_FLAGS, int16]
IFLA_IPTUN_ENCAP_SPORT nlattr[IFLA_IPTUN_ENCAP_SPORT, sock_port]
IFLA_IPTUN_ENCAP_DPORT nlattr[IFLA_IPTUN_ENCAP_DPORT, sock_port]
IFLA_IPTUN_COLLECT_METADATA nlattr[IFLA_IPTUN_COLLECT_METADATA, void]
IFLA_IPTUN_FWMARK nlattr[IFLA_IPTUN_FWMARK, int32]
] [varlen]
ipip6_policy [
IFLA_IPTUN_LINK nlattr[IFLA_IPTUN_LINK, ifindex]
IFLA_IPTUN_LOCAL nlattr[IFLA_IPTUN_LOCAL, ipv4_addr]
IFLA_IPTUN_REMOTE nlattr[IFLA_IPTUN_REMOTE, ipv4_addr]
IFLA_IPTUN_TTL nlattr[IFLA_IPTUN_TTL, int8]
IFLA_IPTUN_TOS nlattr[IFLA_IPTUN_TOS, int8]
IFLA_IPTUN_PMTUDISC nlattr[IFLA_IPTUN_PMTUDISC, int8[0:1]]
IFLA_IPTUN_FLAGS nlattr[IFLA_IPTUN_FLAGS, int16[0:0x40]]
IFLA_IPTUN_PROTO nlattr[IFLA_IPTUN_PROTO, flags[ipip6_ip_proto, int8]]
IFLA_IPTUN_6RD_PREFIX nlattr[IFLA_IPTUN_6RD_PREFIX, ipv6_addr]
IFLA_IPTUN_6RD_RELAY_PREFIX nlattr[IFLA_IPTUN_6RD_RELAY_PREFIX, int32]
IFLA_IPTUN_6RD_PREFIXLEN nlattr[IFLA_IPTUN_6RD_PREFIXLEN, int16]
IFLA_IPTUN_6RD_RELAY_PREFIXLEN nlattr[IFLA_IPTUN_6RD_RELAY_PREFIXLEN, int16]
IFLA_IPTUN_ENCAP_TYPE nlattr[IFLA_IPTUN_ENCAP_TYPE, flags[tunnel_encap_types, int16]]
IFLA_IPTUN_ENCAP_FLAGS nlattr[IFLA_IPTUN_ENCAP_FLAGS, int16]
IFLA_IPTUN_ENCAP_SPORT nlattr[IFLA_IPTUN_ENCAP_SPORT, sock_port]
IFLA_IPTUN_ENCAP_DPORT nlattr[IFLA_IPTUN_ENCAP_DPORT, sock_port]
IFLA_IPTUN_FWMARK nlattr[IFLA_IPTUN_FWMARK, int32]
] [varlen]
ip6_tnl_policy [
IFLA_IPTUN_LINK nlattr[IFLA_IPTUN_LINK, ifindex]
IFLA_IPTUN_LOCAL nlattr[IFLA_IPTUN_LOCAL, ipv6_addr]
IFLA_IPTUN_REMOTE nlattr[IFLA_IPTUN_REMOTE, ipv6_addr]
IFLA_IPTUN_TTL nlattr[IFLA_IPTUN_TTL, int8]
IFLA_IPTUN_ENCAP_LIMIT nlattr[IFLA_IPTUN_ENCAP_LIMIT, int8]
IFLA_IPTUN_FLOWINFO nlattr[IFLA_IPTUN_FLOWINFO, int32]
IFLA_IPTUN_FLAGS nlattr[IFLA_IPTUN_FLAGS, int32[0:0x40]]
IFLA_IPTUN_PROTO nlattr[IFLA_IPTUN_PROTO, flags[ipip6_ip_proto, int8]]
IFLA_IPTUN_ENCAP_TYPE nlattr[IFLA_IPTUN_ENCAP_TYPE, flags[tunnel_encap_types, int16]]
IFLA_IPTUN_ENCAP_FLAGS nlattr[IFLA_IPTUN_ENCAP_FLAGS, int16]
IFLA_IPTUN_ENCAP_SPORT nlattr[IFLA_IPTUN_ENCAP_SPORT, sock_port]
IFLA_IPTUN_ENCAP_DPORT nlattr[IFLA_IPTUN_ENCAP_DPORT, sock_port]
IFLA_IPTUN_COLLECT_METADATA nlattr[IFLA_IPTUN_COLLECT_METADATA, void]
IFLA_IPTUN_FWMARK nlattr[IFLA_IPTUN_FWMARK, int32]
] [varlen]
ipip6_ip_proto = IPPROTO_IPV6, IPPROTO_IPIP, IPPROTO_MPLS
ifa_ipv4_policy [
IFA_LOCAL nlattr[IFA_LOCAL, ipv4_addr]
IFA_ADDRESS nlattr[IFA_ADDRESS, ipv4_addr]
IFA_BROADCAST nlattr[IFA_BROADCAST, ipv4_addr]
IFA_LABEL nlattr[IFA_LABEL, devname]
IFA_CACHEINFO nlattr[IFA_CACHEINFO, ifa_cacheinfo]
IFA_FLAGS nlattr[IFA_FLAGS, flags[ifa_flags, int32]]
IFA_RT_PRIORITY nlattr[IFA_RT_PRIORITY, int32]
IFA_TARGET_NETNSID nlattr[IFA_TARGET_NETNSID, netns_id]
] [varlen]
ifa_ipv6_policy [
IFA_ADDRESS nlattr[IFA_ADDRESS, ipv6_addr]
IFA_LOCAL nlattr[IFA_LOCAL, ipv6_addr]
IFA_CACHEINFO nlattr[IFA_CACHEINFO, ifa_cacheinfo]
IFA_FLAGS nlattr[IFA_FLAGS, flags[ifa_flags, int32]]
IFA_RT_PRIORITY nlattr[IFA_RT_PRIORITY, int32]
IFA_TARGET_NETNSID nlattr[IFA_TARGET_NETNSID, netns_id]
] [varlen]
rtm_ipv4_policy [
RTA_DST nlattr[RTA_DST, ipv4_addr]
RTA_SRC nlattr[RTA_SRC, ipv4_addr]
RTA_IIF nlattr[RTA_IIF, ifindex]
RTA_OIF nlattr[RTA_OIF, ifindex]
RTA_GATEWAY nlattr[RTA_GATEWAY, ipv4_addr]
RTA_PRIORITY nlattr[RTA_PRIORITY, int32]
RTA_PREFSRC nlattr[RTA_PREFSRC, ipv4_addr]
# TODO: what's this? is this interesting?
RTA_METRICS nlnest[RTA_METRICS, array[int8]]
RTA_MULTIPATH nlattr[RTA_MULTIPATH, rtnexthop]
RTA_FLOW nlattr[RTA_FLOW, int32]
RTA_ENCAP_TYPE nlattr[RTA_ENCAP_TYPE, flags[lwtunnel_encap_types, int16]]
RTA_ENCAP nlnest[RTA_ENCAP, lwtunnel_policy]
RTA_UID nlattr[RTA_UID, uid]
RTA_MARK nlattr[RTA_MARK, int32]
RTA_TABLE nlattr[RTA_TABLE, int32]
RTA_IP_PROTO nlattr[RTA_IP_PROTO, flags[rta_ip_protos, int8]]
RTA_SPORT nlattr[RTA_SPORT, sock_port]
RTA_DPORT nlattr[RTA_DPORT, sock_port]
RTA_NH_ID nlattr[RTA_NH_ID, int32]
] [varlen]
rta_ip_protos = IPPROTO_TCP, IPPROTO_UDP, IPPROTO_ICMP, IPPROTO_ICMPV6
rtm_ipv6_policy [
RTA_GATEWAY nlattr[RTA_GATEWAY, ipv6_addr]
RTA_IIF nlattr[RTA_IIF, ifindex]
RTA_OIF nlattr[RTA_OIF, ifindex]
RTA_PRIORITY nlattr[RTA_PRIORITY, int32]
# TODO: what's this? is this interesting?
RTA_METRICS nlnest[RTA_METRICS, array[int8]]
RTA_MULTIPATH nlattr[RTA_MULTIPATH, rtnexthop]
RTA_PREF nlattr[RTA_PREF, int8]
RTA_ENCAP_TYPE nlattr[RTA_ENCAP_TYPE, flags[lwtunnel_encap_types, int16]]
RTA_ENCAP nlnest[RTA_ENCAP, lwtunnel_policy]
RTA_EXPIRES nlattr[RTA_EXPIRES, int32]
RTA_UID nlattr[RTA_UID, uid]
RTA_MARK nlattr[RTA_MARK, int32]
] [varlen]
rtm_mpls_policy [
RTA_DST nlattr[RTA_DST, mpls_label]
RTA_MULTIPATH nlattr[RTA_MULTIPATH, rtnexthop]
RTA_NEWDST nlattr[RTA_NEWDST, array[mpls_label, 32]]
RTA_OIF nlattr[RTA_OIF, ifindex]
RTA_TTL_PROPAGATE nlattr[RTA_TTL_PROPAGATE, int8]
RTA_VIA nlattr[RTA_VIA, sockaddr_generic]
] [varlen]
type fib_rule_hdr[FAMILY] {
family const[FAMILY, int8]
dst_len flags[rtm_addr_len, int8]
rcdst_len flags[rtm_addr_len, int8]
tos int8
table int8
res1 const[0, int8]
res2 const[0, int8]
action flags[fr_actions, int8]
flags flags[fr_flags, int32]
}
fib_rule_uid_range {
start uid
end uid
}
fib_rule_port_range {
start sock_port
end sock_port
}
fib4_rule_policy_generic [
FRA_IIFNAME nlattr[FRA_IIFNAME, devname]
FRA_OIFNAME nlattr[FRA_OIFNAME, devname]
FRA_PRIORITY nlattr[FRA_PRIORITY, int32]
FRA_FWMARK nlattr[FRA_FWMARK, int32]
FRA_FWMASK nlattr[FRA_FWMASK, int32]
FRA_TABLE nlattr[FRA_TABLE, int32]
FRA_SUPPRESS_PREFIXLEN nlattr[FRA_SUPPRESS_PREFIXLEN, int32]
FRA_SUPPRESS_IFGROUP nlattr[FRA_SUPPRESS_IFGROUP, int32]
FRA_GOTO nlattr[FRA_GOTO, int32]
FRA_L3MDEV nlattr[FRA_L3MDEV, int8]
FRA_UID_RANGE nlattr[FRA_UID_RANGE, fib_rule_uid_range]
FRA_PROTOCOL nlattr[FRA_PROTOCOL, flags[rtm_protocol, int8]]
FRA_IP_PROTO nlattr[FRA_IP_PROTO, flags[ipv6_types, int8]]
FRA_SPORT_RANGE nlattr[FRA_SPORT_RANGE, fib_rule_port_range]
FRA_DPORT_RANGE nlattr[FRA_DPORT_RANGE, fib_rule_port_range]
] [varlen]
# FRA_DST/SRC are not in fib4/6_rule_policy. But fib4/6 still need them.
# So I add them here.
fib4_rule_policy [
FRA_DST nlattr[RTA_DST, ipv4_addr]
FRA_SRC nlattr[RTA_SRC, ipv4_addr]
FRA_GENERIC_POLICY fib4_rule_policy_generic
FRA_FLOW nlattr[FRA_FLOW, int32]
FRA_TUN_ID nlnetw[FRA_TUN_ID, int64be]
] [varlen]
fib6_rule_policy [
FRA_DST nlattr[RTA_DST, ipv6_addr]
FRA_SRC nlattr[RTA_SRC, ipv6_addr]
FIB_RULE_POLICY fib4_rule_policy_generic
] [varlen]
nl_neightbl_policy [
NDTA_NAME nlattr[NDTA_NAME, string]
NDTA_THRESH1 nlattr[NDTA_THRESH1, int32]
NDTA_THRESH2 nlattr[NDTA_THRESH2, int32]
NDTA_THRESH3 nlattr[NDTA_THRESH3, int32]
NDTA_GC_INTERVAL nlattr[NDTA_GC_INTERVAL, int64]
NDTA_PARMS nlnest[NDTA_PARMS, array[nl_ntbl_parm_policy]]
] [varlen]
nl_ntbl_parm_policy [
NDTPA_IFINDEX nlattr[NDTPA_IFINDEX, ifindex]
NDTPA_QUEUE_LEN nlattr[NDTPA_QUEUE_LEN, int32]
NDTPA_PROXY_QLEN nlattr[NDTPA_PROXY_QLEN, int32]
NDTPA_APP_PROBES nlattr[NDTPA_APP_PROBES, int32]
NDTPA_UCAST_PROBES nlattr[NDTPA_UCAST_PROBES, int32]
NDTPA_MCAST_PROBES nlattr[NDTPA_MCAST_PROBES, int32]
NDTPA_MCAST_REPROBES nlattr[NDTPA_MCAST_REPROBES, int32]
NDTPA_BASE_REACHABLE_TIME nlattr[NDTPA_BASE_REACHABLE_TIME, int64]
NDTPA_GC_STALETIME nlattr[NDTPA_GC_STALETIME, int64]
NDTPA_DELAY_PROBE_TIME nlattr[NDTPA_DELAY_PROBE_TIME, int64]
NDTPA_RETRANS_TIME nlattr[NDTPA_RETRANS_TIME, int64]
NDTPA_ANYCAST_DELAY nlattr[NDTPA_ANYCAST_DELAY, int64]
NDTPA_PROXY_DELAY nlattr[NDTPA_PROXY_DELAY, int64]
NDTPA_LOCKTIME nlattr[NDTPA_LOCKTIME, int64]
] [varlen]
nda_policy [
NDA_DST_IPV4 nlattr[NDA_DST, ipv4_addr]
NDA_DST_IPV6 nlattr[NDA_DST, ipv6_addr]
NDA_DST_MAC nlattr[NDA_DST, mac_addr]
NDA_LLADDR nlattr[NDA_LLADDR, mac_addr]
NDA_CACHEINFO nlattr[NDA_CACHEINFO, nda_cacheinfo]
NDA_PROBES nlattr[NDA_PROBES, int32]
NDA_VLAN nlattr[NDA_VLAN, int16[0:4]]
NDA_PORT nlattr[NDA_PORT, sock_port]
NDA_VNI nlattr[NDA_VNI, int32]
NDA_IFINDEX nlattr[NDA_IFINDEX, ifindex]
NDA_MASTER nlattr[NDA_MASTER, int32]
NDA_LINK_NETNSID nlattr[NDA_LINK_NETNSID, int32]
NDA_SRC_VNI nlattr[NDA_SRC_VNI, int32]
NDA_FLAGS_EXT nlattr[NDA_FLAGS_EXT, flags[ndm_ext_flags, int32]]
NDA_PROTOCOL nlattr[NDA_PROTOCOL, int8]
NDA_NH_ID nlattr[NDA_NH_ID, int32]
NDA_FDB_EXT_ATTRS nlnest[NDA_FDB_EXT_ATTRS, array[br_nda_fdb_pol]]
] [varlen]
br_nda_fdb_pol [
NFEA_ACTIVITY_NOTIFY nlattr[NFEA_ACTIVITY_NOTIFY, int8]
NFEA_DONT_REFRESH nlattr[NFEA_DONT_REFRESH, void]
] [varlen]
nda_cacheinfo {
ndm_confirmed int32
ndm_used int32
ndm_updated int32
ndm_refcnt int32
}
rtnexthop {
rtnh_len int16
rtnh_flags flags[rtnh_flags, int8]
rtnh_hops int8
rtnh_ifindex ifindex
}
ifa_cacheinfo {
ifa_prefered int32
ifa_valid int32
cstamp int32
tstamp int32
}
br_vlan_db_dump_pol [
BRIDGE_VLANDB_DUMP_FLAGS nlattr[BRIDGE_VLANDB_DUMP_FLAGS, flags[br_vlan_dumpflags, int32]]
]
br_vlan_db_policy$container [
BRIDGE_VLANDB_ENTRY nlnest[BRIDGE_VLANDB_ENTRY, br_vlan_db_policy]
] [varlen]
br_vlan_db_policy [
BRIDGE_VLANDB_ENTRY_INFO nlattr[BRIDGE_VLANDB_ENTRY_INFO, bridge_vlan_info]
BRIDGE_VLANDB_ENTRY_RANGE nlattr[BRIDGE_VLANDB_ENTRY_RANGE, int16[BRIDGE_VLAN_INFO_RANGE_BEGIN:BRIDGE_VLAN_INFO_RANGE_END]]
BRIDGE_VLANDB_ENTRY_STATE nlattr[BRIDGE_VLANDB_ENTRY_STATE, flags[br_vlan_state_options, int8]]
BRIDGE_VLANDB_ENTRY_TUNNEL_INFO nlnest[BRIDGE_VLANDB_ENTRY_TUNNEL_INFO, br_vlandb_tinfo_pol]
BRIDGE_VLANDB_ENTRY_MCAST_ROUTER nlattr[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER, int8]
] [varlen]
bridge_vlan_info {
flags flags[br_vlan_info_flags, int16]
vid int16[0:4]
}
br_vlandb_tinfo_pol [
BRIDGE_VLANDB_TINFO_ID nlattr[BRIDGE_VLANDB_TINFO_ID, int32]
BRIDGE_VLANDB_TINFO_CMD nlattr[BRIDGE_VLANDB_TINFO_CMD, flags[br_vlan_tinfo_cmd, int32]]
] [varlen]
br_mdb_policy [
MDBA_SET_ENTRY nlattr[MDBA_SET_ENTRY, br_mdb_entry]
]
br_mdb_entry {
ifindex ifindex
state flags[br_mdb_entry_state, int8]
flags flags[br_mdb_entry_flags, int8]
vid int16[0:4]
addr br_mdb_entry_sub
}
br_mdb_entry_sub {
u br_mdb_entry_sub_u
proto flags[br_mdb_entry_sub_proto, int16be]
}
br_mdb_entry_sub_u [
ip4 ipv4_addr
in6_addr ipv6_addr
]
type rtm_nh_id int32[0:2]
rtm_nh_policy_get [
NHA_ID nlattr[NHA_ID, rtm_nh_id]
NHA_OIF nlattr[NHA_OIF, ifindex]
NHA_GROUPS nlattr[NHA_GROUPS, void]
NHA_MASTER nlattr[NHA_MASTER, rtm_nh_id]
NHA_FDB nlattr[NHA_FDB, void]
] [varlen]
rtm_nh_policy_new [
NHA_ID nlattr[NHA_ID, rtm_nh_id]
NHA_GROUP nlattr[NHA_GROUP, array[nexthop_grp]]
NHA_GROUP_TYPE nlattr[NHA_GROUP_TYPE, flags[nha_group_types, int16]]
NHA_BLACKHOLE nlattr[NHA_BLACKHOLE, void]
NHA_OIF nlattr[NHA_OIF, ifindex]
NHA_GATEWAY nlattr[NHA_GATEWAY, nha_gateway]
NHA_ENCAP_TYPE nlattr[NHA_ENCAP_TYPE, flags[lwtunnel_encap_types, int16]]
NHA_ENCAP nlnest[NHA_ENCAP, lwtunnel_policy]
NHA_FDB nlattr[NHA_FDB, void]
NHA_RES_GROUP nlnest[NHA_RES_GROUP, array[rtm_nh_res_policy_new]]
] [varlen]
type rtm_nh_policy_del nlattr[NHA_ID, rtm_nh_id]
rtm_nh_res_policy_new [
NHA_RES_GROUP_BUCKETS nlattr[NHA_RES_GROUP_BUCKETS, int16]
NHA_RES_GROUP_IDLE_TIMER nlattr[NHA_RES_GROUP_IDLE_TIMER, int32]
NHA_RES_GROUP_UNBALANCED_TIMER nlattr[NHA_RES_GROUP_UNBALANCED_TIMER, int32]
] [varlen]
nexthop_grp {
id int32[0:2]
weight int8
resvd1 const[0, int8]
resvd2 const[0, int16]
}
nha_gateway [
ip4 ipv4_addr
in6_addr ipv6_addr
]
devconf_ipv4_policy [
NETCONFA_IFINDEX nlattr[NETCONFA_IFINDEX, ifindex]
NETCONFA_FORWARDING nlattr[NETCONFA_FORWARDING, int32]
NETCONFA_RP_FILTER nlattr[NETCONFA_RP_FILTER, int32]
NETCONFA_PROXY_NEIGH nlattr[NETCONFA_PROXY_NEIGH, int32]
IGNORE_ROUTES_WITH_LINKDOWN nlattr[NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN, int32]
] [varlen]
devconf_mpls_policy [
NETCONFA_IFINDEX nlattr[NETCONFA_IFINDEX, ifindex]
IGNORE_ROUTES_WITH_LINKDOWN nlattr[NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN, int32]
] [varlen]
ifla_vf_policy [
IFLA_VF_MAC nlattr[IFLA_VF_MAC, ifla_vf_mac]
IFLA_VF_VLAN nlattr[IFLA_VF_VLAN, ifla_vf_vlan]
IFLA_VF_VLAN_LIST nlnest[IFLA_VF_VLAN_LIST, array[nlattr[IFLA_VF_VLAN_INFO, ifla_vf_vlan_info]]]
IFLA_VF_TX_RATE nlattr[IFLA_VF_TX_RATE, ifla_vf_tx_rate]
IFLA_VF_SPOOFCHK nlattr[IFLA_VF_SPOOFCHK, ifla_vf_spoofchk]
IFLA_VF_RATE nlattr[IFLA_VF_RATE, ifla_vf_rate]
IFLA_VF_LINK_STATE nlattr[IFLA_VF_LINK_STATE, ifla_vf_link_state]
IFLA_VF_RSS_QUERY_EN nlattr[IFLA_VF_RSS_QUERY_EN, ifla_vf_rss_query_en]
IFLA_VF_TRUST nlattr[IFLA_VF_TRUST, ifla_vf_trust]
IFLA_VF_IB_NODE_GUID nlattr[IFLA_VF_IB_NODE_GUID, ifla_vf_guid]
IFLA_VF_IB_PORT_GUID nlattr[IFLA_VF_IB_PORT_GUID, ifla_vf_guid]
] [varlen]
ifla_vf_mac {
vf int32
mac mac_addr
pad array[const[0, int8], 26]
}
ifla_vf_vlan {
vf int32
vlan int32[0:4095]
qos int32
}
ifla_vf_tx_rate {
vf int32
rate int32
}
ifla_vf_rate {
vf int32
min_tx_rate int32
max_tx_rate int32
}
ifla_vf_spoofchk {
vf int32
setting int32
}
ifla_vf_guid {
vf int32
guid int64
}
ifla_vf_link_state {
vf int32
link_state int32
}
ifla_vf_rss_query_en {
vf int32
setting int32
}
ifla_vf_trust {
vf int32
setting int32
}
ifla_vf_vlan_info {
vf int32
vlan int32[0:4095]
qos int32
vlan_proto flags[vlan_proto, int16be]
}
ifla_port_policy [
IFLA_PORT_VF nlattr[IFLA_PORT_VF, int32]
IFLA_PORT_PROFILE nlattr[IFLA_PORT_PROFILE, string]
IFLA_PORT_INSTANCE_UUID nlattr[IFLA_PORT_INSTANCE_UUID, uuid_t]
IFLA_PORT_HOST_UUID nlattr[IFLA_PORT_HOST_UUID, uuid_t]
IFLA_PORT_REQUEST nlattr[IFLA_PORT_REQUEST, int8]
] [varlen]
ifla_xdp_policy [
IFLA_XDP_FD nlattr[IFLA_XDP_FD, fd_bpf_prog]
IFLA_XDP_FLAGS nlattr[IFLA_XDP_FLAGS, flags[ifla_xdp_flags, int32]]
IFLA_XDP_EXPECTED_FD nlattr[IFLA_XDP_EXPECTED_FD, fd_bpf_prog]
] [varlen]
ifla_xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST, XDP_FLAGS_SKB_MODE, XDP_FLAGS_DRV_MODE, XDP_FLAGS_HW_MODE
rtnl_link_ifmap {
mem_start int64
mem_end int64
base_addr int64
irq int16
dma int8
port int8
}
rtnl_net_policy [
NETNSA_NSID nlattr[NETNSA_NSID, netns_id]
NETNSA_PID nlattr[NETNSA_PID, pid]
NETNSA_FD nlattr[NETNSA_FD, fd_namespace]
] [varlen]
rtcanmsg {
can_family const[AF_CAN, int8]
gwtype const[CGW_TYPE_CAN_CAN, int8]
flags flags[rtcanmsg_flags, int16]
}
rtcanmsg_flags = CGW_FLAGS_CAN_ECHO, CGW_FLAGS_CAN_SRC_TSTAMP, CGW_FLAGS_CAN_IIF_TX_OK
lwtunnel_policy [
MPLS_IPTUNNEL_DST nlattr[MPLS_IPTUNNEL_DST, array[mpls_label]]
MPLS_IPTUNNEL_TTL nlattr[MPLS_IPTUNNEL_TTL, int8]
LWTUNNEL_IP_ID nlattr[LWTUNNEL_IP_ID, int64be]
LWTUNNEL_IP_DST nlattr[LWTUNNEL_IP_DST, ipv4_addr]
LWTUNNEL_IP_SRC nlattr[LWTUNNEL_IP_SRC, ipv4_addr]
LWTUNNEL_IP_TTL nlattr[LWTUNNEL_IP_TTL, int8]
LWTUNNEL_IP_TOS nlattr[LWTUNNEL_IP_TOS, int8]
LWTUNNEL_IP_FLAGS nlattr[LWTUNNEL_IP_FLAGS, flags[lwtunnel_ip_flags, int16be]]
LWTUNNEL_IP_OPTS nlnest[LWTUNNEL_IP_OPTS, ip_opts_policy]
ILA_ATTR_LOCATOR nlattr[ILA_ATTR_LOCATOR, int64be]
ILA_ATTR_CSUM_MODE nlattr[ILA_ATTR_CSUM_MODE, flags[ila_attr_csum_mode, int8]]
ILA_ATTR_IDENT_TYPE nlattr[ILA_ATTR_IDENT_TYPE, flags[ila_attr_ident_type, int8]]
ILA_ATTR_HOOK_TYPE nlattr[ILA_ATTR_HOOK_TYPE, flags[ila_attr_hook_type, int8]]
LWTUNNEL_IP6_ID nlattr[LWTUNNEL_IP6_ID, int64be]
LWTUNNEL_IP6_DST nlattr[LWTUNNEL_IP6_DST, ipv6_addr]
LWTUNNEL_IP6_SRC nlattr[LWTUNNEL_IP6_SRC, ipv6_addr]
LWTUNNEL_IP6_HOPLIMIT nlattr[LWTUNNEL_IP6_HOPLIMIT, int8]
LWTUNNEL_IP6_TC nlattr[LWTUNNEL_IP6_TC, int8]
LWTUNNEL_IP6_FLAGS nlattr[LWTUNNEL_IP6_FLAGS, flags[lwtunnel_ip_flags, int16be]]
LWTUNNEL_IP6_OPTS nlattr[LWTUNNEL_IP6_OPTS, ip_opts_policy]
SEG6_IPTUNNEL_SRH nlattr[SEG6_IPTUNNEL_SRH, seg6_tuninfo]
LWT_BPF_IN nlnest[LWT_BPF_IN, bpf_prog_policy]
LWT_BPF_OUT nlnest[LWT_BPF_OUT, bpf_prog_policy]
LWT_BPF_XMIT nlnest[LWT_BPF_XMIT, bpf_prog_policy]
LWT_BPF_XMIT_HEADROOM nlattr[LWT_BPF_XMIT_HEADROOM, int32[0:LWT_BPF_MAX_HEADROOM]]
SEG6_LOCAL_ACTION nlattr[SEG6_LOCAL_ACTION, int32[SEG6_LOCAL_ACTION_END:SEG6_LOCAL_ACTION_END_BPF]]
SEG6_LOCAL_SRH nlattr[SEG6_LOCAL_SRH, ipv6_sr_hdr]
SEG6_LOCAL_TABLE nlattr[SEG6_LOCAL_TABLE, int32]
SEG6_LOCAL_NH4 nlattr[SEG6_LOCAL_NH4, ipv4_addr]
SEG6_LOCAL_NH6 nlattr[SEG6_LOCAL_NH6, ipv6_addr]
SEG6_LOCAL_IIF nlattr[SEG6_LOCAL_IIF, int32]
SEG6_LOCAL_OIF nlattr[SEG6_LOCAL_OIF, int32]
SEG6_LOCAL_BPF nlnest[SEG6_LOCAL_BPF, bpf_prog_policy$seg6_local]
RPL_IPTUNNEL_SRH nlattr[RPL_IPTUNNEL_SRH, ipv6_rpl_sr_hdr]
] [varlen]
# 5832c4a77d693 ("ip_tunnel: convert __be16 tunnel flags to bitmaps") put the constants below
# behind #ifndef __KERNEL__, so they cannot be extracted anymore.
define TUNNEL_GENEVE_OPT __cpu_to_be16(0x0800)
define TUNNEL_VXLAN_OPT __cpu_to_be16(0x1000)
define TUNNEL_ERSPAN_OPT __cpu_to_be16(0x4000)
lwtunnel_ip_flags = TUNNEL_GENEVE_OPT, TUNNEL_VXLAN_OPT, TUNNEL_ERSPAN_OPT
ip_opts_policy [
LWTUNNEL_IP_OPTS_GENEVE nlnest[LWTUNNEL_IP_OPTS_GENEVE, geneve_opt_policy$lwt]
LWTUNNEL_IP_OPTS_VXLAN nlnest[LWTUNNEL_IP_OPTS_VXLAN, vxlan_opt_policy$lwt]
LWTUNNEL_IP_OPTS_ERSPAN nlnest[LWTUNNEL_IP_OPTS_ERSPAN, erspan_opt_policy$lwt]
] [varlen]
geneve_opt_policy$lwt [
LWTUNNEL_IP_OPT_GENEVE_CLASS nlattr[LWTUNNEL_IP_OPT_GENEVE_CLASS, int16be]
LWTUNNEL_IP_OPT_GENEVE_TYPE nlattr[LWTUNNEL_IP_OPT_GENEVE_TYPE, int8]
LWTUNNEL_IP_OPT_GENEVE_DATA nlattr[LWTUNNEL_IP_OPT_GENEVE_DATA, array[int8, 0:128]]
] [varlen]
vxlan_opt_policy$lwt [
LWTUNNEL_IP_OPT_VXLAN_GBP nlattr[LWTUNNEL_IP_OPT_VXLAN_GBP, int32]
] [varlen]
erspan_opt_policy$lwt [
LWTUNNEL_IP_OPT_ERSPAN_VER nlattr[LWTUNNEL_IP_OPT_ERSPAN_VER, int8[1:2]]
LWTUNNEL_IP_OPT_ERSPAN_INDEX nlattr[LWTUNNEL_IP_OPT_ERSPAN_INDEX, int32be]
LWTUNNEL_IP_OPT_ERSPAN_DIR nlattr[LWTUNNEL_IP_OPT_ERSPAN_DIR, int8]
LWTUNNEL_IP_OPT_ERSPAN_HWID nlattr[LWTUNNEL_IP_OPT_ERSPAN_HWID, int8]
] [varlen]
bpf_prog_policy [
LWT_BPF_PROG_FD nlattr[LWT_BPF_PROG_FD, fd_bpf_prog]
LWT_BPF_PROG_NAME nlattr[LWT_BPF_PROG_NAME, string]
] [varlen]
bpf_prog_policy$seg6_local [
SEG6_LOCAL_BPF_PROG nlattr[SEG6_LOCAL_BPF_PROG, fd_bpf_prog]
SEG6_LOCAL_BPF_PROG_NAME nlattr[SEG6_LOCAL_BPF_PROG_NAME, string]
] [varlen]
ipv6_rpl_sr_hdr {
nexthdr int8
hdrlen len[parent, int8]
type const[RPL_IPTUNNEL_SRH, int8]
segments_left int8
control int32
address array[ipv6_addr]
} [packed]
ila_attr_csum_mode = ILA_CSUM_ADJUST_TRANSPORT, ILA_CSUM_NEUTRAL_MAP, ILA_CSUM_NO_ACTION, ILA_CSUM_NEUTRAL_MAP_AUTO
# TODO: describe remaining when supported
ila_attr_ident_type = ILA_ATYPE_IID, ILA_ATYPE_LUID, ILA_ATYPE_USE_FORMAT
ila_attr_hook_type = ILA_HOOK_ROUTE_INPUT, ILA_HOOK_ROUTE_OUTPUT
seg6_tuninfo {
tuninfo seg6_iptunnel_encap
segments array[ipv6_addr, 0:128]
} [packed]
seg6_iptunnel_encap {
mode flags[seg6_iptun_mode, int32]
srh ipv6_sr_hdr
}
seg6_iptun_mode = SEG6_IPTUN_MODE_INLINE, SEG6_IPTUN_MODE_ENCAP, SEG6_IPTUN_MODE_L2ENCAP
cgw_policy [
CGW_MOD_AND nlattr[CGW_MOD_AND, cgw_frame_mod]
CGW_MOD_OR nlattr[CGW_MOD_OR, cgw_frame_mod]
CGW_MOD_XOR nlattr[CGW_MOD_XOR, cgw_frame_mod]
CGW_MOD_SET nlattr[CGW_MOD_SET, cgw_frame_mod]
CGW_CS_XOR nlattr[CGW_CS_XOR, cgw_csum_xor]
CGW_CS_CRC8 nlattr[CGW_CS_CRC8, cgw_csum_crc8]
CGW_SRC_IF nlattr[CGW_SRC_IF, ifindex_vcan]
CGW_DST_IF nlattr[CGW_DST_IF, ifindex_vcan]
CGW_FILTER nlattr[CGW_FILTER, can_filter]
CGW_LIM_HOPS nlattr[CGW_LIM_HOPS, int8]
CGW_MOD_UID nlattr[CGW_MOD_UID, uid]
] [varlen]
cgw_frame_mod {
cf can_frame
modtype flags[cgw_frame_modtype, int8]
} [packed]
cgw_frame_modtype = CGW_MOD_ID, CGW_MOD_DLC, CGW_MOD_DATA
cgw_csum_xor {
from_idx int8[-9:8]
to_idx int8[-9:8]
result_idx int8[-9:8]
init_xor_val int8
} [packed]
cgw_csum_crc8 {
from_idx int8[0:127]
to_idx int8[0:127]
result_idx int8[0:127]
init_crc_val int8
final_xor_val int8
crctab array[int8, 256]
profile flags[cgw_csum_crc8_profile, int8]
profile_data array[int8, 20]
} [packed]
cgw_csum_crc8_profile = CGW_CRC8PRF_UNSPEC, CGW_CRC8PRF_1U8, CGW_CRC8PRF_16U8, CGW_CRC8PRF_SFFID_XOR
rtnl_af = AF_INET, AF_INET6, AF_BRIDGE, AF_MPLS
net_device_flags = IFF_UP, IFF_BROADCAST, IFF_DEBUG, IFF_LOOPBACK, IFF_POINTOPOINT, IFF_NOTRAILERS, IFF_RUNNING, IFF_NOARP, IFF_PROMISC, IFF_ALLMULTI, IFF_MASTER, IFF_SLAVE, IFF_MULTICAST, IFF_PORTSEL, IFF_AUTOMEDIA, IFF_DYNAMIC, IFF_LOWER_UP, IFF_DORMANT, IFF_ECHO
ifa_flags = IFA_F_MANAGETEMPADDR, IFA_F_NOPREFIXROUTE, IFA_F_MCAUTOJOIN, ifa_flags8
ifa_flags8 = IFA_F_SECONDARY, IFA_F_NODAD, IFA_F_OPTIMISTIC, IFA_F_DADFAILED, IFA_F_HOMEADDRESS, IFA_F_DEPRECATED, IFA_F_TENTATIVE, IFA_F_PERMANENT
rt_scope_t = RT_SCOPE_UNIVERSE, RT_SCOPE_SITE, RT_SCOPE_LINK, RT_SCOPE_HOST, RT_SCOPE_NOWHERE
rtm_protocol = RTPROT_UNSPEC, RTPROT_REDIRECT, RTPROT_KERNEL, RTPROT_BOOT, RTPROT_STATIC
rtm_type = RTN_UNSPEC, RTN_UNICAST, RTN_LOCAL, RTN_BROADCAST, RTN_ANYCAST, RTN_MULTICAST, RTN_BLACKHOLE, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_THROW, RTN_NAT, RTN_XRESOLVE
rtm_flags = RTM_F_NOTIFY, RTM_F_CLONED, RTM_F_EQUALIZE, RTM_F_PREFIX, RTM_F_LOOKUP_TABLE, RTM_F_FIB_MATCH
fr_actions = FR_ACT_UNSPEC, FR_ACT_TO_TBL, FR_ACT_GOTO, FR_ACT_NOP, FR_ACT_RES3, FR_ACT_RES4, FR_ACT_BLACKHOLE, FR_ACT_UNREACHABLE, FR_ACT_PROHIBIT
fr_flags = FIB_RULE_PERMANENT, FIB_RULE_INVERT, FIB_RULE_UNRESOLVED, FIB_RULE_IIF_DETACHED, FIB_RULE_OIF_DETACHED, FIB_RULE_FIND_SADDR
lwtunnel_encap_types = LWTUNNEL_ENCAP_NONE, LWTUNNEL_ENCAP_MPLS, LWTUNNEL_ENCAP_IP, LWTUNNEL_ENCAP_ILA, LWTUNNEL_ENCAP_IP6, LWTUNNEL_ENCAP_SEG6, LWTUNNEL_ENCAP_BPF, LWTUNNEL_ENCAP_SEG6_LOCAL, LWTUNNEL_ENCAP_RPL
rt_table_types = RT_TABLE_UNSPEC, RT_TABLE_COMPAT, RT_TABLE_DEFAULT, RT_TABLE_MAIN, RT_TABLE_LOCAL
ndm_state = NUD_INCOMPLETE, NUD_REACHABLE, NUD_STALE, NUD_DELAY, NUD_PROBE, NUD_FAILED, NUD_NOARP, NUD_PERMANENT, NUD_NONE
ndm_flags = NTF_USE, NTF_SELF, NTF_MASTER, NTF_PROXY, NTF_EXT_LEARNED, NTF_OFFLOADED, NTF_STICKY, NTF_ROUTER
ndm_ext_flags = NTF_EXT_MANAGED
ifa_prefixlen = 0, 1, 8, 16, 24, 31, 32, 56, 63, 64, 120, 128
rtm_addr_len = 0, 16, 20, 32, 128
filter_mask = IFLA_STATS_UNSPEC, IFLA_STATS_LINK_64, IFLA_STATS_LINK_XSTATS, IFLA_STATS_LINK_XSTATS_SLAVE, IFLA_STATS_LINK_OFFLOAD_XSTATS, IFLA_STATS_AF_SPEC
tunnel_encap_types = TUNNEL_ENCAP_NONE, TUNNEL_ENCAP_FOU, TUNNEL_ENCAP_GUE, TUNNEL_ENCAP_MPLS
ifal_labels = 0, 1, 2, 3, 4, 5, 6, 7, 11, 12
br_vlan_dumpflags = BRIDGE_VLANDB_DUMPF_STATS
br_vlan_state_options = BR_STATE_DISABLED, BR_STATE_LISTENING, BR_STATE_LEARNING, BR_STATE_FORWARDING, BR_STATE_BLOCKING
br_vlan_info_flags = BRIDGE_VLAN_INFO_MASTER, BRIDGE_VLAN_INFO_PVID, BRIDGE_VLAN_INFO_UNTAGGED, BRIDGE_VLAN_INFO_RANGE_BEGIN, BRIDGE_VLAN_INFO_RANGE_END, BRIDGE_VLAN_INFO_BRENTRY, BRIDGE_VLAN_INFO_ONLY_OPTS
br_vlan_tinfo_cmd = RTM_SETLINK, RTM_DELLINK
br_mdb_entry_state = MDB_TEMPORARY, MDB_PERMANENT
br_mdb_entry_flags = MDB_FLAGS_OFFLOAD, MDB_FLAGS_FAST_LEAVE
br_mdb_entry_sub_proto = ETH_P_IP, ETH_P_IPV6
rtnh_flags = RTNH_F_DEAD, RTNH_F_PERVASIVE, RTNH_F_ONLINK, RTNH_F_OFFLOAD, RTNH_F_LINKDOWN, RTNH_F_UNRESOLVED
nha_group_types = NEXTHOP_GRP_TYPE_MPATH, NEXTHOP_GRP_TYPE_RES
]
|
| 57/2 |
2026/03/11 08:10 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 128460
output: 21
thoughts: 169
Thoughts: **Analyzing the Netlink Route Sending Function**
Okay, so I'm looking at `sendmsg$nl_route` and it's defined, good. I see it takes a file descriptor, the message itself as a `msghdr_netlink` which contains a `netlink_msg_route`, and then some send flags. Right, that makes sense. Now, `netlink_msg_route`… ah, it has a `getlink` member. And *that* is a `netlink_msg` containing `RTM_GETLINK`, an `ifinfomsg` struct (with `AF_UNSPEC`, interesting), and an `ifla_policy`.
So, the next thought is, if I send an `RTM_GETLINK` request and set the `NLM_F_ACK` flag, I'm expecting an acknowledgement message in return. That's the typical pattern, and it's what I want for robust communication. Ah, yes, `NLM_F_ACK` is, of course, part of the `nlmsg_flags`. I need to confirm this quickly. Let's refer to `socket_netlink.txt` for a quick and thorough check on how `nlmsg_flags` are defined, as it holds the key for how the `NLM_F_ACK` is structured within the overall message. I'll make sure it's all configured correctly.
|
| 58/2 |
2026/03/11 08:10 |
tool |
read-description |
0m
Args: map[File:socket_netlink.txt]
Results: map[Output:# Copyright 2017 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.
# AF_NETLINK support.
include <linux/net.h>
include <uapi/linux/netlink.h>
include <uapi/linux/rtnetlink.h>
resource sock_netlink[sock]
type netlink_seq int32[7388453:7388461]
type netlink_port_id int32[635427835:635427839]
socket$netlink(domain const[AF_NETLINK], type const[SOCK_RAW], proto flags[netlink_proto]) sock_netlink
bind$netlink(fd sock_netlink, addr ptr[in, sockaddr_nl_proc], addrlen len[addr])
connect$netlink(fd sock_netlink, addr ptr[in, sockaddr_nl], addrlen len[addr])
getsockname$netlink(fd sock_netlink, addr ptr[out, sockaddr_nl_unspec], addrlen ptr[inout, len[addr, int32]])
getpeername$netlink(fd sock_netlink, peer ptr[out, sockaddr_nl_unspec], peerlen ptr[inout, len[peer, int32]])
sendmsg$netlink(fd sock_netlink, msg ptr[in, msghdr_netlink_generic], f flags[send_flags])
setsockopt$netlink_NETLINK_ADD_MEMBERSHIP(fd sock_netlink, level const[SOL_NETLINK], opt const[NETLINK_ADD_MEMBERSHIP], arg ptr[in, int32[0:31]], arglen len[arg])
setsockopt$netlink_NETLINK_DROP_MEMBERSHIP(fd sock_netlink, level const[SOL_NETLINK], opt const[NETLINK_DROP_MEMBERSHIP], arg ptr[in, int32[0:31]], arglen len[arg])
setsockopt$netlink_NETLINK_PKTINFO(fd sock_netlink, level const[SOL_NETLINK], opt const[NETLINK_PKTINFO], arg ptr[in, int32], arglen len[arg])
setsockopt$netlink_NETLINK_BROADCAST_ERROR(fd sock_netlink, level const[SOL_NETLINK], opt const[NETLINK_BROADCAST_ERROR], arg ptr[in, int32], arglen len[arg])
setsockopt$netlink_NETLINK_NO_ENOBUFS(fd sock_netlink, level const[SOL_NETLINK], opt const[NETLINK_NO_ENOBUFS], arg ptr[in, int32], arglen len[arg])
setsockopt$netlink_NETLINK_RX_RING(fd sock_netlink, level const[SOL_NETLINK], opt const[NETLINK_RX_RING], arg ptr[in, nl_mmap_req], arglen len[arg])
setsockopt$netlink_NETLINK_TX_RING(fd sock_netlink, level const[SOL_NETLINK], opt const[NETLINK_TX_RING], arg ptr[in, nl_mmap_req], arglen len[arg])
setsockopt$netlink_NETLINK_LISTEN_ALL_NSID(fd sock_netlink, level const[SOL_NETLINK], opt const[NETLINK_LISTEN_ALL_NSID], arg ptr[in, int32], arglen len[arg])
setsockopt$netlink_NETLINK_CAP_ACK(fd sock_netlink, level const[SOL_NETLINK], opt const[NETLINK_CAP_ACK], arg ptr[in, int32], arglen len[arg])
getsockopt$netlink(fd sock_netlink, level const[SOL_NETLINK], opt flags[netlink_sockopts], arg buffer[out], arglen ptr[inout, len[arg, int32]])
netlink_proto = NETLINK_ROUTE, NETLINK_UNUSED, NETLINK_USERSOCK, NETLINK_SOCK_DIAG, NETLINK_NFLOG, NETLINK_XFRM, NETLINK_SELINUX, NETLINK_ISCSI, NETLINK_AUDIT, NETLINK_FIB_LOOKUP, NETLINK_CONNECTOR, NETLINK_NETFILTER, NETLINK_DNRTMSG, NETLINK_KOBJECT_UEVENT, NETLINK_GENERIC, NETLINK_SCSITRANSPORT, NETLINK_ECRYPTFS, NETLINK_RDMA, NETLINK_CRYPTO, NETLINK_INET_DIAG
netlink_sockopts = NETLINK_ADD_MEMBERSHIP, NETLINK_DROP_MEMBERSHIP, NETLINK_PKTINFO, NETLINK_BROADCAST_ERROR, NETLINK_NO_ENOBUFS, NETLINK_RX_RING, NETLINK_TX_RING, NETLINK_LISTEN_ALL_NSID, NETLINK_LIST_MEMBERSHIPS, NETLINK_CAP_ACK
netlink_msg_flags = NLM_F_REQUEST, NLM_F_MULTI, NLM_F_ACK, NLM_F_ECHO, NLM_F_DUMP_INTR, NLM_F_DUMP_FILTERED, NLM_F_ROOT, NLM_F_MATCH, NLM_F_ATOMIC, NLM_F_DUMP, NLM_F_REPLACE, NLM_F_EXCL, NLM_F_CREATE, NLM_F_APPEND
netlink_group_bitmap = 0x0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000
sockaddr_nl [
kern sockaddr_nl_kern
proc sockaddr_nl_proc
unspec sockaddr_nl_unspec
]
sockaddr_nl_send [
kern sockaddr_nl_kern
proc sockaddr_nl_proc
]
type sockaddr_nl_t[FAMILY, PID, GROUPS] {
nl_family const[FAMILY, int16]
nl_pad const[0, int16]
nl_pid PID
nl_groups GROUPS
}
type sockaddr_nl_proc sockaddr_nl_t[AF_NETLINK, netlink_port_id, flags[netlink_group_bitmap, int32]]
type sockaddr_nl_kern sockaddr_nl_t[AF_NETLINK, const[0, int32], flags[netlink_group_bitmap, int32]]
type sockaddr_nl_unspec sockaddr_nl_t[AF_UNSPEC, const[0, int32], const[0, int32]]
type msghdr_netlink_full[MSG] {
addr ptr[in, sockaddr_nl_send, opt]
addrlen len[addr, int32]
vec ptr[in, array[iovec[in, MSG]]]
vlen len[vec, intptr]
ctrl ptr[in, array[cmsghdr_un], opt]
ctrllen bytesize[ctrl, intptr]
f flags[send_flags, int32]
}
# Simplified version of msghdr_netlink_full with kernel address, no control data and only 1 iovec.
# It's enough for most protocols.
type msghdr_netlink[MSG] {
addr ptr[in, sockaddr_nl_kern]
addrlen len[addr, int32]
vec ptr[in, iovec[in, MSG]]
vlen const[1, intptr]
ctrl const[0, intptr]
ctrllen const[0, intptr]
f flags[send_flags, int32]
}
# No body. Generic attribute can represent a random body.
type msghdr_netlink_generic msghdr_netlink_full[netlink_msg_t[netlink_random_msg_type, void, nl_generic_attr]]
type netlink_msg_t[TYPE, PAYLOAD, ATTRS] {
len len[parent, int32]
type TYPE
flags flags[netlink_msg_flags, int16]
seq netlink_seq
pid netlink_port_id
payload PAYLOAD
attrs array[ATTRS]
} [packed, align[4]]
type netlink_msg[TYPE, PAYLOAD, ATTRS] netlink_msg_t[const[TYPE, int16], PAYLOAD, ATTRS]
type nlattr_t[TYPE, PAYLOAD] {
nla_len offsetof[size, int16]
nla_type TYPE
payload PAYLOAD
size void
} [packed, align[4]]
type nlattr_tt[TYPE, NETORDER, NESTED, PAYLOAD] {
nla_len offsetof[size, int16]
nla_type TYPE
NLA_F_NET_BYTEORDER const[NETORDER, int16:1]
NLA_F_NESTED const[NESTED, int16:1]
payload PAYLOAD
size void
} [packed, align[4]]
type nlattr[TYPE, PAYLOAD] nlattr_t[const[TYPE, int16], PAYLOAD]
# nlattr with NLA_F_NESTED set.
type nlnest[TYPE, PAYLOAD] nlattr_tt[const[TYPE, int16:14], 0, 1, PAYLOAD]
# nlattr with NLA_F_NET_BYTEORDER set (unused for now).
type nlnetw[TYPE, PAYLOAD] nlattr_tt[const[TYPE, int16:14], 1, 0, PAYLOAD]
# NL80211 has probably the biggest number of netlink attributes.
include <include/uapi/linux/nl80211.h>
define NETLINK_MAX_ATTRIBUTES NL80211_ATTR_MAX
nl_generic_attr [
generic array[int8]
typed nlattr_tt[int16:14[0:NETLINK_MAX_ATTRIBUTES], 0, 0, nl_generic_attr_data]
nested nlattr_tt[int16:14[0:NETLINK_MAX_ATTRIBUTES], 0, 1, array[nl_generic_attr]]
] [varlen]
nl_generic_attr_data [
void void
u32 int32
u64 int64
ipv4 ipv4_addr
ipv6 ipv6_addr
fd fd
pid pid
uid uid
str string
binary array[int8]
] [varlen]
type nla_bitfield32[FLAGS] {
value flags[FLAGS, int32]
selector flags[FLAGS, int32]
}
nl_mmap_req {
bsize int32
bnumber int32
fsize int32
fnumber int32
}
# Removed (if __KERNEL__ defined) in next-20160229 (commit d1b4c689)
define NETLINK_RX_RING 6
define NETLINK_TX_RING 7
# Some approximation for protocols for which we don't have precise descriptions.
define NLMSG_MAX_TYPE NLMSG_MIN_TYPE + 50
type netlink_random_msg_type int16[NLMSG_MIN_TYPE:NLMSG_MAX_TYPE]
]
|
| 59/2 |
2026/03/11 08:10 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 131959
output: 405
thoughts: 1931
Thoughts: **Netlink Message Construction for ACK with RTM_GETLINK**
Alright, let's break this down systematically. I need to construct a `netlink_msg_route` with `NLM_F_ACK` set in the `flags`. First, I confirmed that `netlink_msg_flags` indeed includes `NLM_F_ACK`. Since `netlink_msg_route` is a union, I'm going to leverage `getlink` which is a `netlink_msg` defined as `netlink_msg[RTM_GETLINK, ifinfomsg[AF_UNSPEC], ifla_policy]`. Now, `netlink_msg` is defined as a `netlink_msg_t`.
Looking at `netlink_msg_t`, I see fields like `len`, `type`, `flags`, and `payload`, and the `flags` field is what I need to focus on. My intent is to set the `flags` to `NLM_F_REQUEST` | `NLM_F_ACK`. I verified that `NLM_F_REQUEST` is 1 and `NLM_F_ACK` is 4. I then confirmed the values in the `socket_netlink.txt` file, ensuring I'm using the correct values for bitwise OR. The combination would be `0x5`.
Now, I'm turning my attention to the Syzkaller program.
Here's my attempt:
```
r0 = socket$nl_route(0x10, 0x3, 0x0)
setsockopt$sock_int(r0, 0x1, 0x10, &(0x7f0000000000)=0x1, 0x4)
sendmsg$nl_route(r0, &(0x7f0000000040)={&(0x7f0000000080)={0x10, 0x0, 0x0, 0x0}, 0xc, &(0x7f00000000c0)={&(0x7f0000000100)=@getlink={0x10, 0x12, 0x5, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, []}, 0x10}, 0x1, 0x0, 0x0, 0x0}, 0x0)
recvmsg(r0, &(0x7f0000000140)={0x0, 0x0, &(0x7f0000000180)=[{&(0x7f00000001c0)=""/1024, 0x400}], 0x1, &(0x7f00000005c0)=""/1024, 0x400, 0x0}, 0x0)
```
I need to confirm all the structures. I see that `sendmsg$nl_route` expects a `msghdr_netlink` message. Looking at its definition, I see the expected fields: `addr`, `addrlen`, `vec`, `vlen`, `ctrl`, `ctrllen`, and `f`. So, I check:
```
&(0x7f0000000040)={&(0x7f0000000080)={0x10, 0x0, 0x0, 0x0}, 0xc, &(0x7f00000000c0)={&(0x7f0000000100)=@getlink={0x10, 0x12, 0x5, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, []}, 0x10}, 0x1, 0x0, 0x0, 0x0}
```
Now, focusing on `getlink`. It's a `netlink_msg[RTM_GETLINK, ifinfomsg[AF_UNSPEC], ifla_policy]`. `RTM_GETLINK` is 1
|
| 60/2 |
2026/03/11 08:11 |
tool |
reproduce-crash |
0m
Args: map[ReproSyz:r0 = socket$nl_route(0x10, 0x3, 0x0)
setsockopt$sock_int(r0, 0x1, 0x10, &(0x7f0000000000)=0x1, 0x4)
sendmsg$nl_route(r0, &(0x7f0000000040)={&(0x7f0000000080)={0x10, 0x0, 0x0, 0x0}, 0xc, &(0x7f00000000c0)={&(0x7f0000000100)=@getlink={AUTO, 0x12, 0x5, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, []}, AUTO}, 0x1, 0x0, 0x0, 0x0}, 0x0)
recvmsg(r0, &(0x7f0000000140)={0x0, 0x0, &(0x7f0000000180)=[{&(0x7f00000001c0)=""/1024, 0x400}], 0x1, &(0x7f00000005c0)=""/1024, 0x400, 0x0}, 0x0)
]
Results: map[ReproducedBugTitle: ReproducedCrashReport:]
|
| 61/2 |
2026/03/11 08:11 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 135345
output: 44
thoughts: 364
Thoughts: **Debugging a Netlink Crash That Didn't Happen**
Okay, so the expected crash didn't happen. That's... interesting. Let's dig in. First, a quick sanity check: is there a chance I've misremembered some constant value, like maybe `NLM_F_ACK` isn't actually 4? Nope, checked, it *is* 4, and `NLM_F_REQUEST` is 1, so the combination `0x5` is definitely correct for what I was trying to do.
But wait, `NLM_F_ACK` means it *should* be generating an ACK message. Does `netlink_ack` itself allocate a new socket buffer (`skb`)? Yes, it does. Okay, does it initialize the credentials within the control block (`NETLINK_CB(skb).creds`)? No. And that's where things get interesting.
When `recvmsg` gets called later, I remember the code doing something with those credentials. Let me check... Ah, here it is, inside `netlink_recvmsg`:
```c
memset(&scm, 0, sizeof(scm));
scm.creds = *NETLINK_CREDS(skb);
```
Okay, so `NETLINK_CREDS(skb)` is just a macro for `&NETLINK_CB((skb)).creds`. If the `NETLINK_CB(skb).creds` struct is uninitialized, then `scm.creds` ends up uninitialized. The problem I initially anticipated was the uninitialized `scm.creds` being used.
But wait a minute! `nlmsg_new` calls `alloc_skb`. `alloc_skb` allocates memory from a slab cache. The question is: is that memory *initialized* by default? Is the `cb` array zeroed in a slab cache?
The answer is no, and now that is the problem.
But maybe the slab cache *is* zeroed by default, or maybe KMSAN is not correctly tracking the `cb` array as uninitialized. But wait, KMSAN tracks *all* memory, doesn't it? So, if the `cb` is truly uninitialized, KMSAN *should* be yelling at me!
So why didn't it crash? Now, I need to double-check `netlink_ack` again. I need to be sure I'm not overlooking something obvious.
|
| 62/2 |
2026/03/11 08:11 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_ack]
Results: map[SourceCode:2463: void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
2464: const struct netlink_ext_ack *extack)
2465: {
2466: struct sk_buff *skb;
2467: struct nlmsghdr *rep;
2468: struct nlmsgerr *errmsg;
2469: size_t payload = sizeof(*errmsg);
2470: struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk);
2471: unsigned int flags = 0;
2472: size_t tlvlen;
2473:
2474: /* Error messages get the original request appended, unless the user
2475: * requests to cap the error message, and get extra error data if
2476: * requested.
2477: */
2478: if (err && !test_bit(NETLINK_F_CAP_ACK, &nlk->flags))
2479: payload += nlmsg_len(nlh);
2480: else
2481: flags |= NLM_F_CAPPED;
2482:
2483: tlvlen = netlink_ack_tlv_len(nlk, err, extack);
2484: if (tlvlen)
2485: flags |= NLM_F_ACK_TLVS;
2486:
2487: skb = nlmsg_new(payload + tlvlen, GFP_KERNEL);
2488: if (!skb)
2489: goto err_skb;
2490:
2491: rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
2492: NLMSG_ERROR, sizeof(*errmsg), flags);
2493: if (!rep)
2494: goto err_bad_put;
2495: errmsg = nlmsg_data(rep);
2496: errmsg->error = err;
2497: errmsg->msg = *nlh;
2498:
2499: if (!(flags & NLM_F_CAPPED)) {
2500: if (!nlmsg_append(skb, nlmsg_len(nlh)))
2501: goto err_bad_put;
2502:
2503: memcpy(nlmsg_data(&errmsg->msg), nlmsg_data(nlh),
2504: nlmsg_len(nlh));
2505: }
2506:
2507: if (tlvlen)
2508: netlink_ack_tlv_fill(skb, nlh, err, extack);
2509:
2510: nlmsg_end(skb, rep);
2511:
2512: nlmsg_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid);
2513:
2514: return;
2515:
2516: err_bad_put:
2517: nlmsg_free(skb);
2518: err_skb:
2519: WRITE_ONCE(NETLINK_CB(in_skb).sk->sk_err, ENOBUFS);
2520: sk_error_report(NETLINK_CB(in_skb).sk);
2521: }
SourceFile:net/netlink/af_netlink.c]
|
| 63/2 |
2026/03/11 08:11 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 137269
output: 41
thoughts: 37
Thoughts: Here's my summary, as the thought process unfolds:
**Digging into the Netlink Allocation**
Okay, so I'm working with Netlink message creation, and I remember `nlmsg_new` is the function that does the heavy lifting. Now, a key part of that is going to be memory allocation. The obvious suspect is `alloc_skb`, and I vaguely recall it being part of the process.
So, let's confirm that hypothesis, and figure out the exact allocation strategy by quickly checking out `alloc_skb`. I'm going to jump into `net/core/skbuff.c` and see exactly what's happening there with the `skb` allocation. Let's see how much headroom it is adding, and what parameters it is using.
|
| 64/2 |
2026/03/11 08:11 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/skbuff.c IncludeLines:true Name:alloc_skb]
Results: map[SourceCode:1373: /**
1374: * alloc_skb - allocate a network buffer
1375: * @size: size to allocate
1376: * @priority: allocation mask
1377: *
1378: * This function is a convenient wrapper around __alloc_skb().
1379: */
1380: static inline struct sk_buff *alloc_skb(unsigned int size,
1381: gfp_t priority)
1382: {
1383: return __alloc_skb(size, priority, 0, NUMA_NO_NODE);
1384: }
SourceFile:include/linux/skbuff.h]
|
| 65/2 |
2026/03/11 08:11 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 137715
output: 42
thoughts: 11
Thoughts: Okay, here's my attempt at summarizing the thought process, tailored for an expert audience, and written in the first person:
**Diving into the Kernel's Network Memory Allocation**
Alright, time to dig in. The problem's looking like it might be stemming from the network stack, so my first instinct is to zero in on `__alloc_skb`. This function is fundamental; it’s the workhorse for allocating SKBs (Socket Buffers), which are the backbone of packet handling in the kernel. My initial thought process involves a few key aspects:
* **Memory Pool and Fragmentation:** I need to immediately consider how this function interacts with the kernel's memory management. Is it using a slab allocator? Is there a risk of memory fragmentation at this point? Does the function employ pre-allocation strategies or does it allocate the buffers directly? Any potential issue with zone reclaim?
* **Contiguous Memory:** How does `__alloc_skb` handle the need for contiguous physical memory, particularly with larger SKBs? Are there specific flags being used (like `GFP_DMA` or `GFP_ATOMIC`) that might influence the memory allocation behavior? This can have serious implications on DMA transfers.
* **Error Handling:** It’s critical to investigate the error-handling paths. What happens if the allocation fails? Does it return `NULL` gracefully, or does it trigger an unexpected kernel panic or an unrecoverable error? Are there appropriate error codes set to provide debugging information in the event of failure?
* **Context:** Is this being called from interrupt context, process context, or both? This determines the allowable memory allocation flags and how aggressively the function can attempt to find free memory.
* **SKB Initialization:** Assuming it *does* allocate successfully, how is the SKB initialized? Are the header pointers (e.g., `data`, `tail`, `end`, etc.) set correctly? Is the `skb_shared_info` properly initialized? Any missing initialization could lead to crashes down the line during packet processing.
* **Locking:** The function is likely called from multiple threads. I need to figure out which locks protect the critical sections of the function. Is it using a spinlock, a mutex, or another form of synchronization? If it's not correctly protected, there may be race conditions, double frees, or other data corruption bugs.
I'll start tracing the code in `__alloc_skb` itself and trace any called function to look for these details. I have to look into the implementation to understand how it behaves, its assumptions, its limitations, and any possible areas of concern.
|
| 66/2 |
2026/03/11 08:11 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/skbuff.c IncludeLines:true Name:__alloc_skb]
Results: map[SourceCode: 655: /**
656: * __alloc_skb - allocate a network buffer
657: * @size: size to allocate
658: * @gfp_mask: allocation mask
659: * @flags: If SKB_ALLOC_FCLONE is set, allocate from fclone cache
660: * instead of head cache and allocate a cloned (child) skb.
661: * If SKB_ALLOC_RX is set, __GFP_MEMALLOC will be used for
662: * allocations in case the data is required for writeback
663: * @node: numa node to allocate memory on
664: *
665: * Allocate a new &sk_buff. The returned buffer has no headroom and a
666: * tail room of at least size bytes. The object has a reference count
667: * of one. The return is the buffer. On a failure the return is %NULL.
668: *
669: * Buffers may only be allocated from interrupts using a @gfp_mask of
670: * %GFP_ATOMIC.
671: */
672: struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
673: int flags, int node)
674: {
675: struct sk_buff *skb = NULL;
676: struct kmem_cache *cache;
677: u8 *data;
678:
679: if (sk_memalloc_socks() && (flags & SKB_ALLOC_RX))
680: gfp_mask |= __GFP_MEMALLOC;
681:
682: if (flags & SKB_ALLOC_FCLONE) {
683: cache = net_hotdata.skbuff_fclone_cache;
684: goto fallback;
685: }
686: cache = net_hotdata.skbuff_cache;
687: if (unlikely(node != NUMA_NO_NODE && node != numa_mem_id()))
688: goto fallback;
689:
690: if (flags & SKB_ALLOC_NAPI) {
691: skb = napi_skb_cache_get(true);
692: if (unlikely(!skb))
693: return NULL;
694: } else if (!in_hardirq() && !irqs_disabled()) {
695: local_bh_disable();
696: skb = napi_skb_cache_get(false);
697: local_bh_enable();
698: }
699:
700: if (!skb) {
701: fallback:
702: skb = kmem_cache_alloc_node(cache, gfp_mask & ~GFP_DMA, node);
703: if (unlikely(!skb))
704: return NULL;
705: }
706: skbuff_clear(skb);
707:
708: /* We do our best to align skb_shared_info on a separate cache
709: * line. It usually works because kmalloc(X > SMP_CACHE_BYTES) gives
710: * aligned memory blocks, unless SLUB/SLAB debug is enabled.
711: * Both skb->head and skb_shared_info are cache line aligned.
712: */
713: data = kmalloc_reserve(&size, gfp_mask, node, skb);
714: if (unlikely(!data))
715: goto nodata;
716: /* kmalloc_size_roundup() might give us more room than requested.
717: * Put skb_shared_info exactly at the end of allocated zone,
718: * to allow max possible filling before reallocation.
719: */
720: __finalize_skb_around(skb, data, size);
721:
722: if (flags & SKB_ALLOC_FCLONE) {
723: struct sk_buff_fclones *fclones;
724:
725: fclones = container_of(skb, struct sk_buff_fclones, skb1);
726:
727: /* skb->fclone is a 2bits field.
728: * Replace expensive RMW (skb->fclone = SKB_FCLONE_ORIG)
729: * with a single OR.
730: */
731: BUILD_BUG_ON(SKB_FCLONE_UNAVAILABLE != 0);
732: DEBUG_NET_WARN_ON_ONCE(skb->fclone != SKB_FCLONE_UNAVAILABLE);
733: skb->fclone |= SKB_FCLONE_ORIG;
734:
735: refcount_set(&fclones->fclone_ref, 1);
736: }
737:
738: return skb;
739:
740: nodata:
741: kmem_cache_free(cache, skb);
742: return NULL;
743: }
SourceFile:net/core/skbuff.c]
|
| 67/2 |
2026/03/11 08:11 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 139821
output: 41
thoughts: 25
Thoughts: Here's my thought process, as if I were analyzing that code:
**Diving into the `skbuff_clear` Call**
Okay, so I see a `skbuff_clear(skb)` call. That's immediately interesting, because it usually signifies a crucial cleanup step for a socket buffer, and its implications depend heavily on the context of the larger code. My first instinct, as always, is to understand what's *actually* happening within that function. I need to refresh my mental model of the `skbuff_clear` implementation to ensure I understand how it interacts with the buffer and potential memory management. Let's delve into the guts of `skbuff_clear` and see what it is actually doing.
|
| 68/2 |
2026/03/11 08:11 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/skbuff.c IncludeLines:true Name:skbuff_clear]
Results: map[SourceCode: 311: /*
312: * Only clear those fields we need to clear, not those that we will
313: * actually initialise later. Hence, don't put any more fields after
314: * the tail pointer in struct sk_buff!
315: */
316: static inline void skbuff_clear(struct sk_buff *skb)
317: {
318: /* Replace memset(skb, 0, offsetof(struct sk_buff, tail))
319: * with two smaller memset(), with a barrier() between them.
320: * This forces the compiler to inline both calls.
321: */
322: BUILD_BUG_ON(offsetof(struct sk_buff, tail) <= 128);
323: memset(skb, 0, 128);
324: barrier();
325: memset((void *)skb + 128, 0, offsetof(struct sk_buff, tail) - 128);
326: }
SourceFile:net/core/skbuff.c]
|
| 69/2 |
2026/03/11 08:11 |
llm |
crash-repro-finder |
1m
Model:
Tokens:
input: 140355
output: 40
thoughts: 36
Thoughts: Okay, here's my interpretation of those thoughts, framed as an expert's internal monologue:
**Investigating `skbuff_clear` and `struct sk_buff`**
Right, so `skbuff_clear` is supposed to zero out a portion of an `sk_buff`. The documentation I remember reading is a bit fuzzy, but I recall it being up to `offsetof(struct sk_buff, tail)`. That's a good starting point. But, hang on a second... where *exactly* does the control block, or `cb`, live within the `sk_buff` structure? It's been a while since I really delved into the layout, and that's critical here. Knowing the exact memory range that `skbuff_clear` touches is *essential* to ensuring whatever cleanup is happening isn't inadvertently corrupting any crucial control data. Need to refresh my memory on that `struct`... the cb is somewhere, has to be. Gotta map this out in my mind, or perhaps dig up the definition really quick. This is the kind of detail that bites you if you're not careful.
|
| 70/2 |
2026/03/11 08:13 |
tool |
codesearch-struct-layout |
0m
Args: map[ContextFile:net/core/skbuff.c FieldOffset:<nil> Name:sk_buff]
Results: map[Fields:[map[Name: OffsetBits:0 SizeBits:192] map[Name:sk OffsetBits:192 SizeBits:64] map[Name: OffsetBits:256 SizeBits:64] map[Name:cb OffsetBits:320 SizeBits:384] map[Name: OffsetBits:704 SizeBits:128] map[Name:_nfct OffsetBits:832 SizeBits:64] map[Name:len OffsetBits:896 SizeBits:32] map[Name:data_len OffsetBits:928 SizeBits:32] map[Name:mac_len OffsetBits:960 SizeBits:16] map[Name:hdr_len OffsetBits:976 SizeBits:16] map[Name:queue_mapping OffsetBits:992 SizeBits:16] map[Name:__cloned_offset OffsetBits:1008 SizeBits:0] map[Name:cloned OffsetBits:1008 SizeBits:1] map[Name:nohdr OffsetBits:1009 SizeBits:1] map[Name:fclone OffsetBits:1010 SizeBits:2] map[Name:peeked OffsetBits:1012 SizeBits:1] map[Name:head_frag OffsetBits:1013 SizeBits:1] map[Name:pfmemalloc OffsetBits:1014 SizeBits:1] map[Name:pp_recycle OffsetBits:1015 SizeBits:1] map[Name:active_extensions OffsetBits:1016 SizeBits:8] map[Name: OffsetBits:1024 SizeBits:576] map[Name:tail OffsetBits:1600 SizeBits:32] map[Name:end OffsetBits:1632 SizeBits:32] map[Name:head OffsetBits:1664 SizeBits:64] map[Name:data OffsetBits:1728 SizeBits:64] map[Name:truesize OffsetBits:1792 SizeBits:32] map[Name:users OffsetBits:1824 SizeBits:32] map[Name:extensions OffsetBits:1856 SizeBits:64]]]
|
| 71/2 |
2026/03/11 08:13 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 141249
output: 44
thoughts: 674
Thoughts: **Debugging a KMSAN Uninit-Value Report**
Okay, so I'm looking at this KMSAN report and it's pointing to an uninitialized value in `put_cmsg`. That's strange because, as I understand it, `cb` (control buffer) is located at offset 320 bits, or 40 bytes, and `tail` is at offset 1600 bits, or 200 bytes, within the `skb`. The key thing here is that `cb` *should* be cleared by `skbuff_clear` when the `skb` is allocated. If `cb` is cleared, then `NETLINK_CB(skb).creds`, which lives within `cb`, *should* be zeroed out. So if it's zeroed, then it's not actually *uninitialized*!
Why is KMSAN reporting an uninit-value in this context? I need to re-examine that KMSAN report.
Ah, okay, so the trace shows `put_cmsg` -> `__scm_recv_common` -> `scm_recv` -> `netlink_recvmsg` -> socket receive calls. Okay, and if `cb` is zeroed by `skbuff_clear` during `skb` allocation, then `NETLINK_CB(skb).creds` is also zeroed. Wait, but `skbuff_clear` is called *when* the `skb` is allocated, so maybe `skb->cb` is overwritten by something else after allocation? Or maybe the `skb` is cloned? Does `skb_clone` copy `cb`? Ah, yes, `__skb_clone` *does* copy `cb`. What about when an `skb` is allocated without calling `skbuff_clear`? That's another avenue to explore. Could `skb` be generated by a different subsystem, like `netlink_broadcast`? That's worth checking.
|
| 72/2 |
2026/03/11 08:14 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_broadcast]
Results: map[SourceCode:1554: int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 portid,
1555: u32 group, gfp_t allocation)
1556: {
1557: return netlink_broadcast_filtered(ssk, skb, portid, group, allocation,
1558: NULL, NULL);
1559: }
SourceFile:net/netlink/af_netlink.c]
|
| 73/2 |
2026/03/11 08:14 |
llm |
crash-repro-finder |
1m
Model:
Tokens:
input: 142537
output: 42
thoughts: 107
Thoughts: **KMSAN Puzzler: `skbuff_clear` and Uninitialized Memory**
Okay, so KMSAN tracks uninitialized memory. That much I know. The puzzle here is that `skbuff_clear` zeroes out the `cb` field, which should mean it's initialized. But if `cb` is initialized, why am I seeing reports of uninitialized `ucreds`? The root of it lies in the `memset` operation: `skbuff_clear` uses `memset(skb, 0, offsetof(struct sk_buff, tail))`. KMSAN intercepts `memset` calls, which is crucial here, as it means when the memory is zeroed out by `memset`, KMSAN registers that it is, indeed, initialized. So, if `cb` is zeroed, then KMSAN must consider it initialized. I need to figure out why I am seeing this uninitialized memory if that is the case. Looks like I need to dig into `__scm_recv_common` to understand what is happening.
|
| 74/2 |
2026/03/11 08:16 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/scm.c IncludeLines:true Name:__scm_recv_common]
Results: map[SourceCode: 497: static bool __scm_recv_common(struct sock *sk, struct msghdr *msg,
498: struct scm_cookie *scm, int flags)
499: {
500: if (!msg->msg_control) {
501: if (sk->sk_scm_credentials || sk->sk_scm_pidfd ||
502: scm->fp || scm_has_secdata(sk))
503: msg->msg_flags |= MSG_CTRUNC;
504:
505: scm_destroy(scm);
506: return false;
507: }
508:
509: if (sk->sk_scm_credentials) {
510: struct user_namespace *current_ns = current_user_ns();
511: struct ucred ucreds = {
512: .pid = scm->creds.pid,
513: .uid = from_kuid_munged(current_ns, scm->creds.uid),
514: .gid = from_kgid_munged(current_ns, scm->creds.gid),
515: };
516:
517: put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
518: }
519:
520: scm_passec(sk, msg, scm);
521:
522: if (scm->fp)
523: scm_detach_fds(msg, scm);
524:
525: return true;
526: }
SourceFile:net/core/scm.c]
|
| 75/2 |
2026/03/11 08:16 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 143401
output: 38
thoughts: 38
Thoughts: Okay, here's my interpretation of those thoughts, tailored for an expert audience, presented in the first person:
**Decoding ucred Padding**
Alright, hang on a second. I see this `struct ucred ucreds = { ... };` declaration. Immediately, my mind jumps to the potential for padding within the `struct ucred` definition. That's always the first thing I check when dealing with these sorts of structures. Memory layout is critical, especially when marshaling or interpreting the data. I need to be absolutely certain about the size and alignment of each member to avoid misinterpreting the data. So, let's take a closer look at the *actual* `struct ucred` layout. I need to refresh my mental model of its structure, and confirm that there isn't any unexpected padding that I might not be aware of in my mental stack. This is all about ensuring data integrity and preventing subtle, hard-to-debug memory errors down the line.
|
| 76/2 |
2026/03/11 08:16 |
tool |
codesearch-struct-layout |
0m
Args: map[ContextFile:net/core/scm.c FieldOffset:<nil> Name:ucred]
Results: map[Fields:[map[Name:pid OffsetBits:0 SizeBits:32] map[Name:uid OffsetBits:32 SizeBits:32] map[Name:gid OffsetBits:64 SizeBits:32]]]
|
| 77/2 |
2026/03/11 08:16 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 143748
output: 44
thoughts: 188
Thoughts: **Unraveling a Potential Kernel Vulnerability**
Okay, so I'm looking at this code and immediately I'm thinking, "No padding, good". But wait a minute... what if `scm->creds.pid` is actually uninitialized? Where the heck does `scm->creds` even *come* from? Okay, let's trace this back. Right, in `netlink_recvmsg`, we see a `memset` on `scm`, good, making sure it is zeroed out. Then comes the assignment: `scm.creds = *NETLINK_CREDS(skb)`. Aha, `NETLINK_CREDS(skb)` resolves to `&NETLINK_CB(skb).creds`.
If `NETLINK_CB(skb).creds` is uninitialized, then so is the `scm.creds` we copied over. But didn't we just establish that `skbuff_clear` zeros out the `cb` structure in the `skb`? That *should* mean `NETLINK_CB(skb).creds` is initialized to zero. I mean, it is supposed to be, right?
Is there *any* path where `cb` isn't zeroed? Or, even worse, could there be a situation where `cb` is overwritten with uninitialized data somewhere along the way? I need to go back and check `netlink_ack` again; I'm missing something, or maybe there is a path that allows this to happen.
|
| 78/2 |
2026/03/11 08:16 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_ack]
Results: map[SourceCode:2463: void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
2464: const struct netlink_ext_ack *extack)
2465: {
2466: struct sk_buff *skb;
2467: struct nlmsghdr *rep;
2468: struct nlmsgerr *errmsg;
2469: size_t payload = sizeof(*errmsg);
2470: struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk);
2471: unsigned int flags = 0;
2472: size_t tlvlen;
2473:
2474: /* Error messages get the original request appended, unless the user
2475: * requests to cap the error message, and get extra error data if
2476: * requested.
2477: */
2478: if (err && !test_bit(NETLINK_F_CAP_ACK, &nlk->flags))
2479: payload += nlmsg_len(nlh);
2480: else
2481: flags |= NLM_F_CAPPED;
2482:
2483: tlvlen = netlink_ack_tlv_len(nlk, err, extack);
2484: if (tlvlen)
2485: flags |= NLM_F_ACK_TLVS;
2486:
2487: skb = nlmsg_new(payload + tlvlen, GFP_KERNEL);
2488: if (!skb)
2489: goto err_skb;
2490:
2491: rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
2492: NLMSG_ERROR, sizeof(*errmsg), flags);
2493: if (!rep)
2494: goto err_bad_put;
2495: errmsg = nlmsg_data(rep);
2496: errmsg->error = err;
2497: errmsg->msg = *nlh;
2498:
2499: if (!(flags & NLM_F_CAPPED)) {
2500: if (!nlmsg_append(skb, nlmsg_len(nlh)))
2501: goto err_bad_put;
2502:
2503: memcpy(nlmsg_data(&errmsg->msg), nlmsg_data(nlh),
2504: nlmsg_len(nlh));
2505: }
2506:
2507: if (tlvlen)
2508: netlink_ack_tlv_fill(skb, nlh, err, extack);
2509:
2510: nlmsg_end(skb, rep);
2511:
2512: nlmsg_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid);
2513:
2514: return;
2515:
2516: err_bad_put:
2517: nlmsg_free(skb);
2518: err_skb:
2519: WRITE_ONCE(NETLINK_CB(in_skb).sk->sk_err, ENOBUFS);
2520: sk_error_report(NETLINK_CB(in_skb).sk);
2521: }
SourceFile:net/netlink/af_netlink.c]
|
| 79/2 |
2026/03/11 08:16 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 145292
output: 44
thoughts: 44
Thoughts: **Digging into Netlink Message Allocation**
Okay, so I'm trying to refresh my memory on the Netlink message construction process. A key question keeps popping up: when I use `nlmsg_new`, am I also implicitly calling `alloc_skb` under the hood? It seems likely, but I need to be absolutely sure. The documentation is usually pretty clear, but it's always good to confirm assumptions.
Yes! That's it.
Now, here's another potential point of confusion, does `nlmsg_put` muck around with the `cb` field? Just to clarify, I'll need to double-check the source code for `nlmsg_put` to be certain. I need to make sure I don't introduce a subtle bug because I'm misunderstanding how these functions interact. Let's get the source...
|
| 80/2 |
2026/03/11 08:16 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:nlmsg_put]
Results: map[SourceCode: 983: /**
984: * nlmsg_put - Add a new netlink message to an skb
985: * @skb: socket buffer to store message in
986: * @portid: netlink PORTID of requesting application
987: * @seq: sequence number of message
988: * @type: message type
989: * @payload: length of message payload
990: * @flags: message flags
991: *
992: * Returns: NULL if the tailroom of the skb is insufficient to store
993: * the message header and payload.
994: */
995: static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
996: int type, int payload, int flags)
997: {
998: if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload)))
999: return NULL;
1000:
1001: return __nlmsg_put(skb, portid, seq, type, payload, flags);
1002: }
SourceFile:include/net/netlink.h]
|
| 81/2 |
2026/03/11 08:16 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 145918
output: 45
thoughts: 11
Thoughts: Okay, here's my attempt at summarizing that thought process, keeping in mind I'm speaking to a fellow expert:
**Diving into `__nlmsg_put`**
Right, let's get down to brass tacks. Time to take a closer look at `__nlmsg_put`. This function is fundamental, obviously. We're talking about the bedrock of constructing Netlink messages. I need to refresh my memory on the intricacies, make sure I haven't missed any edge cases in my assumptions, especially regarding memory management and how it interacts with the underlying skb structure. I'm thinking about alignment issues immediately, and potential buffer overflows – got to be completely rigorous here. Are there any subtle differences in behavior across kernel versions I need to account for? I want to solidify the details of how it handles the provided arguments and calculates the size requirements based on the input data. Gotta confirm the message header updates are being handled precisely according to the spec, checking field assignment order.
|
| 82/2 |
2026/03/11 08:16 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:__nlmsg_put]
Results: map[SourceCode:2138: struct nlmsghdr *
2139: __nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, int type, int len, int flags)
2140: {
2141: struct nlmsghdr *nlh;
2142: int size = nlmsg_msg_size(len);
2143:
2144: nlh = skb_put(skb, NLMSG_ALIGN(size));
2145: nlh->nlmsg_type = type;
2146: nlh->nlmsg_len = size;
2147: nlh->nlmsg_flags = flags;
2148: nlh->nlmsg_pid = portid;
2149: nlh->nlmsg_seq = seq;
2150: if (!__builtin_constant_p(size) || NLMSG_ALIGN(size) - size != 0)
2151: memset(nlmsg_data(nlh) + len, 0, NLMSG_ALIGN(size) - size);
2152: return nlh;
2153: }
SourceFile:net/netlink/af_netlink.c]
|
| 83/2 |
2026/03/11 08:16 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 146513
output: 49
thoughts: 49
Thoughts: **Analyzing Potential `cb` Interaction**
Okay, so initially I figured, "Nope, this doesn't touch `cb`," but then a nagging question popped into my head. Hold on a second, what if this `skb` in question wasn't allocated in the typical way? What if it came through `netlink_alloc_large_skb`? That method, as I recall, has some nuances. Gotta check that out. Time to dive into the implementation of `netlink_alloc_large_skb` and make sure my initial assessment is sound. It’s important to remember these subtle allocation methods.
|
| 84/2 |
2026/03/11 08:17 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_alloc_large_skb]
Results: map[SourceCode:1177: struct sk_buff *netlink_alloc_large_skb(unsigned int size, int broadcast)
1178: {
1179: size_t head_size = SKB_HEAD_ALIGN(size);
1180: struct sk_buff *skb;
1181: void *data;
1182:
1183: if (head_size <= PAGE_SIZE || broadcast)
1184: return alloc_skb(size, GFP_KERNEL);
1185:
1186: data = kvmalloc(head_size, GFP_KERNEL);
1187: if (!data)
1188: return NULL;
1189:
1190: skb = __build_skb(data, head_size);
1191: if (!skb)
1192: kvfree(data);
1193: else if (is_vmalloc_addr(data))
1194: skb->destructor = netlink_skb_destructor;
1195:
1196: return skb;
1197: }
SourceFile:net/netlink/af_netlink.c]
|
| 85/2 |
2026/03/11 08:17 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 147077
output: 44
thoughts: 33
Thoughts: Here's my thought process, as if I were analyzing this code:
**Diving into the SKB Construction**
Okay, so I see `__build_skb` called. Right away, my spider sense is tingling because I know the core of SKB construction lies in that area. Let's see what that function actually *does*. Ah, it's immediately calling `__build_skb_around`. Interesting. That means `__build_skb` is likely a wrapper or orchestrator, and the real work, the meat of the SKB build, is happening within `__build_skb_around`. I need to understand that. Let's dig into `__build_skb_around` and understand the mechanics of what's happening there. What are the key parameters being passed? What data structures are it using? I'm betting that's where I'll find the details of buffer allocation, header space management, and potential fragmentation handling. Time to dive deeper.
|
| 86/2 |
2026/03/11 08:17 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/skbuff.c IncludeLines:true Name:__build_skb_around]
Results: map[SourceCode: 453: /* Caller must provide SKB that is memset cleared */
454: static void __build_skb_around(struct sk_buff *skb, void *data,
455: unsigned int frag_size)
456: {
457: unsigned int size = frag_size;
458:
459: /* frag_size == 0 is considered deprecated now. Callers
460: * using slab buffer should use slab_build_skb() instead.
461: */
462: if (WARN_ONCE(size == 0, "Use slab_build_skb() instead"))
463: data = __slab_build_skb(data, &size);
464:
465: __finalize_skb_around(skb, data, size);
466: }
SourceFile:net/core/skbuff.c]
|
| 87/2 |
2026/03/11 08:17 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 147628
output: 42
thoughts: 21
Thoughts: Here's my understanding of the thought process, from the perspective of an expert:
**Understanding SKB Allocation**
Okay, so I'm focusing on how `__build_skb` works. The key is in how it's getting its `skb`. It's not just a generic allocation; it's explicitly pulling the `skb` (socket buffer) from the `skbuff_cache`. That's important. It tells me immediately that we're dealing with optimized memory management. The `skbuff_cache` is likely a slab cache, designed to pre-allocate and reuse these network buffers, which is crucial for performance in a high-throughput network environment. This implies that this function is performance critical. I need to keep this in mind as I continue to analyze this function, or any function that calls it. The implications are: no dynamic memory allocation at the core level of the function.
|
| 88/2 |
2026/03/11 08:17 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/skbuff.c IncludeLines:true Name:__build_skb]
Results: map[SourceCode: 468: /**
469: * __build_skb - build a network buffer
470: * @data: data buffer provided by caller
471: * @frag_size: size of data (must not be 0)
472: *
473: * Allocate a new &sk_buff. Caller provides space holding head and
474: * skb_shared_info. @data must have been allocated from the page
475: * allocator or vmalloc(). (A @frag_size of 0 to indicate a kmalloc()
476: * allocation is deprecated, and callers should use slab_build_skb()
477: * instead.)
478: * The return is the new skb buffer.
479: * On a failure the return is %NULL, and @data is not freed.
480: * Notes :
481: * Before IO, driver allocates only data buffer where NIC put incoming frame
482: * Driver should add room at head (NET_SKB_PAD) and
483: * MUST add room at tail (SKB_DATA_ALIGN(skb_shared_info))
484: * After IO, driver calls build_skb(), to allocate sk_buff and populate it
485: * before giving packet to stack.
486: * RX rings only contains data buffers, not full skbs.
487: */
488: struct sk_buff *__build_skb(void *data, unsigned int frag_size)
489: {
490: struct sk_buff *skb;
491:
492: skb = kmem_cache_alloc(net_hotdata.skbuff_cache,
493: GFP_ATOMIC | __GFP_NOWARN);
494: if (unlikely(!skb))
495: return NULL;
496:
497: skbuff_clear(skb);
498: __build_skb_around(skb, data, frag_size);
499:
500: return skb;
501: }
SourceFile:net/core/skbuff.c]
|
| 89/2 |
2026/03/11 08:17 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 148492
output: 45
thoughts: 54
Thoughts: **Analyzing the Netlink Message Reception**
Okay, so I'm looking at this code and I see that along with the allocation of the `skb`, `skbuff_clear(skb)` is also being called. This implies that the control block (`cb`) associated with the `skb` is guaranteed to be zeroed out upon allocation. That makes sense from a security perspective. It's good to ensure no residual data is present. But now I'm getting hung up on this `ucreds` struct and that it is uninitialized. That seems a bit strange to me. I'm going to revisit `netlink_recvmsg` and see if I can figure out why this variable isn't being explicitly initialized before being used. I need to understand what's happening here.
|
| 90/2 |
2026/03/11 08:17 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_recvmsg]
Results: map[SourceCode:1901: static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1902: int flags)
1903: {
1904: struct scm_cookie scm;
1905: struct sock *sk = sock->sk;
1906: struct netlink_sock *nlk = nlk_sk(sk);
1907: size_t copied, max_recvmsg_len;
1908: struct sk_buff *skb, *data_skb;
1909: int err, ret;
1910:
1911: if (flags & MSG_OOB)
1912: return -EOPNOTSUPP;
1913:
1914: copied = 0;
1915:
1916: skb = skb_recv_datagram(sk, flags, &err);
1917: if (skb == NULL)
1918: goto out;
1919:
1920: data_skb = skb;
1921:
1922: #ifdef CONFIG_COMPAT_NETLINK_MESSAGES
1923: if (unlikely(skb_shinfo(skb)->frag_list)) {
1924: /*
1925: * If this skb has a frag_list, then here that means that we
1926: * will have to use the frag_list skb's data for compat tasks
1927: * and the regular skb's data for normal (non-compat) tasks.
1928: *
1929: * If we need to send the compat skb, assign it to the
1930: * 'data_skb' variable so that it will be used below for data
1931: * copying. We keep 'skb' for everything else, including
1932: * freeing both later.
1933: */
1934: if (flags & MSG_CMSG_COMPAT)
1935: data_skb = skb_shinfo(skb)->frag_list;
1936: }
1937: #endif
1938:
1939: /* Record the max length of recvmsg() calls for future allocations */
1940: max_recvmsg_len = max(READ_ONCE(nlk->max_recvmsg_len), len);
1941: max_recvmsg_len = min_t(size_t, max_recvmsg_len,
1942: SKB_WITH_OVERHEAD(32768));
1943: WRITE_ONCE(nlk->max_recvmsg_len, max_recvmsg_len);
1944:
1945: copied = data_skb->len;
1946: if (len < copied) {
1947: msg->msg_flags |= MSG_TRUNC;
1948: copied = len;
1949: }
1950:
1951: err = skb_copy_datagram_msg(data_skb, 0, msg, copied);
1952:
1953: if (msg->msg_name) {
1954: DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name);
1955: addr->nl_family = AF_NETLINK;
1956: addr->nl_pad = 0;
1957: addr->nl_pid = NETLINK_CB(skb).portid;
1958: addr->nl_groups = netlink_group_mask(NETLINK_CB(skb).dst_group);
1959: msg->msg_namelen = sizeof(*addr);
1960: }
1961:
1962: if (nlk_test_bit(RECV_PKTINFO, sk))
1963: netlink_cmsg_recv_pktinfo(msg, skb);
1964: if (nlk_test_bit(LISTEN_ALL_NSID, sk))
1965: netlink_cmsg_listen_all_nsid(sk, msg, skb);
1966:
1967: memset(&scm, 0, sizeof(scm));
1968: scm.creds = *NETLINK_CREDS(skb);
1969: if (flags & MSG_TRUNC)
1970: copied = data_skb->len;
1971:
1972: skb_free_datagram(sk, skb);
1973:
1974: if (READ_ONCE(nlk->cb_running) &&
1975: atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
1976: ret = netlink_dump(sk, false);
1977: if (ret) {
1978: WRITE_ONCE(sk->sk_err, -ret);
1979: sk_error_report(sk);
1980: }
1981: }
1982:
1983: scm_recv(sock, msg, &scm, flags);
1984: out:
1985: netlink_rcv_wake(sk);
1986: return err ? : copied;
1987: }
SourceFile:net/netlink/af_netlink.c]
|
| 91/2 |
2026/03/11 08:17 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 150226
output: 44
thoughts: 102
Thoughts: **Investigating a Potential Credential Issue in Netlink**
Okay, let's see, I'm trying to wrap my head around this `NETLINK_CREDS(skb)` macro. It's essentially returning the address of `NETLINK_CB(skb).creds`, so that makes sense. My immediate thought is, could there be a situation where `skb` is allocated, but the control block, `cb`, within `skb` isn't properly initialized? Specifically, is it possible for some garbage data in the `creds` field to be used?
I dismiss that thought initially because I remember that `skbuff_clear` should zero out the control block. But, I need to be completely thorough here. I have to consider the possibilities. Hold on… what about `alloc_skb_fclone`? Does that have any special behavior that would allow for an uninitialized `cb`? If it bypasses the normal zeroing, that could be the root cause of the problem.
Alright, time to dig into the code for `alloc_skb_fclone`. Let's see what's really happening in that function. It's time to check the internals.
|
| 92/2 |
2026/03/11 08:17 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/skbuff.c IncludeLines:true Name:alloc_skb_fclone]
Results: map[SourceCode:1423: /**
1424: * alloc_skb_fclone - allocate a network buffer from fclone cache
1425: * @size: size to allocate
1426: * @priority: allocation mask
1427: *
1428: * This function is a convenient wrapper around __alloc_skb().
1429: */
1430: static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
1431: gfp_t priority)
1432: {
1433: return __alloc_skb(size, priority, SKB_ALLOC_FCLONE, NUMA_NO_NODE);
1434: }
SourceFile:include/linux/skbuff.h]
|
| 93/2 |
2026/03/11 08:17 |
llm |
crash-repro-finder |
1m
Model:
Tokens:
input: 150846
output: 41
thoughts: 48
Thoughts: Okay, let me think this through.
**Analyzing SKB Allocation and Cloning**
Alright, so I'm seeing this code path, and it's calling `__alloc_skb`, which then, predictably, calls `skbuff_clear`. Standard stuff. But hold on a second... what happens if this `skb` (socket buffer) was *already* allocated via `skb_clone`? I know that clone creates a new SKB referencing the same data. Does `skbuff_clear` do the right thing in that situation? Is there a risk of double freeing or some other memory corruption? The semantics need to be precise here.
Time to dive into the `skb_clone` function and verify the interaction. I need to understand exactly how the clone interacts with this clear operation, to ensure integrity of the memory management.
|
| 94/2 |
2026/03/11 08:19 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/skbuff.c IncludeLines:true Name:skb_clone]
Results: map[SourceCode:2101: struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
2102: {
2103: struct sk_buff_fclones *fclones = container_of(skb,
2104: struct sk_buff_fclones,
2105: skb1);
2106: struct sk_buff *n;
2107:
2108: if (skb_orphan_frags(skb, gfp_mask))
2109: return NULL;
2110:
2111: if (skb->fclone == SKB_FCLONE_ORIG &&
2112: refcount_read(&fclones->fclone_ref) == 1) {
2113: n = &fclones->skb2;
2114: refcount_set(&fclones->fclone_ref, 2);
2115: n->fclone = SKB_FCLONE_CLONE;
2116: } else {
2117: if (skb_pfmemalloc(skb))
2118: gfp_mask |= __GFP_MEMALLOC;
2119:
2120: n = kmem_cache_alloc(net_hotdata.skbuff_cache, gfp_mask);
2121: if (!n)
2122: return NULL;
2123:
2124: n->fclone = SKB_FCLONE_UNAVAILABLE;
2125: }
2126:
2127: return __skb_clone(n, skb);
2128: }
SourceFile:net/core/skbuff.c]
|
| 95/2 |
2026/03/11 08:19 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 151597
output: 42
thoughts: 11
Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience, and delivered as a first-person summary:
**Digging into `__skb_clone`**
Right, let's dive into this. The initial thought is to go straight for `__skb_clone`. It's a fundamental function when dealing with `skb`s, so it's the obvious starting point if we're looking at network packet cloning. I want to understand exactly how the data buffers are handled, particularly the reference counting and the implications for memory management. I'm thinking about the potential pitfalls here: the edge cases, the race conditions, the interactions with other related functions like `skb_share_check`, and any optimizations that might be in place. We need a clear understanding of what `__skb_clone` actually does. What kind of cloning is it? Deep, shallow? What are the implications if this function is behaving unusually?
|
| 96/2 |
2026/03/11 08:19 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/skbuff.c IncludeLines:true Name:__skb_clone]
Results: map[SourceCode:1607: /*
1608: * You should not add any new code to this function. Add it to
1609: * __copy_skb_header above instead.
1610: */
1611: static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
1612: {
1613: #define C(x) n->x = skb->x
1614:
1615: n->next = n->prev = NULL;
1616: n->sk = NULL;
1617: __copy_skb_header(n, skb);
1618:
1619: C(len);
1620: C(data_len);
1621: C(mac_len);
1622: n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
1623: n->cloned = 1;
1624: n->nohdr = 0;
1625: n->peeked = 0;
1626: C(pfmemalloc);
1627: C(pp_recycle);
1628: n->destructor = NULL;
1629: C(tail);
1630: C(end);
1631: C(head);
1632: C(head_frag);
1633: C(data);
1634: C(truesize);
1635: refcount_set(&n->users, 1);
1636:
1637: atomic_inc(&(skb_shinfo(skb)->dataref));
1638: skb->cloned = 1;
1639:
1640: return n;
1641: #undef C
1642: }
SourceFile:net/core/skbuff.c]
|
| 97/2 |
2026/03/11 08:19 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 152396
output: 44
thoughts: 13
Thoughts: Here's my take on those thoughts, tailored for an expert audience:
**Diving into `__copy_skb_header`**
Okay, time to get my hands dirty. Let's dig into `__copy_skb_header`. It's a critical function, no doubt. Understanding the intricacies of how headers are copied between SKBs is paramount to debugging performance issues and verifying memory integrity, especially when looking at the implications for things like zero-copy operations and shared buffer handling. I need to make sure I grasp the atomics, memory barriers and the way `skb_shared_info` is dealt with in this function. I'm hoping to get a clearer picture of how it handles reference counts, especially if there's any potential for race conditions or unintended shared state. I want to look closely at edge cases, like how it manages fragmented packets and the impact of hardware offloading. Let's see if this reveals any hidden optimizations or potential bottlenecks. This investigation will also inform my approach to security implications - can it be used to trigger use-after-free or other memory-corruption issues?
|
| 98/2 |
2026/03/11 08:19 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/skbuff.c IncludeLines:true Name:__copy_skb_header]
Results: map[SourceCode:1560: static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
1561: {
1562: new->tstamp = old->tstamp;
1563: /* We do not copy old->sk */
1564: new->dev = old->dev;
1565: memcpy(new->cb, old->cb, sizeof(old->cb));
1566: skb_dst_copy(new, old);
1567: __skb_ext_copy(new, old);
1568: __nf_copy(new, old, false);
1569:
1570: /* Note : this field could be in the headers group.
1571: * It is not yet because we do not want to have a 16 bit hole
1572: */
1573: new->queue_mapping = old->queue_mapping;
1574:
1575: memcpy(&new->headers, &old->headers, sizeof(new->headers));
1576: CHECK_SKB_FIELD(protocol);
1577: CHECK_SKB_FIELD(csum);
1578: CHECK_SKB_FIELD(hash);
1579: CHECK_SKB_FIELD(priority);
1580: CHECK_SKB_FIELD(skb_iif);
1581: CHECK_SKB_FIELD(vlan_proto);
1582: CHECK_SKB_FIELD(vlan_tci);
1583: CHECK_SKB_FIELD(transport_header);
1584: CHECK_SKB_FIELD(network_header);
1585: CHECK_SKB_FIELD(mac_header);
1586: CHECK_SKB_FIELD(inner_protocol);
1587: CHECK_SKB_FIELD(inner_transport_header);
1588: CHECK_SKB_FIELD(inner_network_header);
1589: CHECK_SKB_FIELD(inner_mac_header);
1590: CHECK_SKB_FIELD(mark);
1591: #ifdef CONFIG_NETWORK_SECMARK
1592: CHECK_SKB_FIELD(secmark);
1593: #endif
1594: #ifdef CONFIG_NET_RX_BUSY_POLL
1595: CHECK_SKB_FIELD(napi_id);
1596: #endif
1597: CHECK_SKB_FIELD(alloc_cpu);
1598: #ifdef CONFIG_XPS
1599: CHECK_SKB_FIELD(sender_cpu);
1600: #endif
1601: #ifdef CONFIG_NET_SCHED
1602: CHECK_SKB_FIELD(tc_index);
1603: #endif
1604:
1605: }
SourceFile:net/core/skbuff.c]
|
| 99/2 |
2026/03/11 08:19 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 153471
output: 40
thoughts: 192
Thoughts: **Debugging a KMSAN Complaint**
Okay, so I'm looking at this KMSAN complaint and trying to understand what's going on. It seems the code copies `cb`, which, as I recall, should mean that `cb` is always initialized when the `skb` is allocated. But KMSAN is complaining, so something isn't right. What could be the cause?
Wait a second… what if `NETLINK_CREDS(skb)` *isn't* initialized? That could be it! I know that `NETLINK_CB(skb)` is essentially a pointer cast: `*(struct netlink_skb_parms*)&((skb)->cb)`. And `struct netlink_skb_parms` is 48 bytes, and `skb->cb` is 48 bytes too. Makes sense.
If `skb->cb` *is* zeroed by `skbuff_clear`, then `NETLINK_CB(skb)` should also be zeroed. So, is that happening here? Hold on, `skbuff_clear` uses `memset(skb, 0, 128)`. I need to check something important. Is `cb` within the first 128 bytes of `sk_buff`? I should probably check the `sk_buff` layout again.
|
| 100/2 |
2026/03/11 08:20 |
tool |
codesearch-struct-layout |
0m
Args: map[ContextFile:net/core/skbuff.c FieldOffset:<nil> Name:sk_buff]
Results: map[Fields:[map[Name: OffsetBits:0 SizeBits:192] map[Name:sk OffsetBits:192 SizeBits:64] map[Name: OffsetBits:256 SizeBits:64] map[Name:cb OffsetBits:320 SizeBits:384] map[Name: OffsetBits:704 SizeBits:128] map[Name:_nfct OffsetBits:832 SizeBits:64] map[Name:len OffsetBits:896 SizeBits:32] map[Name:data_len OffsetBits:928 SizeBits:32] map[Name:mac_len OffsetBits:960 SizeBits:16] map[Name:hdr_len OffsetBits:976 SizeBits:16] map[Name:queue_mapping OffsetBits:992 SizeBits:16] map[Name:__cloned_offset OffsetBits:1008 SizeBits:0] map[Name:cloned OffsetBits:1008 SizeBits:1] map[Name:nohdr OffsetBits:1009 SizeBits:1] map[Name:fclone OffsetBits:1010 SizeBits:2] map[Name:peeked OffsetBits:1012 SizeBits:1] map[Name:head_frag OffsetBits:1013 SizeBits:1] map[Name:pfmemalloc OffsetBits:1014 SizeBits:1] map[Name:pp_recycle OffsetBits:1015 SizeBits:1] map[Name:active_extensions OffsetBits:1016 SizeBits:8] map[Name: OffsetBits:1024 SizeBits:576] map[Name:tail OffsetBits:1600 SizeBits:32] map[Name:end OffsetBits:1632 SizeBits:32] map[Name:head OffsetBits:1664 SizeBits:64] map[Name:data OffsetBits:1728 SizeBits:64] map[Name:truesize OffsetBits:1792 SizeBits:32] map[Name:users OffsetBits:1824 SizeBits:32] map[Name:extensions OffsetBits:1856 SizeBits:64]]]
|
| 101/2 |
2026/03/11 08:20 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 154574
output: 43
thoughts: 981
Thoughts: **Unraveling a KMSAN Uninitialized Value Report in Netlink**
Okay, I'm looking at this KMSAN report and it's pointing to an uninitialized value. Specifically, it's flagging something related to `ucreds`, which is created inside `__scm_recv_common`. The trace tells me it's originating from `scm_recv` and ultimately `netlink_recvmsg`.
My initial thought was that maybe the `cb` structure in the `skb` (socket buffer) wasn't being fully zeroed out. The code does a `memset(skb, 0, 128)`, and my calculations show that the `cb` struct, specifically, `cb` is fully contained within that zeroing. The `cb` size is 48 bytes, and it starts at offset 40 bytes, ending at 88 bytes. This is less than 128 bytes, meaning memset should cover it. So, that seemed unlikely.
I then considered whether the functions `from_kuid_munged` or `from_kgid_munged` could be returning something uninitialized. But, they're just performing some calculations, so they shouldn't be the source of the issue.
Then I had a breakthrough: what if `scm->creds` itself isn't initialized? Where does `scm` come from? Diving into `netlink_recvmsg`, I see `memset(&scm, 0, sizeof(scm));` followed by `scm.creds = *NETLINK_CREDS(skb);`. So, `scm` is supposed to be zeroed *before* it gets populated.
Could the `skb` be the issue? Is it the right kind of `skb`? There's a check for `frag_list` in that function. If there is a frag list the check determines if the code should use the regular skb's data or the frag_list skb's data. However, the code uses `skb`, not the `data_skb`, so that seems like a dead end.
I know that `skbuff_clear` zeroes the `cb`. However, I started to wonder if an `skb` could be allocated elsewhere (say, by `alloc_skb`) and have its `cb` used by some other layer, then passed to netlink. However, netlink allocates its own `skbs`, so that's not it either.
Then I realized that `netlink_recvmsg` reads from `NETLINK_CREDS(skb)`. What if the `skb` comes from `netlink_sendmsg`? Looking at `netlink_sendmsg`, the code calls `scm_send` and then initializes `NETLINK_CB(skb).creds` *after* the call. So, `NETLINK_CB(skb).creds` is populated from `scm.creds`. This is the important part! Now the question is, is `scm.creds` fully initialized *within* `scm_send`? I need to check `scm_send` now! That's where the uninitialized value might be coming from.
|
| 102/2 |
2026/03/11 08:20 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:scm_send]
Results: map[SourceCode: 91: static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
92: struct scm_cookie *scm, bool forcecreds)
93: {
94: memset(scm, 0, sizeof(*scm));
95: scm->creds.uid = INVALID_UID;
96: scm->creds.gid = INVALID_GID;
97: if (forcecreds)
98: scm_set_cred(scm, task_tgid(current), current_uid(), current_gid());
99: unix_get_peersec_dgram(sock, scm);
100: if (msg->msg_controllen <= 0)
101: return 0;
102: return __scm_send(sock, msg, scm);
103: }
SourceFile:include/net/scm.h]
|
| 103/2 |
2026/03/11 08:20 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 156545
output: 40
thoughts: 54
Thoughts: **Analyzing Potential Vulnerabilities in `memset` Usage**
Okay, so I've confirmed the obvious: `memset(scm, 0, sizeof(*scm))` *is* being used. But my gut is telling me to dig a little deeper here. Just because it's initialized, doesn't mean it's *secure*. The real question is, are there any potential timing issues. What if the `__scm_send` function modifies `scm->creds` after the initialization and leaves some uninitialized padding in the structure? That would be a classic memory disclosure issue. Let's trace it and see how it is handled in `__scm_send`. I'm going to jump in there and dissect its behavior.
|
| 104/2 |
2026/03/11 08:20 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/scm.c IncludeLines:true Name:__scm_send]
Results: map[SourceCode: 166: int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
167: {
168: const struct proto_ops *ops = READ_ONCE(sock->ops);
169: struct cmsghdr *cmsg;
170: int err;
171:
172: for_each_cmsghdr(cmsg, msg) {
173: err = -EINVAL;
174:
175: /* Verify that cmsg_len is at least sizeof(struct cmsghdr) */
176: /* The first check was omitted in <= 2.2.5. The reasoning was
177: that parser checks cmsg_len in any case, so that
178: additional check would be work duplication.
179: But if cmsg_level is not SOL_SOCKET, we do not check
180: for too short ancillary data object at all! Oops.
181: OK, let's add it...
182: */
183: if (!CMSG_OK(msg, cmsg))
184: goto error;
185:
186: if (cmsg->cmsg_level != SOL_SOCKET)
187: continue;
188:
189: switch (cmsg->cmsg_type)
190: {
191: case SCM_RIGHTS:
192: if (!ops || ops->family != PF_UNIX)
193: goto error;
194: err=scm_fp_copy(cmsg, &p->fp);
195: if (err<0)
196: goto error;
197: break;
198: case SCM_CREDENTIALS:
199: {
200: struct ucred creds;
201: kuid_t uid;
202: kgid_t gid;
203: if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred)))
204: goto error;
205: memcpy(&creds, CMSG_DATA(cmsg), sizeof(struct ucred));
206: err = scm_check_creds(&creds);
207: if (err)
208: goto error;
209:
210: if (!p->pid || pid_vnr(p->pid) != creds.pid) {
211: struct pid *pid;
212: err = -ESRCH;
213: pid = find_get_pid(creds.pid);
214: if (!pid)
215: goto error;
216:
217: /* pass a struct pid reference from
218: * find_get_pid() to scm_replace_pid().
219: */
220: err = scm_replace_pid(p, pid);
221: if (err) {
222: put_pid(pid);
223: goto error;
224: }
225: }
226:
227: err = -EINVAL;
228: uid = make_kuid(current_user_ns(), creds.uid);
229: gid = make_kgid(current_user_ns(), creds.gid);
230: if (!uid_valid(uid) || !gid_valid(gid))
231: goto error;
232:
233: p->creds.uid = uid;
234: p->creds.gid = gid;
235: break;
236: }
237: default:
238: goto error;
239: }
240: }
241:
242: if (p->fp && !p->fp->count)
243: {
244: kfree(p->fp);
245: p->fp = NULL;
246: }
247: return 0;
248:
249: error:
250: scm_destroy(p);
251: return err;
252: }
SourceFile:net/core/scm.c]
|
| 105/2 |
2026/03/11 08:20 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 158024
output: 41
thoughts: 143
Thoughts: **Unraveling a Potential Security Flaw**
Okay, let me break this down. I'm looking at this code and immediately something's catching my attention. We're copying a `struct ucred` using `memcpy` from `CMSG_DATA(cmsg)` into a local `creds` variable. The concern, however, is if that `CMSG_DATA(cmsg)` contains uninitialized memory, then `creds` is also going to be filled with uninitialized data. That's the first red flag.
Then I see the subsequent assignment `p->creds.uid = uid; p->creds.gid = gid;`. Okay, so we're setting the user and group IDs. But... wait a minute! My internal alarm bells are going off. The process ID, `p->creds.pid`, is NOT being updated here. That's a critical oversight.
Now, I see the `p->pid` field is updated through a call to `scm_replace_pid(p, pid)`. Okay, that's expected, but `p->creds.pid` is still left untouched. That's concerning. I need to dig deeper into the `scm_replace_pid` function. I have to understand how that interaction works and if there's an implicit update there that I'm missing, or confirm this is, as I suspect, a real vulnerability. This warrants a very close inspection of `scm_replace_pid` and how it interacts with the `creds` struct. This could be a race condition waiting to happen, or worse – a potential information leak or privilege escalation path.
|
| 106/2 |
2026/03/11 08:21 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/scm.c IncludeLines:true Name:scm_replace_pid]
Results: map[SourceCode: 150: static inline int scm_replace_pid(struct scm_cookie *scm, struct pid *pid)
151: {
152: int err;
153:
154: /* drop all previous references */
155: scm_destroy_cred(scm);
156:
157: err = pidfs_register_pid(pid);
158: if (unlikely(err))
159: return err;
160:
161: scm->pid = pid;
162: scm->creds.pid = pid_vnr(pid);
163: return 0;
164: }
SourceFile:net/core/scm.c]
|
| 107/2 |
2026/03/11 08:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 158780
output: 41
thoughts: 110
Thoughts: **Analyzing the `scm->creds.pid` Update**
Okay, so I'm looking at this line: `scm->creds.pid = pid_vnr(pid);`. Right, so `scm->creds.pid` gets updated. Makes sense. But wait a second... this triggers a question, what if the conditional `!p->pid || pid_vnr(p->pid) != creds.pid` is false? Then `scm_replace_pid` *isn't* called. Now I have to go deeper, because my current understanding requires deeper verification to ensure the data is set correctly. Because if `scm_replace_pid` isn't called, what does that mean for the state of `p->creds.pid`? Ah, but I remember, `p->creds.pid` *was* initialized by `scm_set_cred` within `scm_send`. Now I just need to verify that. I'll need to check the logic within `scm_set_cred` to confirm the initialization and what the expected values are in that case.
|
| 108/2 |
2026/03/11 08:21 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/scm.c IncludeLines:true Name:scm_set_cred]
Results: map[SourceCode: 69: static __inline__ void scm_set_cred(struct scm_cookie *scm,
70: struct pid *pid, kuid_t uid, kgid_t gid)
71: {
72: scm->pid = get_pid(pid);
73: scm->creds.pid = pid_vnr(pid);
74: scm->creds.uid = uid;
75: scm->creds.gid = gid;
76: }
SourceFile:include/net/scm.h]
|
| 109/2 |
2026/03/11 08:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 159325
output: 40
thoughts: 647
Thoughts: **Debugging a Kernel Credential Issue**
Okay, so I'm diving into this netlink credential issue. I know `scm->creds` is definitely initialized, so the mystery lies in why `ucreds` appears uninitialized within `__scm_recv_common`. Let's retrace the steps, starting with `netlink_recvmsg`. Okay, I see that the code does a `memset` on `scm`, then assigns `scm.creds` using `NETLINK_CREDS(skb)`. Aha! `NETLINK_CREDS(skb)` resolves to `&NETLINK_CB(skb).creds`. Right, where does that `NETLINK_CB(skb).creds` originate?
Ah, got it! If the `skb` is an ACK message, it's allocated by `netlink_ack`. `netlink_ack` in turn uses `nlmsg_new`, which eventually calls `alloc_skb`. And `alloc_skb` uses `__alloc_skb`, which calls `skbuff_clear`. And *that* zeros out the `cb` structure. So, that's it: `NETLINK_CB(skb).creds` ends up zeroed.
Okay, let's step back for a moment. But a zeroed `scm_creds` is initialized, isn't it? If it's zeroed, that means `pid = 0`, `uid = 0`, and `gid = 0`. `kuid_t` and `kgid_t` are structs wrapping `uid_t` and `gid_t`, so zero initialization on those members would be completely valid. So why did KMSAN flag it as an uninitialized value?
Let's re-examine the KMSAN report, carefully. The critical line is, "uninit-value in put_cmsg+0x534/0xbc0 net/core/scm.c:280". Wait a minute, `put_cmsg` is called with `&ucreds`. `put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);`. Okay, I need to check how `put_cmsg` deals with the `&ucreds` pointer, and see what it's doing with it.
|
| 110/2 |
2026/03/11 08:21 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/scm.c IncludeLines:true Name:put_cmsg]
Results: map[SourceCode: 255: int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)
256: {
257: int cmlen = CMSG_LEN(len);
258:
259: if (msg->msg_flags & MSG_CMSG_COMPAT)
260: return put_cmsg_compat(msg, level, type, len, data);
261:
262: if (!msg->msg_control || msg->msg_controllen < sizeof(struct cmsghdr)) {
263: msg->msg_flags |= MSG_CTRUNC;
264: return 0; /* XXX: return error? check spec. */
265: }
266: if (msg->msg_controllen < cmlen) {
267: msg->msg_flags |= MSG_CTRUNC;
268: cmlen = msg->msg_controllen;
269: }
270:
271: if (msg->msg_control_is_user) {
272: struct cmsghdr __user *cm = msg->msg_control_user;
273:
274: check_object_size(data, cmlen - sizeof(*cm), true);
275:
276: scoped_user_write_access_size(cm, cmlen, efault) {
277: unsafe_put_user(cmlen, &cm->cmsg_len, efault);
278: unsafe_put_user(level, &cm->cmsg_level, efault);
279: unsafe_put_user(type, &cm->cmsg_type, efault);
280: unsafe_copy_to_user(CMSG_USER_DATA(cm), data,
281: cmlen - sizeof(*cm), efault);
282: }
283: } else {
284: struct cmsghdr *cm = msg->msg_control;
285:
286: cm->cmsg_level = level;
287: cm->cmsg_type = type;
288: cm->cmsg_len = cmlen;
289: memcpy(CMSG_DATA(cm), data, cmlen - sizeof(*cm));
290: }
291:
292: cmlen = min(CMSG_SPACE(len), msg->msg_controllen);
293: if (msg->msg_control_is_user)
294: msg->msg_control_user += cmlen;
295: else
296: msg->msg_control += cmlen;
297: msg->msg_controllen -= cmlen;
298: return 0;
299:
300: efault:
301: return -EFAULT;
302: }
SourceFile:net/core/scm.c]
|
| 111/2 |
2026/03/11 08:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 161355
output: 40
thoughts: 179
Thoughts: **Analyzing the Kernel's `unsafe_copy_to_user` Call**
Okay, let's break this down. That `unsafe_copy_to_user` call with `CMSG_USER_DATA(cm), data, cmlen - sizeof(*cm), efault)` is giving me pause. I need to make sure this is safe.
If `cmlen` is the length of a control message containing user credentials, the calculation `cmlen - sizeof(*cm)` needs close scrutiny. Specifically, if `cmlen` is the size of the `ucreds` message (where we expect to have a `ucred` struct in the control message), then that `cmlen - sizeof(*cm)` is supposed to equal the size of our user credential data.
Right, the `ucred` structure itself – let's see, it's 12 bytes. So we expect `cmlen - sizeof(*cm)` to resolve to 12. But hold on, the `CMSG_LEN` macro, which is implied here, aligns the lengths, and that gives me a shiver. So, `CMSG_LEN(12)` is what we need to calculate.
Let's do the math. The `cmsghdr` itself is 16 bytes. Does `CMSG_LEN(12)` expand to `sizeof(struct cmsghdr) + 12`? No, it will be aligned! The size of the `cmsghdr` is 16. That means `CMSG_LEN(12)` is 16 plus 12, or 28 bytes! But it should be aligned! Therefore, I need to go look up and confirm how `CMSG_LEN` is defined and what the alignment requirements are for `cmsghdr` and any data which is stored in the control message. I'm getting a bad feeling here. Let's dig into the implementation of `CMSG_LEN` and confirm.
|
| 112/2 |
2026/03/11 08:21 |
tool |
codesearch-definition-source |
0m
Error:
Args: map[ContextFile:net/core/scm.c IncludeLines:true Name:CMSG_LEN]
Results: map[SourceCode: SourceFile:]
|
| 113/2 |
2026/03/11 08:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 162024
output: 20
thoughts: 11
Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience:
**Grep'ing for `CMSG_LEN`**
Okay, so I'm thinking about the low-level socket programming and message passing in this context. Immediately, my mind jumps to the need to correctly calculate the ancillary data length in control messages. "CMSG_LEN" is the obvious candidate I'm focusing on; it's practically the first thing I'd reach for when dealing with `sendmsg` or `recvmsg`. I need to figure out how to correctly size those control messages, especially if I'm dealing with complex structures within the ancillary data – perhaps file descriptors, credentials, or something similar. I need to make sure I'm not truncating any information or introducing buffer overflows. That `CMSG_LEN` macro is absolutely crucial for proper alignment. I'm going to start looking at where and how it is used within the code base. Let's start with a global search, so I can see every instance and understand how it's being handled in the given context.
|
| 114/2 |
2026/03/11 08:21 |
tool |
grepper |
0m
Args: map[Expression:#define CMSG_LEN]
Results: map[Output:include/linux/socket.h=120=struct cmsghdr {
--
include/linux/socket.h-140-#define CMSG_SPACE(len) (sizeof(struct cmsghdr) + CMSG_ALIGN(len))
include/linux/socket.h:141:#define CMSG_LEN(len) (sizeof(struct cmsghdr) + (len))
include/linux/socket.h-142-
--
tools/perf/trace/beauty/include/linux/socket.h=120=struct cmsghdr {
--
tools/perf/trace/beauty/include/linux/socket.h-140-#define CMSG_SPACE(len) (sizeof(struct cmsghdr) + CMSG_ALIGN(len))
tools/perf/trace/beauty/include/linux/socket.h:141:#define CMSG_LEN(len) (sizeof(struct cmsghdr) + (len))
tools/perf/trace/beauty/include/linux/socket.h-142-
]
|
| 115/2 |
2026/03/11 08:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 162537
output: 38
thoughts: 283
Thoughts: **Debugging a Potential KMSAN Issue in Kernel Credential Passing**
Okay, so `CMSG_LEN(len)` gives me the total control message length, which is `sizeof(struct cmsghdr) + len`. That means `cmlen - sizeof(*cm)` *should* equal the payload `len`. And from what I see in the code, `unsafe_copy_to_user` copies 12 bytes.
Now, I'm thinking about this `ucreds` struct. It looks like it's *supposed* to be 12 bytes: a `pid_t`, a `uid_t`, and a `gid_t`. And it appears to be *fully initialized* in this call. Yet, KMSAN is complaining. Something isn't adding up.
Let me look back at `__scm_recv_common` and the relevant code. Okay, here we have:
```c
struct ucred ucreds = {
.pid = scm->creds.pid,
.uid = from_kuid_munged(current_ns, scm->creds.uid),
.gid = from_kgid_munged(current_ns, scm->creds.gid),
};
```
Wait a minute... `from_kuid_munged` is returning a `uid_t`, and `from_kgid_munged` is returning a `gid_t`. And `pid` is `pid_t`. I'm pretty sure all three of these are 32-bit integers, which would give us a total of 12 bytes. That should be correct!
But... is there *any* padding in `struct ucred`? I need to double-check the definition. Just to be sure. It could be that this is where the error lies.
|
| 116/2 |
2026/03/11 08:21 |
tool |
codesearch-struct-layout |
0m
Args: map[ContextFile:net/core/scm.c FieldOffset:<nil> Name:ucred]
Results: map[Fields:[map[Name:pid OffsetBits:0 SizeBits:32] map[Name:uid OffsetBits:32 SizeBits:32] map[Name:gid OffsetBits:64 SizeBits:32]]]
|
| 117/2 |
2026/03/11 08:21 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 163332
output: 44
thoughts: 408
Thoughts: **Unraveling a Potential Uninitialized Value in Netlink Credentials**
Okay, so I'm digging into this netlink code, and I see this line: `scm->creds.pid`. I need to figure out if it's possible for that to be uninitialized. My immediate concern is, where does `scm->creds` even come from?
I'm in `netlink_recvmsg`, and it looks like `scm` is zeroed out, then `scm.creds` is assigned a value from the socket buffer (`skb`). Specifically, it seems to be `&NETLINK_CB(skb).creds`. Right, I remember that `NETLINK_CB(skb)` is the Control Block for the Socket Buffer. But that brings up the critical question: is there any way for `NETLINK_CB(skb).creds` *not* to be initialized?
I know we checked `netlink_ack` and `nlmsg_new` recently. Let's see... `nlmsg_new` calls `alloc_skb`, which ultimately goes to `skbuff_clear`. And `skbuff_clear` zeros out the entire control block (`cb`). So if `nlmsg_new` allocated the skb, the `creds` field *should* be zeroed.
But wait a minute... what if the `skb` *isn't* allocated by `nlmsg_new`? That's the key. Where else could it come from? What about `netlink_alloc_large_skb`? That also calls `__build_skb`, which calls `skbuff_clear`, so that looks good. `skb_recv_datagram` just dequeues, so it's not a source of allocation. `netlink_ack` we already addressed. `netlink_sendmsg` uses `netlink_alloc_large_skb`, so that seems safe as well. Then there's the `NETLINK_CB(skb).creds = scm.creds` line that's setting the value.
Okay, last one...what about `netlink_dump`? I need to check how `netlink_dump` allocates the `skb`. Looks like that is the last place to check.
|
| 118/2 |
2026/03/11 08:22 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_dump]
Results: map[SourceCode:2253: static int netlink_dump(struct sock *sk, bool lock_taken)
2254: {
2255: struct netlink_sock *nlk = nlk_sk(sk);
2256: struct netlink_ext_ack extack = {};
2257: struct netlink_callback *cb;
2258: struct sk_buff *skb = NULL;
2259: unsigned int rmem, rcvbuf;
2260: size_t max_recvmsg_len;
2261: struct module *module;
2262: int err = -ENOBUFS;
2263: int alloc_min_size;
2264: int alloc_size;
2265:
2266: if (!lock_taken)
2267: mutex_lock(&nlk->nl_cb_mutex);
2268: if (!nlk->cb_running) {
2269: err = -EINVAL;
2270: goto errout_skb;
2271: }
2272:
2273: /* NLMSG_GOODSIZE is small to avoid high order allocations being
2274: * required, but it makes sense to _attempt_ a 32KiB allocation
2275: * to reduce number of system calls on dump operations, if user
2276: * ever provided a big enough buffer.
2277: */
2278: cb = &nlk->cb;
2279: alloc_min_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
2280:
2281: max_recvmsg_len = READ_ONCE(nlk->max_recvmsg_len);
2282: if (alloc_min_size < max_recvmsg_len) {
2283: alloc_size = max_recvmsg_len;
2284: skb = alloc_skb(alloc_size,
2285: (GFP_KERNEL & ~__GFP_DIRECT_RECLAIM) |
2286: __GFP_NOWARN | __GFP_NORETRY);
2287: }
2288: if (!skb) {
2289: alloc_size = alloc_min_size;
2290: skb = alloc_skb(alloc_size, GFP_KERNEL);
2291: }
2292: if (!skb)
2293: goto errout_skb;
2294:
2295: rcvbuf = READ_ONCE(sk->sk_rcvbuf);
2296: rmem = atomic_add_return(skb->truesize, &sk->sk_rmem_alloc);
2297: if (rmem != skb->truesize && rmem >= rcvbuf) {
2298: atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
2299: goto errout_skb;
2300: }
2301:
2302: /* Trim skb to allocated size. User is expected to provide buffer as
2303: * large as max(min_dump_alloc, 32KiB (max_recvmsg_len capped at
2304: * netlink_recvmsg())). dump will pack as many smaller messages as
2305: * could fit within the allocated skb. skb is typically allocated
2306: * with larger space than required (could be as much as near 2x the
2307: * requested size with align to next power of 2 approach). Allowing
2308: * dump to use the excess space makes it difficult for a user to have a
2309: * reasonable static buffer based on the expected largest dump of a
2310: * single netdev. The outcome is MSG_TRUNC error.
2311: */
2312: skb_reserve(skb, skb_tailroom(skb) - alloc_size);
2313:
2314: /* Make sure malicious BPF programs can not read unitialized memory
2315: * from skb->head -> skb->data
2316: */
2317: skb_reset_network_header(skb);
2318: skb_reset_mac_header(skb);
2319:
2320: netlink_skb_set_owner_r(skb, sk);
2321:
2322: if (nlk->dump_done_errno > 0) {
2323: cb->extack = &extack;
2324:
2325: nlk->dump_done_errno = cb->dump(skb, cb);
2326:
2327: /* EMSGSIZE plus something already in the skb means
2328: * that there's more to dump but current skb has filled up.
2329: * If the callback really wants to return EMSGSIZE to user space
2330: * it needs to do so again, on the next cb->dump() call,
2331: * without putting data in the skb.
2332: */
2333: if (nlk->dump_done_errno == -EMSGSIZE && skb->len)
2334: nlk->dump_done_errno = skb->len;
2335:
2336: cb->extack = NULL;
2337: }
2338:
2339: if (nlk->dump_done_errno > 0 ||
2340: skb_tailroom(skb) < nlmsg_total_size(sizeof(nlk->dump_done_errno))) {
2341: mutex_unlock(&nlk->nl_cb_mutex);
2342:
2343: if (sk_filter(sk, skb))
2344: kfree_skb(skb);
2345: else
2346: __netlink_sendskb(sk, skb);
2347: return 0;
2348: }
2349:
2350: if (netlink_dump_done(nlk, skb, cb, &extack))
2351: goto errout_skb;
2352:
2353: #ifdef CONFIG_COMPAT_NETLINK_MESSAGES
2354: /* frag_list skb's data is used for compat tasks
2355: * and the regular skb's data for normal (non-compat) tasks.
2356: * See netlink_recvmsg().
2357: */
2358: if (unlikely(skb_shinfo(skb)->frag_list)) {
2359: if (netlink_dump_done(nlk, skb_shinfo(skb)->frag_list, cb, &extack))
2360: goto errout_skb;
2361: }
2362: #endif
2363:
2364: if (sk_filter(sk, skb))
2365: kfree_skb(skb);
2366: else
2367: __netlink_sendskb(sk, skb);
2368:
2369: if (cb->done)
2370: cb->done(cb);
2371:
2372: WRITE_ONCE(nlk->cb_running, false);
2373: module = cb->module;
2374: skb = cb->skb;
2375: mutex_unlock(&nlk->nl_cb_mutex);
2376: module_put(module);
2377: consume_skb(skb);
2378: return 0;
2379:
2380: errout_skb:
2381: mutex_unlock(&nlk->nl_cb_mutex);
2382: kfree_skb(skb);
2383: return err;
2384: }
SourceFile:net/netlink/af_netlink.c]
|
| 119/2 |
2026/03/11 08:22 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 166460
output: 40
thoughts: 293
Thoughts: **Netlink Credential Concerns**
Okay, so I'm digging into this `netlink_dump` function and how it handles `skb` allocation and transmission. My concern is around the `NETLINK_CB(skb).creds` structure. It looks like `alloc_skb` is used to allocate the `skb`, and then `__netlink_sendskb` sends it. The crux of the matter is whether `NETLINK_CB(skb).creds` is actually *initialized* before transmission. From what I see, it's not explicitly initialized.
However, `alloc_skb` also seems to zero the `cb` area, which should include our `creds` field. So, if `cb` is zeroed, then `NETLINK_CB(skb).creds` *is* zeroed, right? And that's usually considered initialized, according to KMSAN. But that hinges on zeroed `creds` being considered initialized by the kernel memory sanitizer.
Okay, let's look at `struct scm_creds`: `pid`, `uid`, and `gid`. If they're all zero, then it's certainly initialized, from a fundamental perspective, even if those values are not what the sending program actually wanted.
But what if, *somehow*, the `skb` is allocated *without* the `cb` being zeroed? Could that even happen? Back to basics: `__alloc_skb` calls `skbuff_clear`. Right, and `skbuff_clear` uses `memset(skb, 0, 128)`. The key question now is, is the `cb` structure within the first 128 bytes of the `sk_buff` structure? If it isn't, the zeroing won't affect it, and we might have an uninitialized memory read! I should double-check the `sk_buff` layout again to be certain.
|
| 120/2 |
2026/03/11 08:22 |
tool |
codesearch-struct-layout |
0m
Args: map[ContextFile:net/core/skbuff.c FieldOffset:<nil> Name:sk_buff]
Results: map[Fields:[map[Name: OffsetBits:0 SizeBits:192] map[Name:sk OffsetBits:192 SizeBits:64] map[Name: OffsetBits:256 SizeBits:64] map[Name:cb OffsetBits:320 SizeBits:384] map[Name: OffsetBits:704 SizeBits:128] map[Name:_nfct OffsetBits:832 SizeBits:64] map[Name:len OffsetBits:896 SizeBits:32] map[Name:data_len OffsetBits:928 SizeBits:32] map[Name:mac_len OffsetBits:960 SizeBits:16] map[Name:hdr_len OffsetBits:976 SizeBits:16] map[Name:queue_mapping OffsetBits:992 SizeBits:16] map[Name:__cloned_offset OffsetBits:1008 SizeBits:0] map[Name:cloned OffsetBits:1008 SizeBits:1] map[Name:nohdr OffsetBits:1009 SizeBits:1] map[Name:fclone OffsetBits:1010 SizeBits:2] map[Name:peeked OffsetBits:1012 SizeBits:1] map[Name:head_frag OffsetBits:1013 SizeBits:1] map[Name:pfmemalloc OffsetBits:1014 SizeBits:1] map[Name:pp_recycle OffsetBits:1015 SizeBits:1] map[Name:active_extensions OffsetBits:1016 SizeBits:8] map[Name: OffsetBits:1024 SizeBits:576] map[Name:tail OffsetBits:1600 SizeBits:32] map[Name:end OffsetBits:1632 SizeBits:32] map[Name:head OffsetBits:1664 SizeBits:64] map[Name:data OffsetBits:1728 SizeBits:64] map[Name:truesize OffsetBits:1792 SizeBits:32] map[Name:users OffsetBits:1824 SizeBits:32] map[Name:extensions OffsetBits:1856 SizeBits:64]]]
|
| 121/2 |
2026/03/11 08:22 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 167796
output: 43
thoughts: 1277
Thoughts: **Analyzing a KMSAN Uninit-Value Report in Netlink**
Okay, so I'm looking at this KMSAN report pointing to an uninitialized value within `put_cmsg`. The report says it's happening when passing `&ucreds`. My initial thought is that maybe `ucreds` itself is uninitialized, but a quick check reveals that it's initialized with values derived from `scm->creds`. Since `scm->creds` is, in theory, populated from `NETLINK_CB(skb).creds` - which I *thought* was always zeroed, I'm a bit stumped.
My first impulse was to revisit the allocation path. I initially reasoned that since `skbuff_clear` is called on all `alloc_skb` paths, the `cb` should always be zeroed. I double checked the `alloc_skb` logic, including the NAPI cache path, but `skbuff_clear` is called right after getting the skb from the cache. So, allocation via `alloc_skb` should be safe.
Then, the thought hits me, is the `skb` *always* allocated by `alloc_skb`? What about cloning? `skb_clone` calls `__skb_clone`, and then `__copy_skb_header`, which directly copies the `cb` from the original SKB. If the *original* `skb`'s `cb` is uninitialized, that uninitialized data gets copied. But wait, even cloned skbs should be, at some point, allocated via `alloc_skb`, so their `cb` should be zeroed originally.
Then, the lightbulb! What if another layer is *overwriting* `cb` with uninitialized data *before* the skb reaches netlink? Maybe some other driver allocates an skb, uses `cb` for something and leaves uninitialized data there, and then that skb somehow gets passed to netlink? I need to think about how skbs flow to netlink sockets. How does an skb from a different part of the kernel even end up in netlink? `dev_forward_skb` and other forwarding functions come to mind, but no, netlink's not a forwarding layer. It receives skbs that are explicitly sent to it.
So, who sends skbs to netlink sockets? I'm thinking about:
1. `netlink_unicast`
2. `netlink_broadcast`
3. `netlink_ack`
4. `netlink_dump`
5. Kernel users, like `rtmsg_ifinfo` or the audit log, etc.
If a kernel user allocates an `skb` with `nlmsg_new` and sends it, it should be zeroed, right? Hmm, maybe not! What if a kernel user allocates an `skb` directly, then *uses* `cb` for something else *before* calling a netlink function to send it? That's a potential problem! Okay, I need to check how those netlink kernel users operate. I'm going to focus on, say, `rtmsg_ifinfo`. That's where I need to dig.
|
| 122/2 |
2026/03/11 08:22 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/rtnetlink.c IncludeLines:true Name:rtmsg_ifinfo]
Results: map[SourceCode:4455: void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change,
4456: gfp_t flags, u32 portid, const struct nlmsghdr *nlh)
4457: {
4458: rtmsg_ifinfo_event(type, dev, change, rtnl_get_event(0), flags,
4459: NULL, 0, portid, nlh);
4460: }
SourceFile:net/core/rtnetlink.c]
|
| 123/2 |
2026/03/11 08:22 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 169974
output: 45
thoughts: 13
Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience, and delivered as a first-person summary:
**Diving into the `rtmsg_ifinfo_event`**
Right, let's take a look at that `rtmsg_ifinfo_event` function. It’s been bothering me that... well, let's just get down to brass tacks. I'm thinking we need to trace exactly what's going on within that routine. It's the point where we receive information about network interface changes, and I've got a hunch there's a particular edge case we're missing, or maybe not handling optimally. I need to refresh my memory on the data structures it consumes, the assumptions it makes about the network stack's state, and where its output goes. I need to verify that we are correctly handling interface state transitions and making sure that our routing tables stay correct as a result of those state changes.
|
| 124/2 |
2026/03/11 08:22 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/rtnetlink.c IncludeLines:true Name:rtmsg_ifinfo_event]
Results: map[SourceCode:4439: static void rtmsg_ifinfo_event(int type, struct net_device *dev,
4440: unsigned int change, u32 event,
4441: gfp_t flags, int *new_nsid, int new_ifindex,
4442: u32 portid, const struct nlmsghdr *nlh)
4443: {
4444: struct sk_buff *skb;
4445:
4446: if (dev->reg_state != NETREG_REGISTERED)
4447: return;
4448:
4449: skb = rtmsg_ifinfo_build_skb(type, dev, change, event, flags, new_nsid,
4450: new_ifindex, portid, nlh);
4451: if (skb)
4452: rtmsg_ifinfo_send(skb, dev, flags, portid, nlh);
4453: }
SourceFile:net/core/rtnetlink.c]
|
| 125/2 |
2026/03/11 08:22 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 170532
output: 48
thoughts: 16
Thoughts: Okay, here's my attempt at summarizing the thought process, speaking as if these were my internal thoughts, assuming I'm an expert in the field:
**Diving into `rtmsg_ifinfo_build_skb`**
Alright, time to dig into this. I see the prompt is about `rtmsg_ifinfo_build_skb`. Okay, good. Let's see what's going on here. I'm immediately thinking about network interface information and how the kernel builds skbs (socket buffer) to pass along to userspace. I'll need to remember the typical structures involved: `nlmsghdr`, `ifinfomsg`, probably some attribute headers (`rtattr`) for the interface name, address, flags, etc. This function is, in all likelihood, the core of packaging up that ifinfo into a Netlink message. My mind is starting to race – am I dealing with an add, delete, or modify operation? That will affect what information needs to be packed into the skb and the attributes included. Now I am interested to see how it handles the different address families and which attributes are added based on the presence of a specific flag.
|
| 126/2 |
2026/03/11 08:23 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/rtnetlink.c IncludeLines:true Name:rtmsg_ifinfo_build_skb]
Results: map[SourceCode:4396: struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
4397: unsigned int change,
4398: u32 event, gfp_t flags, int *new_nsid,
4399: int new_ifindex, u32 portid,
4400: const struct nlmsghdr *nlh)
4401: {
4402: struct net *net = dev_net(dev);
4403: struct sk_buff *skb;
4404: int err = -ENOBUFS;
4405: u32 seq = 0;
4406:
4407: skb = nlmsg_new(if_nlmsg_size(dev, 0), flags);
4408: if (skb == NULL)
4409: goto errout;
4410:
4411: if (nlmsg_report(nlh))
4412: seq = nlmsg_seq(nlh);
4413: else
4414: portid = 0;
4415:
4416: err = rtnl_fill_ifinfo(skb, dev, dev_net(dev),
4417: type, portid, seq, change, 0, 0, event,
4418: new_nsid, new_ifindex, -1, flags);
4419: if (err < 0) {
4420: /* -EMSGSIZE implies BUG in if_nlmsg_size() */
4421: WARN_ON(err == -EMSGSIZE);
4422: kfree_skb(skb);
4423: goto errout;
4424: }
4425: return skb;
4426: errout:
4427: rtnl_set_sk_err(net, RTNLGRP_LINK, err);
4428: return NULL;
4429: }
SourceFile:net/core/rtnetlink.c]
|
| 127/2 |
2026/03/11 08:23 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 171419
output: 45
thoughts: 1092
Thoughts: **Unraveling the KMSAN Uninit-Value in `put_cmsg`**
Okay, so I'm looking at this KMSAN report pointing to an uninitialized value in `put_cmsg` during netlink message handling. The trace leads me down this path: `nlmsg_new` zeroes the `cb` structure in the `skb`, so that seems okay. But then, I start thinking about the possibility of `netlink_ack` sending an `skb`, and `netlink_recvmsg` reading from `NETLINK_CREDS(skb)`. Now, the crucial part is, if `NETLINK_CB(skb).creds` is zeroed, then `scm.creds` is zeroed, which means `ucreds` should be initialized with zeroes. Therefore, when `put_cmsg` copies `ucreds` to user space, it *should* be fully initialized.
The bug report says: `BUG: KMSAN: uninit-value in put_cmsg+0x534/0xbc0 net/core/scm.c:280`. Let's look at `net/core/scm.c:280` specifically: `unsafe_copy_to_user(CMSG_USER_DATA(cm), data, cmlen - sizeof(*cm), efault);`. KMSAN is flagging this copy to user space. The problem appears to be that the contents of `data` (which is `&ucreds`) is uninitialized. But I thought it was initialized! The code clearly shows that:
```c
struct ucred ucreds = {
.pid = scm->creds.pid,
.uid = from_kuid_munged(current_ns, scm->creds.uid),
.gid = from_kgid_munged(current_ns, scm->creds.gid),
};
```
I'm initializing `ucreds` with the pid, uid, and gid. Hmm, is there any padding in `struct ucred`? No, there is no padding:
```c
struct ucred {
__u32 pid;
__u32 uid;
__u32 gid;
};
```
So, what about `scm->creds.pid` being uninitialized? If `scm->creds` is copied from `NETLINK_CB(skb).creds`, and that's uninitialized, then that's the issue. But wait, `skbuff_clear` zeroes `NETLINK_CB(skb).creds`. Unless it is somehow NOT zeroed...
Let's revisit `netlink_recvmsg`:
```c
memset(&scm, 0, sizeof(scm));
scm.creds = *NETLINK_CREDS(skb);
```
Okay, what if the `skb` isn't the one allocated by `nlmsg_new`? What if it's a `frag_list` skb? I see this check in the code:
```c
#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
if (unlikely(skb_shinfo(skb)->frag_list)) {
if (flags & MSG_CMSG_COMPAT)
data_skb = skb_shinfo(skb)->frag_list;
}
#endif
```
However, `scm.creds = *NETLINK_CREDS(skb);` uses the main `skb`, not `data_skb`. So the `frag_list` skb isn't the problem here. I'm focusing on the main `skb` in this case. What if its `cb` is not initialized? This isn't the case as the function checks if the skb is initialized.
What about `skb` allocated by `netlink_alloc_large_skb` and `head_size > PAGE_SIZE`?
```c
data = kvmalloc(head_size, GFP_KERNEL);
if (!data)
return NULL;
skb = __build_skb(data, head_size);
```
`__build_skb` calls `skbuff_clear`. Is there another way the `skb` is allocated? What if `skb` is allocated by `alloc_skb`, but `cb` is overwritten somehow? I'll need to check `netlink_sendmsg` to look for that.
|
| 128/2 |
2026/03/11 08:23 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_sendmsg]
Results: map[SourceCode:1812: static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
1813: {
1814: struct sock *sk = sock->sk;
1815: struct netlink_sock *nlk = nlk_sk(sk);
1816: DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name);
1817: u32 dst_portid;
1818: u32 dst_group;
1819: struct sk_buff *skb;
1820: int err;
1821: struct scm_cookie scm;
1822: u32 netlink_skb_flags = 0;
1823:
1824: if (msg->msg_flags & MSG_OOB)
1825: return -EOPNOTSUPP;
1826:
1827: if (len == 0) {
1828: pr_warn_once("Zero length message leads to an empty skb\n");
1829: return -ENODATA;
1830: }
1831:
1832: err = scm_send(sock, msg, &scm, true);
1833: if (err < 0)
1834: return err;
1835:
1836: if (msg->msg_namelen) {
1837: err = -EINVAL;
1838: if (msg->msg_namelen < sizeof(struct sockaddr_nl))
1839: goto out;
1840: if (addr->nl_family != AF_NETLINK)
1841: goto out;
1842: dst_portid = addr->nl_pid;
1843: dst_group = ffs(addr->nl_groups);
1844: err = -EPERM;
1845: if ((dst_group || dst_portid) &&
1846: !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
1847: goto out;
1848: netlink_skb_flags |= NETLINK_SKB_DST;
1849: } else {
1850: /* Paired with WRITE_ONCE() in netlink_connect() */
1851: dst_portid = READ_ONCE(nlk->dst_portid);
1852: dst_group = READ_ONCE(nlk->dst_group);
1853: }
1854:
1855: /* Paired with WRITE_ONCE() in netlink_insert() */
1856: if (!READ_ONCE(nlk->bound)) {
1857: err = netlink_autobind(sock);
1858: if (err)
1859: goto out;
1860: } else {
1861: /* Ensure nlk is hashed and visible. */
1862: smp_rmb();
1863: }
1864:
1865: err = -EMSGSIZE;
1866: if (len > sk->sk_sndbuf - 32)
1867: goto out;
1868: err = -ENOBUFS;
1869: skb = netlink_alloc_large_skb(len, dst_group);
1870: if (skb == NULL)
1871: goto out;
1872:
1873: NETLINK_CB(skb).portid = nlk->portid;
1874: NETLINK_CB(skb).dst_group = dst_group;
1875: NETLINK_CB(skb).creds = scm.creds;
1876: NETLINK_CB(skb).flags = netlink_skb_flags;
1877:
1878: err = -EFAULT;
1879: if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
1880: kfree_skb(skb);
1881: goto out;
1882: }
1883:
1884: err = security_netlink_send(sk, skb);
1885: if (err) {
1886: kfree_skb(skb);
1887: goto out;
1888: }
1889:
1890: if (dst_group) {
1891: refcount_inc(&skb->users);
1892: netlink_broadcast(sk, skb, dst_portid, dst_group, GFP_KERNEL);
1893: }
1894: err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags & MSG_DONTWAIT);
1895:
1896: out:
1897: scm_destroy(&scm);
1898: return err;
1899: }
SourceFile:net/netlink/af_netlink.c]
|
| 129/2 |
2026/03/11 08:23 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 174955
output: 48
thoughts: 873
Thoughts: **Unraveling a Kernel Memory Safety Puzzle**
Okay, so I'm diving into this netlink code, and I need to piece together a potential memory safety issue. The starting point seems to be this line: `NETLINK_CB(skb).creds = scm.creds;`. If `scm.creds` is uninitialized, then we're assigning an uninitialized value to the `NETLINK_CB(skb).creds` field. So, the question becomes, is `scm.creds` actually uninitialized in any given execution path?
I see that `scm_send` initializes `scm` using `memset`, then sets `scm->creds.uid` and `scm->creds.gid` to `INVALID_UID` and `INVALID_GID` respectively. If `forcecreds` is true, as it is in `netlink_sendmsg`, then `scm_set_cred` is called to populate the `pid`, `uid`, and `gid` fields, meaning `scm.creds` should be fully initialized in most cases. However...
The plot thickens when `msg->msg_controllen > 0` and `__scm_send` is called. `__scm_send` processes `SCM_CREDENTIALS` control messages. Inside that branch, we have this crucial block of code where `creds` is copied from the control message:
```c
case SCM_CREDENTIALS:
{
struct ucred creds;
kuid_t uid;
kgid_t gid;
if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred)))
goto error;
memcpy(&creds, CMSG_DATA(cmsg), sizeof(struct ucred));
err = scm_check_creds(&creds);
if (err)
goto error;
if (!p->pid || pid_vnr(p->pid) != creds.pid) {
struct pid *pid;
err = -ESRCH;
pid = find_get_pid(creds.pid);
if (!pid)
goto error;
/* pass a struct pid reference from
* find_get_pid() to scm_replace_pid().
*/
err = scm_replace_pid(p, pid);
if (err) {
put_pid(pid);
goto error;
}
}
err = -EINVAL;
uid = make_kuid(current_user_ns(), creds.uid);
gid = make_kgid(current_user_ns(), creds.gid);
if (!uid_valid(uid) || !gid_valid(gid))
goto error;
p->creds.uid = uid;
p->creds.gid = gid;
break;
}
```
Here's the kicker: If `CMSG_DATA(cmsg)` contains uninitialized memory, the local `creds` variable will also be uninitialized. Then, its `pid` is also uninitialized. `find_get_pid(creds.pid)` is then called with this uninitialized `pid`. This is exactly the kind of scenario KMSAN should flag with an uninitialized-value report in `find_get_pid`!
But, I remember the KMSAN report flagged `put_cmsg`. That means the uninitialized value isn't from `__scm_send` at all. This suggests the source might be in `__scm_recv_common`. I'll have to investigate that.
Wait, there is another scenario! What if the `skb` is an ACK message? `netlink_ack` allocates the `skb` with `nlmsg_new`, which in turn calls `alloc_skb`, and that ends up calling `__alloc_skb`. Importantly, `__alloc_skb` calls `skbuff_clear`, which zeroes the `cb` field, meaning the control block. So in this case, `NETLINK_CB(skb).creds` *should* be zeroed. Unless that zeroing is skipped somehow.
Let me take another look at the `struct netlink_skb_parms`. I've got to make sure I'm not missing something subtle in how that structure interacts with the control block. Time to dig deeper and see what I missed in this `struct`!
|
| 130/2 |
2026/03/11 08:23 |
tool |
codesearch-struct-layout |
0m
Args: map[ContextFile:net/netlink/af_netlink.c FieldOffset:<nil> Name:netlink_skb_parms]
Results: map[Fields:[map[Name:creds OffsetBits:0 SizeBits:96] map[Name:portid OffsetBits:96 SizeBits:32] map[Name:dst_group OffsetBits:128 SizeBits:32] map[Name:flags OffsetBits:160 SizeBits:32] map[Name:sk OffsetBits:192 SizeBits:64] map[Name:nsid_is_set OffsetBits:256 SizeBits:8] map[Name:nsid OffsetBits:288 SizeBits:32]]]
|
| 131/2 |
2026/03/11 08:23 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 177019
output: 42
thoughts: 1183
Thoughts: **Analyzing Potential Uninitialized Memory in Netlink SCM Credentials**
Okay, so I'm looking into this KMSAN report pointing to uninitialized memory. `creds` is at offset 0, which is 12 bytes. That lines up with `struct scm_creds`, which is simply three 4-byte fields: `pid`, `uid`, and `gid`, no padding there. The same size as `struct ucred`.
The report says the problem is in `net/core/scm.c:511`, specifically where `ucreds` is created. It copies values from `scm->creds`. If *that* structure is fully initialized, then `ucreds` should be too, right? So where is `scm->creds` coming from? Looking at `netlink_recvmsg`, I see `memset(&scm, 0, sizeof(scm));` followed by a direct copy: `scm.creds = *NETLINK_CREDS(skb);`.
Aha! It hinges on whether `NETLINK_CREDS(skb)` is initialized. Where *does* that come from? If the `skb` is an ACK message, it's allocated by `netlink_ack`, which calls `nlmsg_new`, and that calls `alloc_skb`, which then calls `__alloc_skb`. `__alloc_skb` then calls `skbuff_clear`.
Wait a minute, `skbuff_clear` zeroes `cb`! Let's verify that... Yep, it uses `memset` to zero *part* of the `skb` structure, then another `memset` for the rest. Crucially, it zeros the `cb` member. Does KMSAN know this? Yeah, KMSAN intercepts `memset` calls, which means it should correctly mark that memory as initialized.
But hold on... what if the `skb` is allocated from an SLAB cache, and KMSAN marks it as uninitialized upon allocation. What about `skbuff_clear`, is *that* instrumented by KMSAN? No, `skbuff_clear` is an inline function, so calls to `memset` are instrumented.
Okay, what if the `skb` wasn't allocated by `alloc_skb`? Let's consider alternatives like `kmem_cache_alloc`, but then realized that isn't true, `alloc_skb` or `build_skb` *must* be used to allocate the skb. What if the `skb` isn't an ACK message? Like, is it a message from another subsystem? `rtmsg_ifinfo`, for example, allocates an `skb` and sends it. But that uses `nlmsg_new`, which in turn calls `alloc_skb`.
Now I'm thinking, what about `netlink_alloc_large_skb`? It uses `kvmalloc` and `__build_skb`. `kvmalloc` *doesn't* zero the memory, but `__build_skb` then calls `skbuff_clear`. Wait, `skbuff_clear` zeroes `skb` NOT `skb->head` or `skb->data`. *cb* is in `struct sk_buff`, so *it* should be zeroed!
So, the issue isn't as simple. Is there any path where `cb` is *not* zeroed after all? I need to re-examine `__build_skb` carefully...
|
| 132/2 |
2026/03/11 08:23 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/core/skbuff.c IncludeLines:true Name:__build_skb]
Results: map[SourceCode: 468: /**
469: * __build_skb - build a network buffer
470: * @data: data buffer provided by caller
471: * @frag_size: size of data (must not be 0)
472: *
473: * Allocate a new &sk_buff. Caller provides space holding head and
474: * skb_shared_info. @data must have been allocated from the page
475: * allocator or vmalloc(). (A @frag_size of 0 to indicate a kmalloc()
476: * allocation is deprecated, and callers should use slab_build_skb()
477: * instead.)
478: * The return is the new skb buffer.
479: * On a failure the return is %NULL, and @data is not freed.
480: * Notes :
481: * Before IO, driver allocates only data buffer where NIC put incoming frame
482: * Driver should add room at head (NET_SKB_PAD) and
483: * MUST add room at tail (SKB_DATA_ALIGN(skb_shared_info))
484: * After IO, driver calls build_skb(), to allocate sk_buff and populate it
485: * before giving packet to stack.
486: * RX rings only contains data buffers, not full skbs.
487: */
488: struct sk_buff *__build_skb(void *data, unsigned int frag_size)
489: {
490: struct sk_buff *skb;
491:
492: skb = kmem_cache_alloc(net_hotdata.skbuff_cache,
493: GFP_ATOMIC | __GFP_NOWARN);
494: if (unlikely(!skb))
495: return NULL;
496:
497: skbuff_clear(skb);
498: __build_skb_around(skb, data, frag_size);
499:
500: return skb;
501: }
SourceFile:net/core/skbuff.c]
|
| 133/2 |
2026/03/11 08:23 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 179609
output: 47
thoughts: 91
Thoughts: Okay, let me think this through.
**Analyzing skbuff_clear in the Context of Netlink SKB Allocation**
Right, so I'm focusing on `skbuff_clear`. I know it's being called, that's a given. But my concern is the allocation path. Let's see... *If* the `skb` (socket buffer) is allocated using `netlink_alloc_large_skb`, and *if* `head_size` is less than or equal to `PAGE_SIZE`, then it *should* go through `alloc_skb`, which ultimately calls `__alloc_skb`, which *then* calls `skbuff_clear`. That's the expected path, making sure the SKB is initialized correctly.
But what if, and this is where I need to be precise, the `skb` is allocated via a different method: `netlink_alloc_skb`? I need to trace *that* path and determine if the same initialization steps are taken. The behaviour might be different and I need to check if there is a potential for a problem, or missed initialization. I need to understand that call chain too.
|
| 134/2 |
2026/03/11 08:24 |
tool |
codesearch-definition-source |
0m
Error:
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_alloc_skb]
Results: map[SourceCode: SourceFile:]
|
| 135/2 |
2026/03/11 08:24 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 180019
output: 45
thoughts: 1238
Thoughts: **Analyzing Netlink SKB Credential Handling**
Okay, so I'm diving into how `NETLINK_CB(skb).creds` gets set and whether there are any potential security holes. The core question is: can this structure ever contain uninitialized data, leading to a vulnerability?
First, I'm tracing all the ways an `skb` (socket buffer) can be allocated within the Netlink subsystem. I'm focusing on the allocation points and how the `cb` (control block) within the `sk_buff` is initialized:
* **`nlmsg_new`:** This calls `alloc_skb`, so the buffer is initialized there.
* **`netlink_ack`:** Also calls `nlmsg_new`, and thus also `alloc_skb`. This is important, especially if `nlmsg_new` fails to create the buffer; is an ACK not sent, and any remnants potentially leak?
* **`netlink_dump`:** Uses `alloc_skb`.
* **`netlink_sendmsg`:** Employs `netlink_alloc_large_skb`.
* **`netlink_broadcast`:** Does *not* allocate, it just *sends* the buffer.
* **`netlink_unicast` & `netlink_rcv_skb`:** These don't allocate the buffer, they operate on existing ones.
So, the core allocators are `alloc_skb` and `netlink_alloc_large_skb`. Now, I need to understand how these allocators initialize `cb`.
I'm suspicious of a scenario where `netlink_ack` is used, because of its interaction with other variables. In this case, `skb` is allocated via `nlmsg_new` and is then sent using `nlmsg_unicast`. Does `nlmsg_unicast` modify the `cb` data?
Aha! Now I remember `skbuff_clear` which should zero out the `cb` structure. Let's make sure!
I check `skbuff_clear`. I see it uses `memset` to zero memory. Now I am concerned about the potential for an incomplete zero if the allocation is strange...
```c
static inline void skbuff_clear(struct sk_buff *skb)
{
/* Replace memset(skb, 0, offsetof(struct sk_buff, tail))
* with two smaller memset(), with a barrier() between them.
* This forces the compiler to inline both calls.
*/
BUILD_BUG_ON(offsetof(struct sk_buff, tail) <= 128);
memset(skb, 0, 128);
barrier();
memset((void *)skb + 128, 0, offsetof(struct sk_buff, tail) - 128);
}
```
Okay, it seems like two `memset` calls. The first call zeroes 128 bytes. The second call zeroes the rest of the struct, from the offset of 128 bytes to the end.
* `cb` starts at offset 40 bytes (320 bits) and is 48 bytes (384 bits) long, ending at offset 88.
* The first `memset` covers up to 128 bytes, therefore the first `memset` *does* cover `cb`.
This seems good, `cb` *should* be zeroed by `skbuff_clear`, so that's okay.
I will also check the large allocation to make sure. If `skb` is allocated by `netlink_alloc_large_skb` and `head_size` is greater than `PAGE_SIZE`, then it calls `kvmalloc`, and then `__build_skb`, but `__build_skb` also calls `skbuff_clear`. The same applies if `head_size <= PAGE_SIZE`, it uses `alloc_skb`, calls `__alloc_skb` that calls `skbuff_clear`. So, no matter the size, the `cb` is zeroed.
So, unless there is some other function or interaction that I am missing, this is all solid. I am now confident that `NETLINK_CB(skb).creds` is, indeed, properly zeroed under *all* of these allocation and use cases. I need to keep an eye out for any paths that could overwrite this data, but for now, it's safe.
|
| 136/2 |
2026/03/11 08:24 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:nlmsg_unicast]
Results: map[SourceCode:1188: /**
1189: * nlmsg_unicast - unicast a netlink message
1190: * @sk: netlink socket to spread message to
1191: * @skb: netlink message as socket buffer
1192: * @portid: netlink portid of the destination socket
1193: */
1194: static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 portid)
1195: {
1196: int err;
1197:
1198: err = netlink_unicast(sk, skb, portid, MSG_DONTWAIT);
1199: if (err > 0)
1200: err = 0;
1201:
1202: return err;
1203: }
SourceFile:include/net/netlink.h]
|
| 137/2 |
2026/03/11 08:24 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 182561
output: 45
thoughts: 25
Thoughts: Okay, here's my take on those thoughts, framed from my perspective, as if I'm thinking them through:
**Netlink Unicast Callback Conundrum**
Alright, I'm taking a look at this `netlink_unicast` function, and a question just popped into my head: Does this function, when it's handling its operations, potentially overwrite or interfere with the callback function, `cb`? It's a critical point to consider for the integrity of the overall process. This is something I need to clarify to ensure correct execution.
So, let's dive into the `netlink_unicast` function itself. I need to understand exactly how it uses, or potentially misuses, that callback. I need to see what steps are taken. Specifically I need to look at if and how `cb` is involved, and if anything I see there gives me any indication that there could be some kind of overwrite or reassignment happening that I didn't intend. I'll need to look at the function's internal logic, any possible memory management, and how it handles the callback argument to fully grasp this. It's time to dig in and clarify this potential issue.
|
| 138/2 |
2026/03/11 08:24 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_unicast]
Results: map[SourceCode:1327: int netlink_unicast(struct sock *ssk, struct sk_buff *skb,
1328: u32 portid, int nonblock)
1329: {
1330: struct sock *sk;
1331: int err;
1332: long timeo;
1333:
1334: skb = netlink_trim(skb, gfp_any());
1335:
1336: timeo = sock_sndtimeo(ssk, nonblock);
1337: retry:
1338: sk = netlink_getsockbyportid(ssk, portid);
1339: if (IS_ERR(sk)) {
1340: kfree_skb(skb);
1341: return PTR_ERR(sk);
1342: }
1343: if (netlink_is_kernel(sk))
1344: return netlink_unicast_kernel(sk, skb, ssk);
1345:
1346: if (sk_filter(sk, skb)) {
1347: err = skb->len;
1348: kfree_skb(skb);
1349: sock_put(sk);
1350: return err;
1351: }
1352:
1353: err = netlink_attachskb(sk, skb, &timeo, ssk);
1354: if (err == 1)
1355: goto retry;
1356: if (err)
1357: return err;
1358:
1359: return netlink_sendskb(sk, skb);
1360: }
SourceFile:net/netlink/af_netlink.c]
|
| 139/2 |
2026/03/11 08:24 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 183391
output: 44
thoughts: 23
Thoughts: Okay, here's my interpretation of those thoughts, tailored for an expert audience, and delivered as a first-person internal monologue:
**Investigating a Potential Callback Overwrite in `netlink_trim`**
Alright, I'm taking a look at this `netlink_trim` function. Something's nagging at me – I need to make absolutely sure it doesn't inadvertently overwrite a callback. The potential for unexpected side effects in kernel code always makes me twitchy, especially when dealing with asynchronous operations. I need to get a clear mental picture of exactly what happens when `netlink_trim` is called, and more importantly, how it interacts with the `cb` variable, specifically if it even modifies it, or potentially something that is very near the `cb` variable in memory.
Let's dive right into the source and verify how `netlink_trim` is implemented. I want to see every line of that function. No assumptions. This needs a thorough investigation to confirm.
|
| 140/2 |
2026/03/11 08:24 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_trim]
Results: map[SourceCode:1281: static struct sk_buff *netlink_trim(struct sk_buff *skb, gfp_t allocation)
1282: {
1283: int delta;
1284:
1285: skb_assert_len(skb);
1286: WARN_ON(skb->sk != NULL);
1287: delta = skb->end - skb->tail;
1288: if (is_vmalloc_addr(skb->head) || delta * 2 < skb->truesize)
1289: return skb;
1290:
1291: if (skb_shared(skb)) {
1292: struct sk_buff *nskb = skb_clone(skb, allocation);
1293: if (!nskb)
1294: return skb;
1295: consume_skb(skb);
1296: skb = nskb;
1297: }
1298:
1299: pskb_expand_head(skb, 0, -delta,
1300: (allocation & ~__GFP_DIRECT_RECLAIM) |
1301: __GFP_NOWARN | __GFP_NORETRY);
1302: return skb;
1303: }
SourceFile:net/netlink/af_netlink.c]
|
| 141/2 |
2026/03/11 08:24 |
llm |
crash-repro-finder |
1m
Model:
Tokens:
input: 184054
output: 46
thoughts: 35
Thoughts: **Investigating the `netlink_sendskb` Function**
Okay, so I'm looking at this code and something doesn't quite sit right. Nope, pretty sure this assumption is wrong. I need to dig deeper. The critical question here is whether or not `netlink_sendskb` potentially overwrites that callback variable, `cb`. That's the key to understanding the control flow and potential issues.
Alright, let's dive into the `netlink_sendskb` function itself and see what's actually happening under the hood. Time to trace through the code and verify its behavior with respect to `cb`. It's all about verifying its behavior, it should be simple.
|
| 142/2 |
2026/03/11 08:25 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:netlink_sendskb]
Results: map[SourceCode:1267: int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
1268: {
1269: int len = __netlink_sendskb(sk, skb);
1270:
1271: sock_put(sk);
1272: return len;
1273: }
SourceFile:net/netlink/af_netlink.c]
|
| 143/2 |
2026/03/11 08:25 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 184416
output: 47
thoughts: 13
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:
**Diving into the Netlink Send Function**
Alright, time to dig into this. Based on the current context, the next logical step is to examine the `__netlink_sendskb` function. I need to understand how the system is handling the actual transmission of the socket buffer. What are the key stages? What optimizations are at play? I suspect this is where the meat of the Netlink delivery mechanism resides, and I want to refresh my memory on the interactions with the underlying network stack. This function likely manages packet preparation, interaction with the networking hardware, and any necessary checksum calculations or fragmentation. Let's see what the source code reveals about how it all comes together and how potential issues could manifest.
|
| 144/2 |
2026/03/11 08:26 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/af_netlink.c IncludeLines:true Name:__netlink_sendskb]
Results: map[SourceCode:1256: static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
1257: {
1258: int len = skb->len;
1259:
1260: netlink_deliver_tap(sock_net(sk), skb);
1261:
1262: skb_queue_tail(&sk->sk_receive_queue, skb);
1263: sk->sk_data_ready(sk);
1264: return len;
1265: }
SourceFile:net/netlink/af_netlink.c]
|
| 145/2 |
2026/03/11 08:26 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 184838
output: 39
thoughts: 2718
Thoughts: **Analyzing a KMSAN Report: A Deep Dive into Netlink Credentials**
Okay, so I'm looking at this KMSAN report flagging an uninitialized value in `put_cmsg`. My initial thought is, "Impossible! It's all zeroed!" I'm trying to trace the flow, specifically concerning Netlink messages and how credentials are handled, trying to understand where this uninitialized memory could be introduced. I'm focusing on the `NETLINK_CB(skb).creds` structure.
First, I went through the common `skb` allocation paths: `nlmsg_new`, `netlink_ack`, `netlink_sendmsg`, `rtmsg_ifinfo`, `netlink_dump`, and considered whether `skbuff_clear` was invoked after allocation to initialize the `cb`. The initial allocation and cleanup with zeroing seem sound. But what about the `scm` (socket control message) structure that is used to exchange credentials? `netlink_sendmsg` sets the credentials using `scm.creds`, so maybe that's it? I quickly realized that `netlink_sendmsg` and `scm_send` *should* fully initialize the `scm.creds`.
Then I dove into the KMSAN report, trying to map the call stack to potential culprits. I checked the size of `ucred` for padding—nope, it’s only 12 bytes. I then considered if the copy size in `put_cmsg` could be the issue, but, it copies the same amount as `ucred` (12 bytes) so no issue.
I re-examined the code in `netlink_recvmsg`, specifically where the `scm` credentials are fetched. Could a frag_list `skb` be the issue? No, `netlink_recvmsg` uses the main `skb` for credentials. Is there a scenario where `skb` is allocated with `netlink_alloc_large_skb` and it does not zero the `cb`? Nope, `skbuff_clear` is called. Perhaps `skb` is allocated by `skb_clone`? The original skb would have to be uninitialized... which is impossible.
I focused again on `netlink_sendmsg`, the path where the credentials are *set*. The path where the credentials are sent via a control message. I looked into the logic in `scm_send`, where the `scm.creds` is set, and considered the possibility of uninitialized memory making its way through the credential exchange when control messages are used, specifically when `msg->msg_controllen > 0` and `__scm_send` is called. Within `__scm_send`, the `SCM_CREDENTIALS` case is very interesting. This case copies the credentials from the control message. If the control message data is not fully initialized, this is a likely source of the problem. However, the report is in `put_cmsg`, not the user space copy, which eliminates this path.
I went back to the skb allocation paths one more time. The final possibility must be an allocation path I missed. So where is `NETLINK_CB(skb).creds` *not* zeroed? Is it possible that the `skb` comes from a subsystem I'm not thinking of? Something outside the normal flow? I need to check `audit_log_start`, to see if it allocates skbs. And I must keep digging!
|
| 146/2 |
2026/03/11 08:26 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:kernel/audit.c IncludeLines:true Name:audit_log_start]
Results: map[SourceCode:1891: /**
1892: * audit_log_start - obtain an audit buffer
1893: * @ctx: audit_context (may be NULL)
1894: * @gfp_mask: type of allocation
1895: * @type: audit message type
1896: *
1897: * Returns audit_buffer pointer on success or NULL on error.
1898: *
1899: * Obtain an audit buffer. This routine does locking to obtain the
1900: * audit buffer, but then no locking is required for calls to
1901: * audit_log_*format. If the task (ctx) is a task that is currently in a
1902: * syscall, then the syscall is marked as auditable and an audit record
1903: * will be written at syscall exit. If there is no associated task, then
1904: * task context (ctx) should be NULL.
1905: */
1906: struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
1907: int type)
1908: {
1909: struct audit_buffer *ab;
1910:
1911: if (audit_initialized != AUDIT_INITIALIZED)
1912: return NULL;
1913:
1914: if (unlikely(!audit_filter(type, AUDIT_FILTER_EXCLUDE)))
1915: return NULL;
1916:
1917: /* NOTE: don't ever fail/sleep on these two conditions:
1918: * 1. auditd generated record - since we need auditd to drain the
1919: * queue; also, when we are checking for auditd, compare PIDs using
1920: * task_tgid_vnr() since auditd_pid is set in audit_receive_msg()
1921: * using a PID anchored in the caller's namespace
1922: * 2. generator holding the audit_cmd_mutex - we don't want to block
1923: * while holding the mutex, although we do penalize the sender
1924: * later in audit_receive() when it is safe to block
1925: */
1926: if (!(auditd_test_task(current) || audit_ctl_owner_current())) {
1927: long stime = audit_backlog_wait_time;
1928:
1929: while (audit_backlog_limit &&
1930: (skb_queue_len(&audit_queue) > audit_backlog_limit)) {
1931: /* wake kauditd to try and flush the queue */
1932: wake_up_interruptible(&kauditd_wait);
1933:
1934: /* sleep if we are allowed and we haven't exhausted our
1935: * backlog wait limit */
1936: if (gfpflags_allow_blocking(gfp_mask) && (stime > 0)) {
1937: long rtime = stime;
1938:
1939: DECLARE_WAITQUEUE(wait, current);
1940:
1941: add_wait_queue_exclusive(&audit_backlog_wait,
1942: &wait);
1943: set_current_state(TASK_UNINTERRUPTIBLE);
1944: stime = schedule_timeout(rtime);
1945: atomic_add(rtime - stime, &audit_backlog_wait_time_actual);
1946: remove_wait_queue(&audit_backlog_wait, &wait);
1947: } else {
1948: if (audit_rate_check() && printk_ratelimit())
1949: pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n",
1950: skb_queue_len(&audit_queue),
1951: audit_backlog_limit);
1952: audit_log_lost("backlog limit exceeded");
1953: return NULL;
1954: }
1955: }
1956: }
1957:
1958: ab = audit_buffer_alloc(ctx, gfp_mask, type);
1959: if (!ab) {
1960: audit_log_lost("out of memory in audit_log_start");
1961: return NULL;
1962: }
1963:
1964: audit_get_stamp(ab->ctx, &ab->stamp);
1965: /* cancel dummy context to enable supporting records */
1966: if (ctx)
1967: ctx->dummy = 0;
1968: audit_log_format(ab, "audit(%llu.%03lu:%u): ",
1969: (unsigned long long)ab->stamp.ctime.tv_sec,
1970: ab->stamp.ctime.tv_nsec/1000000,
1971: ab->stamp.serial);
1972:
1973: return ab;
1974: }
SourceFile:kernel/audit.c]
|
| 147/2 |
2026/03/11 08:26 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 189754
output: 39
thoughts: 11
Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person:
**Initial Assessment of Audit Buffer Allocation**
Alright, the next step is to examine `audit_buffer_alloc`. This function is critical, obviously. We're dealing with memory allocation within the audit subsystem, so any issues here could cascade into serious problems – data loss, denial of service, or even security vulnerabilities. My mind immediately begins to analyze its potential failure modes: fragmentation, resource exhaustion, and, of course, any race conditions related to concurrent access. Let's see if the code includes any safeguards or error handling I'd expect. A quick search for dependencies and callers might reveal any hidden complexities. Time to dive in.
|
| 148/2 |
2026/03/11 08:26 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:kernel/audit.c IncludeLines:true Name:audit_buffer_alloc]
Results: map[SourceCode:1828: static struct audit_buffer *audit_buffer_alloc(struct audit_context *ctx,
1829: gfp_t gfp_mask, int type)
1830: {
1831: struct audit_buffer *ab;
1832:
1833: ab = kmem_cache_alloc(audit_buffer_cache, gfp_mask);
1834: if (!ab)
1835: return NULL;
1836:
1837: skb_queue_head_init(&ab->skb_list);
1838:
1839: ab->skb = nlmsg_new(AUDIT_BUFSIZ, gfp_mask);
1840: if (!ab->skb)
1841: goto err;
1842:
1843: skb_queue_tail(&ab->skb_list, ab->skb);
1844:
1845: if (!nlmsg_put(ab->skb, 0, 0, type, 0, 0))
1846: goto err;
1847:
1848: ab->ctx = ctx;
1849: ab->gfp_mask = gfp_mask;
1850:
1851: return ab;
1852:
1853: err:
1854: audit_buffer_free(ab);
1855: return NULL;
1856: }
SourceFile:kernel/audit.c]
|
| 149/2 |
2026/03/11 08:26 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 190389
output: 41
thoughts: 2824
Thoughts: **Debugging a KMSAN Uninitialized Value Report in Netlink Credentials Handling**
Okay, so I'm trying to figure out why KMSAN is reporting an uninitialized value when dealing with netlink credentials. The goal is to determine the origin of a potentially uninitialized value that's being passed to user space. It seems like it must be in the `put_cmsg` function. The process starts with `nlmsg_new`, allocates `skb` which calls `skbuff_clear` (which is important), and proceeds to copy data. Let's trace it carefully.
First, I examined the case where `nlmsg_new` is called and, with my expert knowledge, determined the control block is zeroed as expected. I walked through the code, including the call from `netlink_ack`, ensuring the control block's memory is properly zeroed. I verified that `skbuff_clear` *always* zeroes the first 128 bytes, which contains the `cb` member. Thus, the credentials in the control block should always be zeroed initially. I've eliminated some of the simpler possibilities, like `memset` not being intercepted.
Then, I looked at a case with `netlink_alloc_large_skb` and concluded `cb` is still zeroed. But what if KMSAN is *lying* to me about the zero initialization? No, KMSAN is reliable.
Next, I considered where the credentials themselves come from. In `netlink_recvmsg` I saw `memset(&scm, 0, sizeof(scm));` and `scm.creds = *NETLINK_CREDS(skb);`. But wait, what if `skb` isn't from the normal allocation path, but from `netlink_sendmsg`? Looking at the `scm_send` function, `memset` is called on the `scm` struct, but then I realized if the message control data is set, the contents of the *sent* credentials are copied to the control message data. Thus I checked the `struct ucred` definition to make sure the data size is accurate. It is. I looked again at `put_cmsg`, which copies `ucreds` to user space. The math is right on the `cmlen` check, so the length being copied is correct. But I need to eliminate a potential overflow, by looking at `msg->msg_controllen`.
Then, I looked at the code for `__scm_send`. Here it checks for `SCM_CREDENTIALS` and copies values *from* a control message *to* a `struct ucred` called `creds`. I realized: AHA! If the *receiving* side of the netlink socket sends bad credentials, then those values can be uninitialized, and this could be the source of the issue. The values used here must be correctly initialized, and this is where `creds` gets its values. I remembered KMSAN reported the uninitialized value from `put_cmsg`, so this must not be the cause of the problem, so I went back to the drawing board.
Revisiting the allocation, I checked that even when `netlink_ack` does the allocation, the `cb` is zeroed. Since the first 128 bytes are zeroed, and then I copy the credential values, the values must be zeroed when `nlmsg_new` is called.
This is a subtle issue. The value must come from somewhere, but I've traced the common allocation paths and zeroing. It's almost as if some side effect in the kernel is producing these values, and the trace is hiding something. I need to go back and check the code, methodically, looking for subtle interactions I might be missing. I need to rule out allocation bugs.
|
| 150/2 |
2026/03/11 08:27 |
tool |
codesearch-definition-source |
0m
Error:
Args: map[ContextFile:include/linux/netlink.h IncludeLines:true Name:NETLINK_CB]
Results: map[SourceCode: SourceFile:]
|
| 151/2 |
2026/03/11 08:27 |
llm |
crash-repro-finder |
0m
Model:
Tokens:
input: 194086
output: 20
thoughts: 11
Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience:
**Diving into the NETLINK_CB Rabbit Hole**
Okay, so I'm thinking, let's get down to brass tacks and *grep* for `NETLINK_CB`. This likely indicates that I'm specifically interested in debugging or understanding the Control Block associated with a Netlink socket. This isn't just a casual search; `NETLINK_CB` is a critical structure, and digging into its use offers immediate insight into the kernel's handling of Netlink messages. I expect to find a bunch of places where `NETLINK_CB` is either being initialized, accessed, or manipulated. Depending on the context, the presence of the term could point me to the message handler, or maybe the specific sockets that are communicating over Netlink. It gives me a decent starting point to understand the interactions in a Netlink communication. From the returned grep results, I will begin to formulate where to head next.
|
| 152/2 |
2026/03/11 08:27 |
tool |
grepper |
0m
Args: map[Expression:#define NETLINK_CB]
Results: map[Output:include/linux/netlink.h=25=struct netlink_skb_parms {
--
include/linux/netlink.h-34-
include/linux/netlink.h:35:#define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb))
include/linux/netlink.h-36-#define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds)
]
|
| 153/2 |
2026/03/11 08:27 |
llm |
crash-repro-finder |
6m
Model:
Tokens:
input: 194453
output: 410
thoughts: 62916
|
| 154/2 |
2026/03/11 08:33 |
tool |
set-results |
0m
Args: map[ReproOpts: ReproSyz:r0 = socket$nl_route(0x10, 0x3, 0x0)
setsockopt$sock_int(r0, 0x1, 0x10, &(0x7f0000000000)=0x1, 0x4)
sendmsg$nl_route(r0, &(0x7f0000000040)={&(0x7f0000000080)={0x10, 0x0, 0x0, 0x0}, 0xc, &(0x7f00000000c0)={&(0x7f0000000100)=@getlink={AUTO, 0x12, 0x5, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, []}, AUTO}, 0x1, 0x0, 0x0, 0x0}, 0x0)
recvmsg(r0, &(0x7f0000000140)={0x0, 0x0, &(0x7f0000000180)=[{&(0x7f00000001c0)=""/1024, 0x400}], 0x1, &(0x7f00000005c0)=""/1024, 0x400, 0x0}, 0x0)]
Results: map[ReproOpts: ReproSyz:r0 = socket$nl_route(0x10, 0x3, 0x0)
setsockopt$sock_int(r0, 0x1, 0x10, &(0x7f0000000000)=0x1, 0x4)
sendmsg$nl_route(r0, &(0x7f0000000040)={&(0x7f0000000080)={0x10, 0x0, 0x0, 0x0}, 0xc, &(0x7f00000000c0)={&(0x7f0000000100)=@getlink={AUTO, 0x12, 0x5, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, []}, AUTO}, 0x1, 0x0, 0x0, 0x0}, 0x0)
recvmsg(r0, &(0x7f0000000140)={0x0, 0x0, &(0x7f0000000180)=[{&(0x7f00000001c0)=""/1024, 0x400}], 0x1, &(0x7f00000005c0)=""/1024, 0x400, 0x0}, 0x0)]
|