| Age | Commit message (Collapse) | Author |
|
Add a kselftest suite covering SO_RESERVE_MEM behavior:
- Reject unsupported socket types (UDP/SOCK_DGRAM, UNIX/SOCK_STREAM,
SOCK_RAW, MPTCP) with EOPNOTSUPP, for both zero and non-zero values.
- Validate bounds (negative values and values > SZ_1G return EINVAL).
- Verify reserve adjustments (increase, decrease, page rounding, and
reset to 0) and corresponding sk_meminfo[SK_MEMINFO_FWD_ALLOC] changes
via getsockopt(SO_MEMINFO).
- Exercise cgroup v2 memory.max enforcement returning ENOMEM when the
requested reservation exceeds the cgroup limit.
- Verify that a child socket returned by accept() starts with a 0
reserve even when its parent listener configured a non-zero
SO_RESERVE_MEM.
- Verify reserve retention across TCP send/receive/ACK cycles.
Each test runs in private mount and network namespaces. cgroup2 is
mounted on a private tmpfs, so nothing is left behind in the host
filesystem. The test process is moved to a dedicated leaf cgroup, and
back to its original cgroup on teardown. The memory controller is
enabled in the root of the hierarchy if needed, and left enabled like
selftests/cgroup do, as disabling it could break other users.
Also enable CONFIG_CGROUPS=y and CONFIG_MEMCG=y in
tools/testing/selftests/net/config.
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261001192137.309983-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Add failure tests for slices that escape a subprogram from a dynptr in the
callee stack. Cover immediate use of a ring buffer clone slice,
release-time invalidation of a caller dynptr slice after it crosses a
subprogram return, and immediate use of an skb dynptr slice in a qdisc
program.
Cover the error path where a subprogram would otherwise lose the last
dynptr capable of releasing a referenced resource.
Also add a success control which derives a slice from a caller-owned dynptr
and creates a separate clone in the callee. Destroying that callee-local
clone on return must not invalidate the caller dynptr's slice.
Signed-off-by: Xu Yunxiang <xyx2021@mail.ustc.edu.cn>
Reviewed-by: Amery Hung <ameryhung@gmail.com>
Link: https://lore.kernel.org/bpf/20260927120422.1042107-3-xyx2021@mail.ustc.edu.cn
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
|
|
A data slice is valid only while the specific dynptr that produced it
remains valid. prepare_func_exit() copies a subprogram return value into
the caller and then frees the callee state without applying the normal
destruction semantics to dynptrs in the callee stack.
A callee can therefore derive a slice from a local dynptr, return or spill
the slice into its caller, and then let the dynptr disappear with the
callee frame. The slice retains the id of a dynptr that is no longer in the
verifier state, so the verifier continues to accept accesses through it.
Before the object relationship refactor, bpf_dynptr_data() slices from
referenced dynptrs also carried the shared reference id, allowing a later
release to catch some of these escaped slices. The refactor made those
slices precise children of their source dynptr and exposed the missing
teardown as an accepted stale access even after the shared resource is
released.
Add destroy_dynptrs_in_stack_slots() to apply the existing dynptr teardown
to an inclusive range of stack slots. Reuse it for dynptr initialization,
variable-offset stack writes, and the entire callee stack before freeing
the frame. The teardown rejects losing the last dynptr for a referenced
resource and invalidates the dynptr and all its descendants, including
slices held in the caller. Propagate errors through prepare_func_exit().
Reuse the existing teardown API and diagnostic. Update the affected
callback test expectation in this change so the commit remains test-clean.
Fixes: 308c7a0ae885 ("bpf: Refactor object relationship tracking and fix dynptr UAF bug")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Suggested-by: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Xu Yunxiang <xyx2021@mail.ustc.edu.cn>
Reviewed-by: Amery Hung <ameryhung@gmail.com>
Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://lore.kernel.org/r/CAMB2axOmdHwSrHihSRskDywkCmEGQOX+6dZPN_A9u-HhxY3UDA@mail.gmail.com
Link: https://lore.kernel.org/r/CAMB2axMmrTb+UZ84UD48MwMtXbk1s9bWtreU3AOfjzU0fPT0BA@mail.gmail.com
Link: https://lore.kernel.org/bpf/20260927120422.1042107-2-xyx2021@mail.ustc.edu.cn
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
|
|
Cover two of the basic psp assoc states that have been defeatured. Do
not include tests with shutdown(), connect(..., AF_UNSPEC), etc. I don't
think the coverage is worth the complexity. That should be done with
packetdrill.
Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
Fixes: 6b46ca260e22 ("net: psp: add socket security association code")
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260930-psp-defeat-v2-4-f266e7447129@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Future work will only allow rx-assoc and tx-assoc to be performed when
the sock is in TCP_ESTABLISHED state.
Several assoc_ tests, as well as dev_rotate_spi, test using the rx-assoc
and tx-assoc uapi calls against sockets in TCP_CLOSE state.
These tests don't involve sending or receiving data, nor involve looking
up psp device by dst entry, so using a disposable disconnected socket
was just a convenience. These can be replaced by a disposable loopback
socket.
The loopback sockets are IPv4, where the sockets they replace were
AF_INET6. This doesn't reduce coverage, since the assoc handlers accept
any TCP socket and don't look at the address family.
Some users of rx-assoc and tx-assoc on closed sockets are left if they
validate errors that are returned before the kernel will check the
socket for TCP_ESTABLISHED.
Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
Fixes: 6b46ca260e22 ("net: psp: add socket security association code")
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260930-psp-defeat-v2-1-f266e7447129@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Cover closing what is marked:
- close-on-exec descriptors in the range go, the ones outside stay, and
a range above the table closes nothing
- with CLOSE_RANGE_EXCEPT it is the other way around, and the kept ones
keep their flag, for a window in the middle, at the top and at the
bottom
- descriptors without close-on-exec are never touched, in or out of the
range
- a range that cannot hold an open descriptor keeps nothing, one that
covers everything keeps everything, in place and in a clone
- the unshare form leaves the table it was cloned from alone, with and
without CLOSE_RANGE_EXCEPT
- the unshare form keeps the descriptors without the flag that sit in
the range it drops from, and hands the dropped slots out again
- a kept range above the last descriptor without close-on-exec still
comes back, so the clone is sized off the range too
Also check that asking for CLOSE_RANGE_CLOEXEC at the same time is
refused, whatever else is asked for, and that the bounds are still
checked.
The extra cases came out of the same walk with the close-on-exec mask
on top: a marked and an unmarked descriptor on each side of every window
position, and the size of the clone when only unmarked ones are left in
the range it drops from.
Link: https://patch.msgid.link/20260921-work-file-close_range_except-v1-10-c20d0b49270d@kernel.org
Reviewed-by: Jann Horn <jannh@google.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
Cover the inverted range:
- with plain close the window stays and everything outside of it goes,
stdio included
- a window at the top, one that cannot hold a descriptor and one of a
single descriptor keep just what they name, and so does the unshare
form on a table that is not shared
- with CLOSE_RANGE_CLOEXEC everything outside of the window is marked
and the window is not, in place and in a clone, for a
window in the middle, at the bottom, at the top and above the table
- with CLOSE_RANGE_UNSHARE the table the child cloned from is untouched,
a window near the top of the table comes back whole, one at the bottom
keeps stdio, one that cannot hold a descriptor keeps nothing, and the
slots left behind are handed out again from the bottom
- the bounds are checked before the range is turned around
The extra cases came out of walking the window positions that
__range_close(), __range_cloexec() and dup_fd() tell apart: at the
bottom, in the middle, at the top, above the table, a single descriptor
and none, on a shared and on a private table.
Link: https://patch.msgid.link/20260921-work-file-close_range_except-v1-7-c20d0b49270d@kernel.org
Reviewed-by: Jann Horn <jannh@google.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
Cover a range in the middle of a full word:
- the descriptors in it are gone from the clone and the ones around it
are still there
- the slots are handed out again, the word is not left marked full
- the table the child cloned from is untouched
Link: https://patch.msgid.link/20260921-work-file-close_range_except-v1-2-c20d0b49270d@kernel.org
Reviewed-by: Jann Horn <jannh@google.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
This resolves a number of merge conflicts between the branches, and we
pick up the fixes in 7.3-rc6 that we need for testing.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
check_aggregate_directives() records an optional-data list member
in aggregate_members alongside a variable-length array member, but
the comment on the set still describes only the array form.
Name both member forms.
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
check_aggregate_directives() rejects a second marked member whose
element type differs from the first, because one hook set serves
every marked member of a struct and its item hook takes a single
element type. The README says the members share a hook set but
never states the restriction that follows from it, so a spec
author learns of it only from the diagnostic.
State the restriction where the shared hook set is described.
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
The struct and union emitters raise NotImplementedError when a
"pragma pages" or "pragma aggregate" member is generated for the
client peer. The source subcommand catches the parse and semantic
errors but not that one, so a client generation request for such a
specification emits partial output and then a Python traceback,
which buries the one line that says what is unsupported.
Catch the exception in the source subcommand and report its message
on stderr the way the other diagnostics are reported.
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
check_pages_directives() rejects a union arm declared directly as
a string, with a diagnostic pointing at the directive, but accepts
one declared directly as a variable-length opaque. The union
generator has no arm representation for a direct opaque, so
generation fails with an AttributeError from
emit_union_case_spec_definition() instead. A direct opaque arm was
never generated correctly, marked or not, but the pages validation
exists to report such a directive at its source position.
Extend the union-arm check to a direct variable-length opaque, so
both forms draw the same diagnostic.
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
The optional-data aggregate encoder loops cursor.count times, so the
begin hook must report the element count before the first element is
written. A producer that reads its elements while the reply is
encoded -- NFSv2 READDIR streaming directory entries straight into the
send buffer -- does not know that count in advance, and would have to
materialize the whole list just to satisfy the loop bound.
An optional-data list carries no count on the wire, so nothing forces
one on the encoder. Drive it from the item hook instead: a false
return ends the list, and the framing writes the terminator.
The counted-array form and its hook contract are unchanged. No
in-tree spec marks an optional-data member yet, so no generated code
changes here.
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260908134234.512312-11-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
The hook-driven aggregate codec emits only the counted-array wire
form. XDR list types built on the optional-data idiom ("type *name")
carry no count and cannot be expressed that way. NFSv2 READDIR's
entry list is one such type.
Accept an optional-data member under "pragma aggregate" and emit
value-follows framing in place of the counted array. The element
type's existing single-node encoder already writes its own
value-follows boolean, so the loop calls it once per element and
once more with a NULL element to write the terminator. The struct C
definitions are untouched; only the marked member's framing changes.
The generated decoder fails outright. Decoding a value-follows list
needs a presence-reporting element decoder, which this change does
not add, and a decoder that consumed nothing would leave the stream
at the list data for the next member to misread. NFSv2 READDIR only
encodes its entry list, so the decode path is never exercised.
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260908134234.512312-10-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
A generated variable-length array codec stages the wire array
as a C array and walks it. When the in-kernel object is not that
array, building that array is wasted memory traffic. The NFS_ACLv2
secattr aclent<> list is one such case: it is a Solaris wire form of
the kernel's posix_acl. The hand-rolled codec that performs that
transform forces its containing types to keep external linkage
(pragma public), and that linkage collides at link time with the
same generated types in a sibling program.
Add a per-member "pragma aggregate <struct> <member>" directive. For
a marked member the generated code owns only the wire framing and
calls hand-written begin, item, and end hooks that handle one
element at a time. Interior codec signatures do not change.
The framing-owned loop follows xdr_encode_array2(), whose only
remaining user is fs/nfs_common/nfsacl.c, and seq_file's
start/show/stop, where a guaranteed stop() releases what start()
took. Those APIs take an ops vtable because one loop serves
consumers chosen at run time. Here the consumer is known at
generation time, so the hooks bind by name at link time, as the
ASN.1 compiler's actions do. A missing hook is a link error, the
emitted prototypes enforce the element type, and no indirect call
is added per element.
The item hooks return only success or failure, with no early "no
more elements" return, so that the same hook contract can later
frame the RFC 4506 optional-data idiom, where the application
pushes entries into generated framing.
The front end resolves each marker against the specification and
reports one it cannot honor against its own source position, rather
than degrading silently to the array-walking codec or surfacing as a
traceback from whichever emitter reached it. Absent the marker the
generator emits byte-identical output.
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260908134234.512312-9-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
The pages directive so far drives only the encoder. A bulk argument
such as the payload of an NFS WRITE arrives in the pages of the
server's Receive buffer, but the generated opaque decoder copies it
into a contiguous data pointer. The copy wastes memory bandwidth and
forces the containing procedure decoder to be hand-rolled.
Let the directive drive the decoder as well. Whether a marked member
is decoded in place or encoded by reference follows from whether its
containing type is reachable from an RPC procedure argument. Record
that set during parsing, then close it over nested aggregates and
typedef aliases before the directives are checked. A decoded
page-resident member is represented as a struct xdr_buf so that the
payload can be handed on without a copy. A marked union arm of an
argument type is rejected, since the union generator still emits
only the copying decoder. A marked type reachable from both an
argument and a result is rejected as well: the two representations
differ, and a type carries only one.
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260908134234.512312-8-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
The generated encoder for a variable-length opaque or string
member copies its content into the Reply buffer via
xdr_stream_encode_opaque(). A bulk payload such as an NFS READ
result never resides at the member's data pointer: the server
deposits it directly in the pages of the Reply buffer. Until now
the containing procedure encoder had to be hand-rolled.
Add a per-member directive that makes the emitted encoder call
svcxdr_encode_opaque_payload() for the marked member. The README
documents its syntax and the members it may name. Beyond the
struct and union cases described there, the directive also applies
to a member of a self-referential struct, which xdrgen generates
as an XDR pointer type.
A directive that binds to nothing would degrade silently to the
copying encoder, so the front end rejects one that names an
undeclared type or member, or a member that cannot carry a
payload. It also rejects a second marked member of the same type,
and a type whose members reach more than one marked member:
svcxdr_encode_opaque_payload() consumes the whole page vector and
moves the stream into the tail, so one encoder carries at most one
payload. An array of a marked type counts as reaching it more than
once, since the array encoder emits the element once per entry.
Generated code is unchanged until a specification applies the
directive.
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260908134234.512312-6-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
A per-member code generation directive keyed on the (struct, member)
pair needs the name of the containing struct, but
emit_struct_member_encoder() and emit_struct_member_decoder()
receive only the member declaration.
Pass the containing struct's name to emit_struct_member_encoder() and
emit_struct_member_decoder(), and to the matching emitters in
pointer.py, as a required argument. A struct whose last field refers
to its own type is an _XdrPointer rather than an _XdrStruct, so
pointer.py takes the same argument. No emitter renders the new value
yet, so generated output is byte-identical. A subsequent patch keys
the "pragma pages" encoder on it.
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260908134234.512312-5-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Cover the teardown side of the same rule. Remove one listener, then three,
with the stub silent, and compare what it saw. Three removals must not cost
three timeouts.
Both measurements also pay the svc_unregister() sweep that
nfsd_destroy_serv() runs once the last listener is gone, so that cancels
out of the comparison. The listeners are registered with the stub
answering, so each one has an entry to remove.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260901-nfsd-nl-hang-v5-15-a540d86668b0@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Cover the change that stops a listener_set request from registering after
rpcbind stops answering.
RPCB_STUB_SILENT is new. It reads a call and writes nothing back, so the
kernel waits out its own timeout. RPCB_STUB_REFUSE cannot serve here: a
refusal is an answer, and the count ignores it on purpose.
Every procedure but the NULL one is silenced, so an unregistration goes
unanswered as well. The NULL one has to be answered:
rpcb_create_af_local() builds its client without RPC_CLNT_CREATE_NOPING, so
rpc_create() pings at creation. Silencing that ping too would fail the
AF_LOCAL client, send rpcb_create_local() on to the loopback client of
rpcb_create_local_net(), and leave the stub seeing one call per request no
matter how many listeners it carried.
- rpcb_stop_after_failure. Ask for one listener, then for three, and
compare what the stub saw. Three entries must not cost three times as
much.
- rpcb_silent_set_complete. The entry that finds rpcbind silent is the one
that pays the timeout, and with v3 enabled it is the only entry whose
listener would be lost. Require that a three-entry request brings up all
three, succeeds, and warns.
- rpcb_v4_only_bounded. The case that needs the count rather than a failed
listener. version_set_only() makes the server v4-only, so vs_rpcb_optnl
discards every error and every listener comes up. Require that the
listeners are present, that the ack warns about them, and that three
entries do not cost three round trips.
- rpcb_retry_next_request. The stop lasts for one request. After the stub
starts to answer, the next request must reach rpcbind again.
The counts these tests compare include the unregistrations that the
teardown between the two measurements issues. The preceding patches bound
that direction too, so the sweeps stay at one timeout rather than one per
program and version.
version_set_only() is new. NFSD_CMD_VERSION_SET clears every version
before it reads the request, so one nest leaves the server v4-only. It
returns -EBUSY once a serv exists, so the test calls it first.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260901-nfsd-nl-hang-v5-14-a540d86668b0@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
The creation of a listener registers with rpcbind.
svc_xprt_create_from_sa() passes flags of 0, so pmap_register is true in
svc_setup_socket(). A fresh netns has no rpcbind. Every registration
therefore waits out the local rpcbind timeout, once for each program and
version, and the registration failure then takes the listener down. The
host's rpcbind is not an option either. svc_rpcb_setup() opens with a call
to svc_unregister(), which would clear the host's nfsd entries.
Serve rpcbind from inside the namespace instead. The abstract AF_LOCAL
name that the kernel tries first is per-netns, because
unix_find_abstract() takes a struct net. Bind "\0/run/rpcbind.sock" and
fork a minimal responder:
- the responder never decodes arguments. The NULL procedure gets an empty
success, and SET and UNSET get TRUE.
- the responder answers RPCBVERS_4 as well as RPCBVERS_2. A v4 refusal
makes __svc_rpcb_register6() return -EAFNOSUPPORT, which would leave
every IPv6 listener unregistered.
- the responder counts accepted connections and received calls in a page
that it shares with the test, and reads its mode from that page on every
call. The mode lives there rather than in the child so that a test can
change it with a serv already up: killing and restarting the stub would
close the connection the kernel holds, and rpcb_register_call() issues
UNSET over AF_LOCAL with RPC_TASK_NOCONNECT, so the next call would fail
at once with -ENOTCONN instead of waiting out a timeout.
- PR_SET_PDEATHSIG plus an explicit kill in FIXTURE_TEARDOWN make sure that
no stub outlives its test.
With the stub in place, add the tests that need a serv. These cover the
create, add and remove paths and the LISTENER_GET round trips: tcp, udp,
several listeners at once, an idempotent re-set, the removal of a subset,
the destruction of a serv from an empty list, and IPv6. Two more tests
cover the empty-list request and the -EBUSY refusal after THREADS_SET has
started threads.
The netlink socket asks for NETLINK_EXT_ACK, so that the tests can read the
extack message. It also asks for NETLINK_CAP_ACK, so that the kernel does
not echo the request back and the TLVs sit at a fixed offset.
FIXTURE_TEARDOWN drops whatever a test left running. A listener holds a
reference to the netns, and that netns outlives the test process. Threads
pin the listeners. Anything left up therefore leaks the namespace.
Several of these tests exist to catch a revert, not to describe the
interface. The errno alone shows none of them:
- val_reject_keeps_listeners. An unknown transport name ends in
-EPROTONOSUPPORT either way, because svc_xprt_create_from_sa() returns
that error too. The difference is the state that it leaves. Without the
up-front check, nfsd_nl_listener_set_doit() has already destroyed the
listeners that did not match by the time the name fails.
- val_bad_transport. This test now also requires that the stub saw no
traffic. A request that reaches svc_xprt_create_from_sa() has run
nfsd_create_serv(). svc_bind() then pings rpcbind at client creation and
sweeps stale entries with svc_unregister(). Silence at the stub is
therefore what shows that the kernel refused the request up front.
- val_second_entry_bad. This test now also sends a LISTENER_GET.
svc_xprt_create_from_sa() also returns -EAFNOSUPPORT for the bad entry,
and the doit keeps the listeners that it did create. The well-formed tcp
entry ahead of it would otherwise still be up.
- sem_register_refused. This test puts the stub in a mode that answers
RPCBPROC_SET with FALSE. rpcb_register_call() turns that answer into
-EACCES, svc_register() then fails, and svc_setup_socket() creates no
listener. The bare errno does not show that, because a bind can return
-EACCES too, so the test reads the listener set back and requires that
it is empty.
- sem_create_failure_extack. This test squats on the port first, so the
listener cannot bind. The extack must then name the transport that
failed.
- func_empty_destroys. This test uses the connection count. LISTENER_GET
replies empty both for a destroyed serv and for a live serv with no
permsocks. But only nfsd_destroy_serv() reaches
svc_xprt_destroy_all(..., unregister=true) -> svc_rpcb_cleanup() ->
rpcb_put_local(), which drops the last user and shuts the local client
down. The next serv has to connect again.
- sem_busy_on_change and sem_busy_on_remove read the listeners back,
because -EBUSY says nothing about what the doit did before it returned.
find_listener() matches the address as well as the transport, the family
and the port. Every listener here is created on loopback, so a reply that
names 0.0.0.0 has to fail.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260901-nfsd-nl-hang-v5-13-a540d86668b0@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Add regression tests for the NFSD_CMD_LISTENER_SET checks that
nfsd_nl_validate_listeners() runs before the code takes nfsd_mutex. The
tests cover a bad transport name, an absent transport name, a missing
address, a truncated or unsupported sockaddr, a bad address family, a
malformed entry behind a well-formed one, and more than
NFSD_NL_LISTENER_MAX entries. One more test sends a LISTENER_GET to an
empty netns.
None of these requests reach nfsd_create_serv(), so nothing here creates a
serv or registers with rpcbind. The tests that do need a serv come next,
with a stub.
The tests use kselftest_harness.h, so each test runs in its own net and
mount namespace. /run is masked there. unix_find_bsd() resolves by inode
and takes no struct net, so a connect to "/var/run/rpcbind.sock" from this
netns would otherwise reach the rpcbind on the host. svc_rpcb_setup()
opens with a call to svc_unregister(), which would then clear the host's
nfsd registrations.
The config fragment must therefore cover the fixture as well as nfsd:
NAMESPACES and NET_NS for the unshare(), SHMEM and TMPFS for the mask, and
UNIX for the AF_LOCAL rpcbind client. Without them, every test skips.
Add the new directory to the NFSD MAINTAINERS entry, which does not cover
tools/testing/selftests/ today.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260901-nfsd-nl-hang-v5-12-a540d86668b0@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Add a test for the hw constraints between the playback and capture
devices of an snd-aloop cable, and for the "PCM Slave" controls that
report the playback side's parameters to the capture application.
With notify disabled, a playback opened while a capture is set up must
be pinned to the capture's parameters. With notify enabled, it may pick
others. Starting it stops the running capture, and the "PCM Slave
Format", "Rate", "Channels" and "Access Mode" controls report the new
parameters, each with a value event. A capture opened second is pinned
to the playback either way.
The tests only check hw_refine results, stream states and control
values, so they don't depend on timing. They skip if snd-aloop isn't
loaded or the devices are in use.
Without "ALSA: aloop: Don't constrain playback params in notify mode",
the two notify mode tests fail.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Henrik Enquist <henrik.enquist@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20261003-aloop-notify-fix-v1-2-ba5dfb831bf5@gmail.com
|
|
A control whose register mask is wider than its field clobbers the
field next to it. No event is sent for the neighbour, so nothing
notices. The es8316 bug fixed in
commit 6c1bb4031729 ("ASoC: codec: es8316: "DAC Soft Ramp Rate" is just a 2 bit control")
was one.
Add a test that writes each control's minimum and then its maximum.
After each write it compares the other controls on the card with a
snapshot. The minimum clears the field and the maximum sets its top
bit, which is where a mask one bit too wide lands. Some drivers link
controls on purpose, so a change announced with a value event is only
logged. A silent one fails.
On an HDA HDMI codec and snd-dummy, 39 controls in all, it reports
nothing. A snd-dummy copy with an injected silent overlap fails, and
the same overlap announced with a value event passes.
Suggested-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/all/0fefbfe1-021b-46b2-8945-15956e75e37f@sirena.org.uk/
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260930111534.3782264-3-sammiee5311@gmail.com
|
|
The wait_for_event() skips an event for a different control with a
continue inside its do-while loop. But continue goes straight to the
loop condition, and that tests the mask of the event just skipped. So
a value event for another control ends the wait as if it were ours.
A driver that notifies a second control from its put() queues that
event first. The core only sends ours once put() returns. So the wait
returns early and leaves ours in the queue. The next test then
reports it as spurious. And event_missing passes for a control whose
put() said nothing changed, as long as it notified a neighbour.
To fix this, clear the mask before skipping the event.
Fixes: b1446bda5645 ("kselftest: alsa: Check for event generation when we write to controls")
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260930111534.3782264-2-sammiee5311@gmail.com
|
|
namespace stalls nobody
A readdir of the root of an empty mount namespace stuck in the page
fault of its buffer must stall neither a create nor a lookup in that
directory. The test needs userfaultfd and skips without it.
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-21-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
A getdents64() whose buffer is a page registered with userfaultfd sits
in handle_userfault() with whatever iterate_dir() took before it copied
the entries. Add readdir_hold.h for tests that want to know what that
blocks: it opens the userfaultfd before the test enters a user
namespace, the fault happens in the kernel and needs CAP_SYS_PTRACE in
the initial one, starts the readdir in a thread, waits until that
thread is stuck, queues a create behind it and waits for it to settle,
then probes a lookup with a watchdog and says whether it came back.
The page is released afterwards so that everything drains on a kernel
that still holds the lock across the copy.
The two users follow.
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-20-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
Make sure that we don't automount on top of internal things.
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-12-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
No access time updates for immutable nullfs.
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-11-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
Check MNT_LOCKED:
- A child in a user namespace of its own triggers the tracefs automount
through a directory descriptor on the host's debugfs mount. The copy
in the child's namespace has to be locked and the host's mount unlocked.
- A child moves a bind of that automount beneath a locked covering mount,
unmounts the covering mount and asks for the umount of an unlocked
ancestor. This must not expire the mount which holds the lock now.
- The host mounts and unmounts on a directory that a locked mount covers
in a user namespace further down the propagation chain. That cover has
to be locked afterwards as it was before.
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-10-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
Check that an immutable inode takes no write hint.
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-4-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
A failed REDIST_REGION write can remove redistributor iodevs without
clearing their cached vCPU assignments. A retry then skips those
assignments and leaves the redistributors absent from the MMIO bus.
Create two partial regions, reject a third region that overlaps the
distributor, and retry at a valid address. After initializing the VGIC,
have the guest read GICR_TYPER from all four redistributors and check their
processor numbers. This verifies the final configuration without assuming
that assignments survive the failed write.
Keep the redistributor IPAs outside the guest RAM memslot and install only
the stage-1 mappings needed for the MMIO accesses. If an iodev is missing,
KVM_RUN therefore exits with KVM_EXIT_MMIO. Without the fix, the first
redistributor access exits at 0x8030008.
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Link: https://patch.msgid.link/20260831081005.41346-5-kmehltretter@gmail.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
|
|
Pass the guest-code address to vm_gic_create_with_vcpus(), and use
guest_code at the existing call sites. This lets tests with different guest
code reuse the common VM and VGIC setup while retaining the void *
interface of vm_create_with_vcpus().
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Link: https://patch.msgid.link/20260831081005.41346-4-kmehltretter@gmail.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
|
|
'make rustfmtcheck' checks every .rs file in the tree and fails since
the test in Rust was added:
Diff in tools/testing/selftests/bpf/progs/data_in_arena_rust.rs:42:
#[no_mangle]
static IN_RODATA: Node = Node { val: 3, next: None };
#[no_mangle]
-static mut IN_DATA: Node = Node { val: 20, next: Some(&IN_RODATA) };
+static mut IN_DATA: Node = Node {
+ val: 20,
+ next: Some(&IN_RODATA),
+};
Format the file with rustfmt. The code and the data of the program
don't change.
Fixes: e86cb7315451 ("selftests/bpf: Add test for global data of a program in Rust")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20261003203326.1086454-1-alexei.starovoitov@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
|
|
Signed-off-by: Len Brown <len.brown@intel.com>
|
|
We allocate space for added counters ahead of time,
and we arbitrarily chose 24 added counters of each type.
If a future code flow hits this limit and continues,
and then removes counters, we do a phantom increment
and lose track of the number of added counters.
Increment the count only if there is no error.
Fixes: 388e9c8134be ("tools/power turbostat: Make extensible via the --add parameter")
Assisted-by: Claude: Claude Sonnet 4.6
Signed-off-by: Len Brown <len.brown@intel.com>
|
|
It is possible to leak a file descriptor if a diretory
open succeeds, but the scan fails. Close the fd on error.
Also, on cleanup, check for NULL fd.
Assisted-by: Claude: Claude Sonnet 4.6
Fixes: 4265a86582ea ("tools/power turbostat: Add PMT directory iterator helper")
Signed-off-by: Len Brown <len.brown@intel.com>
|
|
Fix off-by-one error causing last CPU on CWF
to never get a pmt counter allocated.
Fixes: 5ce1e9bbb2a1 ("tools/power turbostat: Add CPU%c1e BIC for CWF")
Assisted-by: GitHub Copilot (claude-sonnet-4.6)
Signed-off-by: Len Brown <len.brown@intel.com>
|
|
When turbostat notices a topology change,
it frees perf file descriptors for each CPU
to prepare to re-initialize.
Fix an off-by-one error in that per-cpu loop that
resulted in a file descriptor leak of the file for
the highest numbered CPU in the system.
Fixes: 67bab430f4e7 ("tools/power turbostat: Group SMI counter with APERF and MPERF")
Assisted-by: GitHub Copilot (claude-sonnet-4.6)
Signed-off-by: Len Brown <len.brown@intel.com>
|
|
When measuring over a suspend cycle, GRX%rc6 and SAM%mc6
are observed to print as numbers much greater than 100%.
Those numbers are not useful, and they mess up the columns.
Detect when they are out of range, and print them as NaN.
Signed-off-by: Len Brown <len.brown@intel.com>
|
|
Three calloc() calls in turbostat lack NULL return checks, leading to
potential NULL pointer dereferences on allocation failure:
1. rapl_perf_init(): the allocated `domain_visited` is used later via
memset(domain_visited, 0, ...) without checking for NULL.
2. added_perf_counters_init_(): the allocated `domain_visited` is used
later via memset() and domain_visited[next_domain] without checking
for NULL.
3. pmt_add_counter(): the allocated `pcounter` is dereferenced
immediately via strncpy(pcounter->name, ...) without checking for
NULL.
Add NULL checks after each calloc(), using the same error handling
style already present in each function: err(-1, ...) for rapl_perf_init(),
errx(1, ...) for added_perf_counters_init_(), and return 1 for
pmt_add_counter().
Signed-off-by: longlong yan <yanlonglong@kylinos.cn>
Signed-off-by: Len Brown <len.brown@intel.com>
|
|
Some systems in the field have perf enabled,
but their kernel perf support lacks the latest L2 stats.
Warn, but don't Err on those systems, and suggest how to avoid the Warn.
Fixes: dd23bfe4c317 ("tools/power turbostat: Add L2 cache statistics")
Reported-by: David Arcari <darcari@redhat.com>
Signed-off-by: Len Brown <len.brown@intel.com>
|
|
GCC doesn't support indirect calls in BPF:
progs/data_in_arena.c: In function 'use_ops':
progs/data_in_arena.c:65:1: error: indirect call in function, which are not supported by eBPF
Call add1() directly when the test is built with GCC. use_ops() still
loads the pointers to data that are next to the pointer to the function
in .data.rel.ro and dereferences them.
Once the build is fixed data_in_arena/arena_var_no_map fails with GCC:
test_arena_var_no_map:FAIL:open unexpected pointer: 0x559fb35d3ca0
GCC doesn't support address spaces. __arena is a type tag only there,
so avar is in .data instead of .addr_space.1 and there is nothing wrong
with the object. Use __arena_global. It puts the variable into
.addr_space.1 with both compilers.
Fixes: 27e24617a83b ("selftests/bpf: Add test for global data in arena")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20261003150456.168903-1-alexei.starovoitov@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
|
|
The addition of SipHash to lib/ predated the existence of the
lib/crypto/ directory. Since SipHash is a cryptographic algorithm, move
it from the top-level lib/ directory to lib/crypto/.
(This does mean HalfSipHash comes with it too, as it's in the same
files. But lib/crypto/ still seems like the proper place for both.)
Specifically:
- Move both siphash.c and siphash_kunit.c. Keep the header
<linux/siphash.h> as-is for now.
- Drop the dedicated MAINTAINERS entry for SipHash, as per the
suggestion from Jason
(https://lore.kernel.org/r/asB7QVFMlgKgbje2@zx2c4.com/). The C files
now just fold up to the "CRYPTO LIBRARY" entry. Add the header
explicitly, as it otherwise would be left unmaintained.
- Move the kconfig option that controls the KUnit test. Put
"CRYPTO_LIB" in its name and update the prompt and help text to make
it consistent with the other crypto library test options.
- Enable the KUnit test in lib/crypto/.kunitconfig.
- Link to siphash.rst from the appropriate place in libcrypto-hash.rst.
- Use obj-y instead of lib-y, for consistency with the fact that
currently lib/crypto/ doesn't use kbuild's support for library file
goals. We could keep it as lib-y, but virtually every kernel needs
SipHash support anyway (with vsprintf, printk, IPv4, IPv6, etc.
depending on it) so there is no practical difference in this case.
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Acked-by: Jason A. Donenfeld <Jason@zx2c4.com>
Link: https://patch.msgid.link/20261003162827.155527-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
|
|
data_in_arena_rust.rs shows why libbpf keeps .data, .bss and .rodata of
a program in Rust in arena. A reference in Rust is an address that can
be stored in data. The list in the test has a node in each of the three
sections. IN_BSS.next is stored by the program, IN_DATA.next is
a relocation in .data against .rodata. sum() follows them and reads all
nodes with the same insns:
5: w0 = *(u32 *)(r1 + 0x8)
8: r1 = *(u64 *)(r1 + 0x0)
The same program without .arena.data section, when the sections are
array maps:
libbpf: elf: skipping relo section(9) .rel.data for section(8) .data
...
16: (79) r1 = *(u64 *)(r1 +0) ; frame1: R1=scalar()
...
13: (61) r0 = *(u32 *)(r1 +8)
R1 invalid mem access 'scalar'
The program is built by upstream rustc for its bpfel-unknown-none
target. Nothing is done to the output: rustc emits LLVM bitcode and
clang makes the object of it for the cpu version of the test_progs
flavor. rustc has no prebuilt core for the target, so core is built from
the source that comes with rustc, like the kernel does it. That takes
5 seconds.
The subtest is skipped when:
- there is no rustc or it is older than 1.87. core is built as edition
2024, which it is since then.
- rustc comes without the source of core (rustup component add rust-src).
- clang is older than 23 or older than LLVM of rustc. It can't read
the bitcode then.
There are no kfuncs in the program. rustc doesn't emit debug info for
extern functions, so there would be no BTF for them.
panic=abort is a stop gap. Nothing in the program panics, so the panic
handler is not loaded. The series from Yonghong are about to add support
for panic=unwind.
Tested with rustc 1.95.0-nightly (LLVM 22.1) and clang 24.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20261002124714.180012-16-alexei.starovoitov@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
|
|
Load the program that reads and writes .data, .bss and .rodata from
the object with .arena.data section. Check that initial values set
through the skeleton reach the program and that the values written by
the program are seen through the skeleton.
Also check:
- alignment of a section.
- pointers to data and to a const string that are stored in data and
in read-only data, next to a pointer to a function that callx uses.
- bpf_strncmp() with a string literal, bpf_printk() and BPF_SNPRINTF().
- an object that has an arena map and __arena variables.
- the load fails when a pointer in data points to a section that is
not in arena or to a variable of the kernel.
- the load fails when there are pointers in data and the arena is
pinned or reused.
- the open fails when there are __arena variables and no arena map.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20261002124714.180012-15-alexei.starovoitov@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
|
|
bpf_printk(), BPF_SNPRINTF(), BPF_SEQ_PRINTF() and bpf_stream_printk()
copy the format into a static const array, which the compiler puts into
.rodata. When global data of the object is in arena .rodata is there
too and the helper doesn't take the format:
R1 type=scalar expected=fp, pkt, pkt_meta, map_key, map_value, mem,
ringbuf_mem, buf, trusted_ptr_, ctx
String literals are in .rodata.str1.1, which libbpf keeps in a read-only
map. No compiler flag moves a named array there. Put the arrays into
.rodata.str with a section attribute.
An object that uses the macros gets one more map, .rodata.str.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20261002124714.180012-14-alexei.starovoitov@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
|
|
All memory of a Rust program is arena, global data included. There are
no address spaces in Rust to say so. LLVM also drops bounds checks of
indexes into constant tables of core that it proved, so the verifier
can't check the access as access to map value.
The object asks for it with a section named .arena.data. What is in
the section doesn't matter:
#[used]
#[link_section = ".arena.data"]
static DATA_IN_ARENA: u8 = 0;
or in C:
char data_in_arena SEC(".arena.data");
There is nothing to tell to libbpf, so bpftool, veristat and other
loaders work with such objects as they are. When the object has the
section:
- .data, .bss and .rodata sections are appended to arena data after
__arena variables, at the alignment of the section. Like __arena
variables the data is at the end of arena.
- relocations of insns against the sections become relocations against
the arena map.
- array maps of the sections are not created.
- when the object has no arena map libbpf creates one that is as large
as the data. bpf_object__find_map_by_name(obj, "arena") finds it and
bpf_map__set_max_entries() makes room for allocations. __arena
variables still need the arena map to be declared.
Read-only sections that stay frozen array maps:
- .data.rel.ro and sections that have relocations in them. The kernel
recognizes pointers to functions in them by value for callx.
- .rodata.str*. They hold const strings for __str arguments of kfuncs.
A copy of them is in arena too.
The program dereferences pointers that it loads from data, so pointers
to data that are stored in data become addresses of arena, wherever the
pointer is. The arena map is created ahead of the other maps then, since
its address goes into their data. A pointer to .rodata.str* points to
the copy. A pointer to a section that is not in arena fails the load:
sec '.data': pointer to 'tbl' at offset 8 can't be resolved:
sec '.data.rel.ro' is not in arena
So does an arena that is pinned or reused. libbpf doesn't mmap it, so
its address is not known.
Programs of the object are loaded with BPF_F_ARENA_SCALAR, since they
access the data through plain numbers.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20261002124714.180012-13-alexei.starovoitov@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
|
|
Check that a variable in DATASEC that is smaller than its type is not
printed when the map is read from bpffs and when bpftool dumps it.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20261002124714.180012-12-alexei.starovoitov@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
|