| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: bq25890: Fix power_supply reference leak
bq25890_fw_probe() acquires a reference to a secondary charger using
power_supply_get_by_name(), but the reference is not released on later
probe failures or on driver detach.
In particular, failures after bq25890_fw_probe() returns successfully,
such as a failure in bq25890_hw_init(), also leak the reference.
Register a device-managed cleanup action immediately after acquiring
the secondary charger. This releases the reference on all subsequent
probe failures and on driver detach.
Found by code review. |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: charger-manager: register regulators before exposing sysfs
charger_manager_remove() and the err_reg_extcon probe error path free each
charger regulator with regulator_put() before tearing down the power_supply
sysfs entries (power_supply_unregister()). charger_manager_remove() also
calls try_charger_enable(cm, false) after the regulator_put() loop. A
concurrent write to a charger's externally_control sysfs attribute that
lands between regulator_put() and power_supply_unregister() can run
charger_externally_control_store() and call try_charger_enable(), which,
when charging is enabled, dereferences the already-freed consumer handle.
When charging is enabled, try_charger_enable(cm, false) in .remove() also
dereferences the freed handles directly. Both leave use-after-free windows.
Symmetrically, probe registers the sysfs entries (power_supply_register)
before acquiring the regulators (regulator_get, inside
charger_manager_register_extcon), so userspace can reach externally_control
before the regulators are available.
Split charger_manager_register_extcon() on the sync/async boundary:
charger_manager_get_regulators() (regulator_get only, no async producer)
now runs before power_supply_register() so sysfs is not live before
regulators are available, and charger_manager_register_extcon() keeps only
the extcon notifier/work setup, still after power_supply_register() so a
power_supply_register() failure cannot reach extcon setup. This keeps the
sysfs setup/teardown ordering symmetric without introducing an asynchronous
producer on the earlier probe-error path.
Move power_supply_unregister() and try_charger_enable(cm, false) ahead of
the regulator_put() loop on both teardown paths, and adjust err_reg_extcon
(power_supply_unregister() then fall through err_regulator for
regulator_put(); get_regulators self-rolls back on its own failure).
This does not address the separate extcon-notifier-driven deref of the same
handles, which needs its own synchronization design.
Found by an in-house static analysis tool. |
| 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: lp8788-charger: fix use-after-free on remove
lp8788_charger_remove() flushes charger_work before unregistering the
IRQs. An IRQ thread can queue charger_work after flush_work() has
returned. The work can then run after devres frees pchg and dereference
it in lp8788_charger_event().
Unregister the IRQs first. free_irq() waits for any running threaded
handler, so no handler can queue more work afterwards. Then use
cancel_work_sync() to cancel pending work or wait for running work to
finish.
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: fix use-after-free
qcom_battmgr_pdr_notify() queues enable_work when the PMIC GLINK service
comes up, and the worker recovers battmgr through container_of() to issue
firmware requests. The PMIC GLINK client stays on the client list until
its devres release action runs, so a PDR notification can keep queueing
the work, and a pending or running worker can access battmgr after devres
frees it.
Make enable_work device-managed with devm_work_autocancel(), registered
before the PMIC GLINK client is allocated. The devres cleanup then
releases the client first, so no further notification can queue the work,
and cancels the work before battmgr is freed.
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:
power: supply: twl4030_charger: cancel workers via devm
bci is devm-allocated. Two workers (bci->work and bci->current_worker)
dereference it. twl4030_bci_remove() disables charging and masks
interrupts. It cancels neither worker. A worker pending at remove() can
run after devm frees bci.
The USB transceiver comes from devm_usb_get_phy_by_node(). devm
unregisters its notifier only after remove() returns. A cancel_work_sync()
in remove() can then race a notifier reschedule. devm_work_autocancel()
and devm_delayed_work_autocancel() avoid that. They cancel the workers
during devm release, before bci is freed.
The current_worker is registered first, since devm will cancel in
reverse order and bci->work can reschedule current_worker.
[Move comment about order into the commit message] |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: ucs1002: fix use-after-free on remove
ucs1002 has no remove callback, so unbind runs entirely through devm.
The alert IRQ handler queues the health_poll delayed work, and the work
reschedules itself while the chip reports a bad-health condition. devm
frees the alert IRQ, which only synchronizes the handler; it does not
cancel the delayed work, which can then run after devm frees the driver
data and dereference it.
Register health_poll with devm_delayed_work_autocancel() before the
alert IRQ is requested. devm then frees the IRQ before cancelling the
work, so the handler can no longer queue it and the work is cancelled
before the driver data is freed.
This issue was found by an in-house static analysis tool. |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: max17040: propagate register read errors
max17040_get_vcell() and max17040_get_soc() ignore errors returned by
regmap_read(). When an I2C transfer fails, the uninitialized register
value is converted and reported to userspace as a valid voltage or state
of charge. The polling worker can also replace the cached state of charge
with the bogus value and emit a spurious change event.
Propagate read errors through the power supply get_property callback and
keep the last valid cached state of charge when polling fails. |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: max17040: synchronize work cancellation on suspend
max17040_work() requeues itself after every poll. cancel_delayed_work()
only cancels a pending instance and does not wait for a callback that is
already running.
If system suspend races with the polling callback, the callback can
continue accessing the fuel gauge and requeue itself after the suspend
callback returns.
Use cancel_delayed_work_sync() to ensure polling is quiesced before
suspend completes. |
| In the Linux kernel, the following vulnerability has been resolved:
s390/cpum_cf: Handle CPU hotplug via prepare/dead callbacks
The command 'perf stat -e cycles -- <command>' crashes the kernel
when CPUs are hotplug added during that run.
Root cause is the allocation of struct cpu_cf_events at first
event initialization. The allocation is dynamic and the first
event that has task context creates such a structure for
each online CPU. This is not sufficient. CPUs may be offline
during event creation and can be set online during the
perf run time. For example commands
# echo 0 > /sys/devices/system/cpu/cpu1/online
# perf stat -e cycles -i -- stress-ng -t10s --matrix X
# sleep 1
# echo 1 > /sys/devices/system/cpu/cpu1/online
create an event for CPUs 0,2-X. Since the events are created with
task-context, the scheduler will eventually schedule the program
on CPU1. This CPU has not created and initialized any per
CPU event infrastructure as that CPU was not online at the time
of the perf invocation. Thus when the scheduler runs stress-ng
on CPU1, the function cpumf_pmu_add() refers to a NULL pointer:
struct cpu_cf_events *cpuhw = this_cpu_cfhw();
This function call is invoked after the task stress-ng has been
made runnable on CPU1. And this_cpu_cfhw() returns NULL.
The result is a panic:
Unable to handle kernel pointer dereference in virtual kernel address space
Failing address: 0000000000000000 TEID: 0000000000000483
....
Krnl PSW : 0404d00180000000 000003ef8291fd0c (cpumf_pmu_add+0x3c/0x80)
....
Call Trace:
[<000003ef8291fd0c>] cpumf_pmu_add+0x3c/0x80
[<000003ef82bb5e3e>] event_sched_in+0xae/0x190
[<000003ef82bb60d6>] merge_sched_in+0x1b6/0x390
[<000003ef82bb65b8>] visit_groups_merge.constprop.0.isra.0+0x308/0x5b0
[<000003ef82bb689a>] pmu_groups_sched_in+0x3a/0x50
[<000003ef82bb6a30>] ctx_sched_in+0x180/0x260
[<000003ef82bb780c>] perf_event_context_sched_in+0x11c/0x2d0
[<000003ef82bb79ee>] __perf_event_task_sched_in+0x2e/0xc0
[<000003ef82994834>] finish_task_switch.isra.0+0x1a4/0x250
....
Last Breaking-Event-Address:
[<000003ef8291f1d8>] this_cpu_cfhw+0x38/0x40
The issue arises only in per-task context when the CPUMF facility is
used and the scheduler picks a random CPU for such a process to run on.
The scheduler enables the CPUMF infrastructure via PMU callback
functions pmu::add() and pmu::del().
Introduce a CPU hotplug prepare/dead callback pair which creates and
removes the per CPU counter data while the CPU is offline. Count the
users which track every CPU (cpu == -1), that is perf_event_open()
events with task context and /dev/hwctr device sessions, in the new
counter cpu_cf_root::tskcnt, protected by pmc_reserve_mutex.
This ensures the infrastructure is available when
new CPU is selected to run the per-task context process.
In cpum_cf_free_root() and cpum_cf_free_cpu() ensure the reference
pointer to data structures is set to NULL before the data is freed
to prevent interrupt handlers to access stale data.
[gor@linux.ibm.com: change commit message] |
| In the Linux kernel, the following vulnerability has been resolved:
s390/percpu: Fix MVIY_PERCPU() with older binutils
Commit a737737cdb9c ("s390/percpu: Infrastructure for more efficient
this_cpu operations") introduced MVIY_PERCPU(), which stringifies
arguments that are already C string literals. This generates an
assembler macro invocation with whitespace-separated quoted arguments:
GEN_MVIY "459712" "%r3"
GNU as versions prior to binutils 2.39 drop the separating whitespace
between quoted macro arguments during input scrubbing. They
consequently parse the invocation as a single argument and emit
repeated warnings:
Warning: missing closing `"'
The .ifc in GEN_MVIY never matches and GNU as exits successfully
without emitting the mviy instruction. As a result, the interrupted
per-CPU sequence is not marked in lowcore and the exception return
path cannot repair the per-CPU address register after migration.
All MVIY_PERCPU() callers pass C string literals. Use them directly
and separate the assembler macro arguments with an explicit comma. The
resulting invocation is:
GEN_MVIY 459712, %r3
This form is unambiguous for GNU as and LLVM's integrated assembler.
This behavior was fixed in GNU as from binutils 2.39, but Linux
supports binutils 2.30. |
| In the Linux kernel, the following vulnerability has been resolved:
s390/dasd: Do not complete a failed ESE read as successful
dasd_int_handler() completes an NRF read of an unallocated ESE track by
calling ese_read() and unconditionally marking the request
DASD_CQR_SUCCESS. dasd_eckd_ese_read() can return an error before it has
zeroed the destination buffer: a failed sense-data parse or a current
track outside the requested range both return early, leaving the
destination pages untouched. The request is still completed successfully,
so the block layer is handed stale / uninitialized memory instead of
zeros.
Check the ese_read() return value and fail the request through the normal
error path instead of forcing DASD_CQR_SUCCESS. |
| In the Linux kernel, the following vulnerability has been resolved:
s390/dasd: Guard sysfs discipline callbacks against unallocated private data
Several sysfs show/store handlers call a discipline callback that
dereferences device->private, either directly or through the
DASD_DEFINE_ATTR() macro. During dasd_generic_set_online() the discipline
is assigned before check_device() allocates device->private, so an
unprivileged read of one of these world-readable attributes in that window
dereferences a NULL pointer and panics.
Guard the dereference inside each callback that actually touches
device->private. |
| 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:
PCI: plda: Fix use-after-free of event IRQs during teardown
plda_pcie_irq_domain_deinit() removes pcie->event_domain via
irq_domain_remove(), but the per-event IRQs mapped from that domain
are requested with devm_request_irq() in plda_init_interrupts(). The
actual free_irq() for a devm-managed IRQ is deferred by devres until
after the calling probe()/remove() function returns.
This means irq_domain_remove() can free the domain's internal data
before the deferred free_irq() for IRQs still mapped into it has run.
When devres later processes that deferred cleanup, it can end up
dereferencing the already-freed domain.
Free each event IRQ explicitly with devm_free_irq() before removing
the domain. This triggers the free immediately and removes the IRQ
from the devres tracking list, so devres will not attempt to free it
a second time later.
Also dispose of the event, INTx, and MSI IRQ mappings with
irq_dispose_mapping() before their owning domains are removed.
Finally, guard the calls to irq_set_chained_handler_and_data() for
pcie->irq, pcie->msi_irq, and pcie->intx_irq so they only run when
those fields hold a valid (>0) IRQ number.
This is a pre-existing issue, flagged by automated review during work
on an earlier, unrelated patch to this driver.
Build-tested and boot-tested on StarFive VisionFive v1.2A board |
| In the Linux kernel, the following vulnerability has been resolved:
PCI: plda: Fix IRQ domain leaks in the error paths of plda_init_interrupts()
plda_init_interrupts() initializes IRQ domains and creates IRQ mapping but
does not unwind them when later step fails.
If platform_get_irq() or either irq_create_mapping() fails
in plda_init_interrupts(), the domains are never deinitialized. If
irq_create_mapping() fails, port->intx_irq stays initialized.
Hence, remove the IRQ domains in the error path by calling
plda_pcie_irq_domain_deinit().
Since plda_pcie_irq_domain_deinit() now disposes of the intx_irq and
msi_irq mappings itself before removing their domains, the msi_irq
mapping failure path can go directly to err_irq_domain_deinit instead of
disposing of port->intx_irq separately first.
This issue was found by automated review of sashiko-bot
[mani: commit log] |