From: Chris Wright Fix a bug spotted by "Michael S. Tsirkin" Introduce a simple helper, vfs_ioctl(), so that both sys_ioctl() and compat_sys_ioctl() call the security hook in all cases and without duplication. Signed-off-by: Chris Wright Signed-off-by: Andrew Morton --- 25-akpm/fs/compat.c | 12 ++++++------ 25-akpm/fs/ioctl.c | 36 +++++++++++++++++++++++------------- 25-akpm/include/linux/fs.h | 2 ++ 3 files changed, 31 insertions(+), 19 deletions(-) diff -puN fs/compat.c~compat-ioctl-security-hook-fixup fs/compat.c --- 25/fs/compat.c~compat-ioctl-security-hook-fixup 2005-01-23 01:40:50.441060096 -0800 +++ 25-akpm/fs/compat.c 2005-01-23 01:40:50.449058880 -0800 @@ -439,6 +439,11 @@ asmlinkage long compat_sys_ioctl(unsigne if (!filp) goto out; + /* RED-PEN how should LSM module know it's handling 32bit? */ + error = security_file_ioctl(filp, cmd, arg); + if (error) + goto out_fput; + /* * To allow the compat_ioctl handlers to be self contained * we need to check the common ioctls here first. @@ -496,11 +501,6 @@ asmlinkage long compat_sys_ioctl(unsigne found_handler: if (t->handler) { - /* RED-PEN how should LSM module know it's handling 32bit? */ - error = security_file_ioctl(filp, cmd, arg); - if (error) - goto out_fput; - lock_kernel(); error = t->handler(fd, cmd, arg, filp); unlock_kernel(); @@ -510,7 +510,7 @@ asmlinkage long compat_sys_ioctl(unsigne up_read(&ioctl32_sem); do_ioctl: - error = sys_ioctl(fd, cmd, arg); + error = vfs_ioctl(filp, fd, cmd, arg); out_fput: fput_light(filp, fput_needed); out: diff -puN fs/ioctl.c~compat-ioctl-security-hook-fixup fs/ioctl.c --- 25/fs/ioctl.c~compat-ioctl-security-hook-fixup 2005-01-23 01:40:50.442059944 -0800 +++ 25-akpm/fs/ioctl.c 2005-01-23 01:40:50.448059032 -0800 @@ -77,25 +77,17 @@ static int file_ioctl(struct file *filp, return do_ioctl(filp, cmd, arg); } - /* * When you add any new common ioctls to the switches above and below * please update compat_sys_ioctl() too. + * + * vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. + * It's just a simple helper for sys_ioctl and compat_sys_ioctl. */ -asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +int vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg) { - struct file * filp; unsigned int flag; - int on, error = -EBADF; - int fput_needed; - - filp = fget_light(fd, &fput_needed); - if (!filp) - goto out; - - error = security_file_ioctl(filp, cmd, arg); - if (error) - goto out_fput; + int on, error = 0; switch (cmd) { case FIOCLEX: @@ -161,6 +153,24 @@ asmlinkage long sys_ioctl(unsigned int f error = do_ioctl(filp, cmd, arg); break; } + return error; +} + +asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + struct file * filp; + int error = -EBADF; + int fput_needed; + + filp = fget_light(fd, &fput_needed); + if (!filp) + goto out; + + error = security_file_ioctl(filp, cmd, arg); + if (error) + goto out_fput; + + error = vfs_ioctl(filp, fd, cmd, arg); out_fput: fput_light(filp, fput_needed); out: diff -puN include/linux/fs.h~compat-ioctl-security-hook-fixup include/linux/fs.h --- 25/include/linux/fs.h~compat-ioctl-security-hook-fixup 2005-01-23 01:40:50.445059488 -0800 +++ 25-akpm/include/linux/fs.h 2005-01-23 01:40:50.451058576 -0800 @@ -1566,6 +1566,8 @@ extern int vfs_stat(char __user *, struc extern int vfs_lstat(char __user *, struct kstat *); extern int vfs_fstat(unsigned int, struct kstat *); +extern int vfs_ioctl(struct file *, unsigned int, unsigned int, unsigned long); + extern struct file_system_type *get_fs_type(const char *name); extern struct super_block *get_super(struct block_device *); extern struct super_block *user_get_super(dev_t); _