Skip to content

Commit 496f937

Browse files
Reodusrafaeljw
authored andcommitted
ACPI: debug: fix signedness issues in read/write helpers
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: 8cfb0cd ("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>
1 parent 07e27ad commit 496f937

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

drivers/acpi/acpi_dbg.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -569,11 +569,11 @@ static int acpi_aml_release(struct inode *inode, struct file *file)
569569
return 0;
570570
}
571571

572-
static int acpi_aml_read_user(char __user *buf, int len)
572+
static ssize_t acpi_aml_read_user(char __user *buf, size_t len)
573573
{
574-
int ret;
575574
struct circ_buf *crc = &acpi_aml_io.out_crc;
576-
int n;
575+
ssize_t ret;
576+
size_t n;
577577
char *p;
578578

579579
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)
582582
/* sync head before removing logs */
583583
smp_rmb();
584584
p = &crc->buf[crc->tail];
585-
n = min(len, circ_count_to_end(crc));
585+
n = min_t(size_t, len, circ_count_to_end(crc));
586586
if (copy_to_user(buf, p, n)) {
587587
ret = -EFAULT;
588588
goto out;
@@ -599,8 +599,8 @@ static int acpi_aml_read_user(char __user *buf, int len)
599599
static ssize_t acpi_aml_read(struct file *file, char __user *buf,
600600
size_t count, loff_t *ppos)
601601
{
602-
int ret = 0;
603-
int size = 0;
602+
ssize_t ret = 0;
603+
ssize_t size = 0;
604604

605605
if (!count)
606606
return 0;
@@ -639,11 +639,11 @@ static ssize_t acpi_aml_read(struct file *file, char __user *buf,
639639
return size > 0 ? size : ret;
640640
}
641641

642-
static int acpi_aml_write_user(const char __user *buf, int len)
642+
static ssize_t acpi_aml_write_user(const char __user *buf, size_t len)
643643
{
644-
int ret;
645644
struct circ_buf *crc = &acpi_aml_io.in_crc;
646-
int n;
645+
ssize_t ret;
646+
size_t n;
647647
char *p;
648648

649649
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)
652652
/* sync tail before inserting cmds */
653653
smp_mb();
654654
p = &crc->buf[crc->head];
655-
n = min(len, circ_space_to_end(crc));
655+
n = min_t(size_t, len, circ_space_to_end(crc));
656656
if (copy_from_user(p, buf, n)) {
657657
ret = -EFAULT;
658658
goto out;
@@ -663,14 +663,14 @@ static int acpi_aml_write_user(const char __user *buf, int len)
663663
ret = n;
664664
out:
665665
acpi_aml_unlock_fifo(ACPI_AML_IN_USER, ret >= 0);
666-
return n;
666+
return ret;
667667
}
668668

669669
static ssize_t acpi_aml_write(struct file *file, const char __user *buf,
670670
size_t count, loff_t *ppos)
671671
{
672-
int ret = 0;
673-
int size = 0;
672+
ssize_t ret = 0;
673+
ssize_t size = 0;
674674

675675
if (!count)
676676
return 0;

0 commit comments

Comments
 (0)