linux/kernel/uid16.c
<<
>>
Prefs
   1/*
   2 *      Wrapper functions for 16bit uid back compatibility. All nicely tied
   3 *      together in the faint hope we can take the out in five years time.
   4 */
   5
   6#include <linux/mm.h>
   7#include <linux/utsname.h>
   8#include <linux/mman.h>
   9#include <linux/notifier.h>
  10#include <linux/reboot.h>
  11#include <linux/prctl.h>
  12#include <linux/capability.h>
  13#include <linux/init.h>
  14#include <linux/highuid.h>
  15#include <linux/security.h>
  16#include <linux/syscalls.h>
  17
  18#include <asm/uaccess.h>
  19
  20SYSCALL_DEFINE3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
  21{
  22        long ret = sys_chown(filename, low2highuid(user), low2highgid(group));
  23        /* avoid REGPARM breakage on x86: */
  24        asmlinkage_protect(3, ret, filename, user, group);
  25        return ret;
  26}
  27
  28SYSCALL_DEFINE3(lchown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
  29{
  30        long ret = sys_lchown(filename, low2highuid(user), low2highgid(group));
  31        /* avoid REGPARM breakage on x86: */
  32        asmlinkage_protect(3, ret, filename, user, group);
  33        return ret;
  34}
  35
  36SYSCALL_DEFINE3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group)
  37{
  38        long ret = sys_fchown(fd, low2highuid(user), low2highgid(group));
  39        /* avoid REGPARM breakage on x86: */
  40        asmlinkage_protect(3, ret, fd, user, group);
  41        return ret;
  42}
  43
  44SYSCALL_DEFINE2(setregid16, old_gid_t, rgid, old_gid_t, egid)
  45{
  46        long ret = sys_setregid(low2highgid(rgid), low2highgid(egid));
  47        /* avoid REGPARM breakage on x86: */
  48        asmlinkage_protect(2, ret, rgid, egid);
  49        return ret;
  50}
  51
  52SYSCALL_DEFINE1(setgid16, old_gid_t, gid)
  53{
  54        long ret = sys_setgid(low2highgid(gid));
  55        /* avoid REGPARM breakage on x86: */
  56        asmlinkage_protect(1, ret, gid);
  57        return ret;
  58}
  59
  60SYSCALL_DEFINE2(setreuid16, old_uid_t, ruid, old_uid_t, euid)
  61{
  62        long ret = sys_setreuid(low2highuid(ruid), low2highuid(euid));
  63        /* avoid REGPARM breakage on x86: */
  64        asmlinkage_protect(2, ret, ruid, euid);
  65        return ret;
  66}
  67
  68SYSCALL_DEFINE1(setuid16, old_uid_t, uid)
  69{
  70        long ret = sys_setuid(low2highuid(uid));
  71        /* avoid REGPARM breakage on x86: */
  72        asmlinkage_protect(1, ret, uid);
  73        return ret;
  74}
  75
  76SYSCALL_DEFINE3(setresuid16, old_uid_t, ruid, old_uid_t, euid, old_uid_t, suid)
  77{
  78        long ret = sys_setresuid(low2highuid(ruid), low2highuid(euid),
  79                                 low2highuid(suid));
  80        /* avoid REGPARM breakage on x86: */
  81        asmlinkage_protect(3, ret, ruid, euid, suid);
  82        return ret;
  83}
  84
  85SYSCALL_DEFINE3(getresuid16, old_uid_t __user *, ruid, old_uid_t __user *, euid, old_uid_t __user *, suid)
  86{
  87        const struct cred *cred = current_cred();
  88        int retval;
  89
  90        if (!(retval   = put_user(high2lowuid(cred->uid),  ruid)) &&
  91            !(retval   = put_user(high2lowuid(cred->euid), euid)))
  92                retval = put_user(high2lowuid(cred->suid), suid);
  93
  94        return retval;
  95}
  96
  97SYSCALL_DEFINE3(setresgid16, old_gid_t, rgid, old_gid_t, egid, old_gid_t, sgid)
  98{
  99        long ret = sys_setresgid(low2highgid(rgid), low2highgid(egid),
 100                                 low2highgid(sgid));
 101        /* avoid REGPARM breakage on x86: */
 102        asmlinkage_protect(3, ret, rgid, egid, sgid);
 103        return ret;
 104}
 105
 106
 107SYSCALL_DEFINE3(getresgid16, old_gid_t __user *, rgid, old_gid_t __user *, egid, old_gid_t __user *, sgid)
 108{
 109        const struct cred *cred = current_cred();
 110        int retval;
 111
 112        if (!(retval   = put_user(high2lowgid(cred->gid),  rgid)) &&
 113            !(retval   = put_user(high2lowgid(cred->egid), egid)))
 114                retval = put_user(high2lowgid(cred->sgid), sgid);
 115
 116        return retval;
 117}
 118
 119SYSCALL_DEFINE1(setfsuid16, old_uid_t, uid)
 120{
 121        long ret = sys_setfsuid(low2highuid(uid));
 122        /* avoid REGPARM breakage on x86: */
 123        asmlinkage_protect(1, ret, uid);
 124        return ret;
 125}
 126
 127SYSCALL_DEFINE1(setfsgid16, old_gid_t, gid)
 128{
 129        long ret = sys_setfsgid(low2highgid(gid));
 130        /* avoid REGPARM breakage on x86: */
 131        asmlinkage_protect(1, ret, gid);
 132        return ret;
 133}
 134
 135static int groups16_to_user(old_gid_t __user *grouplist,
 136    struct group_info *group_info)
 137{
 138        int i;
 139        old_gid_t group;
 140
 141        for (i = 0; i < group_info->ngroups; i++) {
 142                group = high2lowgid(GROUP_AT(group_info, i));
 143                if (put_user(group, grouplist+i))
 144                        return -EFAULT;
 145        }
 146
 147        return 0;
 148}
 149
 150static int groups16_from_user(struct group_info *group_info,
 151    old_gid_t __user *grouplist)
 152{
 153        int i;
 154        old_gid_t group;
 155
 156        for (i = 0; i < group_info->ngroups; i++) {
 157                if (get_user(group, grouplist+i))
 158                        return  -EFAULT;
 159                GROUP_AT(group_info, i) = low2highgid(group);
 160        }
 161
 162        return 0;
 163}
 164
 165SYSCALL_DEFINE2(getgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
 166{
 167        const struct cred *cred = current_cred();
 168        int i;
 169
 170        if (gidsetsize < 0)
 171                return -EINVAL;
 172
 173        i = cred->group_info->ngroups;
 174        if (gidsetsize) {
 175                if (i > gidsetsize) {
 176                        i = -EINVAL;
 177                        goto out;
 178                }
 179                if (groups16_to_user(grouplist, cred->group_info)) {
 180                        i = -EFAULT;
 181                        goto out;
 182                }
 183        }
 184out:
 185        return i;
 186}
 187
 188SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
 189{
 190        struct group_info *group_info;
 191        int retval;
 192
 193        if (!capable(CAP_SETGID))
 194                return -EPERM;
 195        if ((unsigned)gidsetsize > NGROUPS_MAX)
 196                return -EINVAL;
 197
 198        group_info = groups_alloc(gidsetsize);
 199        if (!group_info)
 200                return -ENOMEM;
 201        retval = groups16_from_user(group_info, grouplist);
 202        if (retval) {
 203                put_group_info(group_info);
 204                return retval;
 205        }
 206
 207        retval = set_current_groups(group_info);
 208        put_group_info(group_info);
 209
 210        return retval;
 211}
 212
 213SYSCALL_DEFINE0(getuid16)
 214{
 215        return high2lowuid(current_uid());
 216}
 217
 218SYSCALL_DEFINE0(geteuid16)
 219{
 220        return high2lowuid(current_euid());
 221}
 222
 223SYSCALL_DEFINE0(getgid16)
 224{
 225        return high2lowgid(current_gid());
 226}
 227
 228SYSCALL_DEFINE0(getegid16)
 229{
 230        return high2lowgid(current_egid());
 231}
 232
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.