cleanup compat ioctl handling
Subsystems (3)
PATCH 1/1 cleanup compat ioctl handling
Merge all compat ioctl handling into compat_ioctl.c instead of splitting it over compat.c and compat_ioctl.c. This also allows to get rid of ioctl32.h
fs/compat.c +1 -160
@@ -24,10 +24,8 @@#include <linux/namei.h> #include <linux/file.h> #include <linux/vfs.h> -#include <linux/ioctl32.h> #include <linux/ioctl.h> #include <linux/init.h> -#include <linux/sockios.h> /* for SIOCDEVPRIVATE */ #include <linux/smb.h> #include <linux/smb_mount.h> #include <linux/ncp_mount.h>
@@ -45,13 +43,12 @@#include <linux/personality.h> #include <linux/rwsem.h> #include <linux/tsacct_kern.h> +#include <linux/security.h> #include <linux/highmem.h> #include <linux/poll.h> #include <linux/mm.h> #include <linux/eventpoll.h> -#include <net/sock.h> /* siocdevprivate_ioctl */ -#include <asm/uaccess.h> #include <asm/mmu_context.h> #include <asm/ioctls.h>
@@ -312,162 +309,6 @@ out:return error; } -/* ioctl32 stuff, used by sparc64, parisc, s390x, ppc64, x86_64, MIPS */ - -#define IOCTL_HASHSIZE 256 -static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE ]; - -static inline unsigned long ioctl32_hash (unsigned long cmd) -{ -return (((cmd >>6 ) ^ (cmd >>4 ) ^ cmd)) %IOCTL_HASHSIZE ; -} - -static void ioctl32_insert_translation (struct ioctl_trans *trans) -{ -unsigned long hash; -struct ioctl_trans *t; - - hash =ioctl32_hash (trans->cmd); -if (!ioctl32_hash_table[hash]) - ioctl32_hash_table[hash] = trans; -else { - t = ioctl32_hash_table[hash]; -while (t->next) - t = t->next; - trans->next =NULL ; - t->next = trans; - } -} - -static int __init init_sys32_ioctl (void ) -{ -int i; - -for (i =0 ; i < ioctl_table_size; i++) { -if (ioctl_start[i].next !=0 ) { -printk ("ioctl translation %d bad\n" ,i); -return -1 ; - } - -ioctl32_insert_translation (&ioctl_start[i]); - } -return 0 ; -} - -__initcall (init_sys32_ioctl); - -static void compat_ioctl_error (struct file *filp,unsigned int fd, -unsigned int cmd,unsigned long arg) -{ -char buf[10 ]; -char *fn ="?" ; -char *path; - -/* find the name of the device. */ - path = (char *)__get_free_page (GFP_KERNEL ); -if (path) { - fn =d_path (filp->f_path.dentry, filp->f_path.mnt, path,PAGE_SIZE ); -if (IS_ERR (fn)) - fn ="?" ; - } - -sprintf (buf,"'%c'" , (cmd>>24 ) &0x3f ); -if (!isprint (buf[1 ])) -sprintf (buf,"%02x" , buf[1 ]); -compat_printk ("ioctl32(%s:%d): Unknown cmd fd(%d) " -"cmd(%08x){%s} arg(%08x) on %s\n" , - current->comm, current->pid, - (int )fd, (unsigned int )cmd, buf, - (unsigned int )arg, fn); - -if (path) -free_page ((unsigned long )path); -} - -asmlinkage long compat_sys_ioctl (unsigned int fd,unsigned int cmd, -unsigned long arg) -{ -struct file *filp; -int error = -EBADF ; -struct ioctl_trans *t; -int fput_needed; - - filp =fget_light (fd, &fput_needed); -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. -* Just handle them with the standard handlers below. -*/ -switch (cmd) { -case FIOCLEX : -case FIONCLEX : -case FIONBIO : -case FIOASYNC : -case FIOQSIZE : -break ; - -case FIBMAP : -case FIGETBSZ : -case FIONREAD : -if (S_ISREG (filp->f_path.dentry->d_inode->i_mode)) -break ; -/*FALL THROUGH*/ - -default : -if (filp->f_op && filp->f_op->compat_ioctl) { - error = filp->f_op->compat_ioctl (filp, cmd, arg); -if (error != -ENOIOCTLCMD ) - goto out_fput; - } - -if (!filp->f_op || - (!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl)) - goto do_ioctl; -break ; - } - -for (t = ioctl32_hash_table[ioctl32_hash (cmd)]; t; t = t->next) { -if (t->cmd == cmd) - goto found_handler; - } - -if (S_ISSOCK (filp->f_path.dentry->d_inode->i_mode) && - cmd >=SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE +15 )) { - error =siocdevprivate_ioctl (fd, cmd, arg); - }else { -static int count; - -if (++count <=50 ) -compat_ioctl_error (filp, fd, cmd, arg); - error = -EINVAL ; - } - - goto out_fput; - - found_handler: -if (t->handler) { -lock_kernel (); - error = t->handler (fd, cmd, arg, filp); -unlock_kernel (); - goto out_fput; - } - - do_ioctl: - error =vfs_ioctl (filp, fd, cmd, arg); - out_fput: -fput_light (filp, fput_needed); - out: -return error; -} -static int get_compat_flock (struct flock *kfl,struct compat_flock __user *ufl) { if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) ||
fs/compat_ioctl.c +164 -5
202 lines not on this page · raw message
fs/internal.h +0 -10
@@ -9,8 +9,6 @@* 2 of the License, or (at your option) any later version. */ -#include <linux/ioctl32.h> -struct super_block ;/*
@@ -42,14 +40,6 @@ static inline int sb_is_blkdev_sb(structextern void __init chrdev_init (void );/* -* compat_ioctl.c -*/ -#ifdef CONFIG_COMPAT -extern struct ioctl_trans ioctl_start[]; -extern int ioctl_table_size; -#endif - -/* * namespace.c */ extern int copy_mount_options (const void __user *,unsigned long *);
include/linux/ioctl32.h deleted +0 -17
@@ -1,17 +0,0 @@ -#ifndef IOCTL32_H -#define IOCTL32_H 1 - -#include <linux/compiler.h> /* for __deprecated */ - -struct file ; - -typedef int (*ioctl_trans_handler_t )(unsigned int ,unsigned int , -unsigned long ,struct file *); - -struct ioctl_trans { -unsigned long cmd; -ioctl_trans_handler_t handler; -struct ioctl_trans *next; -}; - -#endif
include/net/sock.h +0 -9
@@ -1398,15 +1398,6 @@ static inline void sock_valbool_flag(strextern __u32 sysctl_wmem_max;extern __u32 sysctl_rmem_max; -#ifdef CONFIG_NET -int siocdevprivate_ioctl (unsigned int fd,unsigned int cmd,unsigned long arg); -#else -static inline int siocdevprivate_ioctl (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -return -ENODEV ; -} -#endif -extern void sk_init (void );#ifdef CONFIG_SYSCTL
Quoted 3 lines · Christoph Hellwig
Merge all compat ioctl handling into
compat_ioctl.cinstead of splitting it overcompat.candcompat_ioctl.c. This also allows to get rid ofioctl32.h
Looks good.
If someone feels the need to do more cleanup here -- it would be also nice to move more handlers to be in ->compat_ioctl and in their respective files than so much compat_ioctl.
-Andi
Quoted 11 lines · Andi Kleen
Quoted 3 lines · Christoph Hellwig
Merge all compat ioctl handling into
compat_ioctl.cinstead of splitting it overcompat.candcompat_ioctl.c. This also allows to get rid ofioctl32.hLooks good.
If someone feels the need to do more cleanup here -- it would be also nice to move more handlers to be in ->compat_ioctl and in their respective files than so much
compat_ioctl.
Arnd had a huge patch series for that that somehow got lost. It would be nice if someone with a little time on his hands could revive parts of it.