RE: [PATCH] mei: lb: read the MTU once
From: Usyskin, Alexander
Date: Thu Oct 29 2026 - 01:21:27 EST
> Subject: [PATCH] mei: lb: read the MTU once
>
> From: Josef Bacik <josef@xxxxxxxxxxxxxx>
>
> mei_cldev_mtu() returns 0 if the client is not connected. A link reset
> disconnects all clients at any time, from the reset work.
>
> mei_lb_push_payload_v2() asks for the MTU to allocate the request buffer
> and asks again for every chunk. If the reset comes in between,
>
> chunk_size = min(payload_size - sent_data, 0 - sizeof(*req));
>
> makes the chunk the whole rest of the payload, and the memcpy() behind it
> writes over the end of the buffer. If the reset comes before the first
> call, kzalloc(0) returns ZERO_SIZE_PTR, which passes the NULL check and is
> dereferenced. An MTU not bigger than the request header has the same
> effect as 0.
>
> Read the MTU once and refuse one which leaves no room for payload. If the
> client has gone, sending the chunk fails.
>
LGTM
Acked-by: Alexander Usyskin <alexander.usyskin@xxxxxxxxx>
> Fixes: 773a43b8627f ("mei: lb: add late binding version 2")
> Cc: stable <stable@xxxxxxxxxx>
> Cc: Alexander Usyskin <alexander.usyskin@xxxxxxxxx>
> Cc: Arnd Bergmann <arnd@xxxxxxxx>
> Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> ---
> drivers/misc/mei/mei_lb.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/misc/mei/mei_lb.c b/drivers/misc/mei/mei_lb.c
> index 9fa69acf28d5..ffaf5be3b605 100644
> --- a/drivers/misc/mei/mei_lb.c
> +++ b/drivers/misc/mei/mei_lb.c
> @@ -312,16 +312,24 @@ static int mei_lb_push_payload_v2(struct device *dev,
> struct mei_cl_device *clde
> size_t chunk_size;
> size_t req_size;
> ssize_t bytes;
> + size_t mtu;
> int ret;
>
> - struct mei_lb2_req *req __free(kfree) = kzalloc(mei_cldev_mtu(cldev),
> GFP_KERNEL);
> + /* The MTU turns into 0 when a link reset disconnects the client */
> + mtu = mei_cldev_mtu(cldev);
> + if (mtu <= sizeof(struct mei_lb2_req)) {
> + dev_err(dev, "MTU is too small: %zu\n", mtu);
> + return -EMSGSIZE;
> + }
> +
> + struct mei_lb2_req *req __free(kfree) = kzalloc(mtu, GFP_KERNEL);
> if (!req)
> return -ENOMEM;
>
> first_chunk = MEI_LB2_FLAG_FST_CHUNK;
> last_chunk = 0;
> do {
> - chunk_size = min(payload_size - sent_data,
> mei_cldev_mtu(cldev) - sizeof(*req));
> + chunk_size = min(payload_size - sent_data, mtu - sizeof(*req));
>
> req_size = struct_size(req, payload, chunk_size);
> if (sent_data + chunk_size == payload_size)
> --
> 2.56.0