aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/rtas.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/rtas.c')
-rw-r--r--arch/powerpc/kernel/rtas.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 4cf674d7d5ae..f386296ff378 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -1013,12 +1013,13 @@ struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
1013 return NULL; 1013 return NULL;
1014} 1014}
1015 1015
1016/* We assume to be passed big endian arguments */
1016asmlinkage int ppc_rtas(struct rtas_args __user *uargs) 1017asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1017{ 1018{
1018 struct rtas_args args; 1019 struct rtas_args args;
1019 unsigned long flags; 1020 unsigned long flags;
1020 char *buff_copy, *errbuf = NULL; 1021 char *buff_copy, *errbuf = NULL;
1021 int nargs; 1022 int nargs, nret, token;
1022 int rc; 1023 int rc;
1023 1024
1024 if (!capable(CAP_SYS_ADMIN)) 1025 if (!capable(CAP_SYS_ADMIN))
@@ -1027,10 +1028,13 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1027 if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0) 1028 if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
1028 return -EFAULT; 1029 return -EFAULT;
1029 1030
1030 nargs = args.nargs; 1031 nargs = be32_to_cpu(args.nargs);
1032 nret = be32_to_cpu(args.nret);
1033 token = be32_to_cpu(args.token);
1034
1031 if (nargs > ARRAY_SIZE(args.args) 1035 if (nargs > ARRAY_SIZE(args.args)
1032 || args.nret > ARRAY_SIZE(args.args) 1036 || nret > ARRAY_SIZE(args.args)
1033 || nargs + args.nret > ARRAY_SIZE(args.args)) 1037 || nargs + nret > ARRAY_SIZE(args.args))
1034 return -EINVAL; 1038 return -EINVAL;
1035 1039
1036 /* Copy in args. */ 1040 /* Copy in args. */
@@ -1038,14 +1042,14 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1038 nargs * sizeof(rtas_arg_t)) != 0) 1042 nargs * sizeof(rtas_arg_t)) != 0)
1039 return -EFAULT; 1043 return -EFAULT;
1040 1044
1041 if (args.token == RTAS_UNKNOWN_SERVICE) 1045 if (token == RTAS_UNKNOWN_SERVICE)
1042 return -EINVAL; 1046 return -EINVAL;
1043 1047
1044 args.rets = &args.args[nargs]; 1048 args.rets = &args.args[nargs];
1045 memset(args.rets, 0, args.nret * sizeof(rtas_arg_t)); 1049 memset(args.rets, 0, nret * sizeof(rtas_arg_t));
1046 1050
1047 /* Need to handle ibm,suspend_me call specially */ 1051 /* Need to handle ibm,suspend_me call specially */
1048 if (args.token == ibm_suspend_me_token) { 1052 if (token == ibm_suspend_me_token) {
1049 rc = rtas_ibm_suspend_me(&args); 1053 rc = rtas_ibm_suspend_me(&args);
1050 if (rc) 1054 if (rc)
1051 return rc; 1055 return rc;
@@ -1062,7 +1066,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1062 1066
1063 /* A -1 return code indicates that the last command couldn't 1067 /* A -1 return code indicates that the last command couldn't
1064 be completed due to a hardware error. */ 1068 be completed due to a hardware error. */
1065 if (args.rets[0] == -1) 1069 if (be32_to_cpu(args.rets[0]) == -1)
1066 errbuf = __fetch_rtas_last_error(buff_copy); 1070 errbuf = __fetch_rtas_last_error(buff_copy);
1067 1071
1068 unlock_rtas(flags); 1072 unlock_rtas(flags);
@@ -1077,7 +1081,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1077 /* Copy out args. */ 1081 /* Copy out args. */
1078 if (copy_to_user(uargs->args + nargs, 1082 if (copy_to_user(uargs->args + nargs,
1079 args.args + nargs, 1083 args.args + nargs,
1080 args.nret * sizeof(rtas_arg_t)) != 0) 1084 nret * sizeof(rtas_arg_t)) != 0)
1081 return -EFAULT; 1085 return -EFAULT;
1082 1086
1083 return 0; 1087 return 0;