aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorNathan Fontenot <nfont@austin.ibm.com>2008-07-30 12:23:27 -0400
committerPaul Mackerras <paulus@samba.org>2008-08-10 20:09:56 -0400
commitb79998fc2e1144919b6b02acbd407a5db1f80ac0 (patch)
treed35e2e7a3ece9c16a73d1fc7f9da00912469f06c /arch/powerpc
parent9ea7d5ad84d61a4e8b892d5ed12ccc26f9d6351b (diff)
powerpc: Zero fill the return values of rtas argument buffer
The kernel copy of the rtas args struct contains the return value(s) for the specified rtas call. These are copied back to user space with the assumption that every value has been set by the rtas call, which turns out to be not always true. Thus userspace can see random values and think the call failed when in fact it succeeded, but for some reason didn't set one of the return values. This fixes the problem by zeroing out the return value fields of the rtas args struct before processing the rtas call. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/rtas.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index c680f1bbd387..1f8505c23548 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -792,6 +792,9 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
792 if (args.token == RTAS_UNKNOWN_SERVICE) 792 if (args.token == RTAS_UNKNOWN_SERVICE)
793 return -EINVAL; 793 return -EINVAL;
794 794
795 args.rets = &args.args[nargs];
796 memset(args.rets, 0, args.nret * sizeof(rtas_arg_t));
797
795 /* Need to handle ibm,suspend_me call specially */ 798 /* Need to handle ibm,suspend_me call specially */
796 if (args.token == ibm_suspend_me_token) { 799 if (args.token == ibm_suspend_me_token) {
797 rc = rtas_ibm_suspend_me(&args); 800 rc = rtas_ibm_suspend_me(&args);
@@ -808,8 +811,6 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
808 enter_rtas(__pa(&rtas.args)); 811 enter_rtas(__pa(&rtas.args));
809 args = rtas.args; 812 args = rtas.args;
810 813
811 args.rets = &args.args[nargs];
812
813 /* A -1 return code indicates that the last command couldn't 814 /* A -1 return code indicates that the last command couldn't
814 be completed due to a hardware error. */ 815 be completed due to a hardware error. */
815 if (args.rets[0] == -1) 816 if (args.rets[0] == -1)