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

Fixed NULL ptr deref in RTAS syscall ppc_rtas()


---

 25-akpm/arch/ppc64/kernel/rtas.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff -puN arch/ppc64/kernel/rtas.c~ppc64-rtas_syscall_fix arch/ppc64/kernel/rtas.c
--- 25/arch/ppc64/kernel/rtas.c~ppc64-rtas_syscall_fix	2004-03-14 15:35:13.895826096 -0800
+++ 25-akpm/arch/ppc64/kernel/rtas.c	2004-03-14 15:35:13.897825792 -0800
@@ -453,6 +453,7 @@ asmlinkage int ppc_rtas(struct rtas_args
 {
 	struct rtas_args args;
 	unsigned long flags;
+	int nargs;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -460,14 +461,15 @@ asmlinkage int ppc_rtas(struct rtas_args
 	if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
 		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.nargs + args.nret > ARRAY_SIZE(args.args))
+	    || nargs + args.nret > ARRAY_SIZE(args.args))
 		return -EINVAL;
 
 	/* Copy in args. */
 	if (copy_from_user(args.args, uargs->args,
-			   args.nargs * sizeof(rtas_arg_t)) != 0)
+			   nargs * sizeof(rtas_arg_t)) != 0)
 		return -EFAULT;
 
 	spin_lock_irqsave(&rtas.lock, flags);
@@ -476,14 +478,15 @@ asmlinkage int ppc_rtas(struct rtas_args
 	enter_rtas((void *)__pa((unsigned long)&get_paca()->xRtas));
 	args = get_paca()->xRtas;
 
+	args.rets  = (rtas_arg_t *)&(args.args[nargs]);
 	if (args.rets[0] == -1)
 		log_rtas_error(&args);
 
 	spin_unlock_irqrestore(&rtas.lock, flags);
 
 	/* Copy out args. */
-	if (copy_to_user(uargs->args + args.nargs,
-			 args.args + args.nargs,
+	if (copy_to_user(uargs->args + nargs,
+			 args.args + nargs,
 			 args.nret * sizeof(rtas_arg_t)) != 0)
 		return -EFAULT;
 

_