The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kernel/uid16.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: b1f90c76839f83edf51347dff05895e7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.