cap_get_ims_certificate() and cap_authenticate() derive copy lengths from response payload sizes without checking the response header size or destination capacity.
Reject responses smaller than their headers with -EMSGSIZE. Reject certificate and signature data larger than their fixed ioctl buffers with -E2BIG.
Signed-off-by: Suraj Theekshana surajtheekshana1111@gmail.com --- drivers/staging/greybus/authentication.c | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/drivers/staging/greybus/authentication.c b/drivers/staging/greybus/authentication.c index d8f2cd4..cbd28a3 100644 --- a/drivers/staging/greybus/authentication.c +++ b/drivers/staging/greybus/authentication.c @@ -128,9 +128,22 @@ static int cap_get_ims_certificate(struct gb_cap *cap, u32 class, u32 id, goto done; }
+ if (op->response->payload_size < sizeof(*response)) { + dev_err(cap->parent, + "invalid IMS certificate response size (%zu)\n", + op->response->payload_size); + ret = -EMSGSIZE; + goto done; + } + response = op->response->payload; *result = response->result_code; *size = op->response->payload_size - sizeof(*response); + if (*size > CAP_CERTIFICATE_MAX_SIZE) { + dev_err(cap->parent, "IMS certificate too large (%u)\n", *size); + ret = -E2BIG; + goto done; + } memcpy(certificate, response->certificate, *size);
done: @@ -167,9 +180,23 @@ static int cap_authenticate(struct gb_cap *cap, u32 auth_type, u8 *uid, goto done; }
+ if (op->response->payload_size < sizeof(*response)) { + dev_err(cap->parent, + "invalid authenticate response size (%zu)\n", + op->response->payload_size); + ret = -EMSGSIZE; + goto done; + } + response = op->response->payload; *result = response->result_code; *signature_size = op->response->payload_size - sizeof(*response); + if (*signature_size > CAP_SIGNATURE_MAX_SIZE) { + dev_err(cap->parent, "authenticate signature too large (%u)\n", + *signature_size); + ret = -E2BIG; + goto done; + } memcpy(auth_response, response->response, sizeof(response->response)); memcpy(signature, response->signature, *signature_size);