diff options
Diffstat (limited to 'fs/compat_ioctl.c')
| -rw-r--r-- | fs/compat_ioctl.c | 104 | 
1 files changed, 42 insertions, 62 deletions
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 410ed188faa..e8228904727 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -19,7 +19,6 @@  #include <linux/compiler.h>  #include <linux/sched.h>  #include <linux/smp.h> -#include <linux/smp_lock.h>  #include <linux/ioctl.h>  #include <linux/if.h>  #include <linux/if_bridge.h> @@ -35,7 +34,7 @@  #include <linux/fs.h>  #include <linux/file.h>  #include <linux/ppp_defs.h> -#include <linux/if_ppp.h> +#include <linux/ppp-ioctl.h>  #include <linux/if_pppox.h>  #include <linux/mtio.h>  #include <linux/auto_fs.h> @@ -43,14 +42,13 @@  #include <linux/tty.h>  #include <linux/vt_kern.h>  #include <linux/fb.h> -#include <linux/videodev.h> +#include <linux/videodev2.h>  #include <linux/netdevice.h>  #include <linux/raw.h>  #include <linux/blkdev.h>  #include <linux/elevator.h>  #include <linux/rtc.h>  #include <linux/pci.h> -#include <linux/module.h>  #include <linux/serial.h>  #include <linux/if_tun.h>  #include <linux/ctype.h> @@ -68,7 +66,8 @@  #include <linux/gigaset_dev.h>  #ifdef CONFIG_BLOCK -#include <linux/loop.h> +#include <linux/cdrom.h> +#include <linux/fd.h>  #include <scsi/scsi.h>  #include <scsi/scsi_ioctl.h>  #include <scsi/sg.h> @@ -104,6 +103,7 @@  #include <linux/hiddev.h> +#define __DVB_CORE__  #include <linux/dvb/audio.h>  #include <linux/dvb/dmx.h>  #include <linux/dvb/frontend.h> @@ -209,6 +209,8 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd,  	err  = get_user(palp, &up->palette);  	err |= get_user(length, &up->length); +	if (err) +		return -EFAULT;  	up_native = compat_alloc_user_space(sizeof(struct video_spu_palette));  	err  = put_user(compat_ptr(palp), &up_native->palette); @@ -605,7 +607,6 @@ struct serial_struct32 {  static int serial_struct_ioctl(unsigned fd, unsigned cmd,  			struct serial_struct32 __user *ss32)  { -        typedef struct serial_struct SS;          typedef struct serial_struct32 SS32;          int err;          struct serial_struct ss; @@ -679,7 +680,8 @@ static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd,  	struct i2c_msg			__user *tmsgs;  	struct i2c_msg32		__user *umsgs;  	compat_caddr_t			datap; -	int				nmsgs, i; +	u32				nmsgs; +	int				i;  	if (get_user(nmsgs, &udata->nmsgs))  		return -EFAULT; @@ -837,9 +839,13 @@ COMPATIBLE_IOCTL(TCSETSW)  COMPATIBLE_IOCTL(TCSETSF)  COMPATIBLE_IOCTL(TIOCLINUX)  COMPATIBLE_IOCTL(TIOCSBRK) +COMPATIBLE_IOCTL(TIOCGDEV)  COMPATIBLE_IOCTL(TIOCCBRK)  COMPATIBLE_IOCTL(TIOCGSID)  COMPATIBLE_IOCTL(TIOCGICOUNT) +COMPATIBLE_IOCTL(TIOCGPKT) +COMPATIBLE_IOCTL(TIOCGPTLCK) +COMPATIBLE_IOCTL(TIOCGEXCL)  /* Little t */  COMPATIBLE_IOCTL(TIOCGETD)  COMPATIBLE_IOCTL(TIOCSETD) @@ -864,6 +870,12 @@ COMPATIBLE_IOCTL(TIOCGPTN)  COMPATIBLE_IOCTL(TIOCSPTLCK)  COMPATIBLE_IOCTL(TIOCSERGETLSR)  COMPATIBLE_IOCTL(TIOCSIG) +#ifdef TIOCSRS485 +COMPATIBLE_IOCTL(TIOCSRS485) +#endif +#ifdef TIOCGRS485 +COMPATIBLE_IOCTL(TIOCGRS485) +#endif  #ifdef TCGETS2  COMPATIBLE_IOCTL(TCGETS2)  COMPATIBLE_IOCTL(TCSETS2) @@ -895,6 +907,8 @@ COMPATIBLE_IOCTL(KDGKBSENT)  COMPATIBLE_IOCTL(KDSKBSENT)  COMPATIBLE_IOCTL(KDGKBDIACR)  COMPATIBLE_IOCTL(KDSKBDIACR) +COMPATIBLE_IOCTL(KDGKBDIACRUC) +COMPATIBLE_IOCTL(KDSKBDIACRUC)  COMPATIBLE_IOCTL(KDKBDREP)  COMPATIBLE_IOCTL(KDGKBLED)  COMPATIBLE_IOCTL(KDGETLED) @@ -940,10 +954,11 @@ COMPATIBLE_IOCTL(MTIOCTOP)  /* Socket level stuff */  COMPATIBLE_IOCTL(FIOQSIZE)  #ifdef CONFIG_BLOCK -/* loop */ -IGNORE_IOCTL(LOOP_CLR_FD)  /* md calls this on random blockdevs */  IGNORE_IOCTL(RAID_VERSION) +/* qemu/qemu-img might call these two on plain files for probing */ +IGNORE_IOCTL(CDROM_DRIVE_STATUS) +IGNORE_IOCTL(FDGETPRM32)  /* SG stuff */  COMPATIBLE_IOCTL(SG_SET_TIMEOUT)  COMPATIBLE_IOCTL(SG_GET_TIMEOUT) @@ -998,6 +1013,7 @@ COMPATIBLE_IOCTL(PPPIOCCONNECT)  COMPATIBLE_IOCTL(PPPIOCDISCONN)  COMPATIBLE_IOCTL(PPPIOCATTCHAN)  COMPATIBLE_IOCTL(PPPIOCGCHAN) +COMPATIBLE_IOCTL(PPPIOCGL2TPSTATS)  /* PPPOX */  COMPATIBLE_IOCTL(PPPOEIOCSFWD)  COMPATIBLE_IOCTL(PPPOEIOCDFWD) @@ -1500,35 +1516,6 @@ static long do_ioctl_trans(int fd, unsigned int cmd,  	return -ENOIOCTLCMD;  } -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, path, PAGE_SIZE); -		if (IS_ERR(fn)) -			fn = "?"; -	} - -	 sprintf(buf,"'%c'", (cmd>>_IOC_TYPESHIFT) & _IOC_TYPEMASK); -	if (!isprint(buf[1])) -		sprintf(buf, "%02x", buf[1]); -	compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) " -			"cmd(%08x){t:%s;sz:%u} arg(%08x) on %s\n", -			current->comm, current->pid, -			(int)fd, (unsigned int)cmd, buf, -			(cmd >> _IOC_SIZESHIFT) & _IOC_SIZEMASK, -			(unsigned int)arg, fn); - -	if (path) -		free_page((unsigned long)path); -} -  static int compat_ioctl_check_table(unsigned int xcmd)  {  	int i; @@ -1551,19 +1538,17 @@ static int compat_ioctl_check_table(unsigned int xcmd)  	return ioctl_pointer[i] == xcmd;  } -asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, -				unsigned long arg) +COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, +		       compat_ulong_t, arg32)  { -	struct file *filp; +	unsigned long arg = arg32; +	struct fd f = fdget(fd);  	int error = -EBADF; -	int fput_needed; - -	filp = fget_light(fd, &fput_needed); -	if (!filp) +	if (!f.file)  		goto out;  	/* RED-PEN how should LSM module know it's handling 32bit? */ -	error = security_file_ioctl(filp, cmd, arg); +	error = security_file_ioctl(f.file, cmd, arg);  	if (error)  		goto out_fput; @@ -1583,30 +1568,30 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,  #if defined(CONFIG_IA64) || defined(CONFIG_X86_64)  	case FS_IOC_RESVSP_32:  	case FS_IOC_RESVSP64_32: -		error = compat_ioctl_preallocate(filp, compat_ptr(arg)); +		error = compat_ioctl_preallocate(f.file, compat_ptr(arg));  		goto out_fput;  #else  	case FS_IOC_RESVSP:  	case FS_IOC_RESVSP64: -		error = ioctl_preallocate(filp, compat_ptr(arg)); +		error = ioctl_preallocate(f.file, compat_ptr(arg));  		goto out_fput;  #endif  	case FIBMAP:  	case FIGETBSZ:  	case FIONREAD: -		if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) +		if (S_ISREG(file_inode(f.file)->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 (f.file->f_op->compat_ioctl) { +			error = f.file->f_op->compat_ioctl(f.file, cmd, arg);  			if (error != -ENOIOCTLCMD)  				goto out_fput;  		} -		if (!filp->f_op || !filp->f_op->unlocked_ioctl) +		if (!f.file->f_op->unlocked_ioctl)  			goto do_ioctl;  		break;  	} @@ -1614,23 +1599,18 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,  	if (compat_ioctl_check_table(XFORM(cmd)))  		goto found_handler; -	error = do_ioctl_trans(fd, cmd, arg, filp); -	if (error == -ENOIOCTLCMD) { -		static int count; - -		if (++count <= 50) -			compat_ioctl_error(filp, fd, cmd, arg); -		error = -EINVAL; -	} +	error = do_ioctl_trans(fd, cmd, arg, f.file); +	if (error == -ENOIOCTLCMD) +		error = -ENOTTY;  	goto out_fput;   found_handler:  	arg = (unsigned long)compat_ptr(arg);   do_ioctl: -	error = do_vfs_ioctl(filp, fd, cmd, arg); +	error = do_vfs_ioctl(f.file, fd, cmd, arg);   out_fput: -	fput_light(filp, fput_needed); +	fdput(f);   out:  	return error;  }  | 
