From: John Rose 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; _