In the Linux kernel, the following vulnerability has been resolved:
mfd: cros_ec: Delay dev_set_drvdata() until probe success
If ec_device_probe() fails, cros_ec_class_release releases memory for the
cros_ec_dev structure. However, because the drvdata was already set,
sub-drivers like cros_ec_typec can still retrieve the stale pointer via the
platform device. This leads to a use-after-free when cros_ec_typec attempts
to access &typec->ec->ec->dev on a device that has already been released.
Move dev_set_drvdata() to ensure that the pointer is only made available
once all initialization steps have succeeded.
sysfs: cannot create duplicate filename '/class/chromeos/cros_ec'
Call trace:
sysfs_do_create_link_sd+0x94/0xdc
sysfs_create_link+0x30/0x44
device_add_class_symlinks+0x90/0x13c
device_add+0xf0/0x50c
ec_device_probe+0x150/0x4f0
platform_probe+0xa0/0xe0
...
BUG: KASAN: invalid-access in __memcpy+0x44/0x230
Write at addr f5ffff809e2d33ac by task kworker/u32:5/125
Pointer tag: [f5], memory tag: [fe]
Tainted : [W]=WARN, [O]=OOT_MODULE
Hardware name: Google Navi unprovisioned 0x7FFFFFFF/sku0 board/sku3
Workqueue: events_unbound deferred_probe_work_func
Call trace:
__memcpy+0x44/0x230
cros_ec_check_features+0x60/0xcc [cros_ec_proto]
cros_typec_probe+0xe8/0x6e0 [cros_ec_typec]
platform_probe+0xa0/0xe0
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: bnep: pin L2CAP connection during netdev registration
bnep_add_connection() reads the L2CAP connection without holding the
channel lock, then passes its HCI device to register_netdev(). Controller
teardown can clear and release that connection concurrently, leaving the
network device registration path to dereference a freed parent device.
Take a reference to the L2CAP connection while holding the channel lock.
Retain it until register_netdev() has taken the parent device reference.
In the Linux kernel, the following vulnerability has been resolved:
netfilter: ebtables: terminate table name before find_table_lock()
update_counters() and compat_update_counters() forward a user-supplied
32-byte table name to find_table_lock() without NUL-terminating it. On a
lookup miss, find_inlist_lock() calls try_then_request_module(..., "%s%s",
"ebtable_", name), and vsnprintf() reads past the name field and the
stack object until it hits a zero byte.
BUG: KASAN: stack-out-of-bounds in string (lib/vsprintf.c:648 lib/vsprintf.c:730)
Read of size 1 at addr ffff8880119dfb20 by task exploit/147
Call Trace:
...
string (lib/vsprintf.c:648 lib/vsprintf.c:730)
vsnprintf (lib/vsprintf.c:2945)
__request_module (kernel/module/kmod.c:150)
do_update_counters.isra.0 (net/bridge/netfilter/ebtables.c:371 net/bridge/netfilter/ebtables.c:380)
update_counters (net/bridge/netfilter/ebtables.c:1440)
do_ebt_set_ctl (net/bridge/netfilter/ebtables.c:2573)
nf_setsockopt (net/netfilter/nf_sockopt.c:101)
ip_setsockopt (net/ipv4/ip_sockglue.c:1424)
raw_setsockopt (net/ipv4/raw.c:847)
__sys_setsockopt (net/socket.c:2393)
...
compat_do_replace() shares the same unterminated name via
compat_copy_ebt_replace_from_user(); terminate it there too so all
find_table_lock() callers behave alike. The other callers already
terminate the name after the copy.
In the Linux kernel, the following vulnerability has been resolved:
netfilter: ebtables: module names must be null-terminated
We need to explicitly check the length, else we may pass non-null
terminated string to request_module().
In the Linux kernel, the following vulnerability has been resolved:
smb: client: resolve SWN tcon from live registrations
cifs_swn_notify() looks up a witness registration by id under
cifs_swnreg_idr_mutex, drops the mutex, and then uses the registration's
cached tcon pointer. That pointer is not a lifetime reference, and it is
not a stable representative once cifs_get_swn_reg() lets multiple tcons
for the same net/share name share one registration id.
A same-share second mount can keep the cifs_swn_reg alive after the first
tcon unregisters and is freed. The registration then still points at the
freed first tcon, so taking tc_lock or incrementing tc_count through
swnreg->tcon only moves the use-after-free earlier. Taking tc_lock while
holding cifs_swnreg_idr_mutex also violates the documented CIFS lock
order.
Fix this by making the registration store only the stable witness
identity: id, net name, share name, and notify flags. When a notify
arrives, copy that identity under cifs_swnreg_idr_mutex, drop the mutex,
then find and pin a live witness tcon that currently matches the net/share
pair under the normal cifs_tcp_ses_lock -> tc_lock order. The notification
path uses that pinned tcon directly and drops the reference when done.
Registration and unregister messages now use the live tcon passed by the
caller instead of a cached tcon in the registration. The final unregister
send is folded into cifs_swn_unregister() while the registration is still
protected by cifs_swnreg_idr_mutex. This removes the previous
find/drop/reacquire raw-pointer window. The release path only removes the
idr entry and frees the stable identity strings.
This preserves the intended one-registration/many-tcon behavior: a
registration id represents a net/share pair, and notify handling acts on a
live representative selected at use time. It also preserves CLIENT_MOVE
ordering for the representative tcon because the old-IP unregister is sent
before cifs_swn_register() sends the new-IP register.
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: L2CAP: validate option length before reading conf opt value
l2cap_get_conf_opt() derives the option length from the
attacker-controlled opt->len field and immediately dereferences
opt->val (as u8, get_unaligned_le16() or get_unaligned_le32(), or a
raw pointer for the default case) before any caller has confirmed
that opt->len bytes are present in the buffer. The callers
(l2cap_parse_conf_req(), l2cap_parse_conf_rsp() and
l2cap_conf_rfc_get()) only detect a malformed option afterwards, once
the running length has gone negative, by which point the
out-of-bounds read has already executed.
An existing post-hoc length check keeps the garbage value from being
consumed, so this is not a data leak in the current control flow. It
is still a validate-after-use ordering bug: up to 4 bytes are read
past the end of the buffer before it is known to contain them, and it
is fragile to future changes in the callers.
Fix it at the source. Pass the end of the buffer into
l2cap_get_conf_opt() and refuse to touch opt->val unless the full
option (header + value) fits. Each caller computes an end pointer
once before the loop and checks the return value directly instead of
inferring the error from a negative length.
In the Linux kernel, the following vulnerability has been resolved:
smb/client: fix chown/chgrp with SMB3 POSIX Extensions
Ownership (chown) and group (chgrp) modifications were being ignored when
mounting with SMB3 POSIX Extensions unless CIFS_MOUNT_CIFS_ACL or
CIFS_MOUNT_MODE_FROM_SID were also explicitly set.
Fix this by checking for posix_extensions in cifs_setattr_nounix() when
updating UID and GID, ensuring that id_mode_to_cifs_acl() is called to map
and set the ownership/group information on the server.
In the Linux kernel, the following vulnerability has been resolved:
nilfs2: reject CLEAN_SEGMENTS ioctl with out-of-range segment numbers
Syzbot reported a hung task in nilfs_transaction_begin() where multiple
tasks performing chmod() on a nilfs2 mount blocked for over 143 seconds
waiting to acquire ns_segctor_sem for read:
INFO: task syz.0.17:5918 blocked for more than 143 seconds.
Call Trace:
schedule+0x164/0x360
rwsem_down_read_slowpath+0x6d9/0x940
down_read+0x99/0x2e0
nilfs_transaction_begin+0x364/0x710 fs/nilfs2/segment.c:221
nilfs_setattr+0x124/0x2c0 fs/nilfs2/inode.c:921
notify_change+0xc1a/0xf40
chmod_common+0x273/0x4a0
do_fchmodat+0x12d/0x230
The writer holding ns_segctor_sem was a concurrent
NILFS_IOCTL_CLEAN_SEGMENTS caller, stuck inside printk while emitting
per-element warnings from nilfs_sufile_updatev():
__nilfs_msg+0x373/0x450 fs/nilfs2/super.c:78
nilfs_sufile_updatev+0x21c/0x6d0 fs/nilfs2/sufile.c:186
nilfs_sufile_freev fs/nilfs2/sufile.h:93 [inline]
nilfs_free_segments fs/nilfs2/segment.c:1140 [inline]
nilfs_segctor_collect_blocks fs/nilfs2/segment.c:1261 [inline]
nilfs_segctor_do_construct+0x1f55/0x76c0
nilfs_clean_segments+0x3bd/0xa50
nilfs_ioctl_clean_segments fs/nilfs2/ioctl.c:922 [inline]
nilfs_ioctl+0x261f/0x2780
The root cause is that user-supplied segment numbers are not validated
before nilfs_clean_segments() begins doing work; the range check on
each segnum is performed deep inside the call chain by
nilfs_sufile_updatev(), which emits a nilfs_warn() per invalid entry
while still holding the segctor lock and the sufile mi_sem. Under load
(repeated invocations across multiple mounts saturating the global
printk path), the cumulative printk latency keeps ns_segctor_sem held
long enough to trip the hung_task watchdog, blocking concurrent
operations such as chmod() that need ns_segctor_sem for read.
Fix by validating the contents of kbufs[4] in nilfs_clean_segments()
immediately after acquiring ns_segctor_sem via nilfs_transaction_lock().
Holding ns_segctor_sem serializes the check against
nilfs_ioctl_resize(), which can modify ns_nsegments, so the validation
uses a consistent value. Out-of-range segment numbers are rejected
with -EINVAL before any segment-cleaning work begins, so the bad
entries never reach the per-element diagnostic path inside
nilfs_sufile_updatev().
In the Linux kernel, the following vulnerability has been resolved:
HID: lg-g15: cancel pending work on remove to fix a use-after-free
lg_g15_data is allocated with devm and holds a work item. The report
handlers schedule that work straight from device input.
lg_g15_event() and lg_g15_v2_event() do it on the backlight cycle key,
and lg_g510_leds_event() does it too. The worker dereferences the
lg_g15_data back through container_of.
The driver had no remove callback and never cancelled the work. So if a
report scheduled the work and the keyboard was then unplugged, devres
freed lg_g15_data while the work was still pending or running, and the
worker touched freed memory. This is a use-after-free. It is reachable
as a race on device unplug.
Add a remove callback that cancels the work before devres frees the
state. g15->work is only initialized for the models that schedule it
(G15, G15 v2, G510). The G13 and Z-10 leave it zeroed, so guard the
cancel on g15->work.func to avoid cancelling a work that was never set
up. The g15 NULL test mirrors the one already in lg_g15_raw_event().
In the Linux kernel, the following vulnerability has been resolved:
HID: appleir: fix UAF on pending key_up_timer in remove()
appleir_remove() runs hid_hw_stop() before timer_delete_sync().
hid_hw_stop() synchronously unregisters the HID input device via
hid_disconnect() -> hidinput_disconnect() -> input_unregister_device(),
which drops the last reference and frees the underlying input_dev when
no userspace handle holds it open.
key_up_tick() reads appleir->input_dev and calls input_report_key() /
input_sync() on it. The timer is armed from appleir_raw_event() with
a HZ/8 (~125 ms) timeout on every keydown and key-repeat report. If a
key was pressed shortly before the device is disconnected, the timer
can fire after hid_hw_stop() has freed input_dev but before the
teardown drains it.
A simple reorder is not sufficient. Putting the timer drain first
still leaves a window where a USB URB completion (raw_event) running
during hid_hw_stop() can call mod_timer() and re-arm the timer, which
then fires after hidinput_disconnect() has freed input_dev. The same
URB-completion window also lets raw_event() reach key_up(), key_down()
and battery_flat() directly, all of which dereference
appleir->input_dev.
Introduce a 'removing' flag on struct appleir, gated by the existing
spinlock. appleir_remove() sets the flag under the lock and then
shuts down the timer with timer_shutdown_sync(), which both drains any
in-flight callback and permanently disables further mod_timer() calls.
appleir_raw_event() and key_up_tick() bail out early if the flag is
set, so no path can arm or run the timer, or dereference
appleir->input_dev, after remove() has started tearing down.
The keyrepeat and flatbattery branches of appleir_raw_event()
previously called into the input layer without holding the spinlock;
take it now so the flag check is well-defined. This incidentally
closes a pre-existing read-side race on appleir->current_key in the
keyrepeat branch.
This bug is structurally a sibling of commit 4db2af929279 ("HID:
appletb-kbd: fix UAF in inactivity-timer cleanup path") and has been
present since the driver was introduced.