
From: Manuel Estrada Sainz <ranty@debian.org>

- undo recent change, made in the believe that "buffer" was the size of
  the whole file, it is just PAGE_SIZE in size.  This was causing kernel
  memory corruption.

  - Since files are allowed to have unknown sizes, by setting their
    size to 0, we can't preallocate a buffer of their size on open.

- Adapt request_firmware() to the sysfs change.

- Adapt drivers/pci/pci-sysfs.c to the sysfs change.



 drivers/base/firmware_class.c |    4 ++--
 drivers/pci/pci-sysfs.c       |   26 ++++++++++++++------------
 fs/sysfs/bin.c                |    4 ++--
 3 files changed, 18 insertions(+), 16 deletions(-)

diff -puN drivers/base/firmware_class.c~sysfs-bin-unbreak-3 drivers/base/firmware_class.c
--- 25/drivers/base/firmware_class.c~sysfs-bin-unbreak-3	2003-08-10 19:42:56.000000000 -0700
+++ 25-akpm/drivers/base/firmware_class.c	2003-08-10 19:42:56.000000000 -0700
@@ -149,7 +149,7 @@ firmware_data_read(struct kobject *kobj,
 	if (offset + count > fw->size)
 		count = fw->size - offset;
 
-	memcpy(buffer + offset, fw->data + offset, count);
+	memcpy(buffer, fw->data + offset, count);
 	return count;
 }
 static int
@@ -198,7 +198,7 @@ firmware_data_write(struct kobject *kobj
 	if (retval)
 		return retval;
 
-	memcpy(fw->data + offset, buffer + offset, count);
+	memcpy(fw->data + offset, buffer, count);
 
 	fw->size = max_t(size_t, offset + count, fw->size);
 
diff -puN drivers/pci/pci-sysfs.c~sysfs-bin-unbreak-3 drivers/pci/pci-sysfs.c
--- 25/drivers/pci/pci-sysfs.c~sysfs-bin-unbreak-3	2003-08-10 19:42:56.000000000 -0700
+++ 25-akpm/drivers/pci/pci-sysfs.c	2003-08-10 19:42:56.000000000 -0700
@@ -67,6 +67,7 @@ pci_read_config(struct kobject *kobj, ch
 {
 	struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
 	unsigned int size = 64;
+	loff_t init_off = off;
 
 	/* Several chips lock up trying to read undefined config space */
 	if (capable(CAP_SYS_ADMIN)) {
@@ -87,7 +88,7 @@ pci_read_config(struct kobject *kobj, ch
 	while (off & 3) {
 		unsigned char val;
 		pci_read_config_byte(dev, off, &val);
-		buf[off] = val;
+		buf[off - init_off] = val;
 		off++;
 		if (--size == 0)
 			break;
@@ -96,10 +97,10 @@ pci_read_config(struct kobject *kobj, ch
 	while (size > 3) {
 		unsigned int val;
 		pci_read_config_dword(dev, off, &val);
-		buf[off] = val & 0xff;
-		buf[off + 1] = (val >> 8) & 0xff;
-		buf[off + 2] = (val >> 16) & 0xff;
-		buf[off + 3] = (val >> 24) & 0xff;
+		buf[off - init_off] = val & 0xff;
+		buf[off - init_off + 1] = (val >> 8) & 0xff;
+		buf[off - init_off + 2] = (val >> 16) & 0xff;
+		buf[off - init_off + 3] = (val >> 24) & 0xff;
 		off += 4;
 		size -= 4;
 	}
@@ -107,7 +108,7 @@ pci_read_config(struct kobject *kobj, ch
 	while (size > 0) {
 		unsigned char val;
 		pci_read_config_byte(dev, off, &val);
-		buf[off] = val;
+		buf[off - init_off] = val;
 		off++;
 		--size;
 	}
@@ -120,6 +121,7 @@ pci_write_config(struct kobject *kobj, c
 {
 	struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
 	unsigned int size = count;
+	loff_t init_off = off;
 
 	if (off > 256)
 		return 0;
@@ -129,24 +131,24 @@ pci_write_config(struct kobject *kobj, c
 	}
 
 	while (off & 3) {
-		pci_write_config_byte(dev, off, buf[off]);
+		pci_write_config_byte(dev, off, buf[off - init_off]);
 		off++;
 		if (--size == 0)
 			break;
 	}
 
 	while (size > 3) {
-		unsigned int val = buf[off];
-		val |= (unsigned int) buf[off + 1] << 8;
-		val |= (unsigned int) buf[off + 2] << 16;
-		val |= (unsigned int) buf[off + 3] << 24;
+		unsigned int val = buf[off - init_off];
+		val |= (unsigned int) buf[off - init_off + 1] << 8;
+		val |= (unsigned int) buf[off - init_off + 2] << 16;
+		val |= (unsigned int) buf[off - init_off + 3] << 24;
 		pci_write_config_dword(dev, off, val);
 		off += 4;
 		size -= 4;
 	}
 
 	while (size > 0) {
-		pci_write_config_byte(dev, off, buf[off]);
+		pci_write_config_byte(dev, off, buf[off - init_off]);
 		off++;
 		--size;
 	}
diff -puN fs/sysfs/bin.c~sysfs-bin-unbreak-3 fs/sysfs/bin.c
--- 25/fs/sysfs/bin.c~sysfs-bin-unbreak-3	2003-08-10 19:42:56.000000000 -0700
+++ 25-akpm/fs/sysfs/bin.c	2003-08-10 19:42:56.000000000 -0700
@@ -47,7 +47,7 @@ read(struct file * file, char __user * u
 		return ret;
 	count = ret;
 
-	if (copy_to_user(userbuf, buffer + offs, count))
+	if (copy_to_user(userbuf, buffer, count))
 		return -EFAULT;
 
 	pr_debug("offs = %lld, *off = %lld, count = %zd\n", offs, *off, count);
@@ -83,7 +83,7 @@ static ssize_t write(struct file * file,
 			count = size - offs;
 	}
 
-	if (copy_from_user(buffer + offs, userbuf, count))
+	if (copy_from_user(buffer, userbuf, count))
 		return -EFAULT;
 
 	count = flush_write(dentry, buffer, offs, count);

_
