X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=fs%2Fcompat_ioctl.c;h=e440a7b95d0275769f5f89124c69c39259785c2f;hb=1833633803c7ef4d8f09877d3f1549cbd252f477;hp=d92bc3eb7afcb33f398dbf35a3e4bc8f2c0c5393;hpb=83ae1b79c898838e16ac8cde69b39d22d36fb035;p=safe%2Fjmp%2Flinux-2.6 diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index d92bc3e..e440a7b 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include @@ -1194,6 +1195,7 @@ static int vt_check(struct file *file) { struct tty_struct *tty; struct inode *inode = file->f_path.dentry->d_inode; + struct vc_data *vc; if (file->f_op->ioctl != tty_ioctl) return -EINVAL; @@ -1204,12 +1206,16 @@ static int vt_check(struct file *file) if (tty->driver->ioctl != vt_ioctl) return -EINVAL; - + + vc = (struct vc_data *)tty->driver_data; + if (!vc_cons_allocated(vc->vc_num)) /* impossible? */ + return -ENOIOCTLCMD; + /* * To have permissions to do most of the vt ioctls, we either have - * to be the owner of the tty, or super-user. + * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG. */ - if (current->signal->tty == tty || capable(CAP_SYS_ADMIN)) + if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG)) return 1; return 0; } @@ -1310,16 +1316,28 @@ static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct unimapdesc32 tmp; struct unimapdesc32 __user *user_ud = compat_ptr(arg); int perm = vt_check(file); - - if (perm < 0) return perm; + struct vc_data *vc; + + if (perm < 0) + return perm; if (copy_from_user(&tmp, user_ud, sizeof tmp)) return -EFAULT; + if (tmp.entries) + if (!access_ok(VERIFY_WRITE, compat_ptr(tmp.entries), + tmp.entry_ct*sizeof(struct unipair))) + return -EFAULT; + vc = ((struct tty_struct *)file->private_data)->driver_data; switch (cmd) { case PIO_UNIMAP: - if (!perm) return -EPERM; - return con_set_unimap(vc_cons[fg_console].d, tmp.entry_ct, compat_ptr(tmp.entries)); + if (!perm) + return -EPERM; + return con_set_unimap(vc, tmp.entry_ct, + compat_ptr(tmp.entries)); case GIO_UNIMAP: - return con_get_unimap(vc_cons[fg_console].d, tmp.entry_ct, &(user_ud->entry_ct), compat_ptr(tmp.entries)); + if (!perm && fg_console != vc->vc_num) + return -EPERM; + return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), + compat_ptr(tmp.entries)); } return 0; } @@ -3472,6 +3490,9 @@ HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans) IGNORE_IOCTL(VFAT_IOCTL_READDIR_BOTH32) IGNORE_IOCTL(VFAT_IOCTL_READDIR_SHORT32) + +/* loop */ +IGNORE_IOCTL(LOOP_CLR_FD) }; #define IOCTL_HASHSIZE 256 @@ -3566,10 +3587,13 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, goto found_handler; } +#ifdef CONFIG_NET if (S_ISSOCK(filp->f_path.dentry->d_inode->i_mode) && cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { error = siocdevprivate_ioctl(fd, cmd, arg); - } else { + } else +#endif + { static int count; if (++count <= 50)