drivers/misc/ds1682.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
Found a couple of issues in the ds1682 driver while reviewing the code:
The EEPROM read/write functions don't check if offset and count exceed
the 10-byte EEPROM size, which could lead to out-of-bounds I2C access.
Also replaced sprintf with scnprintf in the sysfs show function for
better safety.
For reads beyond EEPROM size, return 0. For writes, return -EINVAL if
starting beyond bounds, otherwise truncate to fit within the EEPROM.
Signed-off-by: Wajahat Iqbal <wajahatiqbal22@gmail.com>
---
drivers/misc/ds1682.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c
index cb09e056531a..4cf4b43e5355 100644
--- a/drivers/misc/ds1682.c
+++ b/drivers/misc/ds1682.c
@@ -92,7 +92,7 @@ static ssize_t ds1682_show(struct device *dev,
struct device_attribute *attr,
* Special case: the 32 bit regs are time values with 1/4s
* resolution, scale them up to milliseconds
*/
- return sprintf(buf, "%llu\n", (sattr->nr == 4) ? (val * 250) : val);
+ return scnprintf(buf, PAGE_SIZE, "%llu\n", (sattr->nr == 4) ? (val *
250) : val);
}
static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr,
@@ -163,6 +163,11 @@ static ssize_t ds1682_eeprom_read(struct file
*filp, struct kobject *kobj,
dev_dbg(&client->dev, "ds1682_eeprom_read(p=%p, off=%lli, c=%zi)\n",
buf, off, count);
+ if (off >= DS1682_EEPROM_SIZE)
+ return 0;
+ if (off + count > DS1682_EEPROM_SIZE)
+ count = DS1682_EEPROM_SIZE - off;
+
rc = i2c_smbus_read_i2c_block_data(client, DS1682_REG_EEPROM + off,
count, buf);
if (rc < 0)
@@ -180,6 +185,11 @@ static ssize_t ds1682_eeprom_write(struct file
*filp, struct kobject *kobj,
dev_dbg(&client->dev, "ds1682_eeprom_write(p=%p, off=%lli, c=%zi)\n",
buf, off, count);
+ if (off >= DS1682_EEPROM_SIZE)
+ return -EINVAL;
+ if (off + count > DS1682_EEPROM_SIZE)
+ count = DS1682_EEPROM_SIZE - off;
+
/* Write out to the device */
if (i2c_smbus_write_i2c_block_data(client, DS1682_REG_EEPROM + off,
count, buf) < 0)
--
2.49.0.windows.1
On Sat, Aug 09, 2025 at 08:54:57PM +0500, wajahat iqbal wrote: > Found a couple of issues in the ds1682 driver while reviewing the code: > > The EEPROM read/write functions don't check if offset and count exceed > the 10-byte EEPROM size, which could lead to out-of-bounds I2C access. > > Also replaced sprintf with scnprintf in the sysfs show function for > better safety. > > For reads beyond EEPROM size, return 0. For writes, return -EINVAL if > starting beyond bounds, otherwise truncate to fit within the EEPROM. > > Signed-off-by: Wajahat Iqbal <wajahatiqbal22@gmail.com> > --- > drivers/misc/ds1682.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c > index cb09e056531a..4cf4b43e5355 100644 > --- a/drivers/misc/ds1682.c > +++ b/drivers/misc/ds1682.c > @@ -92,7 +92,7 @@ static ssize_t ds1682_show(struct device *dev, > struct device_attribute *attr, > * Special case: the 32 bit regs are time values with 1/4s > * resolution, scale them up to milliseconds > */ > - return sprintf(buf, "%llu\n", (sattr->nr == 4) ? (val * 250) : val); > + return scnprintf(buf, PAGE_SIZE, "%llu\n", (sattr->nr == 4) ? (val * > 250) : val); > } > > static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr, > @@ -163,6 +163,11 @@ static ssize_t ds1682_eeprom_read(struct file > *filp, struct kobject *kobj, > dev_dbg(&client->dev, "ds1682_eeprom_read(p=%p, off=%lli, c=%zi)\n", > buf, off, count); > > + if (off >= DS1682_EEPROM_SIZE) > + return 0; > + if (off + count > DS1682_EEPROM_SIZE) > + count = DS1682_EEPROM_SIZE - off; > + > rc = i2c_smbus_read_i2c_block_data(client, DS1682_REG_EEPROM + off, > count, buf); > if (rc < 0) > @@ -180,6 +185,11 @@ static ssize_t ds1682_eeprom_write(struct file > *filp, struct kobject *kobj, > dev_dbg(&client->dev, "ds1682_eeprom_write(p=%p, off=%lli, c=%zi)\n", > buf, off, count); > > + if (off >= DS1682_EEPROM_SIZE) > + return -EINVAL; > + if (off + count > DS1682_EEPROM_SIZE) > + count = DS1682_EEPROM_SIZE - off; > + > /* Write out to the device */ > if (i2c_smbus_write_i2c_block_data(client, DS1682_REG_EEPROM + off, > count, buf) < 0) > -- > 2.49.0.windows.1 Hi, This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him a patch that has triggered this response. He used to manually respond to these common problems, but in order to save his sanity (he kept writing the same thing over and over, yet to different people), I was created. Hopefully you will not take offence and will fix the problem in your patch and resubmit it so that it can be accepted into the Linux kernel tree. You are receiving this message because of the following common error(s) as indicated below: - Your patch is malformed (tabs converted to spaces, linewrapped, etc.) and can not be applied. Please read the file, Documentation/process/email-clients.rst in order to fix this. - Your patch did many different things all at once, making it difficult to review. All Linux kernel patches need to only do one thing at a time. If you need to do multiple things (such as clean up all coding style issues in a file/driver), do it in a sequence of patches, each one doing only one thing. This will make it easier to review the patches to ensure that they are correct, and to help alleviate any merge issues that larger patches can cause. If you wish to discuss this problem further, or you have questions about how to resolve this issue, please feel free to respond to this email and Greg will reply once he has dug out from the pending patches received from other developers. thanks, greg k-h's patch email bot
Hi all, Thanks for the ongoing review and feedback. To clarify the question about the SEAM interface and whether this patch should affect multiple drivers: I performed a thorough search through the kernel source for the term SEAMCALL to identify all users of the SEAM interface. Running: => grep -R "SEAMCALL" . from the kernel source root revealed that SEAMCALL is currently only used within the TDX (Intel Trust Domain Extensions) host-side code, located primarily under: arch/x86/virt/vmx/tdx/ No other drivers or subsystems in the drivers/ directory or elsewhere in the kernel tree appear to use this interface. Therefore, this patch targets the sole existing in-tree consumer of the SEAM interface. If other uses appear in the future, I am open to updating them accordingly or submitting follow-up patches. I will also resend this reply including all previous To: and Cc: recipients and format it as plain text with inline replies, as requested. Please let me know if you have further questions or concerns. Best regards, Wajahat Iqbal.
Hi again, Just to add, while sysfs enforces size limits, these only protect accesses through the sysfs interface. Adding explicit bounds checks in the driver helps ensure safety if the functions are called from elsewhere or future code changes bypass sysfs checks. This extra layer helps avoid potential hardware issues or crashes due to out-of-bounds access. Thanks again for reviewing. Best, Wajahat
Le 09/08/2025 à 17:54, wajahat iqbal a écrit : > Found a couple of issues in the ds1682 driver while reviewing the code: > > The EEPROM read/write functions don't check if offset and count exceed > the 10-byte EEPROM size, which could lead to out-of-bounds I2C access. > > Also replaced sprintf with scnprintf in the sysfs show function for > better safety. > > For reads beyond EEPROM size, return 0. For writes, return -EINVAL if > starting beyond bounds, otherwise truncate to fit within the EEPROM. > > Signed-off-by: Wajahat Iqbal <wajahatiqbal22@gmail.com> > --- > drivers/misc/ds1682.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c > index cb09e056531a..4cf4b43e5355 100644 > --- a/drivers/misc/ds1682.c > +++ b/drivers/misc/ds1682.c > @@ -92,7 +92,7 @@ static ssize_t ds1682_show(struct device *dev, > struct device_attribute *attr, > * Special case: the 32 bit regs are time values with 1/4s > * resolution, scale them up to milliseconds > */ > - return sprintf(buf, "%llu\n", (sattr->nr == 4) ? (val * 250) : val); > + return scnprintf(buf, PAGE_SIZE, "%llu\n", (sattr->nr == 4) ? (val * > 250) : val); > } > > static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr, > @@ -163,6 +163,11 @@ static ssize_t ds1682_eeprom_read(struct file > *filp, struct kobject *kobj, > dev_dbg(&client->dev, "ds1682_eeprom_read(p=%p, off=%lli, c=%zi)\n", > buf, off, count); > > + if (off >= DS1682_EEPROM_SIZE) > + return 0; > + if (off + count > DS1682_EEPROM_SIZE) > + count = DS1682_EEPROM_SIZE - off; > + > rc = i2c_smbus_read_i2c_block_data(client, DS1682_REG_EEPROM + off, > count, buf); > if (rc < 0) > @@ -180,6 +185,11 @@ static ssize_t ds1682_eeprom_write(struct file > *filp, struct kobject *kobj, > dev_dbg(&client->dev, "ds1682_eeprom_write(p=%p, off=%lli, c=%zi)\n", > buf, off, count); > > + if (off >= DS1682_EEPROM_SIZE) > + return -EINVAL; > + if (off + count > DS1682_EEPROM_SIZE) > + count = DS1682_EEPROM_SIZE - off; > + > /* Write out to the device */ > if (i2c_smbus_write_i2c_block_data(client, DS1682_REG_EEPROM + off, > count, buf) < 0) Are these new tests really needed? Isn't it already done the same way by the core, because of the ".size = DS1682_EEPROM_SIZE" in ds1682_eeprom_attr? I'm' not really familiar with this code, but my understanding is that it goes thru sysfs_kf_bin_write() and sysfs_kf_bin_read(). CJ
© 2016 - 2025 Red Hat, Inc.