The ibmasm_send_i2o_message() function uses get_dot_command_size() to
compute the byte count for memcpy_toio(), but this value is derived from
user-controlled fields in the dot_command_header (command_size: u8,
data_size: u16) and is never validated against the actual allocation size.
A root user can write a small buffer with inflated header fields, causing
memcpy_toio() to read up to ~65 KB past the end of the allocation into
adjacent kernel heap, which is then forwarded to the service processor
over MMIO.
Silently clamping the copy size is not sufficient: if the header fields
claim a larger size than the buffer, the SP receives a dot command whose
own header is inconsistent with the I2O message length, which can cause
the SP to desynchronize. Reject such commands outright by returning
failure.
Validate command_size before calling get_mfa_inbound() to avoid leaking
an I2O message frame: reading INBOUND_QUEUE_PORT dequeues a hardware
frame from the controller's free pool, and returning without a
corresponding set_mfa_inbound() call would permanently exhaust it.
Additionally, clamp command_size to I2O_COMMAND_SIZE before the
memcpy_toio() so the MMIO write stays within the I2O message frame,
consistent with the clamping already performed by outgoing_message_size()
for the header field.
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Tyllis Xu <LivelyCarpet87@gmail.com>
Link: https://patch.msgid.link/20260314165805.548293-1-LivelyCarpet87@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The command_file_write() handler allocates a kernel buffer of exactly
count bytes and copies user data into it, but does not validate the
buffer against the dot command protocol before passing it to
get_dot_command_size() and get_dot_command_timeout().
Since both the allocation size (count) and the header fields (command_size,
data_size) are independently user-controlled, an attacker can cause
get_dot_command_size() to return a value exceeding the allocation,
triggering OOB reads in get_dot_command_timeout() and an out-of-bounds
memcpy_toio() that leaks kernel heap memory to the service processor.
Fix with two guards: reject writes smaller than sizeof(struct
dot_command_header) before allocation, then after copying user data
reject commands where the buffer is smaller than the total size declared
by the header (sizeof(header) + command_size + data_size). This ensures
all subsequent header and payload field accesses stay within the buffer.
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Tyllis Xu <LivelyCarpet87@gmail.com>
Link: https://patch.msgid.link/20260314165355.548119-1-LivelyCarpet87@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
ibmasm_handle_mouse_interrupt() performs an out-of-bounds MMIO read
when the queue reader or writer index from hardware exceeds
REMOTE_QUEUE_SIZE (60).
A compromised service processor can trigger this by writing an
out-of-range value to the reader or writer MMIO register before
asserting an interrupt. Since writer is re-read from hardware on
every loop iteration, it can also be set to an out-of-range value
after the loop has already started.
The root cause is that get_queue_reader() and get_queue_writer() return
raw readl() values that are passed directly into get_queue_entry(),
which computes:
queue_begin + reader * sizeof(struct remote_input)
with no bounds check. This unchecked MMIO address is then passed to
memcpy_fromio(), reading 8 bytes from unintended device registers.
For sufficiently large values the address falls outside the PCI BAR
mapping entirely, triggering a machine check exception.
Fix by checking both indices against REMOTE_QUEUE_SIZE at the top of
the loop body, before any call to get_queue_entry(). On an out-of-range
value, reset the reader register to 0 via set_queue_reader() before
breaking, so that normal queue operation can resume if the corrupted
hardware state is transient.
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Fixes: 278d72ae88 ("[PATCH] ibmasm driver: redesign handling of remote control events")
Cc: stable@vger.kernel.org
Cc: ychen@northwestern.edu
Signed-off-by: Tyllis Xu <LivelyCarpet87@gmail.com>
Link: https://patch.msgid.link/20260308062108.258940-1-LivelyCarpet87@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The FPC202 dual port controller has 20 regular GPIO lines and 8 special
GPIO lines with LED features. Each one of these "LED GPIOs" can output PWM
and blink signals.
Add support for the eight special-purpose GPIO lines to the existing FPC202
driver's GPIO support. Add support for registering led-class devices on
these GPIO lines.
Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
Link: https://patch.msgid.link/20260331-fpc202-leds-v3-3-74b173537d42@bootlin.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Rockchip SoCs RK3576 and RK3588 read data from the OTP using 32-bit
words instead of normal 8-bit bytes. Similar RK3506, RK3528, RK3562 and
RK3568 will read data from OTP using 16-bit words.
The nvmem core stride and word_size cannot fully be used as cells is not
always aligned. Continue to report a stride=1 and word_size=1 in
nvmem_config and instead handle use of SoC specific word_size internally
in the driver.
Move current SoC specific word_size handling from the RK3588 read_reg
operation to the main read_reg operation to help simplify the SoC
specific read_reg operation and allow code reuse in a future RK3568
reg_read operation.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Tested-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Srinivas Kandagatla <srini@kernel.org>
Link: https://patch.msgid.link/20260327131751.3026030-7-srini@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
cc1352_bootloader_rx() appends each serdev chunk into the fixed
rx_buffer before parsing bootloader packets. The helper can keep
leftover bytes between callbacks and may receive multiple packets in one
callback, so a single count value is not constrained by one packet
length.
Check that the incoming chunk fits in the remaining receive buffer space
before memcpy(). If it does not, drop the staged data and consume the
bytes instead of overflowing rx_buffer.
Fixes: 0cf7befa3e ("greybus: gb-beagleplay: Add firmware upload API")
Cc: stable <stable@kernel.org>
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260402054016.38587-1-pengpeng@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Now that hdlc_tx_frames() can drop frames when the circular buffer is
full, make the failure visible to callers:
- Change hdlc_tx_frames() return type from void to int (-EAGAIN on
buffer full).
- Change gb_beagleplay_start_svc() / gb_beagleplay_stop_svc() to
return int so probe and firmware-upload paths can detect failures.
- gb_message_send(): propagate the error so the greybus core can
handle the transport failure.
- hdlc_tx_s_frame_ack(): log with dev_warn_ratelimited on failure
(ACK loss is recoverable by HDLC retransmission).
- Probe path: propagate start_svc failure via new free_greybus label.
- Firmware upload paths: return FW_UPLOAD_ERR_RW_ERROR when SVC
restart fails instead of silently continuing.
- Remove path: best-effort stop_svc, ignore failure.
Cc: Ayush Singh <ayushdevel1325@gmail.com>
Cc: Johan Hovold <johan@kernel.org>
Cc: Alex Elder <elder@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
Link: https://patch.msgid.link/20260330120801.981506-2-geoffreyhe2@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
hdlc_append() calls usleep_range() to wait for circular buffer space,
but it is called with tx_producer_lock (a spinlock) held via
hdlc_tx_frames() -> hdlc_append_tx_frame()/hdlc_append_tx_u8()/etc.
Sleeping while holding a spinlock is illegal and can trigger
"BUG: scheduling while atomic".
Fix this by moving the buffer-space wait out of hdlc_append() and into
hdlc_tx_frames(), before the spinlock is acquired. The new flow:
1. Pre-calculate the worst-case encoded frame length.
2. Wait (with sleep) outside the lock until enough space is available,
kicking the TX consumer work to drain the buffer.
3. Acquire the spinlock, re-verify space, and write the entire frame
atomically.
This ensures that sleeping only happens without any lock held, and
that frames are either fully enqueued or not written at all.
This bug is found by CodeQL static analysis tool (interprocedural
sleep-in-atomic query) and my code review.
Fixes: ec558bbfea ("greybus: Add BeaglePlay Linux Driver")
Cc: stable <stable@kernel.org>
Cc: Ayush Singh <ayushdevel1325@gmail.com>
Cc: Johan Hovold <johan@kernel.org>
Cc: Alex Elder <elder@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
Link: https://patch.msgid.link/20260330120801.981506-1-geoffreyhe2@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Driver core holds a reference to the USB interface and its parent USB
device while the interface is bound to a driver and there is no need to
take additional references unless the structures are needed after
disconnect.
Drop the redundant device reference to reduce cargo culting, make it
easier to spot drivers where an extra reference is needed, and reduce
the risk of memory leaks when drivers fail to release it.
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260311082226.14865-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
When `flashing_mode` is set, `gb_tty_receive()` routes incoming bytes to
`cc1352_bootloader_rx()`. That helper appends the new bytes to the shared
`rx_buffer` with `memcpy()` but does not check that the chunk fits in the
remaining space first. The normal HDLC receive path already enforces
`MAX_RX_HDLC`, so do the same here before appending bootloader data.
If a packet would overflow the receive buffer, drop it and reset the
bootloader receive state instead of copying past the end of `rx_buffer`.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260322031923.58013-1-pengpeng@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Commit 6cd5a9a35c ("staging/trivial: fix typos concerning "access"")
accidentally changed "Acces I/O Products" to "Access I/O Products",
although "Acces" should actually be a capitalized acronym "ACCES"
(standing for "Acquisition, Control, and Communication: Engineering &
Systems"). Change it in the "aio_aio12_8" and "aio_iiro_16" drivers and
change the Kconfig file to match.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260129114402.11033-1-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "s526" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a Sensoray
526 board. It currently allows any base address to be configured but
the hardware only supports base addresses (configured by on-board DIP
switches) in the range 0 to 0xFFC0 on 64-byte boundaries.
Add a sanity check to ensure the device is not configured at an
unsupported base address.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-47-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "rti800" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a RTI-802
board. It currently allows any base address to be configured but the
hardware only supports base addresses (configured by on-board DIP
switches) in the range 0 to 0x3FC on 4-byte boundaries.
Add a sanity check to ensure the device is not configured at an
unsupported base address.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-46-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "rti800" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a RTI-800
or RTI-815 board. It currently allows any base address to be configured
but the hardware only supports base addresses (configured by on-board
DIP switches) in the range 0 to 0x3F0 on 16-byte boundaries.
Add a sanity check to ensure the device is not configured at an
unsupported base address.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-45-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "pcmmio" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a
PCM-UIO48A or PCM-UIO96A board. It will probably work with the later
PCM-UIO48C and PCM-UIO96C boards. It currently allows any base address
to be configured but the hardware only supports base addresses
(configured by on-board jumpers) in the range 0 to 0xFFF0 on 16-byte
boundaries (for PCM-UIO48C) or 0 to 0xFFE0 on 32-byte boundaries (for
PCM-UIO96C). (The PCM-UIO48A supports base addresses up to 0xFF0 and
the PCI-UIO96A supports base addresses up to 0x7E0.)
Add a sanity check to ensure the device is not configured at an
unsupported base address (allowing for the extended range of the "C"
models).
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-44-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "pcmmio" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a PCM-MIO
board. It currently allows any base address to be configured but the
hardware only supports base addresses (configured by on-board jumpers)
in the range 0 to 0xFFE0 on 32-byte boundaries.
Add a sanity check to ensure the device is not configured at an
unsupported base address.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-43-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "pcmda12" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a
PCM-D/A-12 or PCM-A/D-16 board. It currently allows any base address to
be configured. I cannot find a full manual, but the short datasheet
says it uses 15 consecutive I/O addresses on "any even sixteen port
boundary", so assume it supports base addresses (configured by on-board
jumpers) in the range 0 to 0x3E0 on 32-byte boundaries.
Add a sanity check to ensure the device is not configured at an
unsupported base address.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-42-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "pcmad" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a
PCM-A/D-12 or PCM-A/D-16 board. It currently allows any base address to
be configured but the hardware only supports base addresses (configured
by on-board jumpers) in the range 0 to 0x3FC on 4-byte boundaries.
Add a sanity check to ensure the device is not configured at an
unsupported base address.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-41-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "pcm3724" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a PCM-3724
board. It currently allows any base address to be configured but the
hardware only supports base addresses (configured by on-board DIP
switches) in the range 0 to 0x3F0 on 16-byte boundaries.
Add a sanity check to ensure the device is not configured at an
unsupported base address.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-40-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "pcl818" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a board in
the PCL-818 series. It currently allows any base address to be
configured but the hardware devices only support base addresses
(configured by on-board DIP switches) from 0 to 0x3F0 on 16-byte
boundaries. If the board has a FIFO and jumper JP6 is in the "Enabled"
(default) position, then the base address needs to be on a 32-byte
boundary and the length of the I/O port region will be 32 (to allow
access to the FIFO registers) instead of 16. The state of jumper JP6 is
unknown, so if the board has a FIFO device and is being configured on an
odd 16-byte boundary, assume that jumper JP6 is in the "Disabled"
position (to disallow access to the FIFO registers).
Add a sanity check to ensure the device is not configured at an
unsupported base address.
If the board has a FIFO and is configured on an odd 16-byte boundary,
log a reminder that JP6 needs to be in the "Disabled" position for
correct operation. If the board has a FIFO and is configured on an even
16-byte boundary and the configuration option has been set to use the
FIFO (`it->options[2] == -1`), log a reminder that JP6 needs to be in
the "Enabled" position.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-39-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "pcl816" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a PCL-816
or PCL-814B ISA board. It currently allows any base address to be
configured but the hardware devices only support base addresses
(configured by on-board DIP switches) from 0 to 0x3F0 on 16-byte
boundaries.
Add a sanity check to ensure the device is not configured at an
unsupported base address.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-38-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "pcl812" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of various
analog/digital I/O ISA boards from Advantech, ADLINK, and ICP DAS. It
currently allows any base address to be configured but the hardware
devices only support base addresses (configured by on-board DIP
switches) from 0 or 0x200 (depending on the model) to 0x3F0 on 16-byte
boundaries.
Store the minimum supported I/O base addresses in the static board
information array elements and add a sanity check to ensure the device
is not configured at an unsupported base address.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-37-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The "pcl730" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of various
relay output and digital input ISA board from Advantech, ADLINK, ICP
DAS, and Diamond Systems. It currently allows any base address to be
configured but the hardware devices have restrictions on the base
addresses (configured by on-board DIP switches or jumpers), including
the alignment, which can be larger than the board's I/O register address
span. The Diamond Systems IR104-PBF board is particularly restricted to
4 different base addresses with different sized gaps between the
possible addresses.
Store the minimum supported I/O base addresses and alignment in the
static board information array elements and add a sanity check to ensure
the device is not configured at an unsupported base address. For the
IR104-PBF board, add a special check that the base address is one of the
4 supported base addresses for that board.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-36-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>