| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: cros_usbpd-charger: bound the EC-reported port count
cros_usbpd_charger_probe() reads two port counts from the EC and uses
one of them, num_charger_ports, as the loop bound when populating a
fixed-size array:
struct port_data *ports[EC_USB_PD_MAX_PORTS]; /* 8 entries */
...
for (i = 0; i < charger->num_charger_ports; i++)
charger->ports[charger->num_registered_psy++] = port;
Both num_usbpd_ports (from EC_CMD_USB_PD_PORTS) and num_charger_ports
(from EC_CMD_CHARGE_PORT_COUNT) are u8 values reported by the EC. The
only validation is a sanity check that compares the two EC-reported
values against each other:
if (num_charger_ports < num_usbpd_ports ||
num_charger_ports > num_usbpd_ports + 1)
return -EPROTO;
It never checks either count against EC_USB_PD_MAX_PORTS, the size of
the ports[] array. A malfunctioning, malicious or compromised EC that
reports num_usbpd_ports == num_charger_ports == N for any N > 8 (for
example both 255) passes this check, and the loop then writes N pointers
into the 8-entry ports[] array embedded in the devm_kzalloc()'d
charger_data, overflowing it by up to 255 - 8 = 247 entries (~1976
bytes): a slab out-of-bounds write.
Reject a port count larger than the ports[] array can hold. |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: cros_usbpd: Limit port counts to EC_USB_PD_MAX_PORTS
Currently the cros_usbpd-charger driver probe iterates based on raw
charger port count returned by the embedded controller. The only check
is against the number of USB PD ports which the embedded controller
also defines. A malicious embedded controller could return an inaccurate
port count (up to 255) resulting in an out of bounds write and
subsequent memory corruption.
Update helper functions in cros_usbpd-charger to limit port counts to
EC_USB_PD_MAX_PORTS. |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: lp8727: fix use-after-free in lp8727_release_irq()
lp8727_isr_func(), the threaded IRQ handler, is the only caller that arms
pchg->work via schedule_delayed_work(). lp8727_release_irq() currently
cancels the work before freeing the IRQ, so an IRQ delivered in between
can re-arm the work through the threaded handler. After .remove returns
the devm layer frees pchg while lp8727_delayed_func() may still run and
dereference it.
Free the IRQ first so the threaded handler is quiesced and can no longer
queue work, then cancel the delayed work to drain the final generation.
This issue was found by an in-house static analysis tool. |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: qcom_battmgr: terminate the strings from firmware
The qcom_battmgr_sc8280xp_strcpy() takes a Pascal-style string when the
firmware sends one. Otherwise it copies all BATTMGR_STRING_LEN bytes and
leaves the destination without a terminator.
Those destinations are model_number, serial_number and oem_info, each
BATTMGR_STRING_LEN and declared next to each other. They go out to user
space as val->strval, which power_supply_format_property() prints with
"%s", so a firmware string that fills the whole field makes that read run
into the following members.
Use strscpy() so the copy always terminates, the way the SM8350 path
already does for the same field. |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: rt9455: quiesce delayed work before teardown
The threaded IRQ handler can queue pwr_rdy_work,
max_charging_time_work and batt_presence_work. pwr_rdy_work and
batt_presence_work can also queue max_charging_time_work, while
batt_presence_work can requeue itself.
rt9455_remove() cancels max_charging_time_work before
batt_presence_work. The latter can therefore queue
max_charging_time_work after it has already been cancelled:
rt9455_remove() workqueue
cancel pwr_rdy_work
cancel max_charging_time_work
batt_presence_work queues
max_charging_time_work
cancel batt_presence_work
return
devres frees rt9455_info
max_charging_time_work dereferences
rt9455_info
The IRQ also remains registered until devres cleanup and can queue more
work after any of the cancellation calls. If rt9455_hw_init() fails
after the IRQ has been requested, probe returns without cancelling work
that may already have been queued. A pending callback can then access
rt9455_info after it has been freed.
Register rt9455_cancel_all_delayed_works() through
devm_add_action_or_reset() right after devm_power_supply_register().
devres invokes the action in reverse registration order, after the
managed IRQ has been freed and before rt9455_info is released, so the
delayed works are drained in both rt9455_remove() and the probe error
path. Cancel pwr_rdy_work and batt_presence_work before
max_charging_time_work because both can queue the latter.
This issue was found by an in-house static analysis tool. |
| In the Linux kernel, the following vulnerability has been resolved:
s390/dasd: Propagate partial completion length across ERP recovery
dasd_default_erp_postaction() copies the timing and device state from
the finished ERP request back to the original request but drops
proc_bytes. A request that was partially completed, an ESE read of a
not-yet-allocated track returns fewer bytes than requested, and then
recovered through the ERP chain loses its partial-completion length.
__dasd_cleanup_cqr() then sees proc_bytes == 0 and completes the whole
request instead of requeueing the remainder, silently returning zeroed
data for the part that was never read.
Carry proc_bytes over to the original request like the other
per-request state. |
| In the Linux kernel, the following vulnerability has been resolved:
platform/x86: ISST: Validate level in perf mask ioctls
isst_if_get_perf_level_mask() and isst_if_get_base_freq_mask() use the
user-provided level as an index into perf_levels[] via
_read_pp_level_info() and _read_bf_level_info(), but neither helper
validates it first.
The adjacent level-info helpers reject levels above max_level before
reading the same per-level register block. Add the same bounds checks to
the mask helpers, and reject disabled SST-PP levels in
isst_if_get_perf_level_mask() to match isst_if_get_perf_level_info().
This prevents out-of-bounds reads from the per-level offset table on
invalid ioctl input. |
| In the Linux kernel, the following vulnerability has been resolved:
platform/x86: ISST: Validate socket ID in clos_assoc ioctl
isst_if_clos_assoc() validates the user-supplied socket_id with
'socket_id > topology_max_packages()', but isst_common.sst_inst[] is
allocated with topology_max_packages() entries, so the valid index range
is [0, topology_max_packages()). The '>' comparison lets
socket_id == topology_max_packages() pass and index one entry past the
array.
In addition, isst_common.sst_inst[socket_id] is NULL for an in-range
package that has no bound TPMI SST instance, and the pointer is used
without a NULL check. Both the out-of-bounds entry and the NULL pointer
are then dereferenced by map_partition_power_domain_id() and the
following power_domain_info access.
Reject socket_id >= topology_max_packages() and a NULL sst_inst, matching
the checks already performed by get_instance(). |
| In the Linux kernel, the following vulnerability has been resolved:
mmc: via-sdmmc: stop card-detect handling on probe failure
request_irq() registers the SD card-detect interrupt and the probe enables
it before mmc_add_host() runs. If mmc_add_host() fails, the error path only
unmaps the registers and returns: the interrupt stays registered, so the
handler keeps running against the host once it is freed. via_sdc_isr()
dereferences sdhost and its MMIO base and schedules carddet_work, which
via_sdc_card_detect() also runs against freed memory through its
container_of() dereference.
Add a probe-error path that disables and frees the interrupt and cancels
carddet_work before unmapping. carddet_work can re-enable the device
interrupt via via_reset_pcictrl(), which restores PCIINTCTRL, so mask it
again after cancelling the work.
This issue was found by an in-house static analysis tool and confirmed by
manual code review. |
| In the Linux kernel, the following vulnerability has been resolved:
platform/chrome: sensorhub: Bound the EC-reported sensor number
Each EC FIFO event carries an 8-bit sensor number (in->sensor_num).
cros_ec_sensorhub_ring_handler() validates the FIFO event count, the
per-read count and the ring bound, but not the sensor number, which
cros_ec_sensor_ring_process_event() then uses unchecked to index
sensorhub->batch_state[] - allocated with only sensorhub->sensor_num
entries. A sensor number of sensor_num or larger is an out-of-bounds
read and write of batch_state[].
Validate the sensor number in the ring handler, where each event is read
from the EC, and drop a malformed event before it is used. |
| In the Linux kernel, the following vulnerability has been resolved:
platform/x86: hp-bioscfg: fix off-by-one write in hp_get_string_from_buffer()
hp_get_string_from_buffer() clamps the converted string length against
the destination buffer size with "size > dst_size", so when the
converted length is exactly equal to dst_size, conv_dst_size is left
at dst_size and the unconditional NUL terminator write
dst[conv_dst_size] = 0;
lands one byte past the destination buffer. This is the same shape of
bug as the previously fixed off-by-one in hp_convert_hexstr_to_str():
the buffer is sized correctly for the content, but the terminator
write is never checked against that size.
Fix by changing the comparison to ">=" so conv_dst_size is always left
with room for the terminator.
All fixed-size destinations that reach this function (path[512],
current_value[512], current_password/current_value[64], and the
per-entry buffers in encodings[][512] and prerequisites[][512]) are
affected. |
| In the Linux kernel, the following vulnerability has been resolved:
platform/x86: hp-bioscfg: pass validated element count to package parsers
The per-type package parsers are handed the wrong element count.
hp_init_bios_package_attribute() validates obj->package.count and then
calls one of the five hp_populate_*_package_data() wrappers (string,
integer, enumeration, ordered list, password). Each wrapper forwards a
count to its hp_populate_*_elements_from_package() parser, but instead
of forwarding the validated obj->package.count it derives the count
from elements[0]. elements[0] is the NAME field and is always an
ACPI_TYPE_STRING, so reading ->package.count from it in fact reads
->string.length through the union acpi_object. The parsers thus bound
themselves against the length of the name string rather than against
the real number of elements in the package.
This is safe today because hp_init_bios_package_attribute() refuses any
package that has fewer than the type's element count, so a parser only
ever runs on a full package and never reads past it regardless of the
bogus bound.
An upcoming change relaxes that check to accept shorter packages. Once
a parser can receive fewer elements than its per-type count, a bound
taken from the name length no longer reflects the array size, and the
"elem < count" loop conditions and "elem + n >= count" sub-loop guards
read past the end of elements[] - an out-of-bounds heap read.
Forward the validated obj->package.count to every *_package_data()
wrapper so the parsers bound themselves against the real package size.
This does not change behaviour for the packages that enumerate
correctly today and is a prerequisite for accepting shorter packages
safely. |
| In the Linux kernel, the following vulnerability has been resolved:
io_uring/waitid: honor task_work cancellation
io_waitid_cb() may run through the fallback task_work path when
task_work_add() can no longer queue work to the originating task. The
fallback runs from a kworker and io_uring marks such task work as
canceled through tw.cancel.
io_waitid_cb() currently ignores tw.cancel and calls __do_wait().
waitid is task-context dependent: __do_wait() performs child lookup
relative to current, and the retry path also uses
current->signal->wait_chldexit. If the callback runs from the fallback
kworker, current is therefore not the task that submitted the request.
Honor tw.cancel before entering __do_wait(). Complete the request with
-ECANCELED and skip the siginfo copy, since canceled task work may run
without the submitting task's userspace execution context.
Keep the existing siginfo handling for normal waitid completion and
explicit cancellation. |
| In the Linux kernel, the following vulnerability has been resolved:
interconnect: Fix use after free in icc_get() and of_icc_get_by_index()
In of_icc_get_by_index() and icc_get(), if the dynamic allocation for
path->name fails via kasprintf(), the error handling path directly
calls kfree(path) to free the path object and returns an error.
However, prior to this point, path_find() calls path_init(), which
already links the path's requests into the req_list of the respective
interconnect nodes via hlist_add_head(). Directly invoking kfree(path)
leaves dangling pointers in the hlist. A subsequent call to icc_get()
or icc_set_bw() will traverse or modify these corrupted lists, triggering
a slab use afterfree.
KASAN report showing the vulnerability when reproducing via debugfs:
BUG: KASAN: slab-use-after-free in path_find+0x6f8/0xcfc
Write of size 8 at addr fff000000d43f748 by task sh/1
...
Call trace:
kasan_report+0xac/0xfc
path_find+0x6f8/0xcfc
icc_get+0x148/0x380
icc_get_set+0xf8/0x2d0
...
Freed by task 1:
kfree+0x1a0/0x4a4
icc_get+0x2cc/0x380
icc_get_set+0xf8/0x2d0
Fix this by replacing kfree(path) with the proper teardown function,
icc_put(path), which safely removes the requests from the req_list using
hlist_del() and drops the provider usage references before freeing the
memory.
Additionally, in icc_get(), ensure that the icc_lock mutex is released
prior to calling icc_put(path) to avoid a deadlock, as icc_put()
internally acquires the same lock. |
| In the Linux kernel, the following vulnerability has been resolved:
net: ravb: avoid dereferencing an invalid PTP clock
The PTP clock is unavailable before the first open, so querying its
index can dereference a NULL pointer. Registration failures can also
leave an error pointer in priv->ptp.clock.
Cache the PHC index separately and report -1 while no clock is
registered. Normalize registration errors to NULL and preserve the
static timestamping capabilities. |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: unregister the connection before draining the rx tasklet
smc_conn_free() calls smc_ism_unset_conn() only while the link group is
still on its device list, and never sets conn->killed.
smc_lgr_terminate_sched() unlinks the group immediately and defers killing
its connections to a work item, so a connection freed in that window keeps
its smcd->conn[] slot with both gates in smcd_handle_irq() open, and the
device can re-arm the receive tasklet after tasklet_kill() has returned. On
the DMB-nocopy path the ghost send buffer is freed right after that drain,
so the re-armed tasklet dereferences it.
Unregister unconditionally and drain before the detach at both teardown
sites, mirroring rmb_desc, which smc_buf_unuse() releases after the drain.
Clear conn->sndbuf_desc before freeing it as well, so a reader that samples
the pointer cannot get one that is already freed. |
| In the Linux kernel, the following vulnerability has been resolved:
i3c: master: Fix info leak and UAF in device unregister path
i3c_master_unregister_i3c_devs() clears i3cdev->dev->desc before
calling device_unregister(). During device_unregister(),
device_del() emits a KOBJ_REMOVE uevent and unbinds the driver while
the device descriptor is still expected to be valid. As a result,
i3c_device_uevent() and a racing modalias_show() can observe a NULL
desc and fall back to an uninitialized stack struct i3c_device_info,
leaking kernel stack contents in the generated modalias. Driver
.remove() callbacks may also encounter an unexpected NULL desc during
unbind.
Keep desc valid until device_unregister() has completed. Since
device_unregister() drops the device reference and may free the device,
take an extra reference with get_device() before unregistering. Clear
desc afterwards and release the extra reference with put_device().
This preserves the release-time invariant that desc must be NULL while
avoiding both the information leak and a potential use-after-free from
writing desc after the device has been released. |
| In the Linux kernel, the following vulnerability has been resolved:
wifi: mt76: mt7996: validate default EEPROM firmware size
The default EEPROM firmware is parsed and copied as a full EEPROM
without checking its length. A truncated file can make the driver
read beyond the firmware buffer during variant validation or the
fallback copy.
Reject files shorter than MT7996_EEPROM_SIZE before parsing or
copying the firmware. |
| In the Linux kernel, the following vulnerability has been resolved:
w1: ds28e17: reject an oversize length on an I2C block read
w1_f19_i2c_master_transfer() is the master_xfer for the DS28E17 1-Wire
to I2C bridge. On an I2C_M_RECV_LEN read, it takes the length from the
device. The downstream slave puts a length byte in buf[0]. The driver
then reads that many bytes into buf[1] with w1_f19_i2c_read().
buf[0] is controlled by the device and can be 0 to 255.
w1_f19_i2c_read() only rejects a zero count. The caller buffer is
I2C_SMBUS_BLOCK_MAX + 2, so 34 bytes. A length above 32 makes the read
run past it, up to about 222 bytes out of bounds.
The SMBus core does check buf[0] against I2C_SMBUS_BLOCK_MAX. That
check runs after master_xfer returns. By then the write is already
done. i2c-algo-bit rejects an oversize length before it copies, and
returns -EPROTO.
Reject a length above I2C_SMBUS_BLOCK_MAX at both RECV_LEN sites, the
same way i2c-algo-bit does. |
| In the Linux kernel, the following vulnerability has been resolved:
smack: fix cred UAF in smack_file_send_sigiotask()
When inspecting the credentials of another task, objective credentials
(->real_cred, accessed with __task_cred()) must always be used.
Accessing ->cred on a non-current task is forbidden unless that task is
being created or destroyed; a task is allowed to change its own ->cred
pointer with no synchronization, and changing ->cred should only affect the
current syscall.
smack_file_send_sigiotask() was accessing both sets of credentials: First
tsk->cred, then __task_cred(tsk).
Fix it, always access the objective credentials here.
I have tested that this bug can lead to a KASAN-reported UAF of struct cred
in smack_file_send_sigiotask(), and that this fix prevents the race. |