drivers/acpi/apei/einj-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
The "einj_buf" buffer is 32 chars. Verify that "count" is not too large
for that. Also leave the last character as a NUL terminator to ensure
the string is properly terminated.
Fixes: 0c6176e1e186 ("ACPI: APEI: EINJ: Enable the discovery of EINJv2 capabilities")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
---
v2: I messed up the sizeof() calculation in the copy_from_user() and I put
the parentheses in the wrong place in v1.
drivers/acpi/apei/einj-core.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c
index d6d7e36e3647..2206cbbdccfa 100644
--- a/drivers/acpi/apei/einj-core.c
+++ b/drivers/acpi/apei/einj-core.c
@@ -826,8 +826,11 @@ static ssize_t error_type_set(struct file *file, const char __user *buf,
int rc;
u64 val;
+ if (count > sizeof(einj_buf))
+ return -EINVAL;
+
memset(einj_buf, 0, sizeof(einj_buf));
- if (copy_from_user(einj_buf, buf, count))
+ if (copy_from_user(einj_buf, buf, min(count, sizeof(einj_buf) - 1)))
return -EFAULT;
if (strncmp(einj_buf, "V2_", 3) == 0) {
--
2.47.2
Hello Dan, On Wed, Jun 25, 2025 at 11:34:38AM -0500, Dan Carpenter wrote: > The "einj_buf" buffer is 32 chars. Verify that "count" is not too large > for that. Also leave the last character as a NUL terminator to ensure > the string is properly terminated. > > Fixes: 0c6176e1e186 ("ACPI: APEI: EINJ: Enable the discovery of EINJv2 capabilities") > Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org> > --- > v2: I messed up the sizeof() calculation in the copy_from_user() and I put > the parentheses in the wrong place in v1. > > drivers/acpi/apei/einj-core.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c > index d6d7e36e3647..2206cbbdccfa 100644 > --- a/drivers/acpi/apei/einj-core.c > +++ b/drivers/acpi/apei/einj-core.c > @@ -826,8 +826,11 @@ static ssize_t error_type_set(struct file *file, const char __user *buf, > int rc; > u64 val; > > + if (count > sizeof(einj_buf)) > + return -EINVAL; > + > memset(einj_buf, 0, sizeof(einj_buf)); > - if (copy_from_user(einj_buf, buf, count)) I would add a comment here to explain the -1. It's in the commit log, but that doesn't help a future reader. > + if (copy_from_user(einj_buf, buf, min(count, sizeof(einj_buf) - 1))) > return -EFAULT; > > if (strncmp(einj_buf, "V2_", 3) == 0) { Further down there is: return count; Is that still correct given that you read less now? Best regards Uwe
On Wed, Jun 25, 2025 at 08:04:14PM +0200, Uwe Kleine-König wrote: > Hello Dan, > > On Wed, Jun 25, 2025 at 11:34:38AM -0500, Dan Carpenter wrote: > > The "einj_buf" buffer is 32 chars. Verify that "count" is not too large > > for that. Also leave the last character as a NUL terminator to ensure > > the string is properly terminated. > > > > Fixes: 0c6176e1e186 ("ACPI: APEI: EINJ: Enable the discovery of EINJv2 capabilities") > > Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org> > > --- > > v2: I messed up the sizeof() calculation in the copy_from_user() and I put > > the parentheses in the wrong place in v1. > > > > drivers/acpi/apei/einj-core.c | 5 ++++- > > 1 file changed, 4 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c > > index d6d7e36e3647..2206cbbdccfa 100644 > > --- a/drivers/acpi/apei/einj-core.c > > +++ b/drivers/acpi/apei/einj-core.c > > @@ -826,8 +826,11 @@ static ssize_t error_type_set(struct file *file, const char __user *buf, > > int rc; > > u64 val; > > > > + if (count > sizeof(einj_buf)) > > + return -EINVAL; > > + > > memset(einj_buf, 0, sizeof(einj_buf)); > > - if (copy_from_user(einj_buf, buf, count)) > > I would add a comment here to explain the -1. It's in the commit log, > but that doesn't help a future reader. > Sure. I can add a comment. /* Leave the last character for the NUL terminator */ > > + if (copy_from_user(einj_buf, buf, min(count, sizeof(einj_buf) - 1))) > > return -EFAULT; > > > > if (strncmp(einj_buf, "V2_", 3) == 0) { > > Further down there is: > > return count; > > Is that still correct given that you read less now? Yep. If we don't return count userspace will try again, right? regards, dan carpenter
> > + if (count > sizeof(einj_buf)) Why not: /* Leave the last character for the NUL terminator */ if (count > sizeof(einj_buf) - 1) return -EINVAL; here. Then skip the min(...) addition below. -Tony
On Wed, Jun 25, 2025 at 06:22:57PM +0000, Luck, Tony wrote: > > > + if (count > sizeof(einj_buf)) > > Why not: > /* Leave the last character for the NUL terminator */ > if (count > sizeof(einj_buf) - 1) > return -EINVAL; > > here. Then skip the min(...) addition below. Yeah. You're right. That's a better fix. regards, dan carpenter
© 2016 - 2025 Red Hat, Inc.