Commit graph

1,484,770 commits

Author SHA1 Message Date
Dmitry Torokhov
51cfe54f81 Input: rmi_smbus - fix out-of-bounds read in rmi_smb_write_block()
When chunking writes into SMBus blocks in rmi_smb_write_block(), the
loop calculates block_len using the original total length (len) instead
of the remaining length (cur_len).

If len is greater than 32 bytes (SMB_MAX_COUNT), block_len remains 32
for every iteration, even on the final partial chunk where fewer than 32
bytes remain. This causes smb_block_write() to read 32 bytes from the
advanced data buffer pointer, reading past the end of the input buffer.

Fix this by calculating block_len using cur_len and advancing the buffer
and address pointers by block_len.

Fixes: 82264d0cf7 ("Input: synaptics-rmi4 - add SMBus support")
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot@kernel.org
Assisted-by: LLM
Link: https://patch.msgid.link/anLFSMKSoKyyZ272@google.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2026-08-30 14:42:00 -07:00
Tzung-Bi Shih
e3eceb7651 watchdog: msc313e: Fix NULL pointer dereference in PM callbacks
msc313e_wdt_probe() doesn't set the driver data for the platform device.
As a result, dev_get_drvdata() in msc313e_wdt_suspend() and
msc313e_wdt_resume() will return NULL, leading to a NULL pointer
dereference afterward.

Set the platform device driver data in msc313e_wdt_probe().

Fixes: e9800b7994 ("watchdog: Add Mstar MSC313e WDT driver")
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260827044700.554333-2-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2026-08-30 14:41:21 -07:00
James Hilliard
aab55360fa watchdog: sunxi_wdt: preserve boot-enabled watchdog
sunxi_wdt_probe() unconditionally stops the watchdog even when firmware
left it running. This opens an unprotected interval during boot and
prevents CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED from taking over the active
watchdog.

Detect an enabled watchdog and decode its programmed interval. Preserve
representable timeouts, and round the 0.5-second interval up to the
minimum representable one-second timeout. Use the configured timeout for
reserved interval encodings. Set the Linux reset mode and ping the
watchdog without clearing its enable bit, then mark it hardware-running
before registration so the watchdog core services it until userspace
takes control. Leave disabled watchdogs untouched.

Fixes: d00680ed00 ("watchdog: sunxi: New watchdog driver for Allwinner A10/A13")
Cc: stable@vger.kernel.org
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Link: https://patch.msgid.link/20260827-submit-sunxi-wdt-boot-enabled-v1-v2-1-610d37dccc97@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2026-08-30 14:41:21 -07:00
Maciej Fijalkowski
a8455260b2 ipvlan: unregister upper devices outside pnodes_lock
syzbot reported the following circular locking dependency:

  xs->mutex -> netdev lock -> pnodes_lock -> net->xdp.lock -> xs->mutex

The pnodes_lock -> net->xdp.lock edge is recorded when
ipvlan_device_event(NETDEV_UNREGISTER) calls unregister_netdevice_many()
while holding pnodes_lock.  A nested NETDEV_UNREGISTER notification for
an IPvlan device enters xsk_notifier(), which acquires net->xdp.lock.

Keep pnodes_lock only while marking the upper devices as dying, removing
them from port->ipvlans, and queueing them for unregistration.  Once the
devices have been detached from the protected list, release pnodes_lock
before unregister_netdevice_many() invokes notifier callbacks.

The port remains alive across unregistration because
ipvlan_device_event() holds the reference acquired by ipvlan_port_get().
The dying flag prevents a concurrent ->dellink() callback from deleting a
queued device again.

Fixes: 35add1093e ("ipvlan: Protect ipvl_port.ipvlans with mutex.")
Reported-by: syzbot+aa48b5fe7bfda62d1682@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=aa48b5fe7bfda62d1682
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260828164918.451364-1-maciej.fijalkowski@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-30 14:30:59 -07:00
Baul Lee
4aa61c88b4 vxlan: mdb: Fix use-after-free in vxlan_mdb_remote_src_del()
vxlan_mdb_is_valid_source(), which validates MDBE_ATTR_SOURCE and every
MDBE_ATTR_SRC_LIST member, accepts the all-zeros address.

A source list is only accepted on a (*, G) entry, whose source is the
all-zeros address, and for each member of the list an (S, G) entry is
derived from it by substituting the source. Entries are keyed by a plain
memcmp() of struct vxlan_mdb_entry_key, so if MDBE_ATTR_SOURCE is present
and holds the all-zeros address and the source list holds it as well, the
derived (S, G) key is byte-identical to the (*, G) key and resolves to the
same entry. Omitting MDBE_ATTR_SOURCE is not equivalent, as the key is
then left with a zero address family.

vxlan_mdb_remote_src_del() removes the forwarding entry of a source before
freeing the source entry:

	vxlan_mdb_remote_src_fwd_del(vxlan, group, remote, &ent->addr);
	vxlan_mdb_remote_src_entry_del(ent);

With the keys aliased, the first call deletes the remote of the entry that
owns 'ent' instead of a separate (S, G) entry, and frees 'ent'. The second
call then runs on the freed entry, and its hlist_del() reads ->pprev and
->next out of it and writes through them.

Adding the (*, G) entry with NLM_F_REPLACE and no source list marks the
all-zeros source for deletion and reaches this from the sweep at the end
of vxlan_mdb_remote_srcs_replace().

  BUG: KASAN: slab-use-after-free in __vxlan_mdb_add+0x1cd/0xd70
  Read of size 8 at addr ffff888102852500 by task poc/84
   __vxlan_mdb_add+0x1cd/0xd70
   vxlan_mdb_add+0xc0/0x140
   rtnl_mdb_add+0x157/0x2a0
   rtnetlink_rcv_msg+0x207/0x5a0
  Allocated by task 84:
   __kmalloc_cache_noprof+0x153/0x360
   vxlan_mdb_remote_srcs_add+0x2eb/0x440
   __vxlan_mdb_add+0x803/0xd70
  Freed by task 84:
   kfree+0x14c/0x3b0
   vxlan_mdb_remote_del+0x129/0x1a0
   __vxlan_mdb_del+0x4f/0xe0
   vxlan_mdb_remote_src_fwd_del.isra.0+0x162/0x1b0
   __vxlan_mdb_add+0x1c5/0xd70

The MDB operations are netns-scoped, so an unprivileged user can perform
them in a new user and network namespace.

Reject the all-zeros address in vxlan_mdb_is_valid_source(), which covers
both call sites. A (*, G) entry is expressed by omitting the source, so
nothing legitimate is refused.

Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>

Fixes: a3a48de5ea ("vxlan: mdb: Add MDB control path support")
Signed-off-by: Baul Lee <baul.lee@xbow.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260826173604.90158-1-baul.lee@xbow.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-30 14:19:59 -07:00
Charles Vosburgh
6cfc1b90cb sctp: validate chunk length in the inqueue parser
SCTP chunks always include a four-byte generic header, but
sctp_inq_pop() currently accepts shorter declared lengths. A zero-length
chunk leaves chunk_end at the current header.

When ASCONF is covered by the association's SCTP-AUTH policy,
sctp_assoc_bh_rcv() can continue before the state machine performs its
normal chunk-length check. sctp_inq_pop() then returns the same malformed
chunk repeatedly and the receive softirq can lock up.

A remote SCTP peer can trigger this after establishing an association on
a kernel built with CONFIG_IP_SCTP and configured with
net.sctp.addip_enable=1 and net.sctp.auth_enable=1. The reproducer did
not require application credentials, a shared SCTP AUTH key, or
net.sctp.addip_noauth_enable=1.

On commit f967455fb2 ("seg6: reset IP6CB after IPv6 decapsulation"),
one zero-length ASCONF caused repeated
watchdog soft-lockup reports in a two-vCPU KVM guest. All 3 pre-trigger
health probes succeeded, while 36 of 37 post-trigger probes failed. With
this change, all 37 post-trigger probes succeeded and no equivalent
soft-lockup signature appeared.

Reject chunks shorter than the generic SCTP header at the shared inqueue
parser boundary. Mark the packet for discard before either caller can
continue processing it, while preserving the four-byte generic minimum.
Declared-length 1 through 4 controls and kernel-generated ASCONF traffic
remained healthy. The patched sctp_hello selftest passed for IPv4 and
IPv6.

The complete private reproducer and validation evidence are available
directly to maintainers on request.

Fixes: bbd0d59809 ("[SCTP]: Implement the receive and verification of AUTH chunk")
Cc: stable@vger.kernel.org
Signed-off-by: Charles Vosburgh <theminershive@gmail.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20260827-sctp-zero-chunk-inqueue-v2-1-2e7669c6a6cb@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-30 14:17:53 -07:00
James Nugraha
ac8d6b28d4 net: amd-xgbe: discard rx packets with bad FCS
amd-xgbe driver currently sets the MAC_RCR.DCRCC bit whenever
RX is enabled. This disables hardware FCS validation, causing packets
with bad FCS to be accepted unconditionally.

This change unsets DCRCC so that packets with bad FCS will be dropped,
in-line with typical behaviours of many other network controllers.

Tests:
- Verified that packets with bad FCS are now dropped.
- Verified that receiving packets with bad FCS will increment the
  `rx_crc_errors` counter.

Fixes: c5aa9e3b81 ("amd-xgbe: Initial AMD 10GbE platform driver")
Signed-off-by: James Nugraha <aslan.jnn@gmail.com>
Link: https://patch.msgid.link/20260827232220.69907-1-aslan.jnn@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-30 14:17:19 -07:00
Xuanqiang Luo
ac08d183da raw: annotate disconnect-side IPv4 match writers
raw_v4_match() reads inet_daddr, inet_rcv_saddr and
sk_bound_dev_if locklessly under RCU. Bind and connect writers are
annotated, but __udp_disconnect() still clears the same fields using
plain stores.

Commit 18f116931f ("raw: annotate lockless match fields in
raw_v4_match()") added the lockless readers and annotated the raw bind
and datagram connect writers. Its v4 revision intentionally left the
shared disconnect-side IPv4 writers for follow-up cleanup.

Complete that follow-up by using WRITE_ONCE() for the disconnect-side
stores, including the inet_rcv_saddr reset in inet_reset_saddr(), to
pair with the lockless raw socket matcher.

Fixes: 0daf07e527 ("raw: convert raw sockets to RCU")
Link: https://lore.kernel.org/netdev/20260716142958.3064224-1-runyu.xiao@seu.edu.cn/
Suggested-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260828012918.1461-1-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-30 14:14:57 -07:00
Henry Martin
2cb0b0b1ed sctp: fix soft lockup from unpadded ASCONF-ACK parameter iteration
sctp_verify_asconf() walks ASCONF-ACK parameters with
sctp_walk_params(), which advances by SCTP_PAD4(length), while the
consumer sctp_get_asconf_response() iterates the same parameters
advancing by the raw length, without padding. A single odd-length
parameter desynchronises the two walks and makes the consumer
interpret attacker-controlled bytes at a misaligned offset.

When those bytes yield a length of zero, the while loop over
asconf_ack_len makes no progress, spinning forever in softirq
context, and the watchdog reports a soft lockup. All reads stay
within the received skb, so the lockup is a pure remote denial of
service. A remote peer can trigger it with a crafted ASCONF-ACK on
an ADD-IP enabled association with an outstanding ASCONF (RFC 5061
section 4.1.2 requires the chunk to be authenticated, but the
predefined empty key id 0 allows the peer to compute the same
association HMAC from publicly exchanged parameters, so the gate
does not help).

The SCTP_PARAM_ERR_CAUSE case of sctp_verify_asconf() also performs
no length check, letting a parameter without a complete error
header reach the consumer, which reads errhdr.cause past the end of
the parameter, an out-of-bounds read.

Reject SCTP_PARAM_ERR_CAUSE parameters shorter than
sizeof(struct sctp_addip_param) + sizeof(struct sctp_errhdr) at the
verifier, and advance the consumer iterator with the same padding
rule as the verifier to keep the two walks in lockstep. The verifier
change guarantees a complete error header in every ERR_CAUSE
parameter the consumer can see, so the consumer's asconf_ack_len
check is dropped and it returns err_param->cause directly. The
consumer padding fix is still required because odd lengths remain
valid for SCTP_PARAM_ERR_CAUSE per RFC 5061.

The issue was found by ZeroHive, a vulnerability hunting agent at
Tencent Yunding Lab.

Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20260828042431.3873725-1-bsdhenrymartin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-30 14:14:09 -07:00
Linus Torvalds
cee9395acd Linux 7.3-rc1 v7.3-rc1 2026-08-30 13:34:40 -07:00
Boqun Feng
2af470916a preempt: Remove hardirq_disable_count()
It turns out the previous usage of hardirq_disable_count() in
__irq_exit_rcu() would cause softirq pending issues. Without that usage,
hardirq_disable_count() doesn't need to exist, so remove it.

Also move hardirq_disable_enter/exit() into the Rust specific interrupt_rc
header.

[ tglx: Move the helpers over ]

Signed-off-by: Boqun Feng <boqun@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260827194835.38968-1-boqun@kernel.org
2026-08-30 20:25:21 +02:00
Sven Eckelmann
926013fd40
batman-adv: tt: drop the cleanup label from batadv_tt_local_remove()
With both locked sections moved to their own helpers, the only thing left
in the cleanup section is the reference of the looked up entry. The "out"
label is therefore only reached with a valid entry, except for the lookup
failure at the very beginning.

Return BATADV_NO_FLAGS directly when there is no entry and let the two
remaining cases be an if/else.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:59 +02:00
Sven Eckelmann
931de98d39
batman-adv: tt: extract immediate purge of a local entry
A client which was added after the last ttvn increment was never announced
and can be dropped from the local table right away. The code doing so is
the second half of batadv_tt_local_remove() and needed a goto to skip the
accounting when the entry was already gone from the hash.

Move it to batadv_tt_local_remove_now().

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:59 +02:00
Sven Eckelmann
5e02403a4c
batman-adv: tt: extract marking of a removed local entry
The first locked section of batadv_tt_local_remove() does three things at
once

* it snapshots the flags for the return value
* it marks the client as ROAMed
* it decides whether the entry has to survive until the next ttvn increment

But this complex locked section is in the middle of the function and cannot
be written as scoped_guard() due to goto's in this routine.

Move it to batadv_tt_local_mark_removed() and report the decision via its
return value. But leave the batadv_tt_local_set_pending_event() flag
assembly outside the function because it has no locking requirements.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:59 +02:00
Sven Eckelmann
228c70d51b
batman-adv: tt: extract removal of the superseded local entry
A client which was announced by another originator is no longer a local
client. The code which drops it from the local table and takes over its
WIFI flag is the second cleanup stage of batadv_tt_global_add() and needed
its own goto to skip over the multicast case.

Move it to batadv_tt_global_purge_local().

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:58 +02:00
Sven Eckelmann
3f8e8b42f6
batman-adv: tt: replace add_orig_entry goto in batadv_tt_global_add()
The "add_orig_entry" label was only used to skip the flag merging of the
non-temporary path. Which means that the code jumping to it and the code
below it are the two halves of an if/else.

Both halves now only decide whether the originator list has to be purged,
so turn them into an if/else and purge the list at a single place.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:58 +02:00
Sven Eckelmann
b535e61347
batman-adv: tt: extract merging of flags into existing global entries
When an already known global TT entry is announced again, its flags have to
be merged with the announced ones. Two of the merge steps also decide
whether the originator list has to be purged before the announced
originator is added.

Move this to batadv_tt_global_merge_flags() and let it report via its
return value whether the originator list has to be purged.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:58 +02:00
Sven Eckelmann
d9017aeb40
batman-adv: tt: extract allocation of new global entries
The code which allocates and initializes a brand new global TT entry makes
up a third of batadv_tt_global_add() and only needs the tt_addr, vid and
flags arguments. It is also the only part of the "new entry" branch which
does not deal with the global hash.

Move it to batadv_tt_global_create() and let it return the initialized
entry.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:58 +02:00
Sven Eckelmann
d72e16b1c5
batman-adv: tt: extract update of dynamic client flags
The WIFI and ISOLA flags are re-evaluated on every batadv_tt_local_add()
call, no matter whether a new entry was created or an existing one was
refreshed. It is mostly isolated from the rest of the
batadv_tt_local_add().

Move it to batadv_tt_local_update_flags(). To allow the caller to trigger
the queuing of ADD events, it returns whether one of the flags announced to
the other nodes actually changed.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:58 +02:00
Sven Eckelmann
799152bcf6
batman-adv: tt: decrement count for committed client on local_remove
Local TT entries which have the BATADV_TT_CLIENT_NEW no longer set are
committed. The batadv_tt_local_size_inc() was called for them and thus the
batadv_tt_local_size_dec() has to be called also when
batadv_tt_local_remove() is called for them when the BATADV_TT_CLIENT_NEW
wasn't consumed in the remove path.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:57 +02:00
Sven Eckelmann
ec6edeb755
batman-adv: tt: extract refresh of existing local entries
The handling of a client which is already part of the local translation
table is independent from the rest of batadv_tt_local_add(): it only
refreshes last_seen and evaluates the PENDING and ROAM flags of the entry
which was just looked up.

Move it to batadv_tt_local_add_existing(). It reports via its return value
whether the client has to be announced to the mesh again and whether the
client roamed back to its original location.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:57 +02:00
Sven Eckelmann
a5e5d2709d
batman-adv: tt: replace forward gotos in batadv_tt_local_add()
batadv_tt_local_add() used two labels in the middle of the function to
express which parts of the common tail have to be executed: "add_event" to
announce a (re-)added client and "check_roaming" to skip that announcement.
Jumping forward into the middle of a function makes it hard to see which
path ends up sending an ADD event. Especially since the PENDING branch
reached "add_event" while the branch right below it reached "check_roaming"
instead.

Express the same in an "added" variable and turn the two client cases into
a plain if/else. The PENDING check returned early before the ROAM check
could run, so it becomes an "else if".

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:57 +02:00
Sven Eckelmann
defa87f5ce
batman-adv: tt: extract allocation of new local entries
The code which allocates and initializes a brand new local TT entry makes
up more than a third of batadv_tt_local_add(). It only shares the addr, vid
and iif_is_wifi parameters with the rest of the function.

Move it to batadv_tt_local_create(), which returns the fully initialized
entry. The error paths become plain returns.

The insertion into bat_priv->tt.local_hash intentionally stays in
batadv_tt_local_add(), keeping the extra reference for the hash next to the
error handling which has to drop it again.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:57 +02:00
Sven Eckelmann
3273a5cd2d
batman-adv: tt: look up wifi state of incoming interface in helper
batadv_tt_local_add() only needs to know whether the client was seen on a
wifi interface. But it kept the net_device reference of the incoming
interface alive until its own cleanup section, together with a "net" and an
"in_dev" variable which are of no interest to the rest of the function.

Move the lookup to a small helper which acquires and releases the
net_device reference itself.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:57 +02:00
Sven Eckelmann
01ae63ecd1
batman-adv: tt: don't uncount never committed clients on pending purge
batadv_tt_local_purge_pending_clients() decreases vlan->tt.num_entries for
every entry it unlinks, but an entry which still carries
BATADV_TT_CLIENT_NEW was never counted by batadv_tt_local_transition_new().

batadv_tt_local_resize_to_mtu() calls batadv_tt_local_purge() and
batadv_tt_local_purge_pending_clients() directly, without committing in
between, and it halves its timeout down towards zero. Once the timeout is
short enough, batadv_tt_local_purge_list() marks even freshly added clients
as pending. And each of them decreases a counter it never increased.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:56 +02:00
Sven Eckelmann
f59c4c59df
batman-adv: tt: transition NEW local entries only under lock
The batadv_tt_local_size_inc() must never be called for an entry which was
already removed from the list. Otherwise the removal from the hash cannot
correctly determine if the batadv_tt_local_size_dec() needs to be called or
not.

This assumption is broken by the use of rcu_read_lock() in
batadv_tt_local_transition_new() because it might still see entries in the
list which were already removed by a different context from the list. If it
then increments the size counter, nothing will reduce the counter again.
Simply because the removal (responsible for the decrement) already
happened.

Over the whole time, the actual hash list spinlock must be held when
transitioning NEW local entries to avoid list manipulations.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:56 +02:00
Sven Eckelmann
976b159b3c
batman-adv: tt: use protected flag modifications
The flags of translation table entries are modified in various places using
RMW operations like:

* read flags + add flag + store
* read flags + remove flag + store

These were done without making sure that no other context is doing a
similar operation at the same time. If another context does modify the
flags then it could happen that a store of the flag modifications is simply
lost. This problem can usually be fixed at a later point when the flags are
tried to be adjusted again.

To reduce the time the wrong flags are used, it is better to use a TT entry
specific spinlock when accessing the u16.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:56 +02:00
Sven Eckelmann
52d8c713f4
batman-adv: tt: drop unnecessary cleanup goto in helpers
To use scoped_guard(), it is not allowed to use goto in the same routine.
These goto's should only be used for cleanups but are not necessary of
minimal helpers like batadv_is_my_client(),
batadv_tt_global_client_is_roaming() and
batadv_tt_local_client_is_roaming(). Removing the goto's is actually making
these functions more readable.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:56 +02:00
Sven Eckelmann
e103fbefa0
batman-adv: tt: simplify NEW flag transition code
The function batadv_tt_local_set_flags() implements support for various
flags and to set/unset them. It is also possible to decide whether this
change should increase the TT size or not.

But in reality, this function is only used to transition tt local entries
from the NEW state and count these entries. Remove the rest of the code to
simplify the function.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:56 +02:00
Sven Eckelmann
fd8d892c68
batman-adv: tt: extract code handling a roam on add
The code for handling the roaming of clients is mostly self contained but
embedded in the already too large batadv_tt_local_add function. The
maintainability can be improved by keeping it in an separate function.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:55 +02:00
Sven Eckelmann
bbfb0d2cf0
batman-adv: tt: remove only the entry which was looked up from the hash
batadv_hash_remove() searches a bucket with a compare callback and unlinks
the first matching entry. batadv_compare_tt() matches any entry for the
same MAC address and VLAN, not the object which was passed in, and the
callers in batadv_tt_local_remove() and batadv_tt_global_free() are not
serialized against the rest of the translation table in any way.

So when the looked up entry was already unlinked by another context and a
new entry for the same client was added in the meantime, these two
functions unlink that new entry instead.

Add batadv_compare_tt_entry(), which matches the very object which is
searched for, and use it for both removals. Nothing is unlinked when the
entry is gone already, batadv_hash_remove() then simply returns NULL and
only the reference of the calling context is dropped.

As a side effect the returned hlist_node can no longer belong to a
different object, so both functions can operate on the entry they were
given.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 20:05:45 +02:00
Linus Torvalds
78bb208b99 i2c-fixes for v7.3-rc1
Fixes mainly for teardown and resource handling, runtime PM and
 hardware-specific controller issues.
 
 - core: fix debugfs use-after-free when removing the adapter
 - designware: apply interrupt mask quirk for HJMC3001
 - imx-lpi2c: avoid target accesses on master-only controllers
 - mux: release channel node when adapter registration fails
 - qcom-cci: fix autosuspend and runtime PM cleanup on removal
 - qcom-geni: fix timing parameters for 32 MHz clock
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQScDfrjQa34uOld1VLaeAVmJtMtbgUCapRFYgAKCRDaeAVmJtMt
 bpVsAQDz0v5x5AdiZQS224oErSA6vfd7ztavFkh8gg3tR+PgogEAhhV+xChRle4U
 DTwvfC2DYuzxJxYpuQbMGdvu39cuTgA=
 =t/+3
 -----END PGP SIGNATURE-----

Merge tag 'i2c-fixes-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux

Pull i2c fixes from Andi Shyti:
 "Fixes mainly for teardown and resource handling, runtime PM and
  hardware-specific controller issues:

   - fix debugfs use-after-free when removing the adapter

   - designware: apply interrupt mask quirk for HJMC3001

   - imx-lpi2c: avoid target accesses on master-only controllers

   - mux: release channel node when adapter registration fails

   - qcom-cci: fix autosuspend and runtime PM cleanup on removal

   - qcom-geni: fix timing parameters for 32 MHz clock"

* tag 'i2c-fixes-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux:
  i2c: core: fix debugfs UAF on adapter removal
  i2c: imx-lpi2c: avoid accessing target registers on master-only controllers
  i2c: qcom-cci: fix autosuspend cleanup
  i2c: designware: Enable interrupt mask workaround for HJMC3001
  i2c: qcom-geni: update frequency table to fix timing parameters
  i2c: mux: Fix channel node leak on adapter add failure
2026-08-30 10:53:24 -07:00
Sven Eckelmann
d9304a90ec
batman-adv: ensure u16 aligned mac address in structs
An u8 array in structures have a natural alignment of only 1 byte. An
u8[ETH_ALEN] array must therefore be assumed to only be 1 byte aligned. But
many etherdevices.h functions are requiring a 2 byte (u16) alignment.

All these addresses were either on the start of a struct or after a struct
member which required at least an alignment of 2 byte. Still, annote all
u8[ETH_ALEN] arrays on the stack as __aligned(2) to make sure that this
assumption isn't broken by other modifications inside the structs.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 19:51:11 +02:00
Sven Eckelmann
a5f7058bee
batman-adv: ensure u16 aligned mac address arrays on stack
An u8 array on the stack has a natural alignment of only 1 byte. An
u8[ETH_ALEN] array on the stack must therefore be assumed to only be 1 byte
aligned. But many etherdevices.h functions are requiring a 2 byte (u16)
alignment.

Annote all u8[ETH_ALEN] arrays on the stack as __aligned(2) to make sure
that the compiler takes care of aligning it correctly.

Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260821094813.201800-1-sw%40simonwunderlich.de?part=5
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 19:51:11 +02:00
Sven Eckelmann
776c26254d
batman-adv: use more descriptive var names for is_similar_or_better
neigh1 and neigh2 is not really helpful when looking at a code which needs
to judge the metric similarity between a candidate and a reference. This
already caused an implementation error in the B.A.T.M.A.N. V bonding code.
Simply using "reference" and "candidate" for the neighbors is a lot more
descriptive and makes it easier to understand the code.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 19:51:11 +02:00
Sven Eckelmann
7356a9232d
batman-adv: clarify cut-off in batadv_v_neigh_is_sob kernel-doc
The neigh1 throughput must be more than 3/4 of the neigh2 throughput. Just
3/4 is not enough to return true.

Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 19:51:10 +02:00
Sven Eckelmann
77f653e6f7
batman-adv: bat_v: fix bonding candidate selection
batadv_v_neigh_is_sob() implements the metric (throughput) similarity check
as:

  neigh2 (the reference) has a better throughput than 3/4 of the neigh1
  (candidate) throughput

But this results in a selection of bonding candidates in
batadv_find_router() which have a really low throughput. But the goal must
be to select candidates which have a good throughput.

The neigh1/neigh2 operands must be swapped in the comparison to use the
reference as such and select only neighbor+interface combinations with good
throughput.

Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 19:50:54 +02:00
Sven Eckelmann
b963ee1dc3
batman-adv: drop direction in _batadv_is_ap_isolated kernel-doc
The _batadv_is_ap_isolated() is called by

* batadv_transtable_search()
  - tt_local_entry is the source
  - tt_global_entry is the destination
* batadv_is_ap_isolated
  - tt_local_entry is the destination
  - tt_global_entry is the source

It is therefore incorrect to document the tt_local_entry as sending client
and tt_global_entry as the destination client.

Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 19:48:40 +02:00
Sven Eckelmann
c6c8f1d693
batman-adv: dat: fix printing of unknown 4addr subtype
If an unknown subtype of an unicast 4addr packets was detected in
batadv_dbg_arp(), it is printing the (known) packet_type instead of the
subtype. This must be switched to the subtype to have any kind of use for
the reader of the debug message.

Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-08-30 19:48:30 +02:00
Linus Torvalds
eea8bdcb59 Coccinelle patches for Linux v7.3
Sang-Heon Jeon <ekffu200098@gmail.com> has cleaned up a number
 of the semantic patches in the scripts/coccinelle directory,
 particularly with respect to functions that no longer exist in
 the kernel.  He and I have also done some reorganizations that
 improve performance.
 
 I eliminatd some false positives.
 
 相浦彰 / AIURA,AKIRA <akira.aiura.bj@hitachi.com> fixed an
 out of date URL.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEnGZC8gbRfLXdcpA0F+92B3f5RZ0FAmqUJzoACgkQF+92B3f5
 RZ1ZKA//XmJPmm4VapiaWb3Kd9R11JXEqUrkDMkexkwpa+844xC6XfUKsAJTsxff
 18UksaPH+GQyLInWtu271uPDL+3X/yXbSU0iQA675XVQsG9Bz9MJ3R7tDcmFiJR9
 Oflm7VwlG0QFVk1HVJRtY5+kfZ5ob54CZ82QltHCRIrPKQJ9JWqS8ffnNggLQu91
 D079YK9gL/SqTXsWSUg+oU/TN5zILAZ0XDAdqN5THuMtq3ADurlKoPFeGHTiXdDs
 rFlmbu3XX40aL06qun6B4WLD/86fpvaVQ9NwqJnTEoTA4GNwENY/wYY9GJdsWa7h
 N7bTB7R8g441orRx0CeGyFBJkNocg4V5ImT42aGtsxfgIxDvFPxcfVg3TnCSbO8/
 SYvvnzaIzdYkx41IIIHPLZHNbW96kbT8rI5s3DrkUoKvMePnCtrV/6bR1QFBHdiw
 I5/q4yhFjwvRh5ffiU5McqlYcM4NK1s3lHD+fk6oKf8XOgPzo6b1nBFky+P4Whw+
 Sy/uBM2TrafRlvRrctz0EdhKSQede/Q7OVFcJKOvUUwnYKRqmrM5qPIQvDg6s4zZ
 7NQWK7SsfWFKFUd1mljqN9Pe//fLIxfHKqyQwWtoPJwPmVaKSUTF/UDHu5HR4VVn
 wd4MxZj1ck3Dv/mtvAcJNxKw3+imD+284wPkpsrityMDpdYRHoc=
 =AgiL
 -----END PGP SIGNATURE-----

Merge tag 'cocci-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux

Pull Coccinelle updates from Julia Lawall:

 - Clean up a number of the semantic patches in the scripts/coccinelle
   directory, particularly with respect to functions that no longer
   exist in the kernel (Sang-Heon Jeon)

   He and I have also done some reorganizations that improve
   performance.

 - Eliminate some false positives (me)

 - Fix an out of date URL (相浦彰)

* tag 'cocci-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux:
  coccinelle: ifnulldev_put: update error message
  coccinelle: ifnulldev_put: update outdated helper names
  coccinelle: atomic_as_refcounter: drop atomic_long_dec_and_lock
  coccinelle: kfree_mismatch: drop vmalloc_exec
  coccinelle: pool_zalloc-simple: drop the pci_pool_alloc rules
  coccinelle: zalloc-simple: drop the kmem_alloc rules
  coccinelle: alloc_cast: drop removed allocators
  coccinelle: remove obsolete pci_free_consistent.cocci
  scripts: coccinelle: devm_free: reduce false positives
  coccinelle: misc: struct_size: drop unneeded parentheses
  coccinelle: mini_lock: improve performance when searching loops
  coccinelle: api: check for macro context
  coccinelle: update Coccinelle website URL
  coccinelle: misc: minmax: avoid unhelpful isomorphisms
  coccinelle: misc: minmax: check for the presence of if cases
  coccinelle: misc: minmax: drop unneeded parentheses
  coccinelle: misc: minmax: improve performance when no candidate exists
  coccinelle: double_lock: improve performance when no double lock exists
2026-08-30 10:42:40 -07:00
Darrick J. Wong
cbb4c6d9af CREDITS/mailmap: add some info about Darrick J. Wong
Add myself to CREDITS because apparently I've never done that; and
update mailmap so that all my old email addresses get remapped to the
kernel.org redirector.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-08-30 10:29:08 -07:00
Linus Torvalds
a23cbb0574 - Fix UM build regression caused by the removal of the UM
specific timex.h header. (Thomas Weißschuh)
 
 Signed-off-by: Ingo Molnar <mingo@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmqTmUsRHG1pbmdvQGtl
 cm5lbC5vcmcACgkQEnMQ0APhK1iFihAAtSFpL6WKwu+eTTdTn/J41OCx6SWMw79O
 GRXfHX7HKVS52IhEnh3OWDVcMAqhNXe8oP/JwzBn4EuCv2LrsuBxpiTp6Bq4Y0Da
 Ws16Nb0CRH966L9E6z0kMZQBMsKrLGXGOE+/t9gzHpkTBzJ4a7Dzh1TZX2YudhRO
 lrnS+7azTb5XyshyMDo0C43AH6rUpt1ffYUz0MyACkbWPzQge42O3neN/2gKMDjq
 TM128Man3V4AX6K/9hC4vnvDNYdHsUqxHhc81826wVX7brF74uoYSiogn/AZK7RY
 CK9GQmAv7xo7AJTqe9AKt5dCy/cvVLp4vLqVYMQMGaFB05PF+1EMY69xrAkWnS4k
 1cYnU0hCHN/86XOShe1s0101UPD6ZxYo/WlU53VGRJMNi7Dm5OMFFOGzAK9WfTIB
 4UyOwuzq/505aA8dr5+Hk5PYikDvDXOA/zmqewAMonDrlTWhPBxWV6k+Dhks8WOt
 MIgjoX8wFlA7h0SUQH12XN/pxEBTgNl4P4k8YyHqVwOKN/XPZJ6XPGt2nIc8hnVc
 m3wHxP27x/68Ugpz1a8oADkC6lhDFgTE5XO6mmpfHKaVp/Fwdjrg8atwltHbixiV
 4mo5ZlcI759lN40EBJM4QbGRP8k5TjRGgkUnv7B2qpBBgAvPnCnlMZo0871J6VVz
 0CeKb6kxT+k=
 =eGi8
 -----END PGP SIGNATURE-----

Merge tag 'timers-urgent-2026-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer fix from Ingo Molnar:

 - Fix UM build regression caused by the removal of the UM
   specific timex.h header (Thomas Weißschuh)

* tag 'timers-urgent-2026-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  um: Use asm-generic/timex.h over the host architecture one
2026-08-30 10:19:11 -07:00
Frank Sorenson
fe39cd9d48 cifs: don't update i_size in cifs_do_truncate without a cached handle
If find_writable_file() returns null, cifs_file_flush will return
0 without issuing set_file_size, and the outer 'if (!rc)' block
will set i_size to 0 before telling the server to truncate.  If
the cifs_open() then fails, the inode will have size 0, while
the server file is unchanged.

Move the netfs_resize_file() and cifs_setsize() into the 'if
(cfile)', so they only run after a successful set_file_size.

In the no-handle else branch, evict stale pages with
truncate_inode_pages before the O_TRUNC open to dispose of old
cache pages, and let the open response set the i_size.

Fixes: 110fee6b9b ("smb: client: fix missing timestamp updates with O_TRUNC")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-30 14:05:38 -03:00
Frank Sorenson
1dac61e2c2 smb: client: fix heap overflow in cifs_do_set_acl()
cifs_set_acl() validates ACL size using posix_acl_xattr_size():

        4 + (count * 8)  // 4-byte header + 8 bytes per ACE

cifs_do_set_acl() then calls posix_acl_to_cifs() to write the CIFS
wire format into the same buffer:

        6 + (count * 10)  // 6-byte header + 10 bytes per ACE

An ACL that passes the xattr-based check in cifs_set_acl() can
overflow the heap when posix_acl_to_cifs() writes the larger CIFS
format.

Validate the CIFS format size against the remaining buffer space and
USHRT_MAX before converting--data_count is __u16, so sizes above
USHRT_MAX truncate the on-wire packet length, causing the server to
apply a partial ACL.  Replace MaxDataCount = 1000 with
min(CIFSMaxBufSize, USHRT_MAX).

Fixes: dc1af4c4b4 ("cifs: implement set acl method")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-30 14:05:26 -03:00
Paulo Alcantara
6949939586 smb: client: fix multiuser mount with krb5
Customer reported that they could no longer mount their SMB shares
with multiuser mount option and krb5.  Turned out that the client
wasn't duplicating username option when creating multiuser
connections, therefore failing to retrieve credentials as
cifs.upcall(8) couldn't find them in keytab.

Fix this by duplicating username option (if set) from original fs
context before creating multiuser connections with krb5.

Reproducer:

  ```
  $ ktutil
  ktutil:  add_entry -password -p testuser -k 1 -e aes256-cts
  Password for testuser@ZELDA.TEST:
  ktutil:  write_kt /etc/krb5.keytab
  ktutil:  quit
  $ klist -ke
  Keytab name: FILE:/etc/krb5.keytab
  KVNO Principal
   ---- ----------------------------------------------------------------
     1 testuser@ZELDA.TEST (aes256-cts-hmac-sha1-96)
  $ mount.cifs //w22-root2/scratch /mnt/1 -o \
      	uid=1000,sec=krb5,username=testuser@ZELDA.TEST,multiuser
  mount error(13): Permission denied
  Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and
  kernel log messages (dmesg)
  ```

Reported-by: Jacob Shivers <jshivers@redhat.com>
Fixes: 12b4c5d98c ("smb: client: fix krb5 mount with username option")
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-30 14:05:16 -03:00
Andy Shevchenko
d83a21bb26 smb: client: transport: Fix debug printing in __release_mid()
Long time ago during upgrading printk():s to the respective pr_<level>()
calls one misconversion happened and nobody has noticed that. So,
previously printk(KERN_DEBUG) + printk() worked as one long debug print
since the trailing '\n' is only present in the followup printk() format
string. The culprit change missed that and split the message to two on
the different levels. Restore the original behaviour to make users be
less confused in the most likely never happen cases of partially getting
that message.

Fixes: 0b456f04bc ("cifs: convert printk(LEVEL...) to pr_<level>")
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-30 14:05:05 -03:00
Huiwen He
448ba0ae65 smb/client: invalidate fscache for fallocate range operations
smb3_zero_range(), smb3_punch_hole(), smb3_insert_range(), and
smb3_collapse_range() modify file contents through server-side range
operations. These operations discard the affected page cache, but leave
the FS-Cache cookie valid, so a later read may return data cached before
the range operation.

Fix this by invalidating FS-Cache after outstanding I/O has completed
and before modifying the file on the server.

Run the following as root on a CIFS mount with fsc enabled and an active
CacheFiles backend:

        bash -c '
                MNT=/mnt/cifs
                FILE="$MNT/repro"

                # Generate four 1 MiB random blocks: [A][B][C][D].
                dd if=/dev/urandom of=/tmp/src bs=1M count=4 status=none

                # Expected contents after zeroing B: [A][zero][C][D].
                cp /tmp/src /tmp/expected
                dd if=/dev/zero of=/tmp/expected bs=1M seek=1 count=1 \
                        conv=notrunc status=none
                cp /tmp/src "$FILE"

                # Populate FS-Cache, then discard the page cache.
                sync
                echo 1 > /proc/sys/vm/drop_caches
                cat "$FILE" > /dev/null
                sync
                echo 1 > /proc/sys/vm/drop_caches

                fallocate --zero-range -o 1M -l 1M "$FILE"

                if cmp -s /tmp/expected "$FILE"; then
                        echo "readback: OK"
                else
                        echo "readback: STALE DATA"
                fi
        '

Before this change, the readback differs from /tmp/expected:

        readback: STALE DATA

After this change, it matches:

        readback: OK

Fixes: 30175628bf ("[SMB3] Enable fallocate -z support for SMB3 mounts")
Fixes: 31742c5a33 ("enable fallocate punch hole ("fallocate -p") for SMB3")
Fixes: 5476b5dd82 ("cifs: add support for FALLOC_FL_COLLAPSE_RANGE")
Fixes: 7fe6fe95b9 ("cifs: add FALLOC_FL_INSERT_RANGE support")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-30 14:04:21 -03:00
Huiwen He
01261a6fa4 smb/client: fix stale page cache in insert/collapse range
smb3_insert_range() and smb3_collapse_range() use
truncate_pagecache_range() to invalidate the affected page cache.
However, if off or old_eof is not page-aligned, the boundary pages are
only partially zeroed and remain uptodate. As a result, the client may
return stale data after a successful insert/collapse range operation.

For example, with 4K pages:

    page 0          page 1          page 2
    0------4K       4K------8K      8K------12K
       ^                                ^
    off=2K                       old_eof=10K

Page 1 is removed from the page cache, while the boundary pages are
only partially zeroed. After COPYCHUNK moves the data on the server,
these cached pages may still return stale data.

This can be reproduced on a CIFS mount:

    bash -c '
            FILE=/mnt/scratch/repro

            # Use a 6 KiB file so EOF is not page-aligned.
            dd if=/dev/urandom of=/tmp/src bs=1K count=6 status=none

            # Expected: a 4 KiB hole followed by the original data.
            rm -f /tmp/expected
            truncate -s 4K /tmp/expected
            cat /tmp/src >> /tmp/expected

            cp /tmp/src "$FILE"

            # Prime the page cache before moving data on the server.
            cat "$FILE" > /dev/null

            fallocate --insert-range -o 0 -l 4K "$FILE"

            if cmp -s /tmp/expected "$FILE"; then
                    echo "readback: OK"
            else
                    echo "readback: STALE DATA"
            fi
    '

Fix this by writing back dirty data and discarding the page cache from
the start of the page containing off to EOF before moving data on the
server.

Fixes: 9c8b7a293f ("smb3: fix temporary data corruption in insert range")
Fixes: fa30a81f25 ("smb3: fix temporary data corruption in collapse range")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-30 14:04:21 -03:00
Huiwen He
7811701d6a smb/client: fix integer truncation in collapse range
smb3_collapse_range() stores the ssize_t return value of
smb2_copychunk_range() in an int. A successful copy larger than
INT_MAX is truncated to a negative value and treated as an error.

Reproducer:

	MNT=/mnt/scratch

	truncate -s 2056M "$MNT/file"
	fallocate --collapse-range -o 1M -l 1M "$MNT/file"

Fix this by using __smb2_copychunk_range(), which reports success as
zero instead of returning the copied byte count.

Before this change, the reproducer fails with:

	fallocate: fallocate failed: Success

and the file size remains unchanged at 2056 MiB. After this change, the
reproducer succeeds and the file size becomes the expected 2055 MiB.

Fixes: 5476b5dd82 ("cifs: add support for FALLOC_FL_COLLAPSE_RANGE")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-30 14:04:20 -03:00
Huiwen He
0923ae9f23 smb/client: fix data corruption in emulated insert range
smb3_insert_range() shifts [off, EOF) right with COPYCHUNK, copying from
low to high offsets. When the ranges overlap, the copy can overwrite
source data that has not yet been copied. For a 1 MiB insert at offset 0:

  offset:    0       1M      2M      3M      4M      5M
  before:   |   A   |   B   |   C   |   D   |
  expected: | hole  |   A   |   B   |   C   |   D   |
  current:  | hole  |   A   |   A   |   A   |   A   | (corrupted)

Let x be the insertion offset, L the total length to move, delta the
insert length, and C the normal chunk size allowed by the server.
Insert range maps

  [x, x + L) -> [x + delta, x + delta + L).

When delta >= L, the complete source and target ranges are disjoint, so
the normal copy order and chunk size are safe:

  offset: 0       4       8      12      16      20      24      28      32
  source: [--S0--][--S1--][--S2--][--S3--]
  target:                                 [--T0--][--T1--][--T2--][--T3--]

When delta < L, the complete source and target ranges overlap, so the
copy must proceed from EOF backwards. There are two subcases.

If delta >= C, each corresponding source and target chunk is disjoint.
The 1 MiB example has L = 4 MiB and delta = C = 1 MiB:

  offset: 0       1M      2M      3M      4M      5M
  source: [--S0--][--S1--][--S2--][--S3--]
  target:         [--T0--][--T1--][--T2--][--T3--]

Copying S0 from [0, 1M) to [1M, 2M) overwrites S1 before it is copied.
Processing chunks from EOF backwards prevents this inter-chunk
overwrite.

If delta < C, the source and target ranges of a normal chunk also
overlap. For example, with L = 16, delta = 2 and C = 4:

  offset: 0   2   4   6   8  10  12  14  16  18
  source: [--S0--][--S1--][--S2--][--S3--]
  target:     [--T0--][--T1--][--T2--][--T3--]

Here S0 and T0 overlap over [2,4), S1 and T1 over [6,8), and so on.
Backward ordering cannot control how the server copies bytes inside one
descriptor, so the chunk size must be limited to delta.

Fix this by copying overlapping right shifts from EOF backwards. Limit
the chunk size to delta when delta < C so that each chunk's source and
target ranges do not overlap. Using larger chunks would require a way to
identify servers that safely handle overlapping COPYCHUNK descriptors.

Therefore:

  delta >= L:
    keep the normal copy order and chunk size

  delta < L:
    delta >= C: copy backwards and keep the normal chunk size
    delta <  C: copy backwards and limit the chunk size to delta

Only the delta < C subcase requires reducing the chunk size for data
integrity.

Reproducer:

  bash -c '
          MNT=/mnt/scratch

          # Generate four 1 MiB random blocks: [A][B][C][D].
          dd if=/dev/urandom of=/tmp/src bs=1M count=4 status=none

          # With C = 1 MiB, test delta = C and delta < C.
          for delta in 1M 1K; do
                  truncate -s 0 /tmp/expected
                  truncate -s "$delta" /tmp/expected
                  cat /tmp/src >> /tmp/expected

                  cp /tmp/src "$MNT/file"
                  fallocate --insert-range -o 0 -l "$delta" "$MNT/file"

                  if cmp -s /tmp/expected "$MNT/file"; then
                          echo "delta=$delta: OK"
                  else
                          echo "delta=$delta: CORRUPTED"
                  fi
          done
  '

The corruption reproduces with Samba and ksmbd, while Windows handles
the overlapping COPYCHUNK ranges safely.

The 1 MiB case tests delta >= C, while the 1 KiB case tests delta < C.
Before this change, the reproducer reports:

  delta=1M: CORRUPTED
  delta=1K: CORRUPTED

After this change, it passes against both ksmbd and Samba:

  delta=1M: OK
  delta=1K: OK

Fixes: 7fe6fe95b9 ("cifs: add FALLOC_FL_INSERT_RANGE support")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-30 14:04:20 -03:00