Skip to content

Commit fef747b

Browse files
arndbMartin Schwidefsky
authored andcommitted
s390: use generic UID16 implementation
s390 has an almost identical copy of the code in kernel/uid16.c. The problem here is that it requires calling the regular system calls, which the generic implementation handles correctly, but the internal interfaces are not declared in a global header for this. The best way forward here seems to be to just use the generic code and delete the s390 specific implementation. I keep the changes to uapi/asm/posix_types.h inside of an #ifdef check so user space does not observe any changes. As some of the system calls pass pointers, we also need wrappers in compat_wrapper.c, which I add for all calls with at least one argument. All those wrappers can be removed in a later step. Link: https://lore.kernel.org/lkml/20190116131527.2071570-4-arnd@arndb.de Signed-off-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
1 parent 58fa4a4 commit fef747b

File tree

5 files changed

+41
-252
lines changed

5 files changed

+41
-252
lines changed

arch/s390/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ config COMPAT
379379
select COMPAT_BINFMT_ELF if BINFMT_ELF
380380
select ARCH_WANT_OLD_COMPAT_IPC
381381
select COMPAT_OLD_SIGACTION
382+
select HAVE_UID16
382383
depends on MULTIUSER
383384
help
384385
Select this option if you want to enable your system kernel to

arch/s390/include/uapi/asm/posix_types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ typedef long __kernel_ssize_t;
2020
typedef unsigned short __kernel_old_dev_t;
2121
#define __kernel_old_dev_t __kernel_old_dev_t
2222

23+
#ifdef __KERNEL__
24+
typedef unsigned short __kernel_old_uid_t;
25+
typedef unsigned short __kernel_old_gid_t;
26+
#define __kernel_old_uid_t __kernel_old_uid_t
27+
#endif
28+
2329
#ifndef __s390x__
2430

2531
typedef unsigned long __kernel_ino_t;

arch/s390/kernel/compat_linux.c

Lines changed: 0 additions & 233 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
#include <linux/stat.h>
3535
#include <linux/filter.h>
3636
#include <linux/highmem.h>
37-
#include <linux/highuid.h>
3837
#include <linux/mman.h>
3938
#include <linux/ipv6.h>
4039
#include <linux/in.h>
@@ -58,238 +57,6 @@
5857

5958
#include "compat_linux.h"
6059

61-
/* For this source file, we want overflow handling. */
62-
63-
#undef high2lowuid
64-
#undef high2lowgid
65-
#undef low2highuid
66-
#undef low2highgid
67-
#undef SET_UID16
68-
#undef SET_GID16
69-
#undef NEW_TO_OLD_UID
70-
#undef NEW_TO_OLD_GID
71-
#undef SET_OLDSTAT_UID
72-
#undef SET_OLDSTAT_GID
73-
#undef SET_STAT_UID
74-
#undef SET_STAT_GID
75-
76-
#define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
77-
#define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
78-
#define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
79-
#define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
80-
#define SET_UID16(var, uid) var = high2lowuid(uid)
81-
#define SET_GID16(var, gid) var = high2lowgid(gid)
82-
#define NEW_TO_OLD_UID(uid) high2lowuid(uid)
83-
#define NEW_TO_OLD_GID(gid) high2lowgid(gid)
84-
#define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
85-
#define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
86-
#define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
87-
#define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
88-
89-
COMPAT_SYSCALL_DEFINE3(s390_chown16, const char __user *, filename,
90-
u16, user, u16, group)
91-
{
92-
return ksys_chown(filename, low2highuid(user), low2highgid(group));
93-
}
94-
95-
COMPAT_SYSCALL_DEFINE3(s390_lchown16, const char __user *,
96-
filename, u16, user, u16, group)
97-
{
98-
return ksys_lchown(filename, low2highuid(user), low2highgid(group));
99-
}
100-
101-
COMPAT_SYSCALL_DEFINE3(s390_fchown16, unsigned int, fd, u16, user, u16, group)
102-
{
103-
return ksys_fchown(fd, low2highuid(user), low2highgid(group));
104-
}
105-
106-
COMPAT_SYSCALL_DEFINE2(s390_setregid16, u16, rgid, u16, egid)
107-
{
108-
return sys_setregid(low2highgid(rgid), low2highgid(egid));
109-
}
110-
111-
COMPAT_SYSCALL_DEFINE1(s390_setgid16, u16, gid)
112-
{
113-
return sys_setgid(low2highgid(gid));
114-
}
115-
116-
COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid)
117-
{
118-
return sys_setreuid(low2highuid(ruid), low2highuid(euid));
119-
}
120-
121-
COMPAT_SYSCALL_DEFINE1(s390_setuid16, u16, uid)
122-
{
123-
return sys_setuid(low2highuid(uid));
124-
}
125-
126-
COMPAT_SYSCALL_DEFINE3(s390_setresuid16, u16, ruid, u16, euid, u16, suid)
127-
{
128-
return sys_setresuid(low2highuid(ruid), low2highuid(euid),
129-
low2highuid(suid));
130-
}
131-
132-
COMPAT_SYSCALL_DEFINE3(s390_getresuid16, u16 __user *, ruidp,
133-
u16 __user *, euidp, u16 __user *, suidp)
134-
{
135-
const struct cred *cred = current_cred();
136-
int retval;
137-
u16 ruid, euid, suid;
138-
139-
ruid = high2lowuid(from_kuid_munged(cred->user_ns, cred->uid));
140-
euid = high2lowuid(from_kuid_munged(cred->user_ns, cred->euid));
141-
suid = high2lowuid(from_kuid_munged(cred->user_ns, cred->suid));
142-
143-
if (!(retval = put_user(ruid, ruidp)) &&
144-
!(retval = put_user(euid, euidp)))
145-
retval = put_user(suid, suidp);
146-
147-
return retval;
148-
}
149-
150-
COMPAT_SYSCALL_DEFINE3(s390_setresgid16, u16, rgid, u16, egid, u16, sgid)
151-
{
152-
return sys_setresgid(low2highgid(rgid), low2highgid(egid),
153-
low2highgid(sgid));
154-
}
155-
156-
COMPAT_SYSCALL_DEFINE3(s390_getresgid16, u16 __user *, rgidp,
157-
u16 __user *, egidp, u16 __user *, sgidp)
158-
{
159-
const struct cred *cred = current_cred();
160-
int retval;
161-
u16 rgid, egid, sgid;
162-
163-
rgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->gid));
164-
egid = high2lowgid(from_kgid_munged(cred->user_ns, cred->egid));
165-
sgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->sgid));
166-
167-
if (!(retval = put_user(rgid, rgidp)) &&
168-
!(retval = put_user(egid, egidp)))
169-
retval = put_user(sgid, sgidp);
170-
171-
return retval;
172-
}
173-
174-
COMPAT_SYSCALL_DEFINE1(s390_setfsuid16, u16, uid)
175-
{
176-
return sys_setfsuid(low2highuid(uid));
177-
}
178-
179-
COMPAT_SYSCALL_DEFINE1(s390_setfsgid16, u16, gid)
180-
{
181-
return sys_setfsgid(low2highgid(gid));
182-
}
183-
184-
static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info)
185-
{
186-
struct user_namespace *user_ns = current_user_ns();
187-
int i;
188-
u16 group;
189-
kgid_t kgid;
190-
191-
for (i = 0; i < group_info->ngroups; i++) {
192-
kgid = group_info->gid[i];
193-
group = (u16)from_kgid_munged(user_ns, kgid);
194-
if (put_user(group, grouplist+i))
195-
return -EFAULT;
196-
}
197-
198-
return 0;
199-
}
200-
201-
static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist)
202-
{
203-
struct user_namespace *user_ns = current_user_ns();
204-
int i;
205-
u16 group;
206-
kgid_t kgid;
207-
208-
for (i = 0; i < group_info->ngroups; i++) {
209-
if (get_user(group, grouplist+i))
210-
return -EFAULT;
211-
212-
kgid = make_kgid(user_ns, (gid_t)group);
213-
if (!gid_valid(kgid))
214-
return -EINVAL;
215-
216-
group_info->gid[i] = kgid;
217-
}
218-
219-
return 0;
220-
}
221-
222-
COMPAT_SYSCALL_DEFINE2(s390_getgroups16, int, gidsetsize, u16 __user *, grouplist)
223-
{
224-
const struct cred *cred = current_cred();
225-
int i;
226-
227-
if (gidsetsize < 0)
228-
return -EINVAL;
229-
230-
get_group_info(cred->group_info);
231-
i = cred->group_info->ngroups;
232-
if (gidsetsize) {
233-
if (i > gidsetsize) {
234-
i = -EINVAL;
235-
goto out;
236-
}
237-
if (groups16_to_user(grouplist, cred->group_info)) {
238-
i = -EFAULT;
239-
goto out;
240-
}
241-
}
242-
out:
243-
put_group_info(cred->group_info);
244-
return i;
245-
}
246-
247-
COMPAT_SYSCALL_DEFINE2(s390_setgroups16, int, gidsetsize, u16 __user *, grouplist)
248-
{
249-
struct group_info *group_info;
250-
int retval;
251-
252-
if (!may_setgroups())
253-
return -EPERM;
254-
if ((unsigned)gidsetsize > NGROUPS_MAX)
255-
return -EINVAL;
256-
257-
group_info = groups_alloc(gidsetsize);
258-
if (!group_info)
259-
return -ENOMEM;
260-
retval = groups16_from_user(group_info, grouplist);
261-
if (retval) {
262-
put_group_info(group_info);
263-
return retval;
264-
}
265-
266-
groups_sort(group_info);
267-
retval = set_current_groups(group_info);
268-
put_group_info(group_info);
269-
270-
return retval;
271-
}
272-
273-
COMPAT_SYSCALL_DEFINE0(s390_getuid16)
274-
{
275-
return high2lowuid(from_kuid_munged(current_user_ns(), current_uid()));
276-
}
277-
278-
COMPAT_SYSCALL_DEFINE0(s390_geteuid16)
279-
{
280-
return high2lowuid(from_kuid_munged(current_user_ns(), current_euid()));
281-
}
282-
283-
COMPAT_SYSCALL_DEFINE0(s390_getgid16)
284-
{
285-
return high2lowgid(from_kgid_munged(current_user_ns(), current_gid()));
286-
}
287-
288-
COMPAT_SYSCALL_DEFINE0(s390_getegid16)
289-
{
290-
return high2lowgid(from_kgid_munged(current_user_ns(), current_egid()));
291-
}
292-
29360
#ifdef CONFIG_SYSVIPC
29461
COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second,
29562
compat_ulong_t, third, compat_uptr_t, ptr)

arch/s390/kernel/compat_wrapper.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,3 +184,18 @@ COMPAT_SYSCALL_WRAP5(statx, int, dfd, const char __user *, path, unsigned, flags
184184
COMPAT_SYSCALL_WRAP4(s390_sthyi, unsigned long, code, void __user *, info, u64 __user *, rc, unsigned long, flags);
185185
COMPAT_SYSCALL_WRAP5(kexec_file_load, int, kernel_fd, int, initrd_fd, unsigned long, cmdline_len, const char __user *, cmdline_ptr, unsigned long, flags)
186186
COMPAT_SYSCALL_WRAP4(rseq, struct rseq __user *, rseq, u32, rseq_len, int, flags, u32, sig)
187+
COMPAT_SYSCALL_WRAP3(chown16, const char __user *, filename, u16, user, u16, group);
188+
COMPAT_SYSCALL_WRAP3(lchown16, const char __user *, filename, u16, user, u16, group);
189+
COMPAT_SYSCALL_WRAP3(fchown16, unsigned int, fd, u16, user, u16, group);
190+
COMPAT_SYSCALL_WRAP2(setregid16, u16, rgid, u16, egid);
191+
COMPAT_SYSCALL_WRAP1(setgid16, u16, gid);
192+
COMPAT_SYSCALL_WRAP2(setreuid16, u16, ruid, u16, euid);
193+
COMPAT_SYSCALL_WRAP1(setuid16, u16, uid);
194+
COMPAT_SYSCALL_WRAP3(setresuid16, u16, ruid, u16, euid, u16, suid);
195+
COMPAT_SYSCALL_WRAP3(getresuid16, u16 __user *, ruidp, u16 __user *, euidp, u16 __user *, suidp);
196+
COMPAT_SYSCALL_WRAP3(setresgid16, u16, rgid, u16, egid, u16, sgid);
197+
COMPAT_SYSCALL_WRAP3(getresgid16, u16 __user *, rgidp, u16 __user *, egidp, u16 __user *, sgidp);
198+
COMPAT_SYSCALL_WRAP1(setfsuid16, u16, uid);
199+
COMPAT_SYSCALL_WRAP1(setfsgid16, u16, gid);
200+
COMPAT_SYSCALL_WRAP2(getgroups16, int, gidsetsize, u16 __user *, grouplist);
201+
COMPAT_SYSCALL_WRAP2(setgroups16, int, gidsetsize, u16 __user *, grouplist);

arch/s390/kernel/syscalls/syscall.tbl

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@
2323
13 32 time - compat_sys_time
2424
14 common mknod sys_mknod compat_sys_mknod
2525
15 common chmod sys_chmod compat_sys_chmod
26-
16 32 lchown - compat_sys_s390_lchown16
26+
16 32 lchown - compat_sys_lchown16
2727
19 common lseek sys_lseek compat_sys_lseek
2828
20 common getpid sys_getpid sys_getpid
2929
21 common mount sys_mount compat_sys_mount
3030
22 common umount sys_oldumount compat_sys_oldumount
31-
23 32 setuid - compat_sys_s390_setuid16
32-
24 32 getuid - compat_sys_s390_getuid16
31+
23 32 setuid - compat_sys_setuid16
32+
24 32 getuid - sys_getuid16
3333
25 32 stime - compat_sys_stime
3434
26 common ptrace sys_ptrace compat_sys_ptrace
3535
27 common alarm sys_alarm sys_alarm
@@ -46,11 +46,11 @@
4646
42 common pipe sys_pipe compat_sys_pipe
4747
43 common times sys_times compat_sys_times
4848
45 common brk sys_brk compat_sys_brk
49-
46 32 setgid - compat_sys_s390_setgid16
50-
47 32 getgid - compat_sys_s390_getgid16
49+
46 32 setgid - compat_sys_setgid16
50+
47 32 getgid - sys_getgid16
5151
48 common signal sys_signal compat_sys_signal
52-
49 32 geteuid - compat_sys_s390_geteuid16
53-
50 32 getegid - compat_sys_s390_getegid16
52+
49 32 geteuid - sys_geteuid16
53+
50 32 getegid - sys_getegid16
5454
51 common acct sys_acct compat_sys_acct
5555
52 common umount2 sys_umount compat_sys_umount
5656
54 common ioctl sys_ioctl compat_sys_ioctl
@@ -64,8 +64,8 @@
6464
65 common getpgrp sys_getpgrp sys_getpgrp
6565
66 common setsid sys_setsid sys_setsid
6666
67 common sigaction sys_sigaction compat_sys_sigaction
67-
70 32 setreuid - compat_sys_s390_setreuid16
68-
71 32 setregid - compat_sys_s390_setregid16
67+
70 32 setreuid - compat_sys_setreuid16
68+
71 32 setregid - compat_sys_setregid16
6969
72 common sigsuspend sys_sigsuspend compat_sys_sigsuspend
7070
73 common sigpending sys_sigpending compat_sys_sigpending
7171
74 common sethostname sys_sethostname compat_sys_sethostname
@@ -74,8 +74,8 @@
7474
77 common getrusage sys_getrusage compat_sys_getrusage
7575
78 common gettimeofday sys_gettimeofday compat_sys_gettimeofday
7676
79 common settimeofday sys_settimeofday compat_sys_settimeofday
77-
80 32 getgroups - compat_sys_s390_getgroups16
78-
81 32 setgroups - compat_sys_s390_setgroups16
77+
80 32 getgroups - compat_sys_getgroups16
78+
81 32 setgroups - compat_sys_setgroups16
7979
83 common symlink sys_symlink compat_sys_symlink
8080
85 common readlink sys_readlink compat_sys_readlink
8181
86 common uselib sys_uselib compat_sys_uselib
@@ -87,7 +87,7 @@
8787
92 common truncate sys_truncate compat_sys_truncate
8888
93 common ftruncate sys_ftruncate compat_sys_ftruncate
8989
94 common fchmod sys_fchmod sys_fchmod
90-
95 32 fchown - compat_sys_s390_fchown16
90+
95 32 fchown - compat_sys_fchown16
9191
96 common getpriority sys_getpriority sys_getpriority
9292
97 common setpriority sys_setpriority sys_setpriority
9393
99 common statfs sys_statfs compat_sys_statfs
@@ -126,8 +126,8 @@
126126
135 common sysfs sys_sysfs compat_sys_sysfs
127127
136 common personality sys_s390_personality sys_s390_personality
128128
137 common afs_syscall - -
129-
138 32 setfsuid - compat_sys_s390_setfsuid16
130-
139 32 setfsgid - compat_sys_s390_setfsgid16
129+
138 32 setfsuid - compat_sys_setfsuid16
130+
139 32 setfsgid - compat_sys_setfsgid16
131131
140 32 _llseek - compat_sys_llseek
132132
141 common getdents sys_getdents compat_sys_getdents
133133
142 32 _newselect - compat_sys_select
@@ -153,13 +153,13 @@
153153
161 common sched_rr_get_interval sys_sched_rr_get_interval compat_sys_sched_rr_get_interval
154154
162 common nanosleep sys_nanosleep compat_sys_nanosleep
155155
163 common mremap sys_mremap compat_sys_mremap
156-
164 32 setresuid - compat_sys_s390_setresuid16
157-
165 32 getresuid - compat_sys_s390_getresuid16
156+
164 32 setresuid - compat_sys_setresuid16
157+
165 32 getresuid - compat_sys_getresuid16
158158
167 common query_module - -
159159
168 common poll sys_poll compat_sys_poll
160160
169 common nfsservctl - -
161-
170 32 setresgid - compat_sys_s390_setresgid16
162-
171 32 getresgid - compat_sys_s390_getresgid16
161+
170 32 setresgid - compat_sys_setresgid16
162+
171 32 getresgid - compat_sys_getresgid16
163163
172 common prctl sys_prctl compat_sys_prctl
164164
173 common rt_sigreturn sys_rt_sigreturn compat_sys_rt_sigreturn
165165
174 common rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction
@@ -170,7 +170,7 @@
170170
179 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend
171171
180 common pread64 sys_pread64 compat_sys_s390_pread64
172172
181 common pwrite64 sys_pwrite64 compat_sys_s390_pwrite64
173-
182 32 chown - compat_sys_s390_chown16
173+
182 32 chown - compat_sys_chown16
174174
183 common getcwd sys_getcwd compat_sys_getcwd
175175
184 common capget sys_capget compat_sys_capget
176176
185 common capset sys_capset compat_sys_capset

0 commit comments

Comments
 (0)