summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAl Viro <viro@ftp.linux.org.uk>2008-03-16 22:22:44 +0000
committerJeff Garzik <jeff@garzik.org>2008-03-17 07:56:29 -0400
commit5ffa6d7f613ca0198dae235986443cd921fa2e75 (patch)
treef91ae00e87f9adf78e9b0ad5f3f2e7fe1e49ea94 /drivers
parented773b4ab1387a25b3be027d45c94daae3c8a607 (diff)
downloadlinux-5ffa6d7f613ca0198dae235986443cd921fa2e75.tar.gz
linux-5ffa6d7f613ca0198dae235986443cd921fa2e75.tar.bz2
linux-5ffa6d7f613ca0198dae235986443cd921fa2e75.zip
wan/farsync: copy_from_user() to iomem is wrong
kmalloc intermediate buffer(), do copy_from_user() + memcpy_toio() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wan/farsync.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index cf27bf40d36e..547368e9633d 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -2024,6 +2024,7 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct fstioc_write wrthdr;
struct fstioc_info info;
unsigned long flags;
+ void *buf;
dbg(DBG_IOCTL, "ioctl: %x, %p\n", cmd, ifr->ifr_data);
@@ -2065,16 +2066,22 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -ENXIO;
}
- /* Now copy the data to the card.
- * This will probably break on some architectures.
- * I'll fix it when I have something to test on.
- */
- if (copy_from_user(card->mem + wrthdr.offset,
+ /* Now copy the data to the card. */
+
+ buf = kmalloc(wrthdr.size, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ if (copy_from_user(buf,
ifr->ifr_data + sizeof (struct fstioc_write),
wrthdr.size)) {
+ kfree(buf);
return -EFAULT;
}
+ memcpy_toio(card->mem + wrthdr.offset, buf, wrthdr.size);
+ kfree(buf);
+
/* Writes to the memory of a card in the reset state constitute
* a download
*/