Commit c63aad69 authored by Al Viro's avatar Al Viro

vm86: get rid of get_user_ex() use

Just do a copyin of what we want into a local variable and
be done with that.  We are guaranteed to be on shallow stack
here...

Note that conditional expression for range passed to access_ok()
in mainline had been pointless all along - the only difference
between vm86plus_struct and vm86_struct is that the former has
one extra field in the end and when we get to copyin of that
field (conditional upon 'plus' argument), we use copy_from_user().
Moreover, all fields starting with ->int_revectored are copied
that way, so we only need that check (be it done by access_ok()
or by user_access_begin()) only on the beginning of the structure -
the fields that used to be covered by that get_user_try() block.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 4b842e4e
...@@ -243,6 +243,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus) ...@@ -243,6 +243,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
struct kernel_vm86_regs vm86regs; struct kernel_vm86_regs vm86regs;
struct pt_regs *regs = current_pt_regs(); struct pt_regs *regs = current_pt_regs();
unsigned long err = 0; unsigned long err = 0;
struct vm86_struct v;
err = security_mmap_addr(0); err = security_mmap_addr(0);
if (err) { if (err) {
...@@ -278,39 +279,32 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus) ...@@ -278,39 +279,32 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
if (vm86->saved_sp0) if (vm86->saved_sp0)
return -EPERM; return -EPERM;
if (!access_ok(user_vm86, plus ? if (copy_from_user(&v, user_vm86,
sizeof(struct vm86_struct) : offsetof(struct vm86_struct, int_revectored)))
sizeof(struct vm86plus_struct)))
return -EFAULT; return -EFAULT;
memset(&vm86regs, 0, sizeof(vm86regs)); memset(&vm86regs, 0, sizeof(vm86regs));
get_user_try {
unsigned short seg; vm86regs.pt.bx = v.regs.ebx;
get_user_ex(vm86regs.pt.bx, &user_vm86->regs.ebx); vm86regs.pt.cx = v.regs.ecx;
get_user_ex(vm86regs.pt.cx, &user_vm86->regs.ecx); vm86regs.pt.dx = v.regs.edx;
get_user_ex(vm86regs.pt.dx, &user_vm86->regs.edx); vm86regs.pt.si = v.regs.esi;
get_user_ex(vm86regs.pt.si, &user_vm86->regs.esi); vm86regs.pt.di = v.regs.edi;
get_user_ex(vm86regs.pt.di, &user_vm86->regs.edi); vm86regs.pt.bp = v.regs.ebp;
get_user_ex(vm86regs.pt.bp, &user_vm86->regs.ebp); vm86regs.pt.ax = v.regs.eax;
get_user_ex(vm86regs.pt.ax, &user_vm86->regs.eax); vm86regs.pt.ip = v.regs.eip;
get_user_ex(vm86regs.pt.ip, &user_vm86->regs.eip); vm86regs.pt.cs = v.regs.cs;
get_user_ex(seg, &user_vm86->regs.cs); vm86regs.pt.flags = v.regs.eflags;
vm86regs.pt.cs = seg; vm86regs.pt.sp = v.regs.esp;
get_user_ex(vm86regs.pt.flags, &user_vm86->regs.eflags); vm86regs.pt.ss = v.regs.ss;
get_user_ex(vm86regs.pt.sp, &user_vm86->regs.esp); vm86regs.es = v.regs.es;
get_user_ex(seg, &user_vm86->regs.ss); vm86regs.ds = v.regs.ds;
vm86regs.pt.ss = seg; vm86regs.fs = v.regs.fs;
get_user_ex(vm86regs.es, &user_vm86->regs.es); vm86regs.gs = v.regs.gs;
get_user_ex(vm86regs.ds, &user_vm86->regs.ds);
get_user_ex(vm86regs.fs, &user_vm86->regs.fs); vm86->flags = v.flags;
get_user_ex(vm86regs.gs, &user_vm86->regs.gs); vm86->screen_bitmap = v.screen_bitmap;
vm86->cpu_type = v.cpu_type;
get_user_ex(vm86->flags, &user_vm86->flags);
get_user_ex(vm86->screen_bitmap, &user_vm86->screen_bitmap);
get_user_ex(vm86->cpu_type, &user_vm86->cpu_type);
} get_user_catch(err);
if (err)
return err;
if (copy_from_user(&vm86->int_revectored, if (copy_from_user(&vm86->int_revectored,
&user_vm86->int_revectored, &user_vm86->int_revectored,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment