Use strncpy_from_user() instead of copy_from_user() before sscanf() in
the securedisplay_test debugfs write handler so a full-length write
cannot leave the stack buffer without a terminator.

Signed-off-by: Candice Li <[email protected]>
---
 .../gpu/drm/amd/amdgpu/amdgpu_securedisplay.c | 25 ++++++++++++-------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c
index 3739be1b71e0d3..6c6d73804e34e2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c
@@ -98,15 +98,17 @@ static ssize_t amdgpu_securedisplay_debugfs_write(struct 
file *f, const char __u
        uint32_t phy_id;
        uint32_t op;
        char str[64];
-       int ret;
+       long len;
+       int ret, nargs;
 
-       if (*pos || size > sizeof(str) - 1)
+       if (*pos)
                return -EINVAL;
 
-       memset(str,  0, sizeof(str));
-       ret = copy_from_user(str, buf, size);
-       if (ret)
+       len = strncpy_from_user(str, buf, sizeof(str));
+       if (len < 0)
                return -EFAULT;
+       if (len == 0 || len >= sizeof(str))
+               return -EINVAL;
 
        ret = pm_runtime_get_sync(dev->dev);
        if (ret < 0) {
@@ -114,10 +116,14 @@ static ssize_t amdgpu_securedisplay_debugfs_write(struct 
file *f, const char __u
                return ret;
        }
 
-       if (size < 3)
-               sscanf(str, "%u ", &op);
+       if (len < 3)
+               nargs = sscanf(str, "%u", &op);
        else
-               sscanf(str, "%u %u", &op, &phy_id);
+               nargs = sscanf(str, "%u %u", &op, &phy_id);
+       if (nargs < 1) {
+               pm_runtime_put_autosuspend(dev->dev);
+               return -EINVAL;
+       }
 
        switch (op) {
        case 1:
@@ -135,8 +141,9 @@ static ssize_t amdgpu_securedisplay_debugfs_write(struct 
file *f, const char __u
                mutex_unlock(&psp->securedisplay_context.mutex);
                break;
        case 2:
-               if (size < 3 || phy_id >= TA_SECUREDISPLAY_MAX_PHY) {
+               if (len < 3 || nargs < 2 || phy_id >= TA_SECUREDISPLAY_MAX_PHY) 
{
                        dev_err(adev->dev, "Invalid input: %s\n", str);
+                       pm_runtime_put_autosuspend(dev->dev);
                        return -EINVAL;
                }
                mutex_lock(&psp->securedisplay_context.mutex);
-- 
2.25.1

Reply via email to