X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=fs%2Fcompat_ioctl.c;h=6b44cdc96facd51030d8798f68e3cf68aecc0d4e;hb=5dcccd8d7eae870d85c3f175fd0823d3da07d0e3;hp=6972d242fbdfa429836979a1ca10bff227c70c1d;hpb=6272e2667965dfb5b59199f462cd0f001fb304a6;p=safe%2Fjmp%2Flinux-2.6 diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 6972d24..6b44cdc 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -684,8 +684,10 @@ static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg) if (!err) { err = copy_to_user (ugeo, &geo, 4); err |= __put_user (geo.start, &ugeo->start); + if (err) + err = -EFAULT; } - return err ? -EFAULT : 0; + return err; } static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) @@ -1192,6 +1194,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; @@ -1202,12 +1205,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; } @@ -1308,16 +1315,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; } @@ -3564,10 +3583,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)