diff options
author | Al Viro <viro@ftp.linux.org.uk> | 2008-03-16 22:22:44 +0000 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-03-17 07:56:29 -0400 |
commit | 5ffa6d7f613ca0198dae235986443cd921fa2e75 (patch) | |
tree | f91ae00e87f9adf78e9b0ad5f3f2e7fe1e49ea94 | |
parent | ed773b4ab1387a25b3be027d45c94daae3c8a607 (diff) | |
download | op-kernel-dev-5ffa6d7f613ca0198dae235986443cd921fa2e75.zip op-kernel-dev-5ffa6d7f613ca0198dae235986443cd921fa2e75.tar.gz |
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>
-rw-r--r-- | drivers/net/wan/farsync.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index cf27bf4..547368e 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 */ |