summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
diff options
context:
space:
mode:
authorThomas Fleury <tfleury@nvidia.com>2016-10-28 20:11:36 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2016-12-07 18:01:18 -0500
commitb6411b02908b4f8ccf0ee754ea250c01ecb3f400 (patch)
tree2f197aa4eb2310e9e5f911780107cf1adb7c8ced /drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
parent60a9fcb467a631b3631dbd6058b036223d6d89a3 (diff)
gpu: nvgpu: check untrusted num_entries for clock controls
Jira DNVGPU-125 Change-Id: I0e547b05d57c08f76327869c189498e82f4ffd1a Signed-off-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-on: http://git-master/r/1244916 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
index a00c21b6..aaadd186 100644
--- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
@@ -927,6 +927,7 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g,
927 927
928 u32 clk_domains = 0; 928 u32 clk_domains = 0;
929 u32 num_domains; 929 u32 num_domains;
930 u32 num_entries;
930 u32 i; 931 u32 i;
931 int bit; 932 int bit;
932 int err; 933 int err;
@@ -936,10 +937,10 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g,
936 if (!session) 937 if (!session)
937 return -EINVAL; 938 return -EINVAL;
938 939
939 if (!args->flags) { 940 clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g);
940 clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g); 941 num_domains = hweight_long(clk_domains);
941 num_domains = hweight_long(clk_domains);
942 942
943 if (!args->flags) {
943 if (!args->num_entries) { 944 if (!args->num_entries) {
944 args->num_entries = num_domains; 945 args->num_entries = num_domains;
945 return 0; 946 return 0;
@@ -949,18 +950,21 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g,
949 return -EINVAL; 950 return -EINVAL;
950 951
951 args->num_entries = 0; 952 args->num_entries = 0;
953 num_entries = num_domains;
952 954
953 } else { 955 } else {
954 if (args->flags != NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) 956 if (args->flags != NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS)
955 return -EINVAL; 957 return -EINVAL;
956 958
957 num_domains = args->num_entries; 959 num_entries = args->num_entries;
960 if (num_entries > num_domains)
961 return -EINVAL;
958 } 962 }
959 963
960 entry = (struct nvgpu_gpu_clk_range __user *) 964 entry = (struct nvgpu_gpu_clk_range __user *)
961 (uintptr_t)args->clk_range_entries; 965 (uintptr_t)args->clk_range_entries;
962 966
963 for (i = 0; i < num_domains; i++, entry++) { 967 for (i = 0; i < num_entries; i++, entry++) {
964 968
965 if (args->flags == NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) { 969 if (args->flags == NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) {
966 if (copy_from_user(&clk_range, (void __user *)entry, 970 if (copy_from_user(&clk_range, (void __user *)entry,
@@ -984,7 +988,7 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g,
984 return -EFAULT; 988 return -EFAULT;
985 } 989 }
986 990
987 args->num_entries = num_domains; 991 args->num_entries = num_entries;
988 992
989 return 0; 993 return 0;
990} 994}
@@ -1051,6 +1055,7 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g,
1051 struct nvgpu_clk_session *session = priv->clk_session; 1055 struct nvgpu_clk_session *session = priv->clk_session;
1052 u32 clk_domains = 0; 1056 u32 clk_domains = 0;
1053 u32 num_domains; 1057 u32 num_domains;
1058 u32 num_entries;
1054 u32 i; 1059 u32 i;
1055 int err; 1060 int err;
1056 int bit; 1061 int bit;
@@ -1060,10 +1065,10 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g,
1060 if (!session) 1065 if (!session)
1061 return -EINVAL; 1066 return -EINVAL;
1062 1067
1063 if (!args->flags) { 1068 clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g);
1064 clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g); 1069 num_domains = hweight_long(clk_domains);
1065 num_domains = hweight_long(clk_domains);
1066 1070
1071 if (!args->flags) {
1067 if (!args->num_entries) { 1072 if (!args->num_entries) {
1068 args->num_entries = num_domains; 1073 args->num_entries = num_domains;
1069 return 0; 1074 return 0;
@@ -1073,18 +1078,21 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g,
1073 return -EINVAL; 1078 return -EINVAL;
1074 1079
1075 args->num_entries = 0; 1080 args->num_entries = 0;
1081 num_entries = num_domains;
1076 1082
1077 } else { 1083 } else {
1078 if (args->flags != NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) 1084 if (args->flags != NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS)
1079 return -EINVAL; 1085 return -EINVAL;
1080 1086
1081 num_domains = args->num_entries; 1087 num_entries = args->num_entries;
1088 if (num_entries > num_domains * 3)
1089 return -EINVAL;
1082 } 1090 }
1083 1091
1084 entry = (struct nvgpu_gpu_clk_info __user *) 1092 entry = (struct nvgpu_gpu_clk_info __user *)
1085 (uintptr_t)args->clk_info_entries; 1093 (uintptr_t)args->clk_info_entries;
1086 1094
1087 for (i = 0; i < num_domains; i++, entry++) { 1095 for (i = 0; i < num_entries; i++, entry++) {
1088 1096
1089 if (args->flags == NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) { 1097 if (args->flags == NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) {
1090 if (copy_from_user(&clk_info, (void __user *)entry, 1098 if (copy_from_user(&clk_info, (void __user *)entry,
@@ -1125,7 +1133,7 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g,
1125 return -EFAULT; 1133 return -EFAULT;
1126 } 1134 }
1127 1135
1128 args->num_entries = num_domains; 1136 args->num_entries = num_entries;
1129 1137
1130 return 0; 1138 return 0;
1131} 1139}