From 68f66feb300423bb9ee5daecb1951af394425a38 Mon Sep 17 00:00:00 2001 From: Stephen Tweedie Date: Fri, 13 May 2005 23:31:19 -0400 Subject: [PATCH] Fix root hole in raw device [Patch] Fix raw device ioctl pass-through Raw character devices are supposed to pass ioctls through to the block devices they are bound to. Unfortunately, they are using the wrong function for this: ioctl_by_bdev(), instead of blkdev_ioctl(). ioctl_by_bdev() performs a set_fs(KERNEL_DS) before calling the ioctl, redirecting the user-space buffer access to the kernel address space. This is, needless to say, a bad thing. This was noticed first on s390, where raw IO was non-functioning. The s390 driver config does not actually allow raw IO to be enabled, which was the first part of the problem. Secondly, the s390 kernel address space is distinct from user, causing legal raw ioctls to fail. I've reproduced this on a kernel built with 4G:4G split on x86, which fails in the same way (-EFAULT if the address does not exist kernel-side; returns success without actually populating the user buffer if it does.) The patch below fixes both the config and address-space problems. It's based closely on a patch by Jan Glauber , which has been tested on s390 at IBM. I've tested it on x86 4G:4G (split address space) and x86_64 (common address space). Kernel-address-space access has been assigned CAN-2005-1264. Signed-off-by: Stephen Tweedie Signed-off-by: Dave Jones Signed-off-by: Greg Kroah-Hartman --- drivers/char/raw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char/raw.c') diff --git a/drivers/char/raw.c b/drivers/char/raw.c index a2e33ec79615..131465e8de5a 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -122,7 +122,7 @@ raw_ioctl(struct inode *inode, struct file *filp, { struct block_device *bdev = filp->private_data; - return ioctl_by_bdev(bdev, command, arg); + return blkdev_ioctl(bdev->bd_inode, filp, command, arg); } static void bind_device(struct raw_config_request *rq) -- cgit v1.2.2 From e72022e13d659bece2fc9cb2dd97afa67047dbca Mon Sep 17 00:00:00 2001 From: Stephen Tweedie Date: Wed, 18 May 2005 11:22:31 -0400 Subject: [PATCH] Fix filp being passed through raw ioctl handler Don't pass meaningless file handles to block device ioctls. The recent raw IO ioctl-passthrough fix started passing the raw file handle into the block device ioctl handler. That's unlikely to be useful, as the file handle is actually open on a character-mode raw device, not a block device, so dereferencing it is not going to yield useful results to a block device ioctl handler. Previously we just passed NULL; also not a value that can usefully be dereferenced, but at least if it does happen, we'll oops instead of silently pretending that the file is a block device, so NULL is the more defensive option here. This patch reverts to that behaviour. Noticed by Al Viro. Signed-off-by: Stephen Tweedie Acked-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/char/raw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char/raw.c') diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 131465e8de5a..ca5f42bcaad9 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -122,7 +122,7 @@ raw_ioctl(struct inode *inode, struct file *filp, { struct block_device *bdev = filp->private_data; - return blkdev_ioctl(bdev->bd_inode, filp, command, arg); + return blkdev_ioctl(bdev->bd_inode, NULL, command, arg); } static void bind_device(struct raw_config_request *rq) -- cgit v1.2.2