s390: use generic UID16 implementation
authorArnd Bergmann <arnd@arndb.de>
Wed, 16 Jan 2019 13:15:21 +0000 (14:15 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 18 Jan 2019 08:33:18 +0000 (09:33 +0100)
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>
arch/s390/Kconfig
arch/s390/include/uapi/asm/posix_types.h
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_wrapper.c
arch/s390/kernel/syscalls/syscall.tbl

index ed554b0..41cafd2 100644 (file)
@@ -379,6 +379,7 @@ config COMPAT
        select COMPAT_BINFMT_ELF if BINFMT_ELF
        select ARCH_WANT_OLD_COMPAT_IPC
        select COMPAT_OLD_SIGACTION
+       select HAVE_UID16
        depends on MULTIUSER
        help
          Select this option if you want to enable your system kernel to
index 2a3fc63..1913613 100644 (file)
@@ -20,6 +20,12 @@ typedef long            __kernel_ssize_t;
 typedef unsigned short __kernel_old_dev_t;
 #define __kernel_old_dev_t __kernel_old_dev_t
 
+#ifdef __KERNEL__
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+#define __kernel_old_uid_t __kernel_old_uid_t
+#endif
+
 #ifndef __s390x__
 
 typedef unsigned long   __kernel_ino_t;
index a47f6d3..f9d418d 100644 (file)
@@ -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>
 
 #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)
index 48c4ce6..f54b7b7 100644 (file)
@@ -184,3 +184,18 @@ COMPAT_SYSCALL_WRAP5(statx, int, dfd, const char __user *, path, unsigned, flags
 COMPAT_SYSCALL_WRAP4(s390_sthyi, unsigned long, code, void __user *, info, u64 __user *, rc, unsigned long, flags);
 COMPAT_SYSCALL_WRAP5(kexec_file_load, int, kernel_fd, int, initrd_fd, unsigned long, cmdline_len, const char __user *, cmdline_ptr, unsigned long, flags)
 COMPAT_SYSCALL_WRAP4(rseq, struct rseq __user *, rseq, u32, rseq_len, int, flags, u32, sig)
+COMPAT_SYSCALL_WRAP3(chown16, const char __user *, filename, u16, user, u16, group);
+COMPAT_SYSCALL_WRAP3(lchown16, const char __user *, filename, u16, user, u16, group);
+COMPAT_SYSCALL_WRAP3(fchown16, unsigned int, fd, u16, user, u16, group);
+COMPAT_SYSCALL_WRAP2(setregid16, u16, rgid, u16, egid);
+COMPAT_SYSCALL_WRAP1(setgid16, u16, gid);
+COMPAT_SYSCALL_WRAP2(setreuid16, u16, ruid, u16, euid);
+COMPAT_SYSCALL_WRAP1(setuid16, u16, uid);
+COMPAT_SYSCALL_WRAP3(setresuid16, u16, ruid, u16, euid, u16, suid);
+COMPAT_SYSCALL_WRAP3(getresuid16, u16 __user *, ruidp, u16 __user *, euidp, u16 __user *, suidp);
+COMPAT_SYSCALL_WRAP3(setresgid16, u16, rgid, u16, egid, u16, sgid);
+COMPAT_SYSCALL_WRAP3(getresgid16, u16 __user *, rgidp, u16 __user *, egidp, u16 __user *, sgidp);
+COMPAT_SYSCALL_WRAP1(setfsuid16, u16, uid);
+COMPAT_SYSCALL_WRAP1(setfsgid16, u16, gid);
+COMPAT_SYSCALL_WRAP2(getgroups16, int, gidsetsize, u16 __user *, grouplist);
+COMPAT_SYSCALL_WRAP2(setgroups16, int, gidsetsize, u16 __user *, grouplist);
index 022fc09..f878f74 100644 (file)
 13   32                time                    -                               compat_sys_time
 14   common    mknod                   sys_mknod                       compat_sys_mknod
 15   common    chmod                   sys_chmod                       compat_sys_chmod
-16   32                lchown                  -                               compat_sys_s390_lchown16
+16   32                lchown                  -                               compat_sys_lchown16
 19   common    lseek                   sys_lseek                       compat_sys_lseek
 20   common    getpid                  sys_getpid                      sys_getpid
 21   common    mount                   sys_mount                       compat_sys_mount
 22   common    umount                  sys_oldumount                   compat_sys_oldumount
-23   32                setuid                  -                               compat_sys_s390_setuid16
-24   32                getuid                  -                               compat_sys_s390_getuid16
+23   32                setuid                  -                               compat_sys_setuid16
+24   32                getuid                  -                               sys_getuid16
 25   32                stime                   -                               compat_sys_stime
 26   common    ptrace                  sys_ptrace                      compat_sys_ptrace
 27   common    alarm                   sys_alarm                       sys_alarm
 42   common    pipe                    sys_pipe                        compat_sys_pipe
 43   common    times                   sys_times                       compat_sys_times
 45   common    brk                     sys_brk                         compat_sys_brk
-46   32                setgid                  -                               compat_sys_s390_setgid16
-47   32                getgid                  -                               compat_sys_s390_getgid16
+46   32                setgid                  -                               compat_sys_setgid16
+47   32                getgid                  -                               sys_getgid16
 48   common    signal                  sys_signal                      compat_sys_signal
-49   32                geteuid                 -                               compat_sys_s390_geteuid16
-50   32                getegid                 -                               compat_sys_s390_getegid16
+49   32                geteuid                 -                               sys_geteuid16
+50   32                getegid                 -                               sys_getegid16
 51   common    acct                    sys_acct                        compat_sys_acct
 52   common    umount2                 sys_umount                      compat_sys_umount
 54   common    ioctl                   sys_ioctl                       compat_sys_ioctl
@@ -64,8 +64,8 @@
 65   common    getpgrp                 sys_getpgrp                     sys_getpgrp
 66   common    setsid                  sys_setsid                      sys_setsid
 67   common    sigaction               sys_sigaction                   compat_sys_sigaction
-70   32                setreuid                -                               compat_sys_s390_setreuid16
-71   32                setregid                -                               compat_sys_s390_setregid16
+70   32                setreuid                -                               compat_sys_setreuid16
+71   32                setregid                -                               compat_sys_setregid16
 72   common    sigsuspend              sys_sigsuspend                  compat_sys_sigsuspend
 73   common    sigpending              sys_sigpending                  compat_sys_sigpending
 74   common    sethostname             sys_sethostname                 compat_sys_sethostname
@@ -74,8 +74,8 @@
 77   common    getrusage               sys_getrusage                   compat_sys_getrusage
 78   common    gettimeofday            sys_gettimeofday                compat_sys_gettimeofday
 79   common    settimeofday            sys_settimeofday                compat_sys_settimeofday
-80   32                getgroups               -                               compat_sys_s390_getgroups16
-81   32                setgroups               -                               compat_sys_s390_setgroups16
+80   32                getgroups               -                               compat_sys_getgroups16
+81   32                setgroups               -                               compat_sys_setgroups16
 83   common    symlink                 sys_symlink                     compat_sys_symlink
 85   common    readlink                sys_readlink                    compat_sys_readlink
 86   common    uselib                  sys_uselib                      compat_sys_uselib
@@ -87,7 +87,7 @@
 92   common    truncate                sys_truncate                    compat_sys_truncate
 93   common    ftruncate               sys_ftruncate                   compat_sys_ftruncate
 94   common    fchmod                  sys_fchmod                      sys_fchmod
-95   32                fchown                  -                               compat_sys_s390_fchown16
+95   32                fchown                  -                               compat_sys_fchown16
 96   common    getpriority             sys_getpriority                 sys_getpriority
 97   common    setpriority             sys_setpriority                 sys_setpriority
 99   common    statfs                  sys_statfs                      compat_sys_statfs
 135  common    sysfs                   sys_sysfs                       compat_sys_sysfs
 136  common    personality             sys_s390_personality            sys_s390_personality
 137  common    afs_syscall             -                               -
-138  32                setfsuid                -                               compat_sys_s390_setfsuid16
-139  32                setfsgid                -                               compat_sys_s390_setfsgid16
+138  32                setfsuid                -                               compat_sys_setfsuid16
+139  32                setfsgid                -                               compat_sys_setfsgid16
 140  32                _llseek                 -                               compat_sys_llseek
 141  common    getdents                sys_getdents                    compat_sys_getdents
 142  32                _newselect              -                               compat_sys_select
 161  common    sched_rr_get_interval   sys_sched_rr_get_interval       compat_sys_sched_rr_get_interval
 162  common    nanosleep               sys_nanosleep                   compat_sys_nanosleep
 163  common    mremap                  sys_mremap                      compat_sys_mremap
-164  32                setresuid               -                               compat_sys_s390_setresuid16
-165  32                getresuid               -                               compat_sys_s390_getresuid16
+164  32                setresuid               -                               compat_sys_setresuid16
+165  32                getresuid               -                               compat_sys_getresuid16
 167  common    query_module            -                               -
 168  common    poll                    sys_poll                        compat_sys_poll
 169  common    nfsservctl              -                               -
-170  32                setresgid               -                               compat_sys_s390_setresgid16
-171  32                getresgid               -                               compat_sys_s390_getresgid16
+170  32                setresgid               -                               compat_sys_setresgid16
+171  32                getresgid               -                               compat_sys_getresgid16
 172  common    prctl                   sys_prctl                       compat_sys_prctl
 173  common    rt_sigreturn            sys_rt_sigreturn                compat_sys_rt_sigreturn
 174  common    rt_sigaction            sys_rt_sigaction                compat_sys_rt_sigaction
 179  common    rt_sigsuspend           sys_rt_sigsuspend               compat_sys_rt_sigsuspend
 180  common    pread64                 sys_pread64                     compat_sys_s390_pread64
 181  common    pwrite64                sys_pwrite64                    compat_sys_s390_pwrite64
-182  32                chown                   -                               compat_sys_s390_chown16
+182  32                chown                   -                               compat_sys_chown16
 183  common    getcwd                  sys_getcwd                      compat_sys_getcwd
 184  common    capget                  sys_capget                      compat_sys_capget
 185  common    capset                  sys_capset                      compat_sys_capset