Commit 98102bc1 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Fixed NULL ptr deref in RTAS syscall ppc_rtas()

From: John Rose <johnrose@austin.ibm.com>

Fixed NULL ptr deref in RTAS syscall ppc_rtas()
parent e1297b96
...@@ -453,6 +453,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) ...@@ -453,6 +453,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
{ {
struct rtas_args args; struct rtas_args args;
unsigned long flags; unsigned long flags;
int nargs;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
...@@ -460,14 +461,15 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) ...@@ -460,14 +461,15 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0) if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
return -EFAULT; return -EFAULT;
if (args.nargs > ARRAY_SIZE(args.args) nargs = args.nargs;
if (nargs > ARRAY_SIZE(args.args)
|| args.nret > ARRAY_SIZE(args.args) || args.nret > ARRAY_SIZE(args.args)
|| args.nargs + args.nret > ARRAY_SIZE(args.args)) || nargs + args.nret > ARRAY_SIZE(args.args))
return -EINVAL; return -EINVAL;
/* Copy in args. */ /* Copy in args. */
if (copy_from_user(args.args, uargs->args, if (copy_from_user(args.args, uargs->args,
args.nargs * sizeof(rtas_arg_t)) != 0) nargs * sizeof(rtas_arg_t)) != 0)
return -EFAULT; return -EFAULT;
spin_lock_irqsave(&rtas.lock, flags); spin_lock_irqsave(&rtas.lock, flags);
...@@ -476,14 +478,15 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) ...@@ -476,14 +478,15 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
enter_rtas((void *)__pa((unsigned long)&get_paca()->xRtas)); enter_rtas((void *)__pa((unsigned long)&get_paca()->xRtas));
args = get_paca()->xRtas; args = get_paca()->xRtas;
args.rets = (rtas_arg_t *)&(args.args[nargs]);
if (args.rets[0] == -1) if (args.rets[0] == -1)
log_rtas_error(&args); log_rtas_error(&args);
spin_unlock_irqrestore(&rtas.lock, flags); spin_unlock_irqrestore(&rtas.lock, flags);
/* Copy out args. */ /* Copy out args. */
if (copy_to_user(uargs->args + args.nargs, if (copy_to_user(uargs->args + nargs,
args.args + args.nargs, args.args + nargs,
args.nret * sizeof(rtas_arg_t)) != 0) args.nret * sizeof(rtas_arg_t)) != 0)
return -EFAULT; return -EFAULT;
......
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