File: /usr/src/linux/kernel/uid16.c

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/smp_lock.h>
10     #include <linux/notifier.h>
11     #include <linux/reboot.h>
12     #include <linux/prctl.h>
13     #include <linux/init.h>
14     #include <linux/highuid.h>
15     
16     #include <asm/uaccess.h>
17     
18     extern asmlinkage long sys_chown(const char *, uid_t,gid_t);
19     extern asmlinkage long sys_lchown(const char *, uid_t,gid_t);
20     extern asmlinkage long sys_fchown(unsigned int, uid_t,gid_t);
21     extern asmlinkage long sys_setregid(gid_t, gid_t);
22     extern asmlinkage long sys_setgid(gid_t);
23     extern asmlinkage long sys_setreuid(uid_t, uid_t);
24     extern asmlinkage long sys_setuid(uid_t);
25     extern asmlinkage long sys_setresuid(uid_t, uid_t, uid_t);
26     extern asmlinkage long sys_setresgid(gid_t, gid_t, gid_t);
27     extern asmlinkage long sys_setfsuid(uid_t);
28     extern asmlinkage long sys_setfsgid(gid_t);
29      
30     asmlinkage long sys_chown16(const char * filename, old_uid_t user, old_gid_t group)
31     {
32     	return sys_chown(filename, low2highuid(user), low2highgid(group));
33     }
34     
35     asmlinkage long sys_lchown16(const char * filename, old_uid_t user, old_gid_t group)
36     {
37     	return sys_lchown(filename, low2highuid(user), low2highgid(group));
38     }
39     
40     asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group)
41     {
42     	return sys_fchown(fd, low2highuid(user), low2highgid(group));
43     }
44     
45     asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid)
46     {
47     	return sys_setregid(low2highgid(rgid), low2highgid(egid));
48     }
49     
50     asmlinkage long sys_setgid16(old_gid_t gid)
51     {
52     	return sys_setgid((gid_t)gid);
53     }
54     
55     asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid)
56     {
57     	return sys_setreuid(low2highuid(ruid), low2highuid(euid));
58     }
59     
60     asmlinkage long sys_setuid16(old_uid_t uid)
61     {
62     	return sys_setuid((uid_t)uid);
63     }
64     
65     asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid)
66     {
67     	return sys_setresuid(low2highuid(ruid), low2highuid(euid),
68     		low2highuid(suid));
69     }
70     
71     asmlinkage long sys_getresuid16(old_uid_t *ruid, old_uid_t *euid, old_uid_t *suid)
72     {
73     	int retval;
74     
75     	if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
76     	    !(retval = put_user(high2lowuid(current->euid), euid)))
77     		retval = put_user(high2lowuid(current->suid), suid);
78     
79     	return retval;
80     }
81     
82     asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid)
83     {
84     	return sys_setresgid(low2highgid(rgid), low2highgid(egid),
85     		low2highgid(sgid));
86     }
87     
88     asmlinkage long sys_getresgid16(old_gid_t *rgid, old_gid_t *egid, old_gid_t *sgid)
89     {
90     	int retval;
91     
92     	if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
93     	    !(retval = put_user(high2lowgid(current->egid), egid)))
94     		retval = put_user(high2lowgid(current->sgid), sgid);
95     
96     	return retval;
97     }
98     
99     asmlinkage long sys_setfsuid16(old_uid_t uid)
100     {
101     	return sys_setfsuid((uid_t)uid);
102     }
103     
104     asmlinkage long sys_setfsgid16(old_gid_t gid)
105     {
106     	return sys_setfsgid((gid_t)gid);
107     }
108     
109     asmlinkage long sys_getgroups16(int gidsetsize, old_gid_t *grouplist)
110     {
111     	old_gid_t groups[NGROUPS];
112     	int i,j;
113     
114     	if (gidsetsize < 0)
115     		return -EINVAL;
116     	i = current->ngroups;
117     	if (gidsetsize) {
118     		if (i > gidsetsize)
119     			return -EINVAL;
120     		for(j=0;j<i;j++)
121     			groups[j] = current->groups[j];
122     		if (copy_to_user(grouplist, groups, sizeof(old_gid_t)*i))
123     			return -EFAULT;
124     	}
125     	return i;
126     }
127     
128     asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t *grouplist)
129     {
130     	old_gid_t groups[NGROUPS];
131     	int i;
132     
133     	if (!capable(CAP_SETGID))
134     		return -EPERM;
135     	if ((unsigned) gidsetsize > NGROUPS)
136     		return -EINVAL;
137     	if (copy_from_user(groups, grouplist, gidsetsize * sizeof(old_gid_t)))
138     		return -EFAULT;
139     	for (i = 0 ; i < gidsetsize ; i++)
140     		current->groups[i] = (gid_t)groups[i];
141     	current->ngroups = gidsetsize;
142     	return 0;
143     }
144     
145     asmlinkage long sys_getuid16(void)
146     {
147     	return high2lowuid(current->uid);
148     }
149     
150     asmlinkage long sys_geteuid16(void)
151     {
152     	return high2lowuid(current->euid);
153     }
154     
155     asmlinkage long sys_getgid16(void)
156     {
157     	return high2lowgid(current->gid);
158     }
159     
160     asmlinkage long sys_getegid16(void)
161     {
162     	return high2lowgid(current->egid);
163     }
164