mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 07:04:24 +00:00
accel/qaic: tighten bounds checking in decode_message()
Copy the bounds checking from encode_message() to decode_message().
This patch addresses the following concerns. Ensure that there is
enough space for at least one header so that we don't have a negative
size later.
if (msg_hdr_len < sizeof(*trans_hdr))
Ensure that we have enough space to read the next header from the
msg->data.
if (msg_len > msg_hdr_len - sizeof(*trans_hdr))
return -EINVAL;
Check that the trans_hdr->len is not below the minimum size:
if (hdr_len < sizeof(*trans_hdr))
This minimum check ensures that we don't corrupt memory in
decode_passthrough() when we do.
memcpy(out_trans->data, in_trans->data, len - sizeof(in_trans->hdr));
And finally, use size_add() to prevent an integer overflow:
if (size_add(msg_len, hdr_len) > msg_hdr_len)
Fixes: 129776ac2e
("accel/qaic: Add control path")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Reviewed-by: Pranjal Ramajor Asha Kanojiya <quic_pkanojiy@quicinc.com>
Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
Cc: stable@vger.kernel.org # 6.4.x
Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ZK0Q5nbLyDO7kJa+@moroto
This commit is contained in:
parent
ea33cb6fc2
commit
51b56382ed
1 changed files with 10 additions and 2 deletions
|
@ -956,15 +956,23 @@ static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (msg_hdr_len > QAIC_MANAGE_MAX_MSG_LENGTH)
|
if (msg_hdr_len < sizeof(*trans_hdr) ||
|
||||||
|
msg_hdr_len > QAIC_MANAGE_MAX_MSG_LENGTH)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
user_msg->len = 0;
|
user_msg->len = 0;
|
||||||
user_msg->count = le32_to_cpu(msg->hdr.count);
|
user_msg->count = le32_to_cpu(msg->hdr.count);
|
||||||
|
|
||||||
for (i = 0; i < user_msg->count; ++i) {
|
for (i = 0; i < user_msg->count; ++i) {
|
||||||
|
u32 hdr_len;
|
||||||
|
|
||||||
|
if (msg_len > msg_hdr_len - sizeof(*trans_hdr))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
trans_hdr = (struct wire_trans_hdr *)(msg->data + msg_len);
|
trans_hdr = (struct wire_trans_hdr *)(msg->data + msg_len);
|
||||||
if (msg_len + le32_to_cpu(trans_hdr->len) > msg_hdr_len)
|
hdr_len = le32_to_cpu(trans_hdr->len);
|
||||||
|
if (hdr_len < sizeof(*trans_hdr) ||
|
||||||
|
size_add(msg_len, hdr_len) > msg_hdr_len)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
switch (le32_to_cpu(trans_hdr->type)) {
|
switch (le32_to_cpu(trans_hdr->type)) {
|
||||||
|
|
Loading…
Reference in a new issue