diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-09-29 18:34:13 +0200 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-09-29 18:36:26 +0200 |
commit | 1b3bce4d6bf839304a90951b4b25a5863533bf2a (patch) | |
tree | 42fb1b8c3a0404857f6c3e4c156500d6ab314dbc /drivers/tty | |
parent | i2c compat ioctls: move to ->compat_ioctl() (diff) | |
download | linux-1b3bce4d6bf839304a90951b4b25a5863533bf2a.tar.xz linux-1b3bce4d6bf839304a90951b4b25a5863533bf2a.zip |
VT_RESIZEX: get rid of field-by-field copyin
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/vt/vt_ioctl.c | 68 |
1 files changed, 27 insertions, 41 deletions
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 96d389cb506c..89afc960851e 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -842,58 +842,44 @@ int vt_ioctl(struct tty_struct *tty, case VT_RESIZEX: { - struct vt_consize __user *vtconsize = up; - ushort ll,cc,vlin,clin,vcol,ccol; + struct vt_consize v; if (!perm) return -EPERM; - if (!access_ok(VERIFY_READ, vtconsize, - sizeof(struct vt_consize))) { - ret = -EFAULT; - break; - } + if (copy_from_user(&v, up, sizeof(struct vt_consize))) + return -EFAULT; /* FIXME: Should check the copies properly */ - __get_user(ll, &vtconsize->v_rows); - __get_user(cc, &vtconsize->v_cols); - __get_user(vlin, &vtconsize->v_vlin); - __get_user(clin, &vtconsize->v_clin); - __get_user(vcol, &vtconsize->v_vcol); - __get_user(ccol, &vtconsize->v_ccol); - vlin = vlin ? vlin : vc->vc_scan_lines; - if (clin) { - if (ll) { - if (ll != vlin/clin) { - /* Parameters don't add up */ - ret = -EINVAL; - break; - } - } else - ll = vlin/clin; + if (!v.v_vlin) + v.v_vlin = vc->vc_scan_lines; + if (v.v_clin) { + int rows = v.v_vlin/v.v_clin; + if (v.v_rows != rows) { + if (v.v_rows) /* Parameters don't add up */ + return -EINVAL; + v.v_rows = rows; + } } - if (vcol && ccol) { - if (cc) { - if (cc != vcol/ccol) { - ret = -EINVAL; - break; - } - } else - cc = vcol/ccol; + if (v.v_vcol && v.v_ccol) { + int cols = v.v_vcol/v.v_ccol; + if (v.v_cols != cols) { + if (v.v_cols) + return -EINVAL; + v.v_cols = cols; + } } - if (clin > 32) { - ret = -EINVAL; - break; - } - + if (v.v_clin > 32) + return -EINVAL; + for (i = 0; i < MAX_NR_CONSOLES; i++) { if (!vc_cons[i].d) continue; console_lock(); - if (vlin) - vc_cons[i].d->vc_scan_lines = vlin; - if (clin) - vc_cons[i].d->vc_font.height = clin; + if (v.v_vlin) + vc_cons[i].d->vc_scan_lines = v.v_vlin; + if (v.v_clin) + vc_cons[i].d->vc_font.height = v.v_clin; vc_cons[i].d->vc_resize_user = 1; - vc_resize(vc_cons[i].d, cc, ll); + vc_resize(vc_cons[i].d, v.v_cols, v.v_rows); console_unlock(); } break; |