mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: David Fries <david@fries.net>
To: linux-kernel@vger.kernel.org
Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Subject: [PATCH 16/35] W1: w1_therm fix user buffer overflow and cat
Date: Fri, 28 Mar 2008 07:26:26 -0500	[thread overview]
Message-ID: <20080328122626.GQ3613@spacedout.fries.net> (raw)
In-Reply-To: <200803272343.m2RNhDac017650@SpacedOut.fries.net>

[-- Attachment #1: Type: text/plain, Size: 5501 bytes --]

This switches w1_therm from bin_attribute to device_attribute which
fixes a buffer overflow and some bad behavior.

slaves/w1_therm.c 1.8
Switching the sysfs read from bin_attribute to device_attribute.  The
data is far under PAGE_SIZE so the binary interface isn't required.
As the device_attribute interface will make one call to w1_therm_read per
file open and buffer, the result is, the following problems go away.

buffer overflow:
	Execute a short read on w1_slave and w1_therm_read_bin would still
	return the full string size worth of data clobbering the user space
	buffer when it returned.  Switching to device_attribute avoids the
	buffer overflow problems.  With the snprintf formatted output dealing
	with short reads without doing a conversion per read would have
	been difficult.
bad behavior:
	`cat w1_slave` would cause two temperature conversions to take place.
	Previously the code assumed W1_SLAVE_DATA_SIZE would be returned with
	each read.  It would not return 0 unless the offset was less
	than W1_SLAVE_DATA_SIZE.  The result was the first read did a
	temperature conversion, filled the buffer and returned, the
	offset in the second read would be less than
	W1_SLAVE_DATA_SIZE and also fill the buffer and return, the
	third read would finnally have a big enough offset to return 0
	and cause cat to stop.  Now w1_therm_read will be called at
	most once per open.

w1.h 1.8
w1_therm is no longer using the bin_attribute so the
W1_SLAVE_DATA_SIZE is no longer being used.

Signed-off-by: David Fries <david@fries.net>
---
 drivers/w1/slaves/w1_therm.c |   53 ++++++++++++++---------------------------
 drivers/w1/w1.h              |    1 -
 2 files changed, 18 insertions(+), 36 deletions(-)

diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index dd26db2..ca47421 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -42,26 +42,20 @@ static u8 bad_roms[][9] = {
 				{}
 			};
 
-static ssize_t w1_therm_read_bin(struct kobject *, struct bin_attribute *,
-				 char *, loff_t, size_t);
+static ssize_t w1_therm_read(struct device *device,
+	struct device_attribute *attr, char *buf);
 
-static struct bin_attribute w1_therm_bin_attr = {
-	.attr = {
-		.name = "w1_slave",
-		.mode = S_IRUGO,
-	},
-	.size = W1_SLAVE_DATA_SIZE,
-	.read = w1_therm_read_bin,
-};
+static struct device_attribute w1_therm_attr =
+	__ATTR(w1_slave, S_IRUGO, w1_therm_read, NULL);
 
 static int w1_therm_add_slave(struct w1_slave *sl)
 {
-	return sysfs_create_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+	return device_create_file(&sl->dev, &w1_therm_attr);
 }
 
 static void w1_therm_remove_slave(struct w1_slave *sl)
 {
-	sysfs_remove_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+	device_remove_file(&sl->dev, &w1_therm_attr);
 }
 
 static struct w1_family_ops w1_therm_fops = {
@@ -160,30 +154,19 @@ static int w1_therm_check_rom(u8 rom[9])
 	return 0;
 }
 
-static ssize_t w1_therm_read_bin(struct kobject *kobj,
-				 struct bin_attribute *bin_attr,
-				 char *buf, loff_t off, size_t count)
+static ssize_t w1_therm_read(struct device *device,
+	struct device_attribute *attr, char *buf)
 {
-	struct w1_slave *sl = kobj_to_w1_slave(kobj);
+	struct w1_slave *sl = dev_to_w1_slave(device);
 	struct w1_master *dev = sl->master;
 	u8 rom[9], crc, verdict;
 	int i, max_trying = 10;
+	ssize_t c=PAGE_SIZE;
 
 	mutex_lock(&sl->master->mutex);
 
-	if (off > W1_SLAVE_DATA_SIZE) {
-		count = 0;
-		goto out;
-	}
-	if (off + count > W1_SLAVE_DATA_SIZE) {
-		count = 0;
-		goto out;
-	}
-
-	memset(buf, 0, count);
 	memset(rom, 0, sizeof(rom));
 
-	count = 0;
 	verdict = 0;
 	crc = 0;
 
@@ -200,7 +183,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj,
 
 				w1_write_8(dev, W1_READ_SCRATCHPAD);
 				if ((count = w1_read_block(dev, rom, 9)) != 9) {
-					dev_warn(&dev->dev, "w1_read_block() returned %d instead of 9.\n", count);
+					dev_warn(device, "w1_read_block() returned %u instead of 9.\n", count);
 				}
 
 				crc = w1_calc_crc8(rom, 8);
@@ -215,22 +198,22 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj,
 	}
 
 	for (i = 0; i < 9; ++i)
-		count += sprintf(buf + count, "%02x ", rom[i]);
-	count += sprintf(buf + count, ": crc=%02x %s\n",
+		c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", rom[i]);
+	c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n",
 			   crc, (verdict) ? "YES" : "NO");
 	if (verdict)
 		memcpy(sl->rom, rom, sizeof(sl->rom));
 	else
-		dev_warn(&dev->dev, "18S20 doesn't respond to CONVERT_TEMP.\n");
+		dev_warn(device, "18S20 doesn't respond to CONVERT_TEMP.\n");
 
 	for (i = 0; i < 9; ++i)
-		count += sprintf(buf + count, "%02x ", sl->rom[i]);
+		c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", sl->rom[i]);
 
-	count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom, sl->family->fid));
-out:
+	c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n",
+		w1_convert_temp(rom, sl->family->fid));
 	mutex_unlock(&dev->mutex);
 
-	return count;
+	return PAGE_SIZE - c;
 }
 
 static int __init w1_therm_init(void)
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h
index bad7c7c..ab2944a 100644
--- a/drivers/w1/w1.h
+++ b/drivers/w1/w1.h
@@ -46,7 +46,6 @@ struct w1_reg_num
 #include "w1_family.h"
 
 #define W1_MAXNAMELEN		32
-#define W1_SLAVE_DATA_SIZE	128
 
 #define W1_SEARCH		0xF0
 #define W1_ALARM_SEARCH		0xEC
-- 
1.4.4.4

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

  parent reply	other threads:[~2008-03-28 13:02 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <200803272343.m2RNhDac017650@SpacedOut.fries.net>
2008-03-28 12:23 ` [PATCH 1/35] W1: fix deadlocks and remove w1_control_thread David Fries
2008-03-28 12:24 ` [PATCH 2/35] W1: abort search early on on exit David Fries
2008-03-28 12:24 ` [PATCH 3/35] W1: don't delay search start David Fries
2008-03-28 12:24 ` [PATCH 4/35] W1: w1_process, allow wakeup in sleep David Fries
2008-03-28 12:24 ` [PATCH 5/35] W1: w1_process, remove W1_MASTER_NEED_EXIT, it is redundant David Fries
2008-03-28 12:24 ` [PATCH 6/35] W1: w1_process, block when there's nothing to do David Fries
2008-03-30 11:28   ` Evgeniy Polyakov
2008-03-28 12:25 ` [PATCH 7/35] W1: feature, enable hardware strong pullup David Fries
2008-03-30 11:31   ` Evgeniy Polyakov
2008-03-28 12:25 ` [PATCH 8/35] W1: feature, w1_therm.c use " David Fries
2008-03-30 11:30   ` Evgeniy Polyakov
2008-03-28 12:25 ` [PATCH 9/35] W1: create documentation for the w1_therm slave device David Fries
2008-03-30 11:32   ` Evgeniy Polyakov
2008-03-28 12:25 ` [PATCH 10/35] W1: be able to manually add and remove slaves David Fries
2008-03-30 11:33   ` Evgeniy Polyakov
2008-03-28 12:25 ` [PATCH 11/35] W1: recode w1_slave_found logic David Fries
2008-03-28 12:25 ` [PATCH 12/35] W1: new module parameter search_count David Fries
2008-03-28 12:25 ` [PATCH 13/35] W1: Document add, remove, and search_count David Fries
2008-03-30 11:33   ` Evgeniy Polyakov
2008-03-28 12:25 ` [PATCH 14/35] W1: w1_slave_read_id multiple short read bug David Fries
2008-03-28 12:26 ` [PATCH 15/35] W1: w1_slave_read_id from bin_attribute to device_attribute David Fries
2008-03-28 12:26 ` David Fries [this message]
2008-03-30 11:34   ` [PATCH 16/35] W1: w1_therm fix user buffer overflow and cat Evgeniy Polyakov
2008-03-28 12:26 ` [PATCH 17/35] W1: w1_family, remove unused variable need_exit David Fries
2008-03-28 12:26 ` [PATCH 18/35] W1: w1_therm consistent mutex access code cleanup David Fries
2008-03-28 12:26 ` [PATCH 19/35] W1: w1_int.c use first available master number David Fries
2008-03-28 12:26 ` [PATCH 20/35] W1: w1.c s/printk/dev_dbg/ David Fries
2008-03-30 11:35   ` Evgeniy Polyakov
2008-03-28 12:26 ` [PATCH 21/35] W1: w1_io.c reset comments and msleep David Fries
2008-03-30 11:36   ` Evgeniy Polyakov
2008-03-28 12:27 ` [PATCH 22/35] W1: ds1wm.c msleep for reset David Fries
2008-03-30 11:38   ` Evgeniy Polyakov
2008-03-30 13:43     ` David Fries
2008-03-28 12:27 ` [PATCH 23/35] W1: ds2490.c correct print message David Fries
2008-03-28 12:27 ` [PATCH 24/35] W1: ds2490.c add support for strong pullup David Fries
2008-03-28 12:27 ` [PATCH 25/35] W1: ds2490.c fix grouping error in ds_write_bit David Fries
2008-03-28 12:27 ` [PATCH 26/35] W1: ds2490.c ds_write_bit disable readback David Fries
2008-03-28 12:27 ` [PATCH 27/35] W1: ds2490.c disable bit read and write David Fries
2008-03-28 12:27 ` [PATCH 28/35] W1: ds2490.c simplify and fix ds_touch_bit David Fries
2008-03-28 12:27 ` [PATCH 29/35] W1: ds2490.c ds_dump_status rework David Fries
2008-03-28 12:27 ` [PATCH 30/35] W1: ds2490.c ds_reset remove ds_wait_status David Fries
2008-03-28 12:27 ` [PATCH 31/35] W1: ds2490.c reset ds2490 in init David Fries
2008-03-28 12:27 ` [PATCH 32/35] W1: ds2490.c magic number work David Fries
2008-03-28 12:27 ` [PATCH 33/35] W1: ds2490.c ds_write_block remove extra ds_wait_status David Fries
2008-03-28 12:27 ` [PATCH 34/35] W1: Documentation/w1/masters/ds2490 update David Fries
2008-03-30 11:43   ` Evgeniy Polyakov
2008-04-13 23:09     ` David Fries
2008-03-28 12:28 ` [PATCH 35/35] W1: ds2490.c optimize ds_set_pullup David Fries

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080328122626.GQ3613@spacedout.fries.net \
    --to=david@fries.net \
    --cc=johnpol@2ka.mipt.ru \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®