From: Al Viro Date: Sun, 16 Mar 2008 22:22:44 +0000 (+0000) Subject: wan/farsync: copy_from_user() to iomem is wrong X-Git-Tag: v2.6.25-rc7~54^2~40 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=5ffa6d7f613ca0198dae235986443cd921fa2e75;p=linux-2.6-omap-h63xx.git wan/farsync: copy_from_user() to iomem is wrong kmalloc intermediate buffer(), do copy_from_user() + memcpy_toio() Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index cf27bf40d36..547368e9633 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 */