Add amdgpu_atpx_buffer_validate() to check that the returned ACPI
buffer is of type ACPI_TYPE_BUFFER, is large enough to hold the u16
size field, and that the BIOS-reported size does not exceed the actual
allocation length or fall below the minimum required by the caller.
Use it in VERIFY_INTERFACE and GET_PX_PARAMETERS callers.

Signed-off-by: Lijo Lazar <[email protected]>
Assisted-by: Claude Sonnet (Cursor AI)
---
 .../gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c  | 33 ++++++++++++-------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
index 3893e6fc2f03..e2a4644896ca 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
@@ -89,6 +89,15 @@ bool amdgpu_is_atpx_hybrid(void)
        return amdgpu_atpx_priv.atpx.is_hybrid;
 }
 
+static bool amdgpu_atpx_buffer_validate(const union acpi_object *obj,
+                                       size_t min_size)
+{
+       return obj && obj->type == ACPI_TYPE_BUFFER &&
+              obj->buffer.length >= sizeof(u16) &&
+              obj->buffer.length >= *(u16 *)obj->buffer.pointer &&
+              *(u16 *)obj->buffer.pointer >= min_size;
+}
+
 /**
  * amdgpu_atpx_call - call an ATPX method
  *
@@ -179,15 +188,15 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
                if (!info)
                        return -EIO;
 
-               memset(&output, 0, sizeof(output));
-
-               size = *(u16 *) info->buffer.pointer;
-               if (size < 10) {
-                       pr_err("ATPX buffer is too small: %zu\n", size);
+               if (!amdgpu_atpx_buffer_validate(info, sizeof(output))) {
+                       pr_err("Invalid ATPX GET_PX_PARAMETERS response\n");
                        kfree(info);
                        return -EINVAL;
                }
-               size = min(sizeof(output), size);
+
+               memset(&output, 0, sizeof(output));
+
+               size = min(sizeof(output), (size_t)*(u16 
*)info->buffer.pointer);
 
                memcpy(&output, info->buffer.pointer, size);
 
@@ -258,15 +267,15 @@ static int amdgpu_atpx_verify_interface(struct 
amdgpu_atpx *atpx)
        if (!info)
                return -EIO;
 
-       memset(&output, 0, sizeof(output));
-
-       size = *(u16 *) info->buffer.pointer;
-       if (size < 8) {
-               pr_err("ATPX buffer is too small: %zu\n", size);
+       if (!amdgpu_atpx_buffer_validate(info, sizeof(output))) {
+               pr_err("Invalid ATPX VERIFY_INTERFACE response\n");
                err = -EINVAL;
                goto out;
        }
-       size = min(sizeof(output), size);
+
+       memset(&output, 0, sizeof(output));
+
+       size = min(sizeof(output), (size_t)*(u16 *)info->buffer.pointer);
 
        memcpy(&output, info->buffer.pointer, size);
 
-- 
2.49.0

Reply via email to