Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  Wrapper functions for 16bit uid back compatibility. All nicely tied
0004  *  together in the faint hope we can take the out in five years time.
0005  */
0006 
0007 #include <linux/mm.h>
0008 #include <linux/mman.h>
0009 #include <linux/notifier.h>
0010 #include <linux/reboot.h>
0011 #include <linux/prctl.h>
0012 #include <linux/capability.h>
0013 #include <linux/init.h>
0014 #include <linux/highuid.h>
0015 #include <linux/security.h>
0016 #include <linux/cred.h>
0017 #include <linux/syscalls.h>
0018 
0019 #include <linux/uaccess.h>
0020 
0021 #include "uid16.h"
0022 
0023 SYSCALL_DEFINE3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
0024 {
0025     return ksys_chown(filename, low2highuid(user), low2highgid(group));
0026 }
0027 
0028 SYSCALL_DEFINE3(lchown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
0029 {
0030     return ksys_lchown(filename, low2highuid(user), low2highgid(group));
0031 }
0032 
0033 SYSCALL_DEFINE3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group)
0034 {
0035     return ksys_fchown(fd, low2highuid(user), low2highgid(group));
0036 }
0037 
0038 SYSCALL_DEFINE2(setregid16, old_gid_t, rgid, old_gid_t, egid)
0039 {
0040     return __sys_setregid(low2highgid(rgid), low2highgid(egid));
0041 }
0042 
0043 SYSCALL_DEFINE1(setgid16, old_gid_t, gid)
0044 {
0045     return __sys_setgid(low2highgid(gid));
0046 }
0047 
0048 SYSCALL_DEFINE2(setreuid16, old_uid_t, ruid, old_uid_t, euid)
0049 {
0050     return __sys_setreuid(low2highuid(ruid), low2highuid(euid));
0051 }
0052 
0053 SYSCALL_DEFINE1(setuid16, old_uid_t, uid)
0054 {
0055     return __sys_setuid(low2highuid(uid));
0056 }
0057 
0058 SYSCALL_DEFINE3(setresuid16, old_uid_t, ruid, old_uid_t, euid, old_uid_t, suid)
0059 {
0060     return __sys_setresuid(low2highuid(ruid), low2highuid(euid),
0061                  low2highuid(suid));
0062 }
0063 
0064 SYSCALL_DEFINE3(getresuid16, old_uid_t __user *, ruidp, old_uid_t __user *, euidp, old_uid_t __user *, suidp)
0065 {
0066     const struct cred *cred = current_cred();
0067     int retval;
0068     old_uid_t ruid, euid, suid;
0069 
0070     ruid = high2lowuid(from_kuid_munged(cred->user_ns, cred->uid));
0071     euid = high2lowuid(from_kuid_munged(cred->user_ns, cred->euid));
0072     suid = high2lowuid(from_kuid_munged(cred->user_ns, cred->suid));
0073 
0074     if (!(retval   = put_user(ruid, ruidp)) &&
0075         !(retval   = put_user(euid, euidp)))
0076         retval = put_user(suid, suidp);
0077 
0078     return retval;
0079 }
0080 
0081 SYSCALL_DEFINE3(setresgid16, old_gid_t, rgid, old_gid_t, egid, old_gid_t, sgid)
0082 {
0083     return __sys_setresgid(low2highgid(rgid), low2highgid(egid),
0084                  low2highgid(sgid));
0085 }
0086 
0087 SYSCALL_DEFINE3(getresgid16, old_gid_t __user *, rgidp, old_gid_t __user *, egidp, old_gid_t __user *, sgidp)
0088 {
0089     const struct cred *cred = current_cred();
0090     int retval;
0091     old_gid_t rgid, egid, sgid;
0092 
0093     rgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->gid));
0094     egid = high2lowgid(from_kgid_munged(cred->user_ns, cred->egid));
0095     sgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->sgid));
0096 
0097     if (!(retval   = put_user(rgid, rgidp)) &&
0098         !(retval   = put_user(egid, egidp)))
0099         retval = put_user(sgid, sgidp);
0100 
0101     return retval;
0102 }
0103 
0104 SYSCALL_DEFINE1(setfsuid16, old_uid_t, uid)
0105 {
0106     return __sys_setfsuid(low2highuid(uid));
0107 }
0108 
0109 SYSCALL_DEFINE1(setfsgid16, old_gid_t, gid)
0110 {
0111     return __sys_setfsgid(low2highgid(gid));
0112 }
0113 
0114 static int groups16_to_user(old_gid_t __user *grouplist,
0115     struct group_info *group_info)
0116 {
0117     struct user_namespace *user_ns = current_user_ns();
0118     int i;
0119     old_gid_t group;
0120     kgid_t kgid;
0121 
0122     for (i = 0; i < group_info->ngroups; i++) {
0123         kgid = group_info->gid[i];
0124         group = high2lowgid(from_kgid_munged(user_ns, kgid));
0125         if (put_user(group, grouplist+i))
0126             return -EFAULT;
0127     }
0128 
0129     return 0;
0130 }
0131 
0132 static int groups16_from_user(struct group_info *group_info,
0133     old_gid_t __user *grouplist)
0134 {
0135     struct user_namespace *user_ns = current_user_ns();
0136     int i;
0137     old_gid_t group;
0138     kgid_t kgid;
0139 
0140     for (i = 0; i < group_info->ngroups; i++) {
0141         if (get_user(group, grouplist+i))
0142             return  -EFAULT;
0143 
0144         kgid = make_kgid(user_ns, low2highgid(group));
0145         if (!gid_valid(kgid))
0146             return -EINVAL;
0147 
0148         group_info->gid[i] = kgid;
0149     }
0150 
0151     return 0;
0152 }
0153 
0154 SYSCALL_DEFINE2(getgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
0155 {
0156     const struct cred *cred = current_cred();
0157     int i;
0158 
0159     if (gidsetsize < 0)
0160         return -EINVAL;
0161 
0162     i = cred->group_info->ngroups;
0163     if (gidsetsize) {
0164         if (i > gidsetsize) {
0165             i = -EINVAL;
0166             goto out;
0167         }
0168         if (groups16_to_user(grouplist, cred->group_info)) {
0169             i = -EFAULT;
0170             goto out;
0171         }
0172     }
0173 out:
0174     return i;
0175 }
0176 
0177 SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
0178 {
0179     struct group_info *group_info;
0180     int retval;
0181 
0182     if (!may_setgroups())
0183         return -EPERM;
0184     if ((unsigned)gidsetsize > NGROUPS_MAX)
0185         return -EINVAL;
0186 
0187     group_info = groups_alloc(gidsetsize);
0188     if (!group_info)
0189         return -ENOMEM;
0190     retval = groups16_from_user(group_info, grouplist);
0191     if (retval) {
0192         put_group_info(group_info);
0193         return retval;
0194     }
0195 
0196     groups_sort(group_info);
0197     retval = set_current_groups(group_info);
0198     put_group_info(group_info);
0199 
0200     return retval;
0201 }
0202 
0203 SYSCALL_DEFINE0(getuid16)
0204 {
0205     return high2lowuid(from_kuid_munged(current_user_ns(), current_uid()));
0206 }
0207 
0208 SYSCALL_DEFINE0(geteuid16)
0209 {
0210     return high2lowuid(from_kuid_munged(current_user_ns(), current_euid()));
0211 }
0212 
0213 SYSCALL_DEFINE0(getgid16)
0214 {
0215     return high2lowgid(from_kgid_munged(current_user_ns(), current_gid()));
0216 }
0217 
0218 SYSCALL_DEFINE0(getegid16)
0219 {
0220     return high2lowgid(from_kgid_munged(current_user_ns(), current_egid()));
0221 }