diff options
author | Arnd Bergmann <arnd@arndb.de> | 2019-01-16 16:15:21 +0300 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2019-01-18 11:33:18 +0300 |
commit | fef747bab3c09b30b82f76a391ee0ed83d2d6965 (patch) | |
tree | 3a32716e2fd14f6c045240a9a82bdf28bb7b37f5 /arch/s390/kernel/compat_linux.c | |
parent | 58fa4a410fc31afe08d0d0c6b6d8860c22ec17c2 (diff) | |
download | linux-fef747bab3c09b30b82f76a391ee0ed83d2d6965.tar.xz |
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>
Diffstat (limited to 'arch/s390/kernel/compat_linux.c')
-rw-r--r-- | arch/s390/kernel/compat_linux.c | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index a47f6d3c6d5b..f9d418d1b619 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -34,7 +34,6 @@ #include <linux/stat.h> #include <linux/filter.h> #include <linux/highmem.h> -#include <linux/highuid.h> #include <linux/mman.h> #include <linux/ipv6.h> #include <linux/in.h> @@ -58,238 +57,6 @@ #include "compat_linux.h" -/* For this source file, we want overflow handling. */ - -#undef high2lowuid -#undef high2lowgid -#undef low2highuid -#undef low2highgid -#undef SET_UID16 -#undef SET_GID16 -#undef NEW_TO_OLD_UID -#undef NEW_TO_OLD_GID -#undef SET_OLDSTAT_UID -#undef SET_OLDSTAT_GID -#undef SET_STAT_UID -#undef SET_STAT_GID - -#define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) -#define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) -#define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid) -#define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid) -#define SET_UID16(var, uid) var = high2lowuid(uid) -#define SET_GID16(var, gid) var = high2lowgid(gid) -#define NEW_TO_OLD_UID(uid) high2lowuid(uid) -#define NEW_TO_OLD_GID(gid) high2lowgid(gid) -#define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) -#define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) -#define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) -#define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) - -COMPAT_SYSCALL_DEFINE3(s390_chown16, const char __user *, filename, - u16, user, u16, group) -{ - return ksys_chown(filename, low2highuid(user), low2highgid(group)); -} - -COMPAT_SYSCALL_DEFINE3(s390_lchown16, const char __user *, - filename, u16, user, u16, group) -{ - return ksys_lchown(filename, low2highuid(user), low2highgid(group)); -} - -COMPAT_SYSCALL_DEFINE3(s390_fchown16, unsigned int, fd, u16, user, u16, group) -{ - return ksys_fchown(fd, low2highuid(user), low2highgid(group)); -} - -COMPAT_SYSCALL_DEFINE2(s390_setregid16, u16, rgid, u16, egid) -{ - return sys_setregid(low2highgid(rgid), low2highgid(egid)); -} - -COMPAT_SYSCALL_DEFINE1(s390_setgid16, u16, gid) -{ - return sys_setgid(low2highgid(gid)); -} - -COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid) -{ - return sys_setreuid(low2highuid(ruid), low2highuid(euid)); -} - -COMPAT_SYSCALL_DEFINE1(s390_setuid16, u16, uid) -{ - return sys_setuid(low2highuid(uid)); -} - -COMPAT_SYSCALL_DEFINE3(s390_setresuid16, u16, ruid, u16, euid, u16, suid) -{ - return sys_setresuid(low2highuid(ruid), low2highuid(euid), - low2highuid(suid)); -} - -COMPAT_SYSCALL_DEFINE3(s390_getresuid16, u16 __user *, ruidp, - u16 __user *, euidp, u16 __user *, suidp) -{ - const struct cred *cred = current_cred(); - int retval; - u16 ruid, euid, suid; - - ruid = high2lowuid(from_kuid_munged(cred->user_ns, cred->uid)); - euid = high2lowuid(from_kuid_munged(cred->user_ns, cred->euid)); - suid = high2lowuid(from_kuid_munged(cred->user_ns, cred->suid)); - - if (!(retval = put_user(ruid, ruidp)) && - !(retval = put_user(euid, euidp))) - retval = put_user(suid, suidp); - - return retval; -} - -COMPAT_SYSCALL_DEFINE3(s390_setresgid16, u16, rgid, u16, egid, u16, sgid) -{ - return sys_setresgid(low2highgid(rgid), low2highgid(egid), - low2highgid(sgid)); -} - -COMPAT_SYSCALL_DEFINE3(s390_getresgid16, u16 __user *, rgidp, - u16 __user *, egidp, u16 __user *, sgidp) -{ - const struct cred *cred = current_cred(); - int retval; - u16 rgid, egid, sgid; - - rgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->gid)); - egid = high2lowgid(from_kgid_munged(cred->user_ns, cred->egid)); - sgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->sgid)); - - if (!(retval = put_user(rgid, rgidp)) && - !(retval = put_user(egid, egidp))) - retval = put_user(sgid, sgidp); - - return retval; -} - -COMPAT_SYSCALL_DEFINE1(s390_setfsuid16, u16, uid) -{ - return sys_setfsuid(low2highuid(uid)); -} - -COMPAT_SYSCALL_DEFINE1(s390_setfsgid16, u16, gid) -{ - return sys_setfsgid(low2highgid(gid)); -} - -static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info) -{ - struct user_namespace *user_ns = current_user_ns(); - int i; - u16 group; - kgid_t kgid; - - for (i = 0; i < group_info->ngroups; i++) { - kgid = group_info->gid[i]; - group = (u16)from_kgid_munged(user_ns, kgid); - if (put_user(group, grouplist+i)) - return -EFAULT; - } - - return 0; -} - -static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist) -{ - struct user_namespace *user_ns = current_user_ns(); - int i; - u16 group; - kgid_t kgid; - - for (i = 0; i < group_info->ngroups; i++) { - if (get_user(group, grouplist+i)) - return -EFAULT; - - kgid = make_kgid(user_ns, (gid_t)group); - if (!gid_valid(kgid)) - return -EINVAL; - - group_info->gid[i] = kgid; - } - - return 0; -} - -COMPAT_SYSCALL_DEFINE2(s390_getgroups16, int, gidsetsize, u16 __user *, grouplist) -{ - const struct cred *cred = current_cred(); - int i; - - if (gidsetsize < 0) - return -EINVAL; - - get_group_info(cred->group_info); - i = cred->group_info->ngroups; - if (gidsetsize) { - if (i > gidsetsize) { - i = -EINVAL; - goto out; - } - if (groups16_to_user(grouplist, cred->group_info)) { - i = -EFAULT; - goto out; - } - } -out: - put_group_info(cred->group_info); - return i; -} - -COMPAT_SYSCALL_DEFINE2(s390_setgroups16, int, gidsetsize, u16 __user *, grouplist) -{ - struct group_info *group_info; - int retval; - - if (!may_setgroups()) - return -EPERM; - if ((unsigned)gidsetsize > NGROUPS_MAX) - return -EINVAL; - - group_info = groups_alloc(gidsetsize); - if (!group_info) - return -ENOMEM; - retval = groups16_from_user(group_info, grouplist); - if (retval) { - put_group_info(group_info); - return retval; - } - - groups_sort(group_info); - retval = set_current_groups(group_info); - put_group_info(group_info); - - return retval; -} - -COMPAT_SYSCALL_DEFINE0(s390_getuid16) -{ - return high2lowuid(from_kuid_munged(current_user_ns(), current_uid())); -} - -COMPAT_SYSCALL_DEFINE0(s390_geteuid16) -{ - return high2lowuid(from_kuid_munged(current_user_ns(), current_euid())); -} - -COMPAT_SYSCALL_DEFINE0(s390_getgid16) -{ - return high2lowgid(from_kgid_munged(current_user_ns(), current_gid())); -} - -COMPAT_SYSCALL_DEFINE0(s390_getegid16) -{ - return high2lowgid(from_kgid_munged(current_user_ns(), current_egid())); -} - #ifdef CONFIG_SYSVIPC COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second, compat_ulong_t, third, compat_uptr_t, ptr) |