| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
dm_early_create: fix freeing used table on dm_resume failure
If dm_resume fails, the kernel attempts to free table with
dm_table_destroy, but the table was already instantiated with
dm_swap_table. This commit skips the call to dm_table_destroy in this
case. |
| In the Linux kernel, the following vulnerability has been resolved:
can: bcm: add missing device refcount for CAN filter removal
sashiko-bot remarked a problem with a concurrent device unregistration
in isotp.c which also is present in the bcm.c code. A former fix for raw.c
commit c275a176e4b6 ("can: raw: add missing refcount for memory leak fix")
introduced a netdevice_tracker which solves the issue for bcm.c too.
bcm_release(), bcm_delete_rx_op() and bcm_notifier() relied on
dev_get_by_index(ifindex) to re-find the device for an rx_op before
unregistering its filter. If a concurrent NETDEV_UNREGISTER has already
unlisted the device from the ifindex table, that lookup fails and
can_rx_unregister() is silently skipped, leaving a stale CAN filter
pointing at the soon-to-be-freed bcm_op/socket.
Hold a netdev_hold()/netdev_put() tracked reference on op->rx_reg_dev
from the moment the rx filter is registered in bcm_rx_setup() until it
is unregistered in bcm_rx_unreg(), and use that reference directly in
bcm_release() and bcm_delete_rx_op() instead of re-looking the device
up by ifindex. |
| In the Linux kernel, the following vulnerability has been resolved:
can: bcm: add missing rcu list annotations and operations
sashiko-bot remarked the missing use of list_add_rcu() in
bcm_[rx|tx]_setup() to have a proper initialized bcm_op structure
when bcm_proc_show() traverses the bcm_op's under rcu_read_lock().
To cover all initial settings of the bcm_op's the list_add_rcu() calls
are moved to the end of the setup code.
While at it, also fix the mirroring removal side: bcm_release() called
bcm_remove_op() - which frees the op via call_rcu() - on ops that were
still linked in bo->tx_ops/bo->rx_ops, without list_del_rcu() first.
Unlink each op with list_del_rcu() before handing it to bcm_remove_op(),
matching the existing pattern in bcm_delete_tx_op()/bcm_delete_rx_op(). |
| In the Linux kernel, the following vulnerability has been resolved:
can: isotp: fix use-after-free race with concurrent NETDEV_UNREGISTER
isotp_release() looked up the bound network device via dev_get_by_index()
using the stored ifindex. During device unregistration the device is
unlisted from the ifindex hash before the NETDEV_UNREGISTER notifier
chain runs, so a concurrent isotp_release() could find no device, skip
can_rx_unregister() entirely, and still proceed to free the socket.
Since isotp_release() had already removed itself from the isotp
notifier list at that point, isotp_notify() would never get a chance to
clean up either, leaving a stale CAN filter that keeps pointing at the
freed socket.
Fix this the same way raw.c already does: hold a tracked reference to
the bound net_device in the socket (so->dev/so->dev_tracker) from
bind() onward instead of re-resolving it from the ifindex, and
serialize bind()/release() with rtnl_lock() so that so->dev is always
consistent with what the NETDEV_UNREGISTER notifier sees. so->dev
stays valid regardless of ifindex-hash unlisting, and is only ever
cleared by whichever of isotp_release()/isotp_notify() gets there
first, so the filter is always removed exactly once.
isotp_bind() now rejects a (re)bind with -EAGAIN while so->[tx|rx].state
isn't ISOTP_IDLE yet, so a timer left running by a prior
NETDEV_UNREGISTER can't act on a newly bound so->ifindex. Both checks
share the same lock_sock() section, so there is no window in which a
concurrent isotp_notify() clearing so->bound could be missed. |
| In the Linux kernel, the following vulnerability has been resolved:
can: isotp: use unconditional synchronize_rcu() in isotp_release()
isotp_notify() unregisters the (RCU) CAN filters via can_rx_unregister()
and clears so->bound without waiting for a grace period. isotp_release()
uses so->bound to decide whether it needs to call synchronize_rcu()
before cancelling so->rxtimer, so when NETDEV_UNREGISTER runs first it
skips that synchronize_rcu() and can cancel the timer while an
in-flight isotp_rcv() is still executing and about to re-arm it via
isotp_send_fc(), leading to a use-after-free timer callback on the
freed socket.
sakisho-bot remarked a problem with rtnl_lock held in isotp_notify(),
therefore make isotp_release() always call synchronize_rcu() before
cancelling the timers, regardless of so->bound. This still closes the
original race (isotp_notify() clearing so->bound without waiting for
in-flight isotp_rcv() callers before isotp_release() cancels the RX
timer) without adding any RCU wait to the netdevice notifier path. |
| In the Linux kernel, the following vulnerability has been resolved:
tpm: tpm2-sessions: wait for async KPP completion in tpm_buf_append_salt
tpm_buf_append_salt() in drivers/char/tpm/tpm2-sessions.c calls
crypto_kpp_generate_public_key() and crypto_kpp_compute_shared_secret()
without installing a completion callback, discards both return values,
and immediately frees the kpp_request via kpp_request_free(). When the
resolved ecdh-nist-p256 KPP backend is asynchronous (atmel-ecc, HPRE,
keembay-ocs), either operation returns -EINPROGRESS and the deferred
completion worker dereferences the freed request.
The path fires automatically from the hwrng_fillfn kernel thread via
tpm_get_random -> tpm2_get_random -> tpm2_start_auth_session ->
tpm_buf_append_salt on every entropy poll, without any userland action.
Install crypto_req_done as the completion callback, wrap both KPP
operations in crypto_wait_req(), and propagate errors to the caller.
The wait is a no-op for synchronous backends. |
| In the Linux kernel, the following vulnerability has been resolved:
sunrpc: harden rq_procinfo lifecycle to prevent double-free
The svc_release_rqst() function executes the callback inside
rqstp->rq_procinfo->pc_release. However, if a worker thread begins
processing a new request and encounters an early error path (e.g.,
unsupported protocol, short frame, or bad auth) before a valid
rq_procinfo is installed, a stale release hook can be re-triggered
against reused state from the previous RPC, resulting in a double-free
or use-after-free vulnerability.
Harden the lifecycle of rq_procinfo by:
1. Ensuring svc_release_rqst() always clears rq_procinfo after the
optional pc_release() call, regardless of whether the hook exists.
2. Explicitly clearing rq_procinfo at request entry in svc_process()
before any early decode or drop paths.
3. Ensuring svc_process_bc() does the same at backchannel entry.
This guarantees that error flows will not encounter a non-NULL stale
rq_procinfo pointer when there is nothing to release. |
| In the Linux kernel, the following vulnerability has been resolved:
batman-adv: access unicast_ttvn skb->data only after skb realloc
The pskb_may_pull() called by batadv_get_vid() could reallocate the buffer
behind the skb. Variables which were pointing to the old buffer need to be
reassigned to avoid an use-after-free.
This was done correctly for the ethernet header but missed for the
unicast_packet pointer. |
| In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: pin upper rpc_clnt across the TLS connect_worker
The TLS connect path has a use-after-free: nothing pins the
upper rpc_clnt across the delayed connect_worker. xs_connect()
stores task->tk_client in sock_xprt::clnt as a raw pointer
and queues the worker; for TLS-secured transports that worker
is xs_tcp_tls_setup_socket(), which reads several fields out
of the saved pointer (cl_timeout, cl_program, cl_prog,
cl_vers, cl_cred, cl_stats) to construct the args for the
inner handshake rpc_clnt.
The xprt does not reference the rpc_clnt; the rpc_clnt
references the xprt. xs_destroy() does cancel the
connect_worker, but it runs only when the xprt's refcount
drops to zero, which cannot happen until the rpc_clnt
releases its cl_xprt reference in rpc_free_client_work().
When a TLS handshake fails fatally (for example, an mTLS
mount whose client cert does not match the server), the
connecting task is woken with -EACCES and exits, the mount
caller invokes rpc_shutdown_client(), and the upper rpc_clnt
is freed before the queued connect_worker fires.
xs_tcp_tls_setup_socket() then dereferences the freed clnt,
producing the refcount_t underflow Michael Nemanov reported.
Take a reference on the upper rpc_clnt in xs_connect() for
TLS transports via a new rpc_hold_client() helper, and drop
it in the connect_worker's exit path with rpc_release_client().
The xprt_lock_connect() / xprt_unlock_connect() pairing
already serialises xs_connect() with xs_tcp_tls_setup_socket(),
so the take and release are balanced one-for-one.
The non-TLS connect worker (xs_tcp_setup_socket) never reads
sock_xprt::clnt, so leave that path alone and avoid the
clnt-holds-xprt-holds-clnt cycle that would otherwise prevent
xprt destruction. |
| In the Linux kernel, the following vulnerability has been resolved:
ntfs: avoid stale runlist element dereference in fallocate
ntfs_attr_fallocate() allocates holes and delayed allocations inside
initialized size by looking up the current runlist element under
ni->runlist.lock. The returned struct runlist_element is only a borrowed
pointer into ni->runlist.rl. A writer can replace and free that array
after the read lock is dropped, so later reads of rl->lcn, rl->length and
rl->vcn can touch freed memory.
The buggy scenario involves two paths, with each column showing the order
within that path:
ntfs_attr_fallocate():
1. Take ni->runlist.lock for read.
2. Get rl from ntfs_attr_find_vcn_nolock().
3. Drop ni->runlist.lock.
4. Read rl->lcn, rl->length and rl->vcn.
mmap page_mkwrite:
1. Enter ntfs_filemap_page_mkwrite().
2. Reach __ntfs_write_iomap_begin() and ntfs_attr_map_cluster().
3. Merge allocation state with ntfs_runlists_merge().
4. Reallocate ni->runlist.rl in ntfs_rl_realloc(), freeing the old array.
Validation reproduced this kernel report:
BUG: KASAN: slab-use-after-free in ntfs_attr_fallocate+0xbb8/0xd00
Call Trace:
<TASK>
dump_stack_lvl+0x66/0xa0
print_report+0xce/0x630
? ntfs_attr_fallocate+0xbb8/0xd00
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x20d/0x410
? ntfs_attr_fallocate+0xbb8/0xd00
kasan_report+0xe0/0x110
? ntfs_attr_fallocate+0xbb8/0xd00
ntfs_attr_fallocate+0xbb8/0xd00
? lock_acquire+0x2b8/0x2f0
? __pfx_ntfs_attr_fallocate+0x10/0x10
? 0xffffffffc0000095
? down_write+0x10d/0x1e0
ntfs_fallocate+0x5c9/0x1d00
? __pfx_ntfs_fallocate+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? lock_acquire+0x2b8/0x2f0
? srso_alias_return_thunk+0x5/0xfbef5
? selinux_file_permission+0x3a7/0x510
vfs_fallocate+0x29d/0xd30
__x64_sys_fallocate+0xc7/0x150
? do_syscall_64+0x81/0x6a0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Allocated by task 410:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0xaa/0xb0
__kvmalloc_node_noprof+0x353/0x920
ntfs_rl_realloc+0x3f/0x110
ntfs_runlists_merge+0xaa3/0x3010
ntfs_attr_map_cluster+0x4e5/0xf80
ntfs_attr_fallocate+0x53f/0xd00
ntfs_fallocate+0x5c9/0x1d00
vfs_fallocate+0x29d/0xd30
__x64_sys_fallocate+0xc7/0x150
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 424:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
kfree+0x307/0x580
ntfs_rl_realloc+0x6f/0x110
ntfs_runlists_merge+0x7b1/0x3010
ntfs_attr_map_cluster+0x4e5/0xf80
__ntfs_write_iomap_begin+0x8cd/0x2280
iomap_iter+0x6de/0x11e0
iomap_page_mkwrite+0x391/0x650
ntfs_filemap_page_mkwrite+0x1ac/0x400
do_page_mkwrite+0x15c/0x280
__handle_mm_fault+0xd6d/0x1ca0
handle_mm_fault+0x19c/0x470
do_user_addr_fault+0x23b/0x9c0
exc_page_fault+0x5c/0xc0
asm_exc_page_fault+0x26/0x30
Fix this by copying the needed runlist fields while the read lock is still
held and using only those scalar snapshots after unlocking.
After the snapshot, ntfs_attr_map_cluster() can also find that the range
is already mapped and return balloc=false. Only call ntfs_dio_zero_range()
when new clusters were allocated, matching the write iomap path and
preserving the zero-newly-allocated-holes behavior. |
| In the Linux kernel, the following vulnerability has been resolved:
net: udp_tunnel: prevent double queueing in udp_tunnel_nic_device_sync
Yue Sun reported a use-after-free and debugobjects warning in
udp_tunnel_nic_device_sync_work() during concurrent device operations.
The workqueue core clears the internal pending bit before invoking the
worker. At that point, a concurrent thread can queue the work again.
When the already running worker eventually clears the work_pending flag
to 0, it mistakenly clears the flag for the newly queued instance.
udp_tunnel_nic_unregister() then observes work_pending as 0 and frees
the structure while the second work item is still active in the queue,
leading to UAF.
Fix this by returning early in udp_tunnel_nic_device_sync() if
work_pending is already set, preventing redundant work queueing. |
| In the Linux kernel, the following vulnerability has been resolved:
netfilter: nf_nat_sip: reload possible stale data pointer
quoting sashiko:
------------------------------------------------------------------------
[..] noticed a potential memory bug and header corruption involving the
SIP NAT helper.
In net/netfilter/nf_nat_sip.c:nf_nat_sip():
if (skb_ensure_writable(skb, skb->len)) {
nf_ct_helper_log(skb, ct, "cannot mangle packet");
return NF_DROP;
}
uh = (void *)skb->data + protoff;
uh->dest = ct_sip_info->forced_dport;
if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, protoff,
0, 0, NULL, 0)) {
If a cloned or fragmented SKB is reallocated by skb_ensure_writable(), the
old data buffer is freed. However, nf_nat_sip() fails to update *dptr to
point to the new buffer.
It also appears to use nf_nat_mangle_udp_packet() on what could be a TCP
packet, which would overwrite the sequence number with a checksum update.
------------------------------------------------------------------------
nf_conntrack_sip linerizes skbs, hence no fragmented skb can be seen.
But clones are possible, so rebuild dptr.
Disable nf_nat_mangle_udp_packet() branch for TCP streams.
It doesn't look like this can ever happen, else we should have received
bug reports about this, so just check the conntrack is UDP and drop
otherwise.
The calling conntrack_sip set ->forced_dport for SIP_HDR_VIA_UDP messages,
so I don't think this is ever expected to be true for a TCP stream. |
| In the Linux kernel, the following vulnerability has been resolved:
KVM: Move kvm_io_bus_get_dev() locking responsibilities to callers
kvm_io_bus_get_dev() returns a device that is only matched by the
address, and nothing else. This can cause a lifetime issue if
the matched device is not the expected type, as by the time
the caller can introspect the object, it might be gone (the srcu
lock having been dropped).
Given that there is only a single user of this helper, the simplest
option is to move the locking responsibility to the caller, which
can keep the srcu lock held for as long as it wants.
Note that this aligns with other kvm_io_bus*() helpers, which
already require the srcu lock to be held by the callers. |
| In the Linux kernel, the following vulnerability has been resolved:
ksmbd: fix use-after-free of conn->preauth_info in concurrent SMB2 NEGOTIATE
conn->preauth_info is shared connection state (struct
preauth_integrity_info, kmalloc-96) that is allocated and freed by the
SMB2 NEGOTIATE handler and read by the response send path.
smb2_handle_negotiate() allocates conn->preauth_info, and on a
deassemble_neg_contexts() failure kfrees it and sets it to NULL. Both the
allocation and the free/NULL happen under ksmbd_conn_lock(conn) (the
connection srv_mutex), which is held across the whole handler body.
The response send path smb3_preauth_hash_rsp(), called from the send:
block of __handle_ksmbd_work(), reads conn->preauth_info and dereferences
conn->preauth_info->Preauth_HashValue (via
ksmbd_gen_preauth_integrity_hash()) without taking conn_lock. When a
client drives two SMB2 NEGOTIATE requests on the same connection, one
worker can free conn->preauth_info on the failing-negotiate path while a
concurrent send-path worker is reading it, producing a slab
use-after-free read (KASAN-confirmed).
The send-path read tested conn->preauth_info for NULL but raced with the
free that occurs between the NULL check and the dereference, so the NULL
guard alone does not close the window.
Serialize the NEGOTIATE-branch read in smb3_preauth_hash_rsp() under
ksmbd_conn_lock(conn) and re-check conn->preauth_info inside the lock.
Because the negotiate handler holds conn_lock across its kfree + NULL
assignment, a reader that also takes conn_lock either runs fully before
the allocation or fully after the NULL store, and can never observe the
freed-but-not-yet-NULLed pointer. ksmbd_gen_preauth_integrity_hash()
takes no locks itself (it only computes a SHA-512 over the buffer), so
no lock-ordering inversion is introduced, and conn_lock is a sleepable
mutex which is safe on this send path (it already performs network I/O). |
| In the Linux kernel, the following vulnerability has been resolved:
net/9p: fix race condition on rdma->state in trans_rdma.c
The rdma->state field is modified without holding req_lock in both
recv_done() and p9_cm_event_handler(), while rdma_request() accesses
the same field under the req_lock spinlock. This inconsistent locking
creates a race condition:
- recv_done() running in softirq completion context sets
rdma->state = P9_RDMA_FLUSHING without acquiring req_lock
- p9_cm_event_handler() modifies rdma->state at multiple points
(ADDR_RESOLVED, ROUTE_RESOLVED, ESTABLISHED, CLOSED) without
req_lock
- rdma_request() uses spin_lock_irqsave(&rdma->req_lock, flags) to
protect the read-modify-write of rdma->state
The race can cause lost state transitions: recv_done() or the CM
event handler could set state to FLUSHING/CLOSED while rdma_request()
is concurrently checking or modifying state under the lock, leading to
the FLUSHING transition being silently overwritten by CLOSING. This
corrupts the connection state machine and can cause use-after-free on
RDMA request objects during teardown.
Fix by adding req_lock protection to all rdma->state modifications in
recv_done() and p9_cm_event_handler(), matching the pattern already
used in rdma_request(). Use spin_lock_irqsave/spin_unlock_irqrestore
in the CM event handler since it can race with recv_done() which runs
in softirq context.
Tested with a kernel module that races two threads (simulating
rdma_request and recv_done/CM handler) on rdma->state with proper
locking: 5.5M+ FLUSHING writes over 27M iterations with 0 lost
transitions. |
| In the Linux kernel, the following vulnerability has been resolved:
KVM: arm64: vgic: Handle race between interrupt affinity change and LPI disabling
Hyunwoo Kim reports some really bad races should the following
situation occur:
- LPI-I is pending in vcpu-B's AP list
- vcpu-A writes to vcpu-B's RD to disable its LPIs
- vcpu-C moves I from B to C
If the last two race nicely enough, vgic_prune_ap_list() can drop
the irq and AP list locks, reacquire them, and in the interval
the irq has been freed. UAF follows.
The fix is two-fold:
- Before dropping the irq and ap_list locks, take a reference on
the irq
- Do not try to handle migration of the pending bit: there is no
expectation that this state is retained, as per the architecture
With that, we're sure that the interrupt is still around, and we
safely remove it from the AP list as it has no target at this
stage (unless another interrupt fires, but that's another story). |
| In the Linux kernel, the following vulnerability has been resolved:
drm/xe: fix NPD in bo_meminfo()
When a buffer object is purged, its ttm.resource is set to NULL via the
TTM pipeline gutting flow. However, the BO remains in the client's
object list until userspace explicitly closes the GEM handle. If memory
stats are queried during this time, accessing bo->ttm.resource->mem_type
will result in a NULL pointer dereference.
Fix this by safely skipping purged BOs in bo_meminfo, as they no longer
consume any memory.
User is getting NPD on device resume, and possible theory is that in
bo_move(), if we need to evict something to SYSTEM to save the CCS state,
but the BO is marked as dontneed, this won't trigger a move but will
nuke the pages, leaving us with a NULL bo resource. And the meminfo()
doesn't look ready to handle a NULL resource.
v2 (Sashiko):
- There could potentially be other cases where we might end up with a
NULL resource, so make this a general NULL check for now.
(cherry picked from commit c9a8e7daa0afe3161111e27fd92176e608c7f186) |
| In the Linux kernel, the following vulnerability has been resolved:
afs: Fix reinitialisation of the inode, in particular ->lock_work
It seems that initalising afs_vnode::lock_work a single time in the slab's
init function isn't sufficient for work_structs. This results in the
DEBUG_OBJECTS debugging stuff producing a warning occasionally when running
the generic/131 xfstest:
ODEBUG: activate not available (active state 0) object: 0000000016d8760f object type: work_struct hint: afs_lock_work+0x0/0x220
WARNING: lib/debugobjects.c:629 at debug_print_object+0x4b/0x90, CPU#3: locktest/7695
...
CPU: 3 UID: 0 PID: 7695 Comm: locktest Tainted: G S 7.1.0-build3+ #2771 PREEMPT
...
RIP: 0010:debug_print_object+0x65/0x90
...
Call Trace:
<TASK>
? __pfx_afs_lock_work+0x10/0x10
debug_object_activate+0x122/0x170
insert_work+0x25/0x60
__queue_work+0x2e0/0x340
queue_delayed_work_on+0x48/0x70
afs_fl_release_private+0x57/0x70
locks_release_private+0x5c/0xa0
locks_free_lock+0xe/0x20
posix_lock_inode+0x55f/0x5b0
locks_lock_inode_wait+0x81/0x140
? file_write_and_wait_range+0x50/0x70
afs_lock+0xcd/0x110
fcntl_setlk+0x10d/0x260
do_fcntl+0x24e/0x5b0
__do_sys_fcntl+0x6a/0x90
do_syscall_64+0x11e/0x310
entry_SYSCALL_64_after_hwframe+0x71/0x79
Fix this by reinitialising ->lock_work after allocating an inode.
Also, flush ->lock_work when the inode is being evicted to make sure it's
not still running. |
| In the Linux kernel, the following vulnerability has been resolved:
netfilter: ipset: fix order of kfree_rcu() and rcu_assign_pointer()
Sashiko pointed out that kfree_rcu() was called before
rcu_assign_pointer() in handling the comment extension.
Fix the order so that rcu_assign_pointer() called first. |
| In the Linux kernel, the following vulnerability has been resolved:
net: watchdog: fix refcount tracking races
Blamed commit converted the untracked dev_hold()/dev_put() calls
in the watchdog code to use the tracked dev_hold_track()/dev_put_track()
(which were later renamed/interfaced to netdev_hold() and netdev_put()).
By introducing dev->watchdog_dev_tracker to store the
reference tracking information without adding synchronization
between netdev_watchdog_up() and dev_watchdog(), it enabled the
race condition where this pointer could be overwritten or freed
concurrently, leading to the list corruption crash syzbot reported:
list_del corruption, ffff888114a18c00->next is NULL
kernel BUG at lib/list_debug.c:52 !
Oops: invalid opcode: 0000 [#1] SMP KASAN PTI
CPU: 1 UID: 0 PID: 91 Comm: kworker/u8:5 Not tainted syzkaller #0 PREEMPT(lazy)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/09/2026
Workqueue: events_unbound linkwatch_event
RIP: 0010:__list_del_entry_valid_or_report.cold+0x22/0x2a lib/list_debug.c:52
Call Trace:
<TASK>
__list_del_entry_valid include/linux/list.h:132 [inline]
__list_del_entry include/linux/list.h:246 [inline]
list_move_tail include/linux/list.h:341 [inline]
ref_tracker_free+0x1a7/0x6c0 lib/ref_tracker.c:329
netdev_tracker_free include/linux/netdevice.h:4491 [inline]
netdev_put include/linux/netdevice.h:4508 [inline]
netdev_put include/linux/netdevice.h:4504 [inline]
netdev_watchdog_down net/sched/sch_generic.c:600 [inline]
dev_deactivate_many+0x28c/0xfe0 net/sched/sch_generic.c:1363
dev_deactivate+0x109/0x1d0 net/sched/sch_generic.c:1397
linkwatch_do_dev net/core/link_watch.c:184 [inline]
linkwatch_do_dev+0xd3/0x120 net/core/link_watch.c:166
__linkwatch_run_queue+0x3a5/0x810 net/core/link_watch.c:240
linkwatch_event+0x8f/0xc0 net/core/link_watch.c:314
process_one_work+0xa0e/0x1980 kernel/workqueue.c:3314
process_scheduled_works kernel/workqueue.c:3397 [inline]
worker_thread+0x5ef/0xe50 kernel/workqueue.c:3478
kthread+0x370/0x450 kernel/kthread.c:436
ret_from_fork+0x69a/0xc80 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
This patch has three coordinated parts:
1) Add dev->watchdog_lock and dev->watchdog_ref_held to serialize watchdog operations.
2) Remove netdev_watchdog_up() call from netif_carrier_on():
This ensures netdev_watchdog_up() is only called from process/BH context
(via linkwatch workqueue dev_activate()), allowing us to use
spin_lock_bh() for synchronization.
3) Synchronize watchdog up and watchdog timer:
Protect netdev_watchdog_up() with tx_global_lock and watchdog_lock.
Only allocate a new tracker in netdev_watchdog_up() if one is
not already present.
In dev_watchdog(), ensure we don't release the tracker if the
timer was rescheduled either by dev_watchdog() itself or concurrently
by netdev_watchdog_up(). |