mtdchar.c: ioctl always returns 0 as size written for ppc64
PATCH 1/1 mtdchar.c: ioctl always returns 0 as size written for ppc64
"include/linux/mtd/mtd.h" declares "mtd_oob_ops.retlen" as size_t, which is 64 bits on targets with a 64 bit addressing. The MEMWRITEOOB ioctl calls copy_to_user() to write it back to "mtd_oob_buf.length", which is declared in "include/linux/mtd-abi.h" as uint32_t. Since powerpc is a big endian architecture, this only copies the upper 32 bits of the address, which is always 0.
Signed-off-by David Scidmore <dscidmore at xes-inc.com>
------
drivers/mtd/mtdchar.c +7 -2
@@ -483,6 +482,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, {struct mtd_oob_buf buf;struct mtd_oob_ops ops; +uint32_t retlen;if (!(file->f_mode &2 ))return -EPERM ;
@@ -522,8 +522,12 @@ static int mtd_ioctl(struct inode *inode, struct file *file, buf.start &= ~(mtd->oobsize -1 ); ret = mtd->write_oob (mtd, buf.start, &ops); -if (copy_to_user (argp +sizeof (uint32_t ), &ops.oobretlen, -sizeof (uint32_t ))) +if (ops.oobretlen >0xFFFFFFFFU ) + ret = -EOVERFLOW ; + retlen = ops.oobretlen; +if (copy_to_user (&((struct mtd_oob_buf *)argp)->length, + &retlen, +sizeof (buf.length))) ret = -EFAULT ;kfree (ops.oobbuf);
Signature · 5 lines
David Scidmore Quality Manager Extreme Engineering Solutions 608-833-1155 ext 101 www.xes-inc.com
drivers/mtd/mtdchar.c +7 -2
@@ -483,6 +482,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, {struct mtd_oob_buf buf;struct mtd_oob_ops ops; +uint32_t retlen;if (!(file->f_mode &2 ))return -EPERM ;
@@ -522,8 +522,12 @@ static int mtd_ioctl(struct inode *inode, struct file *file, buf.start &= ~(mtd->oobsize -1 ); ret = mtd->write_oob (mtd, buf.start, &ops); -if (copy_to_user (argp +sizeof (uint32_t ), &ops.oobretlen, -sizeof (uint32_t ))) +if (ops.oobretlen >0xFFFFFFFFU ) + ret = -EOVERFLOW ; + retlen = ops.oobretlen; +if (copy_to_user (&((struct mtd_oob_buf *)argp)->length, + &retlen, +sizeof (buf.length))) ret = -EFAULT ;kfree (ops.oobbuf);