aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kernel/compat_linux.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index ab64bdbab2ae..f0273ed760ef 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -173,11 +173,14 @@ asmlinkage long sys32_setfsgid16(u16 gid)
173 173
174static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info) 174static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info)
175{ 175{
176 struct user_namespace *user_ns = current_user_ns();
176 int i; 177 int i;
177 u16 group; 178 u16 group;
179 kgid_t kgid;
178 180
179 for (i = 0; i < group_info->ngroups; i++) { 181 for (i = 0; i < group_info->ngroups; i++) {
180 group = (u16)GROUP_AT(group_info, i); 182 kgid = GROUP_AT(group_info, i);
183 group = (u16)from_kgid_munged(user_ns, kgid);
181 if (put_user(group, grouplist+i)) 184 if (put_user(group, grouplist+i))
182 return -EFAULT; 185 return -EFAULT;
183 } 186 }
@@ -187,13 +190,20 @@ static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info
187 190
188static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist) 191static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist)
189{ 192{
193 struct user_namespace *user_ns = current_user_ns();
190 int i; 194 int i;
191 u16 group; 195 u16 group;
196 kgid_t kgid;
192 197
193 for (i = 0; i < group_info->ngroups; i++) { 198 for (i = 0; i < group_info->ngroups; i++) {
194 if (get_user(group, grouplist+i)) 199 if (get_user(group, grouplist+i))
195 return -EFAULT; 200 return -EFAULT;
196 GROUP_AT(group_info, i) = (gid_t)group; 201
202 kgid = make_kgid(user_ns, (gid_t)group);
203 if (!gid_valid(kgid))
204 return -EINVAL;
205
206 GROUP_AT(group_info, i) = kgid;
197 } 207 }
198 208
199 return 0; 209 return 0;