]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ACPI: debug: fix signedness issues in read/write helpers
authorAmir Mohammad Jahangirzad <a.jahangirzad@gmail.com>
Tue, 23 Sep 2025 01:31:13 +0000 (05:01 +0330)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 23 Sep 2025 13:45:28 +0000 (15:45 +0200)
In the ACPI debugger interface, the helper functions for read and write
operations use "int" as the length parameter data type. When a large
"size_t count" is passed from the file operations, this cast to "int"
results in truncation and a negative value due to signed integer
representation.

Logically, this negative number propagates to the min() calculation,
where it is selected over the positive buffer space value, leading to
unexpected behavior. Subsequently, when this negative value is used in
copy_to_user() or copy_from_user(), it is interpreted as a large positive
value due to the unsigned nature of the size parameter in these functions,
causing the copy operations to attempt handling sizes far beyond the
intended buffer limits.

Address the issue by:
 - Changing the length parameters in acpi_aml_read_user() and
   acpi_aml_write_user() from "int" to "size_t", aligning with the
   expected unsigned size semantics.
 - Updating return types and local variables in acpi_aml_read() and
   acpi_aml_write() to "ssize_t" for consistency with kernel file
   operation conventions.
 - Using "size_t" for the "n" variable to ensure calculations remain
   unsigned.
 - Using min_t() for circ_count_to_end() and circ_space_to_end() to
   ensure type-safe comparisons and prevent integer overflow.

Signed-off-by: Amir Mohammad Jahangirzad <a.jahangirzad@gmail.com>
Link: https://patch.msgid.link/20250923013113.20615-1-a.jahangirzad@gmail.com
[ rjw: Changelog tweaks, local variable definitions ordering adjustments ]
Fixes: 8cfb0cdf07e2 ("ACPI / debugger: Add IO interface to access debugger functionalities")
Cc: 4.5+ <stable@vger.kernel.org> # 4.5+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/acpi_dbg.c

index d50261d05f3a1ab63dfd09878c262943e0bd79e8..515b20d0b698a49eb68599471999f1b5aa8cd3f7 100644 (file)
@@ -569,11 +569,11 @@ static int acpi_aml_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int acpi_aml_read_user(char __user *buf, int len)
+static ssize_t acpi_aml_read_user(char __user *buf, size_t len)
 {
-       int ret;
        struct circ_buf *crc = &acpi_aml_io.out_crc;
-       int n;
+       ssize_t ret;
+       size_t n;
        char *p;
 
        ret = acpi_aml_lock_read(crc, ACPI_AML_OUT_USER);
@@ -582,7 +582,7 @@ static int acpi_aml_read_user(char __user *buf, int len)
        /* sync head before removing logs */
        smp_rmb();
        p = &crc->buf[crc->tail];
-       n = min(len, circ_count_to_end(crc));
+       n = min_t(size_t, len, circ_count_to_end(crc));
        if (copy_to_user(buf, p, n)) {
                ret = -EFAULT;
                goto out;
@@ -599,8 +599,8 @@ out:
 static ssize_t acpi_aml_read(struct file *file, char __user *buf,
                             size_t count, loff_t *ppos)
 {
-       int ret = 0;
-       int size = 0;
+       ssize_t ret = 0;
+       ssize_t size = 0;
 
        if (!count)
                return 0;
@@ -639,11 +639,11 @@ again:
        return size > 0 ? size : ret;
 }
 
-static int acpi_aml_write_user(const char __user *buf, int len)
+static ssize_t acpi_aml_write_user(const char __user *buf, size_t len)
 {
-       int ret;
        struct circ_buf *crc = &acpi_aml_io.in_crc;
-       int n;
+       ssize_t ret;
+       size_t n;
        char *p;
 
        ret = acpi_aml_lock_write(crc, ACPI_AML_IN_USER);
@@ -652,7 +652,7 @@ static int acpi_aml_write_user(const char __user *buf, int len)
        /* sync tail before inserting cmds */
        smp_mb();
        p = &crc->buf[crc->head];
-       n = min(len, circ_space_to_end(crc));
+       n = min_t(size_t, len, circ_space_to_end(crc));
        if (copy_from_user(p, buf, n)) {
                ret = -EFAULT;
                goto out;
@@ -663,14 +663,14 @@ static int acpi_aml_write_user(const char __user *buf, int len)
        ret = n;
 out:
        acpi_aml_unlock_fifo(ACPI_AML_IN_USER, ret >= 0);
-       return n;
+       return ret;
 }
 
 static ssize_t acpi_aml_write(struct file *file, const char __user *buf,
                              size_t count, loff_t *ppos)
 {
-       int ret = 0;
-       int size = 0;
+       ssize_t ret = 0;
+       ssize_t size = 0;
 
        if (!count)
                return 0;