1 /* $Id: sys_sparc32.c,v 1.182.2.1 2002/02/20 08:49:24 davem Exp $
2  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
3  *
4  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
6  *
7  * These routines maintain argument size conversion between 32bit and 64bit
8  * environment.
9  */
10 
11 #include <linux/config.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/fs.h>
15 #include <linux/mm.h>
16 #include <linux/file.h>
17 #include <linux/signal.h>
18 #include <linux/utime.h>
19 #include <linux/resource.h>
20 #include <linux/times.h>
21 #include <linux/utsname.h>
22 #include <linux/timex.h>
23 #include <linux/smp.h>
24 #include <linux/smp_lock.h>
25 #include <linux/sem.h>
26 #include <linux/msg.h>
27 #include <linux/shm.h>
28 #include <linux/slab.h>
29 #include <linux/uio.h>
30 #include <linux/nfs_fs.h>
31 #include <linux/smb_fs.h>
32 #include <linux/smb_mount.h>
33 #include <linux/ncp_fs.h>
34 #include <linux/quota.h>
35 #include <linux/quotacompat.h>
36 #include <linux/module.h>
37 #include <linux/sunrpc/svc.h>
38 #include <linux/nfsd/nfsd.h>
39 #include <linux/nfsd/cache.h>
40 #include <linux/nfsd/xdr.h>
41 #include <linux/nfsd/syscall.h>
42 #include <linux/poll.h>
43 #include <linux/personality.h>
44 #include <linux/stat.h>
45 #include <linux/filter.h>
46 #include <linux/highmem.h>
47 #include <linux/highuid.h>
48 #include <linux/mman.h>
49 #include <linux/ipv6.h>
50 #include <linux/in.h>
51 #include <linux/icmpv6.h>
52 #include <linux/sysctl.h>
53 #include <linux/vmalloc.h>
54 #include <linux/dnotify.h>
55 #include <linux/netfilter_ipv4/ip_tables.h>
56 
57 #include <asm/types.h>
58 #include <asm/ipc.h>
59 #include <asm/uaccess.h>
60 #include <asm/fpumacro.h>
61 #include <asm/semaphore.h>
62 
63 #include <net/scm.h>
64 
65 /* Use this to get at 32-bit user passed pointers. */
66 /* Things to consider: the low-level assembly stub does
67    srl x, 0, x for first four arguments, so if you have
68    pointer to something in the first four arguments, just
69    declare it as a pointer, not u32. On the other side,
70    arguments from 5th onwards should be declared as u32
71    for pointers, and need AA() around each usage.
72    A() macro should be used for places where you e.g.
73    have some internal variable u32 and just want to get
74    rid of a compiler warning. AA() has to be used in
75    places where you want to convert a function argument
76    to 32bit pointer or when you e.g. access pt_regs
77    structure and want to consider 32bit registers only.
78    -jj
79  */
80 #define A(__x) ((unsigned long)(__x))
81 #define AA(__x)				\
82 ({	unsigned long __ret;		\
83 	__asm__ ("srl	%0, 0, %0"	\
84 		 : "=r" (__ret)		\
85 		 : "0" (__x));		\
86 	__ret;				\
87 })
88 
89 extern asmlinkage long sys_chown(const char *, uid_t,gid_t);
90 extern asmlinkage long sys_lchown(const char *, uid_t,gid_t);
91 extern asmlinkage long sys_fchown(unsigned int, uid_t,gid_t);
92 extern asmlinkage long sys_setregid(gid_t, gid_t);
93 extern asmlinkage long sys_setgid(gid_t);
94 extern asmlinkage long sys_setreuid(uid_t, uid_t);
95 extern asmlinkage long sys_setuid(uid_t);
96 extern asmlinkage long sys_setresuid(uid_t, uid_t, uid_t);
97 extern asmlinkage long sys_setresgid(gid_t, gid_t, gid_t);
98 extern asmlinkage long sys_setfsuid(uid_t);
99 extern asmlinkage long sys_setfsgid(gid_t);
100 
101 /* For this source file, we want overflow handling. */
102 
103 #undef high2lowuid
104 #undef high2lowgid
105 #undef low2highuid
106 #undef low2highgid
107 #undef SET_UID16
108 #undef SET_GID16
109 #undef NEW_TO_OLD_UID
110 #undef NEW_TO_OLD_GID
111 #undef SET_OLDSTAT_UID
112 #undef SET_OLDSTAT_GID
113 #undef SET_STAT_UID
114 #undef SET_STAT_GID
115 
116 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
117 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
118 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
119 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
120 #define SET_UID16(var, uid)	var = high2lowuid(uid)
121 #define SET_GID16(var, gid)	var = high2lowgid(gid)
122 #define NEW_TO_OLD_UID(uid)	high2lowuid(uid)
123 #define NEW_TO_OLD_GID(gid)	high2lowgid(gid)
124 #define SET_OLDSTAT_UID(stat, uid)	(stat).st_uid = high2lowuid(uid)
125 #define SET_OLDSTAT_GID(stat, gid)	(stat).st_gid = high2lowgid(gid)
126 #define SET_STAT_UID(stat, uid)		(stat).st_uid = high2lowuid(uid)
127 #define SET_STAT_GID(stat, gid)		(stat).st_gid = high2lowgid(gid)
128 
sys32_chown16(const char * filename,u16 user,u16 group)129 asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
130 {
131 	return sys_chown(filename, low2highuid(user), low2highgid(group));
132 }
133 
sys32_lchown16(const char * filename,u16 user,u16 group)134 asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
135 {
136 	return sys_lchown(filename, low2highuid(user), low2highgid(group));
137 }
138 
sys32_fchown16(unsigned int fd,u16 user,u16 group)139 asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
140 {
141 	return sys_fchown(fd, low2highuid(user), low2highgid(group));
142 }
143 
sys32_setregid16(u16 rgid,u16 egid)144 asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
145 {
146 	return sys_setregid(low2highgid(rgid), low2highgid(egid));
147 }
148 
sys32_setgid16(u16 gid)149 asmlinkage long sys32_setgid16(u16 gid)
150 {
151 	return sys_setgid((gid_t)gid);
152 }
153 
sys32_setreuid16(u16 ruid,u16 euid)154 asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
155 {
156 	return sys_setreuid(low2highuid(ruid), low2highuid(euid));
157 }
158 
sys32_setuid16(u16 uid)159 asmlinkage long sys32_setuid16(u16 uid)
160 {
161 	return sys_setuid((uid_t)uid);
162 }
163 
sys32_setresuid16(u16 ruid,u16 euid,u16 suid)164 asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
165 {
166 	return sys_setresuid(low2highuid(ruid), low2highuid(euid),
167 		low2highuid(suid));
168 }
169 
sys32_getresuid16(u16 * ruid,u16 * euid,u16 * suid)170 asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
171 {
172 	int retval;
173 
174 	if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
175 	    !(retval = put_user(high2lowuid(current->euid), euid)))
176 		retval = put_user(high2lowuid(current->suid), suid);
177 
178 	return retval;
179 }
180 
sys32_setresgid16(u16 rgid,u16 egid,u16 sgid)181 asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
182 {
183 	return sys_setresgid(low2highgid(rgid), low2highgid(egid),
184 		low2highgid(sgid));
185 }
186 
sys32_getresgid16(u16 * rgid,u16 * egid,u16 * sgid)187 asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
188 {
189 	int retval;
190 
191 	if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
192 	    !(retval = put_user(high2lowgid(current->egid), egid)))
193 		retval = put_user(high2lowgid(current->sgid), sgid);
194 
195 	return retval;
196 }
197 
sys32_setfsuid16(u16 uid)198 asmlinkage long sys32_setfsuid16(u16 uid)
199 {
200 	return sys_setfsuid((uid_t)uid);
201 }
202 
sys32_setfsgid16(u16 gid)203 asmlinkage long sys32_setfsgid16(u16 gid)
204 {
205 	return sys_setfsgid((gid_t)gid);
206 }
207 
sys32_getgroups16(int gidsetsize,u16 * grouplist)208 asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
209 {
210 	u16 groups[NGROUPS];
211 	int i,j;
212 
213 	if (gidsetsize < 0)
214 		return -EINVAL;
215 	i = current->ngroups;
216 	if (gidsetsize) {
217 		if (i > gidsetsize)
218 			return -EINVAL;
219 		for(j=0;j<i;j++)
220 			groups[j] = current->groups[j];
221 		if (copy_to_user(grouplist, groups, sizeof(u16)*i))
222 			return -EFAULT;
223 	}
224 	return i;
225 }
226 
sys32_setgroups16(int gidsetsize,u16 * grouplist)227 asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
228 {
229 	u16 groups[NGROUPS];
230 	int i;
231 
232 	if (!capable(CAP_SETGID))
233 		return -EPERM;
234 	if ((unsigned) gidsetsize > NGROUPS)
235 		return -EINVAL;
236 	if (copy_from_user(groups, grouplist, gidsetsize * sizeof(u16)))
237 		return -EFAULT;
238 	for (i = 0 ; i < gidsetsize ; i++)
239 		current->groups[i] = (gid_t)groups[i];
240 	current->ngroups = gidsetsize;
241 	return 0;
242 }
243 
sys32_getuid16(void)244 asmlinkage long sys32_getuid16(void)
245 {
246 	return high2lowuid(current->uid);
247 }
248 
sys32_geteuid16(void)249 asmlinkage long sys32_geteuid16(void)
250 {
251 	return high2lowuid(current->euid);
252 }
253 
sys32_getgid16(void)254 asmlinkage long sys32_getgid16(void)
255 {
256 	return high2lowgid(current->gid);
257 }
258 
sys32_getegid16(void)259 asmlinkage long sys32_getegid16(void)
260 {
261 	return high2lowgid(current->egid);
262 }
263 
264 /* 32-bit timeval and related flotsam.  */
265 
266 struct timeval32
267 {
268     int tv_sec, tv_usec;
269 };
270 
271 struct itimerval32
272 {
273     struct timeval32 it_interval;
274     struct timeval32 it_value;
275 };
276 
get_tv32(struct timeval * o,struct timeval32 * i)277 static inline long get_tv32(struct timeval *o, struct timeval32 *i)
278 {
279 	return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
280 		(__get_user(o->tv_sec, &i->tv_sec) |
281 		 __get_user(o->tv_usec, &i->tv_usec)));
282 }
283 
put_tv32(struct timeval32 * o,struct timeval * i)284 static inline long put_tv32(struct timeval32 *o, struct timeval *i)
285 {
286 	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
287 		(__put_user(i->tv_sec, &o->tv_sec) |
288 		 __put_user(i->tv_usec, &o->tv_usec)));
289 }
290 
get_it32(struct itimerval * o,struct itimerval32 * i)291 static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
292 {
293 	return (!access_ok(VERIFY_READ, i32, sizeof(*i32)) ||
294 		(__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
295 		 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
296 		 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
297 		 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
298 }
299 
put_it32(struct itimerval32 * o,struct itimerval * i)300 static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
301 {
302 	return (!access_ok(VERIFY_WRITE, i32, sizeof(*i32)) ||
303 		(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
304 		 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
305 		 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
306 		 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
307 }
308 
309 extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
310 
sys32_ioperm(u32 from,u32 num,int on)311 asmlinkage int sys32_ioperm(u32 from, u32 num, int on)
312 {
313 	return sys_ioperm((unsigned long)from, (unsigned long)num, on);
314 }
315 
316 struct msgbuf32 { s32 mtype; char mtext[1]; };
317 
318 struct ipc_perm32
319 {
320 	key_t    	  key;
321         __kernel_uid_t32  uid;
322         __kernel_gid_t32  gid;
323         __kernel_uid_t32  cuid;
324         __kernel_gid_t32  cgid;
325         __kernel_mode_t32 mode;
326         unsigned short  seq;
327 };
328 
329 struct semid_ds32 {
330         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
331         __kernel_time_t32 sem_otime;              /* last semop time */
332         __kernel_time_t32 sem_ctime;              /* last change time */
333         u32 sem_base;              /* ptr to first semaphore in array */
334         u32 sem_pending;          /* pending operations to be processed */
335         u32 sem_pending_last;    /* last pending operation */
336         u32 undo;                  /* undo requests on this array */
337         unsigned short  sem_nsems;              /* no. of semaphores in array */
338 };
339 
340 struct semid64_ds32 {
341 	struct ipc64_perm sem_perm;		  /* this structure is the same on sparc32 and sparc64 */
342 	unsigned int	  __pad1;
343 	__kernel_time_t32 sem_otime;
344 	unsigned int	  __pad2;
345 	__kernel_time_t32 sem_ctime;
346 	u32 sem_nsems;
347 	u32 __unused1;
348 	u32 __unused2;
349 };
350 
351 struct msqid_ds32
352 {
353         struct ipc_perm32 msg_perm;
354         u32 msg_first;
355         u32 msg_last;
356         __kernel_time_t32 msg_stime;
357         __kernel_time_t32 msg_rtime;
358         __kernel_time_t32 msg_ctime;
359         u32 wwait;
360         u32 rwait;
361         unsigned short msg_cbytes;
362         unsigned short msg_qnum;
363         unsigned short msg_qbytes;
364         __kernel_ipc_pid_t32 msg_lspid;
365         __kernel_ipc_pid_t32 msg_lrpid;
366 };
367 
368 struct msqid64_ds32 {
369 	struct ipc64_perm msg_perm;
370 	unsigned int   __pad1;
371 	__kernel_time_t32 msg_stime;
372 	unsigned int   __pad2;
373 	__kernel_time_t32 msg_rtime;
374 	unsigned int   __pad3;
375 	__kernel_time_t32 msg_ctime;
376 	unsigned int  msg_cbytes;
377 	unsigned int  msg_qnum;
378 	unsigned int  msg_qbytes;
379 	__kernel_pid_t32 msg_lspid;
380 	__kernel_pid_t32 msg_lrpid;
381 	unsigned int  __unused1;
382 	unsigned int  __unused2;
383 };
384 
385 
386 struct shmid_ds32 {
387 	struct ipc_perm32       shm_perm;
388 	int                     shm_segsz;
389 	__kernel_time_t32       shm_atime;
390 	__kernel_time_t32       shm_dtime;
391 	__kernel_time_t32       shm_ctime;
392 	__kernel_ipc_pid_t32    shm_cpid;
393 	__kernel_ipc_pid_t32    shm_lpid;
394 	unsigned short          shm_nattch;
395 };
396 
397 struct shmid64_ds32 {
398 	struct ipc64_perm	shm_perm;
399 	unsigned int		__pad1;
400 	__kernel_time_t32	shm_atime;
401 	unsigned int		__pad2;
402 	__kernel_time_t32	shm_dtime;
403 	unsigned int		__pad3;
404 	__kernel_time_t32	shm_ctime;
405 	__kernel_size_t32	shm_segsz;
406 	__kernel_pid_t32	shm_cpid;
407 	__kernel_pid_t32	shm_lpid;
408 	unsigned int		shm_nattch;
409 	unsigned int		__unused1;
410 	unsigned int		__unused2;
411 };
412 
413 
414 /*
415  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
416  *
417  * This is really horribly ugly.
418  */
419 #define IPCOP_MASK(__x)	(1UL << ((__x)&~IPC_64))
do_sys32_semctl(int first,int second,int third,void * uptr)420 static int do_sys32_semctl(int first, int second, int third, void *uptr)
421 {
422 	union semun fourth;
423 	u32 pad;
424 	int err = -EINVAL;
425 
426 	if (!uptr)
427 		goto out;
428 	err = -EFAULT;
429 	if (get_user (pad, (u32 *)uptr))
430 		goto out;
431 	if ((third & ~IPC_64) == SETVAL)
432 		fourth.val = (int)pad;
433 	else
434 		fourth.__pad = (void *)A(pad);
435 	if (IPCOP_MASK (third) &
436 	    (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) | IPCOP_MASK (GETVAL) |
437 	     IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
438 	     IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) | IPCOP_MASK (IPC_RMID))) {
439 		err = sys_semctl (first, second, third, fourth);
440 	} else if (third & IPC_64) {
441 		struct semid64_ds s;
442 		struct semid64_ds32 *usp = (struct semid64_ds32 *)A(pad);
443 		mm_segment_t old_fs;
444 		int need_back_translation;
445 
446 		if (third == (IPC_SET|IPC_64)) {
447 			err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
448 			err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
449 			err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
450 			if (err)
451 				goto out;
452 			fourth.__pad = &s;
453 		}
454 		need_back_translation =
455 			(IPCOP_MASK (third) &
456 			 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
457 		if (need_back_translation)
458 			fourth.__pad = &s;
459 		old_fs = get_fs ();
460 		set_fs (KERNEL_DS);
461 		err = sys_semctl (first, second, third, fourth);
462 		set_fs (old_fs);
463 		if (need_back_translation) {
464 			int err2 = copy_to_user (&usp->sem_perm, &s.sem_perm, sizeof(struct ipc64_perm) + 2*sizeof(time_t));
465 			err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
466 			if (err2) err = -EFAULT;
467 		}
468 	} else {
469 		struct semid_ds s;
470 		struct semid_ds32 *usp = (struct semid_ds32 *)A(pad);
471 		mm_segment_t old_fs;
472 		int need_back_translation;
473 
474 		if (third == IPC_SET) {
475 			err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
476 			err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
477 			err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
478 			if (err)
479 				goto out;
480 			fourth.__pad = &s;
481 		}
482 		need_back_translation =
483 			(IPCOP_MASK (third) &
484 			 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
485 		if (need_back_translation)
486 			fourth.__pad = &s;
487 		old_fs = get_fs ();
488 		set_fs (KERNEL_DS);
489 		err = sys_semctl (first, second, third, fourth);
490 		set_fs (old_fs);
491 		if (need_back_translation) {
492 			int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
493 			err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
494 			err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
495 			err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
496 			err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
497 			err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
498 			err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
499 			err2 |= __put_user (s.sem_otime, &usp->sem_otime);
500 			err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
501 			err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
502 			if (err2) err = -EFAULT;
503 		}
504 	}
505 out:
506 	return err;
507 }
508 
do_sys32_msgsnd(int first,int second,int third,void * uptr)509 static int do_sys32_msgsnd(int first, int second, int third, void *uptr)
510 {
511 	struct msgbuf *p;
512 	struct msgbuf32 *up;
513 	mm_segment_t old_fs;
514 	int err;
515 
516 	if (second < 0)
517 		return -EINVAL;
518 
519 	p = kmalloc(second + sizeof (struct msgbuf), GFP_USER);
520 	if (!p)
521 		return -ENOMEM;
522 
523 	up = (struct msgbuf32 *)uptr;
524 	err = -EFAULT;
525 	if (get_user(p->mtype, &up->mtype) ||
526 	    __copy_from_user(p->mtext, up->mtext, second))
527 		goto out;
528 
529 	old_fs = get_fs();
530 	set_fs(KERNEL_DS);
531 	err = sys_msgsnd(first, p, second, third);
532 	set_fs(old_fs);
533 out:
534 	kfree(p);
535 	return err;
536 }
537 
do_sys32_msgrcv(int first,int second,int msgtyp,int third,int version,void * uptr)538 static int do_sys32_msgrcv (int first, int second, int msgtyp, int third,
539 			    int version, void *uptr)
540 {
541 	struct msgbuf32 *up;
542 	struct msgbuf *p;
543 	mm_segment_t old_fs;
544 	int err;
545 
546 	if (second < 0)
547 		return -EINVAL;
548 
549 	if (!version) {
550 		struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
551 		struct ipc_kludge ipck;
552 
553 		err = -EINVAL;
554 		if (!uptr)
555 			goto out;
556 		err = -EFAULT;
557 		if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
558 			goto out;
559 		uptr = (void *)A(ipck.msgp);
560 		msgtyp = ipck.msgtyp;
561 	}
562 	err = -ENOMEM;
563 	p = kmalloc (second + sizeof (struct msgbuf), GFP_USER);
564 	if (!p)
565 		goto out;
566 	old_fs = get_fs ();
567 	set_fs (KERNEL_DS);
568 	err = sys_msgrcv (first, p, second, msgtyp, third);
569 	set_fs (old_fs);
570 	if (err < 0)
571 		goto free_then_out;
572 	up = (struct msgbuf32 *)uptr;
573 	if (put_user (p->mtype, &up->mtype) ||
574 	    __copy_to_user (up->mtext, p->mtext, err))
575 		err = -EFAULT;
576 free_then_out:
577 	kfree (p);
578 out:
579 	return err;
580 }
581 
do_sys32_msgctl(int first,int second,void * uptr)582 static int do_sys32_msgctl (int first, int second, void *uptr)
583 {
584 	int err;
585 
586 	if (IPCOP_MASK (second) &
587 	    (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
588 	     IPCOP_MASK (IPC_RMID))) {
589 		err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
590 	} else if (second & IPC_64) {
591 		struct msqid64_ds m;
592 		struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
593 		mm_segment_t old_fs;
594 
595 		if (second == (IPC_SET|IPC_64)) {
596 			err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
597 			err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
598 			err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
599 			err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
600 			if (err)
601 				goto out;
602 		}
603 		old_fs = get_fs ();
604 		set_fs (KERNEL_DS);
605 		err = sys_msgctl (first, second, (struct msqid_ds *)&m);
606 		set_fs (old_fs);
607 		if (IPCOP_MASK (second) &
608 		    (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
609 			int err2 = copy_to_user(&up->msg_perm, &m.msg_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
610 			err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
611 			err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
612 			err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
613 			err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
614 			err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
615 			if (err2)
616 				err = -EFAULT;
617 		}
618 	} else {
619 		struct msqid_ds m;
620 		struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
621 		mm_segment_t old_fs;
622 
623 		if (second == IPC_SET) {
624 			err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
625 			err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
626 			err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
627 			err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
628 			if (err)
629 				goto out;
630 		}
631 		old_fs = get_fs ();
632 		set_fs (KERNEL_DS);
633 		err = sys_msgctl (first, second, &m);
634 		set_fs (old_fs);
635 		if (IPCOP_MASK (second) &
636 		    (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
637 			int err2 = put_user (m.msg_perm.key, &up->msg_perm.key);
638 			err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid);
639 			err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid);
640 			err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid);
641 			err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid);
642 			err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode);
643 			err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq);
644 			err2 |= __put_user (m.msg_stime, &up->msg_stime);
645 			err2 |= __put_user (m.msg_rtime, &up->msg_rtime);
646 			err2 |= __put_user (m.msg_ctime, &up->msg_ctime);
647 			err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
648 			err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
649 			err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
650 			err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
651 			err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
652 			if (err2)
653 				err = -EFAULT;
654 		}
655 	}
656 
657 out:
658 	return err;
659 }
660 
do_sys32_shmat(int first,int second,u32 third,int version,void * uptr)661 static int do_sys32_shmat(int first, int second, u32 third, int version, void *uptr)
662 {
663 	unsigned long raddr;
664 	u32 *uaddr = (u32 *)A(third);
665 	int err = -EINVAL;
666 
667 	if (version == 1)
668 		goto out;
669 	err = sys_shmat(first, uptr, second, &raddr);
670 	if (err)
671 		goto out;
672 	err = put_user(raddr, uaddr);
673 out:
674 	return err;
675 }
676 
do_sys32_shmctl(int first,int second,void * uptr)677 static int do_sys32_shmctl (int first, int second, void *uptr)
678 {
679 	int err;
680 
681 	if (IPCOP_MASK (second) &
682 	    (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | IPCOP_MASK (SHM_UNLOCK) |
683 	     IPCOP_MASK (IPC_RMID))) {
684 		if (second == (IPC_INFO|IPC_64))
685 			second = IPC_INFO; /* So that we don't have to translate it */
686 		err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
687 	} else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {
688 		struct shmid64_ds s;
689 		struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
690 		mm_segment_t old_fs;
691 
692 		if (second == (IPC_SET|IPC_64)) {
693 			err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
694 			err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
695 			err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
696 			if (err)
697 				goto out;
698 		}
699 		old_fs = get_fs ();
700 		set_fs (KERNEL_DS);
701 		err = sys_shmctl (first, second, (struct shmid_ds *)&s);
702 		set_fs (old_fs);
703 		if (err < 0)
704 			goto out;
705 
706 		/* Mask it even in this case so it becomes a CSE. */
707 		if (IPCOP_MASK (second) &
708 		    (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
709 			int err2 = copy_to_user (&up->shm_perm, &s.shm_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
710 			err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
711 			err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
712 			err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
713 			err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
714 			if (err2)
715 				err = -EFAULT;
716 		}
717 	} else {
718 		struct shmid_ds s;
719 		struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
720 		mm_segment_t old_fs;
721 
722 		second &= ~IPC_64;
723 		if (second == IPC_SET) {
724 			err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
725 			err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
726 			err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
727 			if (err)
728 				goto out;
729 		}
730 		old_fs = get_fs ();
731 		set_fs (KERNEL_DS);
732 		err = sys_shmctl (first, second, &s);
733 		set_fs (old_fs);
734 		if (err < 0)
735 			goto out;
736 
737 		/* Mask it even in this case so it becomes a CSE. */
738 		if (second == SHM_INFO) {
739 			struct shm_info32 {
740 				int used_ids;
741 				u32 shm_tot, shm_rss, shm_swp;
742 				u32 swap_attempts, swap_successes;
743 			} *uip = (struct shm_info32 *)uptr;
744 			struct shm_info *kp = (struct shm_info *)&s;
745 			int err2 = put_user (kp->used_ids, &uip->used_ids);
746 			err2 |= __put_user (kp->shm_tot, &uip->shm_tot);
747 			err2 |= __put_user (kp->shm_rss, &uip->shm_rss);
748 			err2 |= __put_user (kp->shm_swp, &uip->shm_swp);
749 			err2 |= __put_user (kp->swap_attempts, &uip->swap_attempts);
750 			err2 |= __put_user (kp->swap_successes, &uip->swap_successes);
751 			if (err2)
752 				err = -EFAULT;
753 		} else if (IPCOP_MASK (second) &
754 			   (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
755 			int err2 = put_user (s.shm_perm.key, &up->shm_perm.key);
756 			err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid);
757 			err2 |= __put_user (high2lowuid(s.shm_perm.gid), &up->shm_perm.gid);
758 			err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid);
759 			err2 |= __put_user (high2lowuid(s.shm_perm.cgid), &up->shm_perm.cgid);
760 			err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode);
761 			err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq);
762 			err2 |= __put_user (s.shm_atime, &up->shm_atime);
763 			err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
764 			err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
765 			err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
766 			err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
767 			err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
768 			err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
769 			if (err2)
770 				err = -EFAULT;
771 		}
772 	}
773 out:
774 	return err;
775 }
776 
alloc_user_space(long len)777 static __inline__ void *alloc_user_space(long len)
778 {
779 	struct pt_regs *regs = current->thread.kregs;
780 	unsigned long usp = regs->u_regs[UREG_I6];
781 
782 	if (!(current->thread.flags & SPARC_FLAG_32BIT))
783 		usp += STACK_BIAS;
784 	else
785 		usp &= 0xffffffffUL;
786 
787 	return (void *) (usp - len);
788 }
789 
790 struct timespec32 {
791 	s32    tv_sec;
792 	s32    tv_nsec;
793 };
794 
sys32_semtimedop(int semid,struct sembuf * tsems,int nsems,const struct timespec32 * timeout32)795 static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems,
796 			    const struct timespec32 *timeout32)
797 {
798 	struct timespec32 t32;
799 	struct timespec *t64 = alloc_user_space(sizeof(*t64));
800 
801 	if (copy_from_user(&t32, timeout32, sizeof(t32)))
802 		return -EFAULT;
803 
804 	if (put_user(t32.tv_sec, &t64->tv_sec) ||
805 	    put_user(t32.tv_nsec, &t64->tv_nsec))
806 		return -EFAULT;
807 
808 	return sys_semtimedop(semid, tsems, nsems, t64);
809 }
810 
sys32_ipc(u32 call,u32 first,u32 second,u32 third,s32 __ptr,s32 __fifth)811 asmlinkage int sys32_ipc (u32 call, u32 first, u32 second, u32 third, s32 __ptr, s32 __fifth)
812 {
813 	int version, err;
814 	u32 ptr = (u32) __ptr;
815 	u32 fifth = (u32) __fifth;
816 
817 	version = call >> 16; /* hack for backward compatibility */
818 	call &= 0xffff;
819 
820 	if (call <= SEMCTL)
821 		switch (call) {
822 		case SEMOP:
823 			/* struct sembuf is the same on 32 and 64bit :)) */
824 			err = sys_semtimedop((int)first,
825 					     (struct sembuf *)A(ptr),
826 					     second, NULL);
827 			goto out;
828 		case SEMTIMEDOP:
829 			err = sys32_semtimedop((int)first,
830 					       (struct sembuf *)A(ptr),
831 					       second,
832 					       (const struct timespec32 *)
833 					       A(fifth));
834 		case SEMGET:
835 			err = sys_semget((key_t)first, (int)second,
836 					 (int)third);
837 			goto out;
838 		case SEMCTL:
839 			err = do_sys32_semctl((int)first, (int)second,
840 					      (int)third, (void *) A(ptr));
841 			goto out;
842 		default:
843 			err = -ENOSYS;
844 			goto out;
845 		};
846 	if (call <= MSGCTL)
847 		switch (call) {
848 		case MSGSND:
849 			err = do_sys32_msgsnd((int)first, (int)second,
850 					      (int)third, (void *)A(ptr));
851 			goto out;
852 		case MSGRCV:
853 			err = do_sys32_msgrcv((int)first, (int)second,
854 					      (int)fifth, (int)third,
855 					      version, (void *)A(ptr));
856 			goto out;
857 		case MSGGET:
858 			err = sys_msgget((key_t)first, (int)second);
859 			goto out;
860 		case MSGCTL:
861 			err = do_sys32_msgctl((int)first, (int)second,
862 					      (void *)A(ptr));
863 			goto out;
864 		default:
865 			err = -ENOSYS;
866 			goto out;
867 		}
868 	if (call <= SHMCTL)
869 		switch (call) {
870 		case SHMAT:
871 			err = do_sys32_shmat((int)first, (int)second, third,
872 					     version, (void *)A(ptr));
873 			goto out;
874 		case SHMDT:
875 			err = sys_shmdt((char *)A(ptr));
876 			goto out;
877 		case SHMGET:
878 			err = sys_shmget((key_t)first, second, (int)third);
879 			goto out;
880 		case SHMCTL:
881 			err = do_sys32_shmctl((int)first, (int)second,
882 					      (void *)A(ptr));
883 			goto out;
884 		default:
885 			err = -ENOSYS;
886 			goto out;
887 		}
888 
889 	err = -ENOSYS;
890 
891 out:
892 	return err;
893 }
894 
get_flock(struct flock * kfl,struct flock32 * ufl)895 static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
896 {
897 	int err;
898 
899 	err = get_user(kfl->l_type, &ufl->l_type);
900 	err |= __get_user(kfl->l_whence, &ufl->l_whence);
901 	err |= __get_user(kfl->l_start, &ufl->l_start);
902 	err |= __get_user(kfl->l_len, &ufl->l_len);
903 	err |= __get_user(kfl->l_pid, &ufl->l_pid);
904 	return err;
905 }
906 
put_flock(struct flock * kfl,struct flock32 * ufl)907 static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
908 {
909 	int err;
910 
911 	err = __put_user(kfl->l_type, &ufl->l_type);
912 	err |= __put_user(kfl->l_whence, &ufl->l_whence);
913 	err |= __put_user(kfl->l_start, &ufl->l_start);
914 	err |= __put_user(kfl->l_len, &ufl->l_len);
915 	err |= __put_user(kfl->l_pid, &ufl->l_pid);
916 	return err;
917 }
918 
919 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
920 
sys32_fcntl(unsigned int fd,unsigned int cmd,unsigned long arg)921 asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
922 {
923 	switch (cmd) {
924 	case F_GETLK:
925 	case F_SETLK:
926 	case F_SETLKW:
927 		{
928 			struct flock f;
929 			mm_segment_t old_fs;
930 			long ret;
931 
932 			if (get_flock(&f, (struct flock32 *)arg))
933 				return -EFAULT;
934 			old_fs = get_fs(); set_fs (KERNEL_DS);
935 			ret = sys_fcntl(fd, cmd, (unsigned long)&f);
936 			set_fs (old_fs);
937 			if (ret) return ret;
938 			if (put_flock(&f, (struct flock32 *)arg))
939 				return -EFAULT;
940 			return 0;
941 		}
942 	default:
943 		return sys_fcntl(fd, cmd, (unsigned long)arg);
944 	}
945 }
946 
sys32_fcntl64(unsigned int fd,unsigned int cmd,unsigned long arg)947 asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
948 {
949 	if (cmd >= F_GETLK64 && cmd <= F_SETLKW64)
950 		return sys_fcntl(fd, cmd + F_GETLK - F_GETLK64, arg);
951 	return sys32_fcntl(fd, cmd, arg);
952 }
953 
954 struct user_dqblk32 {
955     __u32 dqb_bhardlimit;
956     __u32 dqb_bsoftlimit;
957     __u32 dqb_curblocks;
958     __u32 dqb_ihardlimit;
959     __u32 dqb_isoftlimit;
960     __u32 dqb_curinodes;
961     __kernel_time_t32 dqb_btime;
962     __kernel_time_t32 dqb_itime;
963 };
964 
965 extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
966 
sys32_quotactl(int cmd,const char * special,int id,caddr_t addr)967 asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr)
968 {
969 	int cmds = cmd >> SUBCMDSHIFT;
970 	int err;
971 	struct v1c_mem_dqblk d;
972 	mm_segment_t old_fs;
973 	char *spec;
974 
975 	switch (cmds) {
976 	case Q_V1_GETQUOTA:
977 		break;
978 	case Q_V1_SETQUOTA:
979 	case Q_V1_SETUSE:
980 	case Q_V1_SETQLIM:
981 		if (copy_from_user(&d, addr, sizeof(struct user_dqblk32)))
982 			return -EFAULT;
983 		d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime;
984 		d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime;
985 		break;
986 	default:
987 		return sys_quotactl(cmd, special, id, addr);
988 	}
989 	spec = getname(special);
990 	err = PTR_ERR(spec);
991 	if (IS_ERR(spec))
992 		return err;
993 	old_fs = get_fs();
994 	set_fs (KERNEL_DS);
995 	err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
996 	set_fs (old_fs);
997 	putname (spec);
998 	if (cmds == Q_V1_GETQUOTA) {
999 		__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
1000 		((struct user_dqblk32 *)&d)->dqb_itime = i;
1001 		((struct user_dqblk32 *)&d)->dqb_btime = b;
1002 		if (copy_to_user(addr, &d, sizeof(struct user_dqblk32)))
1003 			return -EFAULT;
1004 	}
1005 	return err;
1006 }
1007 
put_statfs(struct statfs32 * ubuf,struct statfs * kbuf)1008 static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
1009 {
1010 	int err;
1011 
1012 	err = put_user (kbuf->f_type, &ubuf->f_type);
1013 	err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
1014 	err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
1015 	err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
1016 	err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
1017 	err |= __put_user (kbuf->f_files, &ubuf->f_files);
1018 	err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
1019 	err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
1020 	err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
1021 	err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
1022 	return err;
1023 }
1024 
1025 extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
1026 
sys32_statfs(const char * path,struct statfs32 * buf)1027 asmlinkage int sys32_statfs(const char * path, struct statfs32 *buf)
1028 {
1029 	int ret;
1030 	struct statfs s;
1031 	mm_segment_t old_fs = get_fs();
1032 	char *pth;
1033 
1034 	pth = getname (path);
1035 	ret = PTR_ERR(pth);
1036 	if (!IS_ERR(pth)) {
1037 		set_fs (KERNEL_DS);
1038 		ret = sys_statfs((const char *)pth, &s);
1039 		set_fs (old_fs);
1040 		putname (pth);
1041 		if (put_statfs(buf, &s))
1042 			return -EFAULT;
1043 	}
1044 	return ret;
1045 }
1046 
1047 extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);
1048 
sys32_fstatfs(unsigned int fd,struct statfs32 * buf)1049 asmlinkage int sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
1050 {
1051 	int ret;
1052 	struct statfs s;
1053 	mm_segment_t old_fs = get_fs();
1054 
1055 	set_fs (KERNEL_DS);
1056 	ret = sys_fstatfs(fd, &s);
1057 	set_fs (old_fs);
1058 	if (put_statfs(buf, &s))
1059 		return -EFAULT;
1060 	return ret;
1061 }
1062 
1063 extern asmlinkage long sys_truncate(const char * path, unsigned long length);
1064 extern asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
1065 
sys32_truncate64(const char * path,unsigned long high,unsigned long low)1066 asmlinkage int sys32_truncate64(const char * path, unsigned long high, unsigned long low)
1067 {
1068 	if ((int)high < 0)
1069 		return -EINVAL;
1070 	else
1071 		return sys_truncate(path, (high << 32) | low);
1072 }
1073 
sys32_ftruncate64(unsigned int fd,unsigned long high,unsigned long low)1074 asmlinkage int sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
1075 {
1076 	if ((int)high < 0)
1077 		return -EINVAL;
1078 	else
1079 		return sys_ftruncate(fd, (high << 32) | low);
1080 }
1081 
1082 extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
1083 
1084 struct utimbuf32 {
1085 	__kernel_time_t32 actime, modtime;
1086 };
1087 
sys32_utime(char * filename,struct utimbuf32 * times)1088 asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
1089 {
1090 	struct utimbuf t;
1091 	mm_segment_t old_fs;
1092 	int ret;
1093 	char *filenam;
1094 
1095 	if (!times)
1096 		return sys_utime(filename, NULL);
1097 	if (get_user (t.actime, &times->actime) ||
1098 	    __get_user (t.modtime, &times->modtime))
1099 		return -EFAULT;
1100 	filenam = getname (filename);
1101 	ret = PTR_ERR(filenam);
1102 	if (!IS_ERR(filenam)) {
1103 		old_fs = get_fs();
1104 		set_fs (KERNEL_DS);
1105 		ret = sys_utime(filenam, &t);
1106 		set_fs (old_fs);
1107 		putname (filenam);
1108 	}
1109 	return ret;
1110 }
1111 
1112 struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
1113 
1114 typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
1115 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
1116 
do_readv_writev32(int type,struct file * file,const struct iovec32 * vector,u32 count)1117 static long do_readv_writev32(int type, struct file *file,
1118 			      const struct iovec32 *vector, u32 count)
1119 {
1120 	__kernel_ssize_t32 tot_len;
1121 	struct iovec iovstack[UIO_FASTIOV];
1122 	struct iovec *iov=iovstack, *ivp;
1123 	long retval, i;
1124 	io_fn_t fn;
1125 	iov_fn_t fnv;
1126 
1127 	/* First get the "struct iovec" from user memory and
1128 	 * verify all the pointers
1129 	 */
1130 	retval = 0;
1131 	if (!count)
1132 		goto out_nofree;
1133 	retval = -EFAULT;
1134 	if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
1135 		goto out_nofree;
1136 	retval = -EINVAL;
1137 	if (count > UIO_MAXIOV)
1138 		goto out_nofree;
1139 	if (count > UIO_FASTIOV) {
1140 		retval = -ENOMEM;
1141 		iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
1142 		if (!iov)
1143 			goto out_nofree;
1144 	}
1145 
1146 	tot_len = 0;
1147 	i = count;
1148 	ivp = iov;
1149 	retval = -EINVAL;
1150 	while(i > 0) {
1151 		__kernel_ssize_t32 tmp = tot_len;
1152 		__kernel_ssize_t32 len;
1153 		u32 buf;
1154 
1155 		__get_user(len, &vector->iov_len);
1156 		__get_user(buf, &vector->iov_base);
1157 		if (len < 0)	/* size_t not fittina an ssize_t32 .. */
1158 			goto out;
1159 		tot_len += len;
1160 		if (tot_len < tmp) /* maths overflow on the ssize_t32 */
1161 			goto out;
1162 		ivp->iov_base = (void *)A(buf);
1163 		ivp->iov_len = (__kernel_size_t) len;
1164 		vector++;
1165 		ivp++;
1166 		i--;
1167 	}
1168 
1169 	/* VERIFY_WRITE actually means a read, as we write to user space */
1170 	retval = rw_verify_area((type == VERIFY_WRITE ? READ : WRITE),
1171 				   file, &file->f_pos, tot_len);
1172 	if (retval)
1173 		goto out;
1174 
1175 	/* VERIFY_WRITE actually means a read, as we write to user space */
1176 	fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev);
1177 	if (fnv) {
1178 		retval = fnv(file, iov, count, &file->f_pos);
1179 		goto out;
1180 	}
1181 
1182 	fn = (type == VERIFY_WRITE ? file->f_op->read :
1183 	      (io_fn_t) file->f_op->write);
1184 
1185 	ivp = iov;
1186 	while (count > 0) {
1187 		void * base;
1188 		int len, nr;
1189 
1190 		base = ivp->iov_base;
1191 		len = ivp->iov_len;
1192 		ivp++;
1193 		count--;
1194 		nr = fn(file, base, len, &file->f_pos);
1195 		if (nr < 0) {
1196 			if (!retval)
1197 				retval = nr;
1198 			break;
1199 		}
1200 		retval += nr;
1201 		if (nr != len)
1202 			break;
1203 	}
1204 out:
1205 	if (iov != iovstack)
1206 		kfree(iov);
1207 out_nofree:
1208 	/* VERIFY_WRITE actually means a read, as we write to user space */
1209 	if ((retval + (type == VERIFY_WRITE)) > 0)
1210 		dnotify_parent(file->f_dentry,
1211 			(type == VERIFY_WRITE) ? DN_ACCESS : DN_MODIFY);
1212 
1213 	return retval;
1214 }
1215 
sys32_readv(int fd,struct iovec32 * vector,u32 count)1216 asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count)
1217 {
1218 	struct file *file;
1219 	long ret = -EBADF;
1220 
1221 	file = fget(fd);
1222 	if(!file)
1223 		goto bad_file;
1224 
1225 	if (file->f_op && (file->f_mode & FMODE_READ) &&
1226 	    (file->f_op->readv || file->f_op->read))
1227 		ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
1228 	fput(file);
1229 
1230 bad_file:
1231 	return ret;
1232 }
1233 
sys32_writev(int fd,struct iovec32 * vector,u32 count)1234 asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count)
1235 {
1236 	struct file *file;
1237 	int ret = -EBADF;
1238 
1239 	file = fget(fd);
1240 	if(!file)
1241 		goto bad_file;
1242 	if (file->f_op && (file->f_mode & FMODE_WRITE) &&
1243 	    (file->f_op->writev || file->f_op->write))
1244 		ret = do_readv_writev32(VERIFY_READ, file, vector, count);
1245 	fput(file);
1246 
1247 bad_file:
1248 	return ret;
1249 }
1250 
1251 /* readdir & getdents */
1252 
1253 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
1254 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1255 
1256 struct old_linux_dirent32 {
1257 	u32		d_ino;
1258 	u32		d_offset;
1259 	unsigned short	d_namlen;
1260 	char		d_name[1];
1261 };
1262 
1263 struct readdir_callback32 {
1264 	struct old_linux_dirent32 * dirent;
1265 	int count;
1266 };
1267 
fillonedir(void * __buf,const char * name,int namlen,loff_t offset,ino_t ino,unsigned int d_type)1268 static int fillonedir(void * __buf, const char * name, int namlen,
1269 		      loff_t offset, ino_t ino, unsigned int d_type)
1270 {
1271 	struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
1272 	struct old_linux_dirent32 * dirent;
1273 
1274 	if (buf->count)
1275 		return -EINVAL;
1276 	buf->count++;
1277 	dirent = buf->dirent;
1278 	put_user(ino, &dirent->d_ino);
1279 	put_user(offset, &dirent->d_offset);
1280 	put_user(namlen, &dirent->d_namlen);
1281 	copy_to_user(dirent->d_name, name, namlen);
1282 	put_user(0, dirent->d_name + namlen);
1283 	return 0;
1284 }
1285 
old32_readdir(unsigned int fd,struct old_linux_dirent32 * dirent,unsigned int count)1286 asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
1287 {
1288 	int error = -EBADF;
1289 	struct file * file;
1290 	struct readdir_callback32 buf;
1291 
1292 	file = fget(fd);
1293 	if (!file)
1294 		goto out;
1295 
1296 	buf.count = 0;
1297 	buf.dirent = dirent;
1298 
1299 	error = vfs_readdir(file, fillonedir, &buf);
1300 	if (error < 0)
1301 		goto out_putf;
1302 	error = buf.count;
1303 
1304 out_putf:
1305 	fput(file);
1306 out:
1307 	return error;
1308 }
1309 
1310 struct linux_dirent32 {
1311 	u32		d_ino;
1312 	u32		d_off;
1313 	unsigned short	d_reclen;
1314 	char		d_name[1];
1315 };
1316 
1317 struct getdents_callback32 {
1318 	struct linux_dirent32 * current_dir;
1319 	struct linux_dirent32 * previous;
1320 	int count;
1321 	int error;
1322 };
1323 
filldir(void * __buf,const char * name,int namlen,loff_t offset,ino_t ino,unsigned int d_type)1324 static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
1325 		   unsigned int d_type)
1326 {
1327 	struct linux_dirent32 * dirent;
1328 	struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
1329 	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
1330 
1331 	buf->error = -EINVAL;	/* only used if we fail.. */
1332 	if (reclen > buf->count)
1333 		return -EINVAL;
1334 	dirent = buf->previous;
1335 	if (dirent)
1336 		put_user(offset, &dirent->d_off);
1337 	dirent = buf->current_dir;
1338 	buf->previous = dirent;
1339 	put_user(ino, &dirent->d_ino);
1340 	put_user(reclen, &dirent->d_reclen);
1341 	copy_to_user(dirent->d_name, name, namlen);
1342 	put_user(0, dirent->d_name + namlen);
1343 	dirent = (void *) dirent + reclen;
1344 	buf->current_dir = dirent;
1345 	buf->count -= reclen;
1346 	return 0;
1347 }
1348 
sys32_getdents(unsigned int fd,struct linux_dirent32 * dirent,unsigned int count)1349 asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
1350 {
1351 	struct file * file;
1352 	struct linux_dirent32 * lastdirent;
1353 	struct getdents_callback32 buf;
1354 	int error = -EBADF;
1355 
1356 	file = fget(fd);
1357 	if (!file)
1358 		goto out;
1359 
1360 	buf.current_dir = dirent;
1361 	buf.previous = NULL;
1362 	buf.count = count;
1363 	buf.error = 0;
1364 
1365 	error = vfs_readdir(file, filldir, &buf);
1366 	if (error < 0)
1367 		goto out_putf;
1368 	lastdirent = buf.previous;
1369 	error = buf.error;
1370 	if(lastdirent) {
1371 		put_user(file->f_pos, &lastdirent->d_off);
1372 		error = count - buf.count;
1373 	}
1374 out_putf:
1375 	fput(file);
1376 out:
1377 	return error;
1378 }
1379 
1380 /* end of readdir & getdents */
1381 
1382 /*
1383  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
1384  * 64-bit unsigned longs.
1385  */
1386 
1387 static inline int
get_fd_set32(unsigned long n,unsigned long * fdset,u32 * ufdset)1388 get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
1389 {
1390 	if (ufdset) {
1391 		unsigned long odd;
1392 
1393 		if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
1394 			return -EFAULT;
1395 
1396 		odd = n & 1UL;
1397 		n &= ~1UL;
1398 		while (n) {
1399 			unsigned long h, l;
1400 			__get_user(l, ufdset);
1401 			__get_user(h, ufdset+1);
1402 			ufdset += 2;
1403 			*fdset++ = h << 32 | l;
1404 			n -= 2;
1405 		}
1406 		if (odd)
1407 			__get_user(*fdset, ufdset);
1408 	} else {
1409 		/* Tricky, must clear full unsigned long in the
1410 		 * kernel fdset at the end, this makes sure that
1411 		 * actually happens.
1412 		 */
1413 		memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
1414 	}
1415 	return 0;
1416 }
1417 
1418 static inline void
set_fd_set32(unsigned long n,u32 * ufdset,unsigned long * fdset)1419 set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
1420 {
1421 	unsigned long odd;
1422 
1423 	if (!ufdset)
1424 		return;
1425 
1426 	odd = n & 1UL;
1427 	n &= ~1UL;
1428 	while (n) {
1429 		unsigned long h, l;
1430 		l = *fdset++;
1431 		h = l >> 32;
1432 		__put_user(l, ufdset);
1433 		__put_user(h, ufdset+1);
1434 		ufdset += 2;
1435 		n -= 2;
1436 	}
1437 	if (odd)
1438 		__put_user(*fdset, ufdset);
1439 }
1440 
1441 #define MAX_SELECT_SECONDS \
1442 	((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1443 
sys32_select(int n,u32 * inp,u32 * outp,u32 * exp,u32 tvp_x)1444 asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
1445 {
1446 	fd_set_bits fds;
1447 	struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
1448 	char *bits;
1449 	unsigned long nn;
1450 	long timeout;
1451 	int ret, size;
1452 
1453 	timeout = MAX_SCHEDULE_TIMEOUT;
1454 	if (tvp) {
1455 		time_t sec, usec;
1456 
1457 		if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
1458 		    || (ret = __get_user(sec, &tvp->tv_sec))
1459 		    || (ret = __get_user(usec, &tvp->tv_usec)))
1460 			goto out_nofds;
1461 
1462 		ret = -EINVAL;
1463 		if(sec < 0 || usec < 0)
1464 			goto out_nofds;
1465 
1466 		if ((unsigned long) sec < MAX_SELECT_SECONDS) {
1467 			timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
1468 			timeout += sec * (unsigned long) HZ;
1469 		}
1470 	}
1471 
1472 	ret = -EINVAL;
1473 	if (n < 0)
1474 		goto out_nofds;
1475 	if (n > current->files->max_fdset)
1476 		n = current->files->max_fdset;
1477 
1478 	/*
1479 	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1480 	 * since we used fdset we need to allocate memory in units of
1481 	 * long-words.
1482 	 */
1483 	ret = -ENOMEM;
1484 	size = FDS_BYTES(n);
1485 	bits = kmalloc(6 * size, GFP_KERNEL);
1486 	if (!bits)
1487 		goto out_nofds;
1488 	fds.in      = (unsigned long *)  bits;
1489 	fds.out     = (unsigned long *) (bits +   size);
1490 	fds.ex      = (unsigned long *) (bits + 2*size);
1491 	fds.res_in  = (unsigned long *) (bits + 3*size);
1492 	fds.res_out = (unsigned long *) (bits + 4*size);
1493 	fds.res_ex  = (unsigned long *) (bits + 5*size);
1494 
1495 	nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
1496 	if ((ret = get_fd_set32(nn, fds.in, inp)) ||
1497 	    (ret = get_fd_set32(nn, fds.out, outp)) ||
1498 	    (ret = get_fd_set32(nn, fds.ex, exp)))
1499 		goto out;
1500 	zero_fd_set(n, fds.res_in);
1501 	zero_fd_set(n, fds.res_out);
1502 	zero_fd_set(n, fds.res_ex);
1503 
1504 	ret = do_select(n, &fds, &timeout);
1505 
1506 	if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
1507 		time_t sec = 0, usec = 0;
1508 		if (timeout) {
1509 			sec = timeout / HZ;
1510 			usec = timeout % HZ;
1511 			usec *= (1000000/HZ);
1512 		}
1513 		put_user(sec, &tvp->tv_sec);
1514 		put_user(usec, &tvp->tv_usec);
1515 	}
1516 
1517 	if (ret < 0)
1518 		goto out;
1519 	if (!ret) {
1520 		ret = -ERESTARTNOHAND;
1521 		if (signal_pending(current))
1522 			goto out;
1523 		ret = 0;
1524 	}
1525 
1526 	set_fd_set32(nn, inp, fds.res_in);
1527 	set_fd_set32(nn, outp, fds.res_out);
1528 	set_fd_set32(nn, exp, fds.res_ex);
1529 
1530 out:
1531 	kfree(bits);
1532 out_nofds:
1533 	return ret;
1534 }
1535 
cp_new_stat32(struct inode * inode,struct stat32 * statbuf)1536 static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
1537 {
1538 	unsigned long ino, blksize, blocks;
1539 	kdev_t dev, rdev;
1540 	umode_t mode;
1541 	nlink_t nlink;
1542 	uid_t uid;
1543 	gid_t gid;
1544 	off_t size;
1545 	time_t atime, mtime, ctime;
1546 	int err;
1547 
1548 	/* Stream the loads of inode data into the load buffer,
1549 	 * then we push it all into the store buffer below.  This
1550 	 * should give optimal cache performance.
1551 	 */
1552 	ino = inode->i_ino;
1553 	dev = inode->i_dev;
1554 	mode = inode->i_mode;
1555 	nlink = inode->i_nlink;
1556 	uid = inode->i_uid;
1557 	gid = inode->i_gid;
1558 	rdev = inode->i_rdev;
1559 	size = inode->i_size;
1560 	atime = inode->i_atime;
1561 	mtime = inode->i_mtime;
1562 	ctime = inode->i_ctime;
1563 	blksize = inode->i_blksize;
1564 	blocks = inode->i_blocks;
1565 
1566 	err  = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
1567 	err |= put_user(ino, &statbuf->st_ino);
1568 	err |= put_user(mode, &statbuf->st_mode);
1569 	err |= put_user(nlink, &statbuf->st_nlink);
1570 	err |= put_user(high2lowuid(uid), &statbuf->st_uid);
1571 	err |= put_user(high2lowgid(gid), &statbuf->st_gid);
1572 	err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
1573 	err |= put_user(size, &statbuf->st_size);
1574 	err |= put_user(atime, &statbuf->st_atime);
1575 	err |= put_user(0, &statbuf->__unused1);
1576 	err |= put_user(mtime, &statbuf->st_mtime);
1577 	err |= put_user(0, &statbuf->__unused2);
1578 	err |= put_user(ctime, &statbuf->st_ctime);
1579 	err |= put_user(0, &statbuf->__unused3);
1580 	if (blksize) {
1581 		err |= put_user(blksize, &statbuf->st_blksize);
1582 		err |= put_user(blocks, &statbuf->st_blocks);
1583 	} else {
1584 		unsigned int tmp_blocks;
1585 
1586 #define D_B   7
1587 #define I_B   (BLOCK_SIZE / sizeof(unsigned short))
1588 		tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
1589 		if (tmp_blocks > D_B) {
1590 			unsigned int indirect;
1591 
1592 			indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
1593 			tmp_blocks += indirect;
1594 			if (indirect > 1) {
1595 				indirect = (indirect - 1 + I_B - 1) / I_B;
1596 				tmp_blocks += indirect;
1597 				if (indirect > 1)
1598 					tmp_blocks++;
1599 			}
1600 		}
1601 		err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
1602 		err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
1603 #undef D_B
1604 #undef I_B
1605 	}
1606 	err |= put_user(0, &statbuf->__unused4[0]);
1607 	err |= put_user(0, &statbuf->__unused4[1]);
1608 
1609 	return err;
1610 }
1611 
1612 /* Perhaps this belongs in fs.h or similar. -DaveM */
1613 static __inline__ int
do_revalidate(struct dentry * dentry)1614 do_revalidate(struct dentry *dentry)
1615 {
1616 	struct inode * inode = dentry->d_inode;
1617 	if (inode->i_op && inode->i_op->revalidate)
1618 		return inode->i_op->revalidate(dentry);
1619 	return 0;
1620 }
1621 
sys32_newstat(char * filename,struct stat32 * statbuf)1622 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
1623 {
1624 	struct nameidata nd;
1625 	int error;
1626 
1627 	error = user_path_walk(filename, &nd);
1628 	if (!error) {
1629 		error = do_revalidate(nd.dentry);
1630 		if (!error)
1631 			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
1632 		path_release(&nd);
1633 	}
1634 	return error;
1635 }
1636 
sys32_newlstat(char * filename,struct stat32 * statbuf)1637 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
1638 {
1639 	struct nameidata nd;
1640 	int error;
1641 
1642 	error = user_path_walk_link(filename, &nd);
1643 	if (!error) {
1644 		error = do_revalidate(nd.dentry);
1645 		if (!error)
1646 			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
1647 
1648 		path_release(&nd);
1649 	}
1650 	return error;
1651 }
1652 
sys32_newfstat(unsigned int fd,struct stat32 * statbuf)1653 asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
1654 {
1655 	struct file *f;
1656 	int err = -EBADF;
1657 
1658 	f = fget(fd);
1659 	if (f) {
1660 		struct dentry * dentry = f->f_dentry;
1661 
1662 		err = do_revalidate(dentry);
1663 		if (!err)
1664 			err = cp_new_stat32(dentry->d_inode, statbuf);
1665 		fput(f);
1666 	}
1667 	return err;
1668 }
1669 
1670 extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
1671 
sys32_sysfs(int option,u32 arg1,u32 arg2)1672 asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2)
1673 {
1674 	return sys_sysfs(option, arg1, arg2);
1675 }
1676 
1677 struct ncp_mount_data32_v3 {
1678         int version;
1679         unsigned int ncp_fd;
1680         __kernel_uid_t32 mounted_uid;
1681         __kernel_pid_t32 wdog_pid;
1682         unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
1683         unsigned int time_out;
1684         unsigned int retry_count;
1685         unsigned int flags;
1686         __kernel_uid_t32 uid;
1687         __kernel_gid_t32 gid;
1688         __kernel_mode_t32 file_mode;
1689         __kernel_mode_t32 dir_mode;
1690 };
1691 
1692 struct ncp_mount_data32_v4 {
1693 	int version;
1694 	/* all members below are "long" in ABI ... i.e. 32bit on sparc32, while 64bits on sparc64 */
1695 	unsigned int flags;
1696 	unsigned int mounted_uid;
1697 	int wdog_pid;
1698 
1699 	unsigned int ncp_fd;
1700 	unsigned int time_out;
1701 	unsigned int retry_count;
1702 
1703 	unsigned int uid;
1704 	unsigned int gid;
1705 	unsigned int file_mode;
1706 	unsigned int dir_mode;
1707 };
1708 
do_ncp_super_data_conv(void * raw_data)1709 static void *do_ncp_super_data_conv(void *raw_data)
1710 {
1711 	switch (*(int*)raw_data) {
1712 		case NCP_MOUNT_VERSION:
1713 			{
1714 				struct ncp_mount_data news, *n = &news;
1715 				struct ncp_mount_data32_v3 *n32 = (struct ncp_mount_data32_v3 *)raw_data;
1716 
1717 				n->version = n32->version;
1718 				n->ncp_fd = n32->ncp_fd;
1719 				n->mounted_uid = low2highuid(n32->mounted_uid);
1720 				n->wdog_pid = n32->wdog_pid;
1721 				memmove (n->mounted_vol, n32->mounted_vol, sizeof (n32->mounted_vol));
1722 				n->time_out = n32->time_out;
1723 				n->retry_count = n32->retry_count;
1724 				n->flags = n32->flags;
1725 				n->uid = low2highuid(n32->uid);
1726 				n->gid = low2highgid(n32->gid);
1727 				n->file_mode = n32->file_mode;
1728 				n->dir_mode = n32->dir_mode;
1729 				memcpy(raw_data, n, sizeof(*n));
1730 			}
1731 			break;
1732 		case NCP_MOUNT_VERSION_V4:
1733 			{
1734 				struct ncp_mount_data_v4 news, *n = &news;
1735 				struct ncp_mount_data32_v4 *n32 = (struct ncp_mount_data32_v4 *)raw_data;
1736 
1737 				n->version = n32->version;
1738 				n->flags = n32->flags;
1739 				n->mounted_uid = n32->mounted_uid;
1740 				n->wdog_pid = n32->wdog_pid;
1741 				n->ncp_fd = n32->ncp_fd;
1742 				n->time_out = n32->time_out;
1743 				n->retry_count = n32->retry_count;
1744 				n->uid = n32->uid;
1745 				n->gid = n32->gid;
1746 				n->file_mode = n32->file_mode;
1747 				n->dir_mode = n32->dir_mode;
1748 				memcpy(raw_data, n, sizeof(*n));
1749 			}
1750 			break;
1751 		default:
1752 			/* do not touch unknown structures */
1753 			break;
1754 	}
1755 	return raw_data;
1756 }
1757 
1758 struct smb_mount_data32 {
1759         int version;
1760         __kernel_uid_t32 mounted_uid;
1761         __kernel_uid_t32 uid;
1762         __kernel_gid_t32 gid;
1763         __kernel_mode_t32 file_mode;
1764         __kernel_mode_t32 dir_mode;
1765 };
1766 
do_smb_super_data_conv(void * raw_data)1767 static void *do_smb_super_data_conv(void *raw_data)
1768 {
1769 	struct smb_mount_data news, *s = &news;
1770 	struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
1771 
1772 	s->version = s32->version;
1773 	s->mounted_uid = low2highuid(s32->mounted_uid);
1774 	s->uid = low2highuid(s32->uid);
1775 	s->gid = low2highgid(s32->gid);
1776 	s->file_mode = s32->file_mode;
1777 	s->dir_mode = s32->dir_mode;
1778 	memcpy(raw_data, s, sizeof(struct smb_mount_data));
1779 	return raw_data;
1780 }
1781 
copy_mount_stuff_to_kernel(const void * user,unsigned long * kernel)1782 static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
1783 {
1784 	int i;
1785 	unsigned long page;
1786 	struct vm_area_struct *vma;
1787 
1788 	*kernel = 0;
1789 	if(!user)
1790 		return 0;
1791 	vma = find_vma(current->mm, (unsigned long)user);
1792 	if(!vma || (unsigned long)user < vma->vm_start)
1793 		return -EFAULT;
1794 	if(!(vma->vm_flags & VM_READ))
1795 		return -EFAULT;
1796 	i = vma->vm_end - (unsigned long) user;
1797 	if(PAGE_SIZE <= (unsigned long) i)
1798 		i = PAGE_SIZE - 1;
1799 	if(!(page = __get_free_page(GFP_KERNEL)))
1800 		return -ENOMEM;
1801 	if(copy_from_user((void *) page, user, i)) {
1802 		free_page(page);
1803 		return -EFAULT;
1804 	}
1805 	*kernel = page;
1806 	return 0;
1807 }
1808 
1809 #define SMBFS_NAME	"smbfs"
1810 #define NCPFS_NAME	"ncpfs"
1811 
sys32_mount(char * dev_name,char * dir_name,char * type,unsigned long new_flags,u32 data)1812 asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
1813 {
1814 	unsigned long type_page = 0;
1815 	unsigned long data_page = 0;
1816 	unsigned long dev_page = 0;
1817 	unsigned long dir_page = 0;
1818 	int err, is_smb, is_ncp;
1819 
1820 	is_smb = is_ncp = 0;
1821 
1822 	err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
1823 	if (err)
1824 		goto out;
1825 
1826 	if (type_page) {
1827 		is_smb = !strcmp((char *)type_page, SMBFS_NAME);
1828 		is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
1829 	} else {
1830 		is_smb = is_ncp = 0;
1831 	}
1832 
1833 	err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
1834 	if (err)
1835 		goto type_out;
1836 
1837 	err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
1838 	if (err)
1839 		goto data_out;
1840 
1841 	err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
1842 	if (err)
1843 		goto dev_out;
1844 
1845 	if (!is_smb && !is_ncp) {
1846 		lock_kernel();
1847 		err = do_mount((char*)dev_page, (char*)dir_page,
1848 				(char*)type_page, new_flags, (char*)data_page);
1849 		unlock_kernel();
1850 	} else {
1851 		if (is_ncp)
1852 			do_ncp_super_data_conv((void *)data_page);
1853 		else
1854 			do_smb_super_data_conv((void *)data_page);
1855 
1856 		lock_kernel();
1857 		err = do_mount((char*)dev_page, (char*)dir_page,
1858 				(char*)type_page, new_flags, (char*)data_page);
1859 		unlock_kernel();
1860 	}
1861 	free_page(dir_page);
1862 
1863 dev_out:
1864 	free_page(dev_page);
1865 
1866 data_out:
1867 	free_page(data_page);
1868 
1869 type_out:
1870 	free_page(type_page);
1871 
1872 out:
1873 	return err;
1874 }
1875 
1876 struct rusage32 {
1877         struct timeval32 ru_utime;
1878         struct timeval32 ru_stime;
1879         s32    ru_maxrss;
1880         s32    ru_ixrss;
1881         s32    ru_idrss;
1882         s32    ru_isrss;
1883         s32    ru_minflt;
1884         s32    ru_majflt;
1885         s32    ru_nswap;
1886         s32    ru_inblock;
1887         s32    ru_oublock;
1888         s32    ru_msgsnd;
1889         s32    ru_msgrcv;
1890         s32    ru_nsignals;
1891         s32    ru_nvcsw;
1892         s32    ru_nivcsw;
1893 };
1894 
put_rusage(struct rusage32 * ru,struct rusage * r)1895 static int put_rusage (struct rusage32 *ru, struct rusage *r)
1896 {
1897 	int err;
1898 
1899 	err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
1900 	err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
1901 	err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
1902 	err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
1903 	err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
1904 	err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
1905 	err |= __put_user (r->ru_idrss, &ru->ru_idrss);
1906 	err |= __put_user (r->ru_isrss, &ru->ru_isrss);
1907 	err |= __put_user (r->ru_minflt, &ru->ru_minflt);
1908 	err |= __put_user (r->ru_majflt, &ru->ru_majflt);
1909 	err |= __put_user (r->ru_nswap, &ru->ru_nswap);
1910 	err |= __put_user (r->ru_inblock, &ru->ru_inblock);
1911 	err |= __put_user (r->ru_oublock, &ru->ru_oublock);
1912 	err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
1913 	err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
1914 	err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
1915 	err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
1916 	err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
1917 	return err;
1918 }
1919 
sys32_wait4(__kernel_pid_t32 pid,unsigned int * stat_addr,int options,struct rusage32 * ru)1920 asmlinkage int sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
1921 {
1922 	if (!ru)
1923 		return sys_wait4(pid, stat_addr, options, NULL);
1924 	else {
1925 		struct rusage r;
1926 		int ret;
1927 		unsigned int status;
1928 		mm_segment_t old_fs = get_fs();
1929 
1930 		set_fs (KERNEL_DS);
1931 		ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
1932 		set_fs (old_fs);
1933 		if (put_rusage (ru, &r)) return -EFAULT;
1934 		if (stat_addr && put_user (status, stat_addr))
1935 			return -EFAULT;
1936 		return ret;
1937 	}
1938 }
1939 
1940 struct sysinfo32 {
1941         s32 uptime;
1942         u32 loads[3];
1943         u32 totalram;
1944         u32 freeram;
1945         u32 sharedram;
1946         u32 bufferram;
1947         u32 totalswap;
1948         u32 freeswap;
1949         unsigned short procs;
1950 	unsigned short pad;
1951 	u32 totalhigh;
1952 	u32 freehigh;
1953 	u32 mem_unit;
1954 	char _f[20-2*sizeof(int)-sizeof(int)];
1955 };
1956 
1957 extern asmlinkage int sys_sysinfo(struct sysinfo *info);
1958 
sys32_sysinfo(struct sysinfo32 * info)1959 asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
1960 {
1961 	struct sysinfo s;
1962 	int ret, err;
1963 	int bitcount = 0;
1964 	mm_segment_t old_fs = get_fs ();
1965 
1966 	set_fs(KERNEL_DS);
1967 	ret = sys_sysinfo(&s);
1968 	set_fs(old_fs);
1969 	/* Check to see if any memory value is too large for 32-bit and
1970          * scale down if needed.
1971          */
1972 	if ((s.totalram >> 32) || (s.totalswap >> 32)) {
1973 		while (s.mem_unit < PAGE_SIZE) {
1974 			s.mem_unit <<= 1;
1975 			bitcount++;
1976 		}
1977 		s.totalram >>= bitcount;
1978 		s.freeram >>= bitcount;
1979 		s.sharedram >>= bitcount;
1980 		s.bufferram >>= bitcount;
1981 		s.totalswap >>= bitcount;
1982 		s.freeswap >>= bitcount;
1983 		s.totalhigh >>= bitcount;
1984 		s.freehigh >>= bitcount;
1985 	}
1986 
1987 	err = put_user (s.uptime, &info->uptime);
1988 	err |= __put_user (s.loads[0], &info->loads[0]);
1989 	err |= __put_user (s.loads[1], &info->loads[1]);
1990 	err |= __put_user (s.loads[2], &info->loads[2]);
1991 	err |= __put_user (s.totalram, &info->totalram);
1992 	err |= __put_user (s.freeram, &info->freeram);
1993 	err |= __put_user (s.sharedram, &info->sharedram);
1994 	err |= __put_user (s.bufferram, &info->bufferram);
1995 	err |= __put_user (s.totalswap, &info->totalswap);
1996 	err |= __put_user (s.freeswap, &info->freeswap);
1997 	err |= __put_user (s.procs, &info->procs);
1998 	err |= __put_user (s.totalhigh, &info->totalhigh);
1999 	err |= __put_user (s.freehigh, &info->freehigh);
2000 	err |= __put_user (s.mem_unit, &info->mem_unit);
2001 	if (err)
2002 		return -EFAULT;
2003 	return ret;
2004 }
2005 
2006 extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
2007 
sys32_sched_rr_get_interval(__kernel_pid_t32 pid,struct timespec32 * interval)2008 asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
2009 {
2010 	struct timespec t;
2011 	int ret;
2012 	mm_segment_t old_fs = get_fs ();
2013 
2014 	set_fs (KERNEL_DS);
2015 	ret = sys_sched_rr_get_interval(pid, &t);
2016 	set_fs (old_fs);
2017 	if (put_user (t.tv_sec, &interval->tv_sec) ||
2018 	    __put_user (t.tv_nsec, &interval->tv_nsec))
2019 		return -EFAULT;
2020 	return ret;
2021 }
2022 
2023 extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
2024 
sys32_nanosleep(struct timespec32 * rqtp,struct timespec32 * rmtp)2025 asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
2026 {
2027 	struct timespec t;
2028 	int ret;
2029 	mm_segment_t old_fs = get_fs ();
2030 
2031 	if (get_user (t.tv_sec, &rqtp->tv_sec) ||
2032 	    __get_user (t.tv_nsec, &rqtp->tv_nsec))
2033 		return -EFAULT;
2034 	set_fs (KERNEL_DS);
2035 	ret = sys_nanosleep(&t, rmtp ? &t : NULL);
2036 	set_fs (old_fs);
2037 	if (rmtp && ret == -EINTR) {
2038 		if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
2039 	    	    __put_user (t.tv_nsec, &rmtp->tv_nsec))
2040 			return -EFAULT;
2041 	}
2042 	return ret;
2043 }
2044 
2045 extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
2046 
sys32_sigprocmask(int how,old_sigset_t32 * set,old_sigset_t32 * oset)2047 asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
2048 {
2049 	old_sigset_t s;
2050 	int ret;
2051 	mm_segment_t old_fs = get_fs();
2052 
2053 	if (set && get_user (s, set)) return -EFAULT;
2054 	set_fs (KERNEL_DS);
2055 	ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
2056 	set_fs (old_fs);
2057 	if (ret) return ret;
2058 	if (oset && put_user (s, oset)) return -EFAULT;
2059 	return 0;
2060 }
2061 
2062 extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
2063 
sys32_rt_sigprocmask(int how,sigset_t32 * set,sigset_t32 * oset,__kernel_size_t32 sigsetsize)2064 asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize)
2065 {
2066 	sigset_t s;
2067 	sigset_t32 s32;
2068 	int ret;
2069 	mm_segment_t old_fs = get_fs();
2070 
2071 	if (set) {
2072 		if (copy_from_user (&s32, set, sizeof(sigset_t32)))
2073 			return -EFAULT;
2074 		switch (_NSIG_WORDS) {
2075 		case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
2076 		case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
2077 		case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
2078 		case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
2079 		}
2080 	}
2081 	set_fs (KERNEL_DS);
2082 	ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize);
2083 	set_fs (old_fs);
2084 	if (ret) return ret;
2085 	if (oset) {
2086 		switch (_NSIG_WORDS) {
2087 		case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
2088 		case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
2089 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
2090 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
2091 		}
2092 		if (copy_to_user (oset, &s32, sizeof(sigset_t32)))
2093 			return -EFAULT;
2094 	}
2095 	return 0;
2096 }
2097 
2098 extern asmlinkage int sys_sigpending(old_sigset_t *set);
2099 
sys32_sigpending(old_sigset_t32 * set)2100 asmlinkage int sys32_sigpending(old_sigset_t32 *set)
2101 {
2102 	old_sigset_t s;
2103 	int ret;
2104 	mm_segment_t old_fs = get_fs();
2105 
2106 	set_fs (KERNEL_DS);
2107 	ret = sys_sigpending(&s);
2108 	set_fs (old_fs);
2109 	if (put_user (s, set)) return -EFAULT;
2110 	return ret;
2111 }
2112 
2113 extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
2114 
sys32_rt_sigpending(sigset_t32 * set,__kernel_size_t32 sigsetsize)2115 asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
2116 {
2117 	sigset_t s;
2118 	sigset_t32 s32;
2119 	int ret;
2120 	mm_segment_t old_fs = get_fs();
2121 
2122 	set_fs (KERNEL_DS);
2123 	ret = sys_rt_sigpending(&s, sigsetsize);
2124 	set_fs (old_fs);
2125 	if (!ret) {
2126 		switch (_NSIG_WORDS) {
2127 		case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
2128 		case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
2129 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
2130 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
2131 		}
2132 		if (copy_to_user (set, &s32, sizeof(sigset_t32)))
2133 			return -EFAULT;
2134 	}
2135 	return ret;
2136 }
2137 
2138 asmlinkage int
sys32_rt_sigtimedwait(sigset_t32 * uthese,siginfo_t32 * uinfo,struct timespec32 * uts,__kernel_size_t32 sigsetsize)2139 sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
2140 		      struct timespec32 *uts, __kernel_size_t32 sigsetsize)
2141 {
2142 	int ret, sig;
2143 	sigset_t these;
2144 	sigset_t32 these32;
2145 	struct timespec ts;
2146 	siginfo_t info;
2147 	long timeout = 0;
2148 
2149 	/* XXX: Don't preclude handling different sized sigset_t's.  */
2150 	if (sigsetsize != sizeof(sigset_t))
2151 		return -EINVAL;
2152 
2153 	if (copy_from_user (&these32, uthese, sizeof(sigset_t32)))
2154 		return -EFAULT;
2155 
2156 	switch (_NSIG_WORDS) {
2157 	case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
2158 	case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
2159 	case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
2160 	case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
2161 	}
2162 
2163 	/*
2164 	 * Invert the set of allowed signals to get those we
2165 	 * want to block.
2166 	 */
2167 	sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
2168 	signotset(&these);
2169 
2170 	if (uts) {
2171 		if (get_user (ts.tv_sec, &uts->tv_sec) ||
2172 		    get_user (ts.tv_nsec, &uts->tv_nsec))
2173 			return -EINVAL;
2174 		if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
2175 		    || ts.tv_sec < 0)
2176 			return -EINVAL;
2177 	}
2178 
2179 	spin_lock_irq(&current->sigmask_lock);
2180 	sig = dequeue_signal(&these, &info);
2181 	if (!sig) {
2182 		timeout = MAX_SCHEDULE_TIMEOUT;
2183 		if (uts)
2184 			timeout = (timespec_to_jiffies(&ts)
2185 				   + (ts.tv_sec || ts.tv_nsec));
2186 
2187 		if (timeout) {
2188 			/* None ready -- temporarily unblock those we're
2189 			 * interested while we are sleeping in so that we'll
2190 			 * be awakened when they arrive.  */
2191 			sigset_t oldblocked = current->blocked;
2192 			sigandsets(&current->blocked, &current->blocked, &these);
2193 			recalc_sigpending(current);
2194 			spin_unlock_irq(&current->sigmask_lock);
2195 
2196 			current->state = TASK_INTERRUPTIBLE;
2197 			timeout = schedule_timeout(timeout);
2198 
2199 			spin_lock_irq(&current->sigmask_lock);
2200 			sig = dequeue_signal(&these, &info);
2201 			current->blocked = oldblocked;
2202 			recalc_sigpending(current);
2203 		}
2204 	}
2205 	spin_unlock_irq(&current->sigmask_lock);
2206 
2207 	if (sig) {
2208 		ret = sig;
2209 		if (uinfo) {
2210 			if (copy_siginfo_to_user32(uinfo, &info))
2211 				ret = -EFAULT;
2212 		}
2213 	} else {
2214 		ret = -EAGAIN;
2215 		if (timeout)
2216 			ret = -EINTR;
2217 	}
2218 
2219 	return ret;
2220 }
2221 
2222 extern asmlinkage int
2223 sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
2224 
2225 asmlinkage int
sys32_rt_sigqueueinfo(int pid,int sig,siginfo_t32 * uinfo)2226 sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
2227 {
2228 	siginfo_t info;
2229 	int ret;
2230 	mm_segment_t old_fs = get_fs();
2231 
2232 	if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
2233 	    copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
2234 		return -EFAULT;
2235 	set_fs (KERNEL_DS);
2236 	ret = sys_rt_sigqueueinfo(pid, sig, &info);
2237 	set_fs (old_fs);
2238 	return ret;
2239 }
2240 
2241 struct tms32 {
2242 	__kernel_clock_t32 tms_utime;
2243 	__kernel_clock_t32 tms_stime;
2244 	__kernel_clock_t32 tms_cutime;
2245 	__kernel_clock_t32 tms_cstime;
2246 };
2247 
2248 extern asmlinkage long sys_times(struct tms * tbuf);
2249 
sys32_times(struct tms32 * tbuf)2250 asmlinkage long sys32_times(struct tms32 *tbuf)
2251 {
2252 	struct tms t;
2253 	long ret;
2254 	mm_segment_t old_fs = get_fs ();
2255 	int err;
2256 
2257 	set_fs (KERNEL_DS);
2258 	ret = sys_times(tbuf ? &t : NULL);
2259 	set_fs (old_fs);
2260 	if (tbuf) {
2261 		err = put_user (t.tms_utime, &tbuf->tms_utime);
2262 		err |= __put_user (t.tms_stime, &tbuf->tms_stime);
2263 		err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
2264 		err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
2265 		if (err)
2266 			ret = -EFAULT;
2267 	}
2268 	return ret;
2269 }
2270 
2271 #define RLIM_INFINITY32	0x7fffffff
2272 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
2273 
2274 struct rlimit32 {
2275 	u32	rlim_cur;
2276 	u32	rlim_max;
2277 };
2278 
2279 extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
2280 
sys32_getrlimit(unsigned int resource,struct rlimit32 * rlim)2281 asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
2282 {
2283 	struct rlimit r;
2284 	int ret;
2285 	mm_segment_t old_fs = get_fs ();
2286 
2287 	set_fs (KERNEL_DS);
2288 	ret = sys_getrlimit(resource, &r);
2289 	set_fs (old_fs);
2290 	if (!ret) {
2291 		ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
2292 		ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
2293 	}
2294 	return ret;
2295 }
2296 
2297 extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
2298 
sys32_setrlimit(unsigned int resource,struct rlimit32 * rlim)2299 asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
2300 {
2301 	struct rlimit r;
2302 	int ret;
2303 	mm_segment_t old_fs = get_fs ();
2304 
2305 	if (resource >= RLIM_NLIMITS) return -EINVAL;
2306 	if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
2307 	    __get_user (r.rlim_max, &rlim->rlim_max))
2308 		return -EFAULT;
2309 	if (r.rlim_cur == RLIM_INFINITY32)
2310 		r.rlim_cur = RLIM_INFINITY;
2311 	if (r.rlim_max == RLIM_INFINITY32)
2312 		r.rlim_max = RLIM_INFINITY;
2313 	set_fs (KERNEL_DS);
2314 	ret = sys_setrlimit(resource, &r);
2315 	set_fs (old_fs);
2316 	return ret;
2317 }
2318 
2319 extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
2320 
sys32_getrusage(int who,struct rusage32 * ru)2321 asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
2322 {
2323 	struct rusage r;
2324 	int ret;
2325 	mm_segment_t old_fs = get_fs();
2326 
2327 	set_fs (KERNEL_DS);
2328 	ret = sys_getrusage(who, &r);
2329 	set_fs (old_fs);
2330 	if (put_rusage (ru, &r)) return -EFAULT;
2331 	return ret;
2332 }
2333 
2334 /* XXX This really belongs in some header file... -DaveM */
2335 #define MAX_SOCK_ADDR	128		/* 108 for Unix domain -
2336 					   16 for IP, 16 for IPX,
2337 					   24 for IPv6,
2338 					   about 80 for AX.25 */
2339 
2340 extern struct socket *sockfd_lookup(int fd, int *err);
2341 
2342 /* XXX This as well... */
sockfd_put(struct socket * sock)2343 extern __inline__ void sockfd_put(struct socket *sock)
2344 {
2345 	fput(sock->file);
2346 }
2347 
2348 struct msghdr32 {
2349         u32               msg_name;
2350         int               msg_namelen;
2351         u32               msg_iov;
2352         __kernel_size_t32 msg_iovlen;
2353         u32               msg_control;
2354         __kernel_size_t32 msg_controllen;
2355         unsigned          msg_flags;
2356 };
2357 
2358 struct cmsghdr32 {
2359         __kernel_size_t32 cmsg_len;
2360         int               cmsg_level;
2361         int               cmsg_type;
2362 };
2363 
2364 /* Bleech... */
2365 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2366 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2367 
2368 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2369 
2370 #define CMSG32_DATA(cmsg)	((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2371 #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2372 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2373 
2374 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2375 				    (struct cmsghdr32 *)(ctl) : \
2376 				    (struct cmsghdr32 *)NULL)
2377 #define CMSG32_FIRSTHDR(msg)	__CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2378 #define CMSG32_OK(ucmlen, ucmsg, mhdr) \
2379 	((ucmlen) >= sizeof(struct cmsghdr32) && \
2380 	 (ucmlen) <= (unsigned long) \
2381 	 ((mhdr)->msg_controllen - \
2382 	  ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
2383 
__cmsg32_nxthdr(void * __ctl,__kernel_size_t __size,struct cmsghdr32 * __cmsg,int __cmsg_len)2384 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
2385 					      struct cmsghdr32 *__cmsg, int __cmsg_len)
2386 {
2387 	struct cmsghdr32 * __ptr;
2388 
2389 	__ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
2390 				     CMSG32_ALIGN(__cmsg_len));
2391 	if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
2392 		return NULL;
2393 
2394 	return __ptr;
2395 }
2396 
cmsg32_nxthdr(struct msghdr * __msg,struct cmsghdr32 * __cmsg,int __cmsg_len)2397 __inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
2398 					    struct cmsghdr32 *__cmsg,
2399 					    int __cmsg_len)
2400 {
2401 	return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
2402 			       __cmsg, __cmsg_len);
2403 }
2404 
iov_from_user32_to_kern(struct iovec * kiov,struct iovec32 * uiov32,int niov)2405 static inline int iov_from_user32_to_kern(struct iovec *kiov,
2406 					  struct iovec32 *uiov32,
2407 					  int niov)
2408 {
2409 	int tot_len = 0;
2410 
2411 	while(niov > 0) {
2412 		u32 len, buf;
2413 
2414 		if(get_user(len, &uiov32->iov_len) ||
2415 		   get_user(buf, &uiov32->iov_base)) {
2416 			tot_len = -EFAULT;
2417 			break;
2418 		}
2419 		tot_len += len;
2420 		kiov->iov_base = (void *)A(buf);
2421 		kiov->iov_len = (__kernel_size_t) len;
2422 		uiov32++;
2423 		kiov++;
2424 		niov--;
2425 	}
2426 	return tot_len;
2427 }
2428 
msghdr_from_user32_to_kern(struct msghdr * kmsg,struct msghdr32 * umsg)2429 static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
2430 					     struct msghdr32 *umsg)
2431 {
2432 	u32 tmp1, tmp2, tmp3;
2433 	int err;
2434 
2435 	err = get_user(tmp1, &umsg->msg_name);
2436 	err |= __get_user(tmp2, &umsg->msg_iov);
2437 	err |= __get_user(tmp3, &umsg->msg_control);
2438 	if (err)
2439 		return -EFAULT;
2440 
2441 	kmsg->msg_name = (void *)A(tmp1);
2442 	kmsg->msg_iov = (struct iovec *)A(tmp2);
2443 	kmsg->msg_control = (void *)A(tmp3);
2444 
2445 	err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
2446 	err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
2447 	err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
2448 	err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
2449 
2450 	return err;
2451 }
2452 
2453 /* I've named the args so it is easy to tell whose space the pointers are in. */
verify_iovec32(struct msghdr * kern_msg,struct iovec * kern_iov,char * kern_address,int mode)2454 static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
2455 			  char *kern_address, int mode)
2456 {
2457 	int tot_len;
2458 
2459 	if(kern_msg->msg_namelen) {
2460 		if(mode==VERIFY_READ) {
2461 			int err = move_addr_to_kernel(kern_msg->msg_name,
2462 						      kern_msg->msg_namelen,
2463 						      kern_address);
2464 			if(err < 0)
2465 				return err;
2466 		}
2467 		kern_msg->msg_name = kern_address;
2468 	} else
2469 		kern_msg->msg_name = NULL;
2470 
2471 	if(kern_msg->msg_iovlen > UIO_FASTIOV) {
2472 		kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
2473 				   GFP_KERNEL);
2474 		if(!kern_iov)
2475 			return -ENOMEM;
2476 	}
2477 
2478 	tot_len = iov_from_user32_to_kern(kern_iov,
2479 					  (struct iovec32 *)kern_msg->msg_iov,
2480 					  kern_msg->msg_iovlen);
2481 	if(tot_len >= 0)
2482 		kern_msg->msg_iov = kern_iov;
2483 	else if(kern_msg->msg_iovlen > UIO_FASTIOV)
2484 		kfree(kern_iov);
2485 
2486 	return tot_len;
2487 }
2488 
2489 /* There is a lot of hair here because the alignment rules (and
2490  * thus placement) of cmsg headers and length are different for
2491  * 32-bit apps.  -DaveM
2492  */
cmsghdr_from_user32_to_kern(struct msghdr * kmsg,unsigned char * stackbuf,int stackbuf_size)2493 static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
2494 				       unsigned char *stackbuf, int stackbuf_size)
2495 {
2496 	struct cmsghdr32 *ucmsg;
2497 	struct cmsghdr *kcmsg, *kcmsg_base;
2498 	__kernel_size_t32 ucmlen;
2499 	__kernel_size_t kcmlen, tmp;
2500 	int err = -EFAULT;
2501 
2502 	kcmlen = 0;
2503 	kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
2504 	ucmsg = CMSG32_FIRSTHDR(kmsg);
2505 	while(ucmsg != NULL) {
2506 		if (get_user(ucmlen, &ucmsg->cmsg_len))
2507 			return -EFAULT;
2508 
2509 		/* Catch bogons. */
2510 		if (!CMSG32_OK(ucmlen, ucmsg, kmsg))
2511 			return -EINVAL;
2512 
2513 		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2514 		       CMSG_ALIGN(sizeof(struct cmsghdr)));
2515 		tmp = CMSG_ALIGN(tmp);
2516 		kcmlen += tmp;
2517 		ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2518 	}
2519 	if(kcmlen == 0)
2520 		return -EINVAL;
2521 
2522 	/* The kcmlen holds the 64-bit version of the control length.
2523 	 * It may not be modified as we do not stick it into the kmsg
2524 	 * until we have successfully copied over all of the data
2525 	 * from the user.
2526 	 */
2527 	if(kcmlen > stackbuf_size)
2528 		kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
2529 	if(kcmsg == NULL)
2530 		return -ENOBUFS;
2531 
2532 	/* Now copy them over neatly. */
2533 	memset(kcmsg, 0, kcmlen);
2534 	ucmsg = CMSG32_FIRSTHDR(kmsg);
2535 	while(ucmsg != NULL) {
2536 		if (__get_user(ucmlen, &ucmsg->cmsg_len))
2537 			goto Efault;
2538 		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2539 		       CMSG_ALIGN(sizeof(struct cmsghdr)));
2540 		if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp))
2541 			goto Einval;
2542 		kcmsg->cmsg_len = tmp;
2543 		tmp = CMSG_ALIGN(tmp);
2544 		if (__get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level) ||
2545 		    __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type) ||
2546 		    copy_from_user(CMSG_DATA(kcmsg),
2547 				   CMSG32_DATA(ucmsg),
2548 				   (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
2549 			goto Efault;
2550 
2551 		/* Advance. */
2552 		kcmsg = (struct cmsghdr *)((char *)kcmsg + tmp);
2553 		ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2554 	}
2555 
2556 	/* Ok, looks like we made it.  Hook it up and return success. */
2557 	kmsg->msg_control = kcmsg_base;
2558 	kmsg->msg_controllen = kcmlen;
2559 	return 0;
2560 
2561 Einval:
2562 	err = -EINVAL;
2563 Efault:
2564 	if (kcmsg_base != (struct cmsghdr *)stackbuf)
2565 		kfree(kcmsg_base);
2566 	return err;
2567 }
2568 
put_cmsg32(struct msghdr * kmsg,int level,int type,int len,void * data)2569 static void put_cmsg32(struct msghdr *kmsg, int level, int type,
2570 		       int len, void *data)
2571 {
2572 	struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2573 	struct cmsghdr32 cmhdr;
2574 	int cmlen = CMSG32_LEN(len);
2575 
2576 	if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
2577 		kmsg->msg_flags |= MSG_CTRUNC;
2578 		return;
2579 	}
2580 
2581 	if(kmsg->msg_controllen < cmlen) {
2582 		kmsg->msg_flags |= MSG_CTRUNC;
2583 		cmlen = kmsg->msg_controllen;
2584 	}
2585 	cmhdr.cmsg_level = level;
2586 	cmhdr.cmsg_type = type;
2587 	cmhdr.cmsg_len = cmlen;
2588 
2589 	if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
2590 		return;
2591 	if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
2592 		return;
2593 	cmlen = CMSG32_SPACE(len);
2594 	kmsg->msg_control += cmlen;
2595 	kmsg->msg_controllen -= cmlen;
2596 }
2597 
scm_detach_fds32(struct msghdr * kmsg,struct scm_cookie * scm)2598 static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
2599 {
2600 	struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2601 	int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
2602 	int fdnum = scm->fp->count;
2603 	struct file **fp = scm->fp->fp;
2604 	int *cmfptr;
2605 	int err = 0, i;
2606 
2607 	if (fdnum < fdmax)
2608 		fdmax = fdnum;
2609 
2610 	for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
2611 		int new_fd;
2612 		err = get_unused_fd();
2613 		if (err < 0)
2614 			break;
2615 		new_fd = err;
2616 		err = put_user(new_fd, cmfptr);
2617 		if (err) {
2618 			put_unused_fd(new_fd);
2619 			break;
2620 		}
2621 		/* Bump the usage count and install the file. */
2622 		get_file(fp[i]);
2623 		fd_install(new_fd, fp[i]);
2624 	}
2625 
2626 	if (i > 0) {
2627 		int cmlen = CMSG32_LEN(i * sizeof(int));
2628 		if (!err)
2629 			err = put_user(SOL_SOCKET, &cm->cmsg_level);
2630 		if (!err)
2631 			err = put_user(SCM_RIGHTS, &cm->cmsg_type);
2632 		if (!err)
2633 			err = put_user(cmlen, &cm->cmsg_len);
2634 		if (!err) {
2635 			cmlen = CMSG32_SPACE(i * sizeof(int));
2636 			kmsg->msg_control += cmlen;
2637 			kmsg->msg_controllen -= cmlen;
2638 		}
2639 	}
2640 	if (i < fdnum)
2641 		kmsg->msg_flags |= MSG_CTRUNC;
2642 
2643 	/*
2644 	 * All of the files that fit in the message have had their
2645 	 * usage counts incremented, so we just free the list.
2646 	 */
2647 	__scm_destroy(scm);
2648 }
2649 
2650 /* In these cases we (currently) can just copy to data over verbatim
2651  * because all CMSGs created by the kernel have well defined types which
2652  * have the same layout in both the 32-bit and 64-bit API.  One must add
2653  * some special cased conversions here if we start sending control messages
2654  * with incompatible types.
2655  *
2656  * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2657  * we do our work.  The remaining cases are:
2658  *
2659  * SOL_IP	IP_PKTINFO	struct in_pktinfo	32-bit clean
2660  *		IP_TTL		int			32-bit clean
2661  *		IP_TOS		__u8			32-bit clean
2662  *		IP_RECVOPTS	variable length		32-bit clean
2663  *		IP_RETOPTS	variable length		32-bit clean
2664  *		(these last two are clean because the types are defined
2665  *		 by the IPv4 protocol)
2666  *		IP_RECVERR	struct sock_extended_err +
2667  *				struct sockaddr_in	32-bit clean
2668  * SOL_IPV6	IPV6_RECVERR	struct sock_extended_err +
2669  *				struct sockaddr_in6	32-bit clean
2670  *		IPV6_PKTINFO	struct in6_pktinfo	32-bit clean
2671  *		IPV6_HOPLIMIT	int			32-bit clean
2672  *		IPV6_FLOWINFO	u32			32-bit clean
2673  *		IPV6_HOPOPTS	ipv6 hop exthdr		32-bit clean
2674  *		IPV6_DSTOPTS	ipv6 dst exthdr(s)	32-bit clean
2675  *		IPV6_RTHDR	ipv6 routing exthdr	32-bit clean
2676  *		IPV6_AUTHHDR	ipv6 auth exthdr	32-bit clean
2677  */
cmsg32_recvmsg_fixup(struct msghdr * kmsg,unsigned long orig_cmsg_uptr,__kernel_size_t orig_cmsg_len)2678 static void cmsg32_recvmsg_fixup(struct msghdr *kmsg,
2679 		unsigned long orig_cmsg_uptr, __kernel_size_t orig_cmsg_len)
2680 {
2681 	unsigned char *workbuf, *wp;
2682 	unsigned long bufsz, space_avail;
2683 	struct cmsghdr *ucmsg;
2684 
2685 	bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
2686 	space_avail = kmsg->msg_controllen + bufsz;
2687 	wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
2688 	if(workbuf == NULL)
2689 		goto fail;
2690 
2691 	/* To make this more sane we assume the kernel sends back properly
2692 	 * formatted control messages.  Because of how the kernel will truncate
2693 	 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2694 	 */
2695 	ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
2696 	while(((unsigned long)ucmsg) <=
2697 	      (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
2698 		struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
2699 		int clen64, clen32;
2700 
2701 		/* UCMSG is the 64-bit format CMSG entry in user-space.
2702 		 * KCMSG32 is within the kernel space temporary buffer
2703 		 * we use to convert into a 32-bit style CMSG.
2704 		 */
2705 		__get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
2706 		__get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
2707 		__get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
2708 
2709 		clen64 = kcmsg32->cmsg_len;
2710 		if ((clen64 < CMSG_ALIGN(sizeof(*ucmsg))) ||
2711 				(clen64 > (orig_cmsg_len + wp - workbuf)))
2712 			break;
2713 		if (kcmsg32->cmsg_level == SOL_SOCKET &&
2714 			kcmsg32->cmsg_type == SO_TIMESTAMP) {
2715 			struct timeval tv;
2716 			struct timeval32 *tv32;
2717 
2718 			if (clen64 != CMSG_LEN(sizeof(struct timeval))) {
2719 				kfree(workbuf);
2720 				goto fail;
2721 			}
2722 
2723 			copy_from_user(&tv, CMSG_DATA(ucmsg), sizeof(tv));
2724 			tv32 = (struct timeval32 *)CMSG32_DATA(kcmsg32);
2725 			tv32->tv_sec = tv.tv_sec;
2726 			tv32->tv_usec = tv.tv_usec;
2727 			clen32 = sizeof(*tv32) +
2728 				  CMSG32_ALIGN(sizeof(struct cmsghdr32));
2729 		} else {
2730 			copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
2731 				       clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
2732 			clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
2733 				  CMSG32_ALIGN(sizeof(struct cmsghdr32)));
2734 		}
2735 		kcmsg32->cmsg_len = clen32;
2736 
2737 		ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
2738 		wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
2739 	}
2740 
2741 	/* Copy back fixed up data, and adjust pointers. */
2742 	bufsz = (wp - workbuf);
2743 	copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
2744 
2745 	kmsg->msg_control = (struct cmsghdr *)
2746 		(((char *)orig_cmsg_uptr) + bufsz);
2747 	kmsg->msg_controllen = space_avail - bufsz;
2748 
2749 	kfree(workbuf);
2750 	return;
2751 
2752 fail:
2753 	/* If we leave the 64-bit format CMSG chunks in there,
2754 	 * the application could get confused and crash.  So to
2755 	 * ensure greater recovery, we report no CMSGs.
2756 	 */
2757 	kmsg->msg_controllen += bufsz;
2758 	kmsg->msg_control = (void *) orig_cmsg_uptr;
2759 }
2760 
sys32_sendmsg(int fd,struct msghdr32 * user_msg,unsigned user_flags)2761 asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
2762 {
2763 	struct socket *sock;
2764 	char address[MAX_SOCK_ADDR];
2765 	struct iovec iov[UIO_FASTIOV];
2766 	unsigned char ctl[sizeof(struct cmsghdr) + 20];
2767 	unsigned char *ctl_buf = ctl;
2768 	struct msghdr kern_msg;
2769 	int err, total_len;
2770 
2771 	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2772 		return -EFAULT;
2773 	if(kern_msg.msg_iovlen > UIO_MAXIOV)
2774 		return -EINVAL;
2775 	err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
2776 	if (err < 0)
2777 		goto out;
2778 	total_len = err;
2779 
2780 	if(kern_msg.msg_controllen) {
2781 		err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
2782 		if(err)
2783 			goto out_freeiov;
2784 		ctl_buf = kern_msg.msg_control;
2785 	}
2786 	kern_msg.msg_flags = user_flags;
2787 
2788 	sock = sockfd_lookup(fd, &err);
2789 	if (sock != NULL) {
2790 		if (sock->file->f_flags & O_NONBLOCK)
2791 			kern_msg.msg_flags |= MSG_DONTWAIT;
2792 		err = sock_sendmsg(sock, &kern_msg, total_len);
2793 		sockfd_put(sock);
2794 	}
2795 
2796 	/* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2797 	if(ctl_buf != ctl)
2798 		kfree(ctl_buf);
2799 out_freeiov:
2800 	if(kern_msg.msg_iov != iov)
2801 		kfree(kern_msg.msg_iov);
2802 out:
2803 	return err;
2804 }
2805 
sys32_recvmsg(int fd,struct msghdr32 * user_msg,unsigned int user_flags)2806 asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
2807 {
2808 	struct iovec iovstack[UIO_FASTIOV];
2809 	struct msghdr kern_msg;
2810 	char addr[MAX_SOCK_ADDR];
2811 	struct socket *sock;
2812 	struct iovec *iov = iovstack;
2813 	struct sockaddr *uaddr;
2814 	int *uaddr_len;
2815 	unsigned long cmsg_ptr;
2816 	__kernel_size_t cmsg_len;
2817 	int err, total_len, len = 0;
2818 
2819 	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2820 		return -EFAULT;
2821 	if(kern_msg.msg_iovlen > UIO_MAXIOV)
2822 		return -EINVAL;
2823 
2824 	uaddr = kern_msg.msg_name;
2825 	uaddr_len = &user_msg->msg_namelen;
2826 	err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
2827 	if (err < 0)
2828 		goto out;
2829 	total_len = err;
2830 
2831 	cmsg_ptr = (unsigned long) kern_msg.msg_control;
2832 	cmsg_len = kern_msg.msg_controllen;
2833 	kern_msg.msg_flags = 0;
2834 
2835 	sock = sockfd_lookup(fd, &err);
2836 	if (sock != NULL) {
2837 		struct scm_cookie scm;
2838 
2839 		if (sock->file->f_flags & O_NONBLOCK)
2840 			user_flags |= MSG_DONTWAIT;
2841 		memset(&scm, 0, sizeof(scm));
2842 		err = sock->ops->recvmsg(sock, &kern_msg, total_len,
2843 					 user_flags, &scm);
2844 		if(err >= 0) {
2845 			len = err;
2846 			if(!kern_msg.msg_control) {
2847 				if(sock->passcred || scm.fp)
2848 					kern_msg.msg_flags |= MSG_CTRUNC;
2849 				if(scm.fp)
2850 					__scm_destroy(&scm);
2851 			} else {
2852 				/* If recvmsg processing itself placed some
2853 				 * control messages into user space, it's is
2854 				 * using 64-bit CMSG processing, so we need
2855 				 * to fix it up before we tack on more stuff.
2856 				 */
2857 				if((unsigned long) kern_msg.msg_control != cmsg_ptr)
2858 					cmsg32_recvmsg_fixup(&kern_msg,
2859 							cmsg_ptr, cmsg_len);
2860 
2861 				/* Wheee... */
2862 				if(sock->passcred)
2863 					put_cmsg32(&kern_msg,
2864 						   SOL_SOCKET, SCM_CREDENTIALS,
2865 						   sizeof(scm.creds), &scm.creds);
2866 				if(scm.fp != NULL)
2867 					scm_detach_fds32(&kern_msg, &scm);
2868 			}
2869 		}
2870 		sockfd_put(sock);
2871 	}
2872 
2873 	if(uaddr != NULL && err >= 0)
2874 		err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
2875 	if(cmsg_ptr != 0 && err >= 0) {
2876 		unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
2877 		__kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
2878 		err |= __put_user(uclen, &user_msg->msg_controllen);
2879 	}
2880 	if(err >= 0)
2881 		err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
2882 	if(kern_msg.msg_iov != iov)
2883 		kfree(kern_msg.msg_iov);
2884 out:
2885 	if(err < 0)
2886 		return err;
2887 	return len;
2888 }
2889 
2890 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
2891 				     char *optval, int optlen);
2892 
do_netfilter_replace(int fd,int level,int optname,char * optval,int optlen)2893 static int do_netfilter_replace(int fd, int level, int optname,
2894 				char *optval, int optlen)
2895 {
2896 	struct ipt_replace32 {
2897 		char name[IPT_TABLE_MAXNAMELEN];
2898 		__u32 valid_hooks;
2899 		__u32 num_entries;
2900 		__u32 size;
2901 		__u32 hook_entry[NF_IP_NUMHOOKS];
2902 		__u32 underflow[NF_IP_NUMHOOKS];
2903 		__u32 num_counters;
2904 		__u32 counters;
2905 		struct ipt_entry entries[0];
2906 	} *repl32 = (struct ipt_replace32 *)optval;
2907 	struct ipt_replace *krepl;
2908 	struct ipt_counters *counters32;
2909 	__u32 origsize;
2910 	unsigned int kreplsize, kcountersize;
2911 	mm_segment_t old_fs;
2912 	int ret;
2913 
2914 	if (optlen < sizeof(repl32))
2915 		return -EINVAL;
2916 
2917 	if (copy_from_user(&origsize,
2918 			&repl32->size,
2919 			sizeof(origsize)))
2920 		return -EFAULT;
2921 
2922 	kreplsize = sizeof(*krepl) + origsize;
2923 	kcountersize = krepl->num_counters * sizeof(struct ipt_counters);
2924 
2925 	/* Hack: Causes ipchains to give correct error msg --RR */
2926 	if (optlen != kreplsize)
2927 		return -ENOPROTOOPT;
2928 
2929 	krepl = (struct ipt_replace *)vmalloc(kreplsize);
2930 	if (krepl == NULL)
2931 		return -ENOMEM;
2932 
2933 	if (copy_from_user(krepl, optval, kreplsize)) {
2934 		vfree(krepl);
2935 		return -EFAULT;
2936 	}
2937 
2938 	counters32 = (struct ipt_counters *)AA(
2939 		((struct ipt_replace32 *)krepl)->counters);
2940 
2941 	kcountersize = krepl->num_counters * sizeof(struct ipt_counters);
2942 	krepl->counters = (struct ipt_counters *)vmalloc(kcountersize);
2943 	if (krepl->counters == NULL) {
2944 		vfree(krepl);
2945 		return -ENOMEM;
2946 	}
2947 
2948 	old_fs = get_fs();
2949 	set_fs(KERNEL_DS);
2950 	ret = sys_setsockopt(fd, level, optname,
2951 			     (char *)krepl, kreplsize);
2952 	set_fs(old_fs);
2953 
2954 	if (ret == 0 &&
2955 		copy_to_user(counters32, krepl->counters, kcountersize))
2956 			ret = -EFAULT;
2957 
2958 	vfree(krepl->counters);
2959 	vfree(krepl);
2960 
2961 	return ret;
2962 }
2963 
do_set_attach_filter(int fd,int level,int optname,char * optval,int optlen)2964 static int do_set_attach_filter(int fd, int level, int optname,
2965 				char *optval, int optlen)
2966 {
2967 	struct sock_fprog32 {
2968 		__u16 len;
2969 		__u32 filter;
2970 	} *fprog32 = (struct sock_fprog32 *)optval;
2971 	struct sock_fprog kfprog;
2972 	struct sock_filter *kfilter;
2973 	unsigned int fsize;
2974 	mm_segment_t old_fs;
2975 	__u32 uptr;
2976 	int ret;
2977 
2978 	if (get_user(kfprog.len, &fprog32->len) ||
2979 	    __get_user(uptr, &fprog32->filter))
2980 		return -EFAULT;
2981 
2982 	kfprog.filter = (struct sock_filter *)A(uptr);
2983 	fsize = kfprog.len * sizeof(struct sock_filter);
2984 
2985 	kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
2986 	if (kfilter == NULL)
2987 		return -ENOMEM;
2988 
2989 	if (copy_from_user(kfilter, kfprog.filter, fsize)) {
2990 		kfree(kfilter);
2991 		return -EFAULT;
2992 	}
2993 
2994 	kfprog.filter = kfilter;
2995 
2996 	old_fs = get_fs();
2997 	set_fs(KERNEL_DS);
2998 	ret = sys_setsockopt(fd, level, optname,
2999 			     (char *)&kfprog, sizeof(kfprog));
3000 	set_fs(old_fs);
3001 
3002 	kfree(kfilter);
3003 
3004 	return ret;
3005 }
3006 
do_set_sock_timeout(int fd,int level,int optname,char * optval,int optlen)3007 static int do_set_sock_timeout(int fd, int level, int optname, char *optval, int optlen)
3008 {
3009 	struct timeval32 *up = (struct timeval32 *) optval;
3010 	struct timeval ktime;
3011 	mm_segment_t old_fs;
3012 	int err;
3013 
3014 	if (optlen < sizeof(*up))
3015 		return -EINVAL;
3016 	if (get_user(ktime.tv_sec, &up->tv_sec) ||
3017 	    __get_user(ktime.tv_usec, &up->tv_usec))
3018 		return -EFAULT;
3019 	old_fs = get_fs();
3020 	set_fs(KERNEL_DS);
3021 	err = sys_setsockopt(fd, level, optname, (char *) &ktime, sizeof(ktime));
3022 	set_fs(old_fs);
3023 
3024 	return err;
3025 }
3026 
sys32_setsockopt(int fd,int level,int optname,char * optval,int optlen)3027 asmlinkage int sys32_setsockopt(int fd, int level, int optname,
3028 				char *optval, int optlen)
3029 {
3030 	if (optname == IPT_SO_SET_REPLACE)
3031 		return do_netfilter_replace(fd, level, optname,
3032 					    optval, optlen);
3033 	if (level == SOL_SOCKET && optname == SO_ATTACH_FILTER)
3034 		return do_set_attach_filter(fd, level, optname,
3035 					    optval, optlen);
3036 	if (level == SOL_SOCKET &&
3037 	    (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
3038 		return do_set_sock_timeout(fd, level, optname, optval, optlen);
3039 
3040 	return sys_setsockopt(fd, level, optname, optval, optlen);
3041 }
3042 
3043 extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
3044 				      char *optval, int *optlen);
3045 
do_get_sock_timeout(int fd,int level,int optname,char * optval,int * optlen)3046 static int do_get_sock_timeout(int fd, int level, int optname, char *optval, int *optlen)
3047 {
3048 	struct timeval32 *up = (struct timeval32 *) optval;
3049 	struct timeval ktime;
3050 	mm_segment_t old_fs;
3051 	int len, err;
3052 
3053 	if (get_user(len, optlen))
3054 		return -EFAULT;
3055 	if (len < sizeof(*up))
3056 		return -EINVAL;
3057 	len = sizeof(ktime);
3058 	old_fs = get_fs();
3059 	set_fs(KERNEL_DS);
3060 	err = sys_getsockopt(fd, level, optname, (char *) &ktime, &len);
3061 	set_fs(old_fs);
3062 
3063 	if (!err) {
3064 		if (put_user(sizeof(*up), optlen) ||
3065 		    put_user(ktime.tv_sec, &up->tv_sec) ||
3066 		    __put_user(ktime.tv_usec, &up->tv_usec))
3067 			err = -EFAULT;
3068 	}
3069 	return err;
3070 }
3071 
sys32_getsockopt(int fd,int level,int optname,char * optval,int * optlen)3072 asmlinkage int sys32_getsockopt(int fd, int level, int optname,
3073 				char *optval, int *optlen)
3074 {
3075 	if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
3076 		return do_get_sock_timeout(fd, level, optname, optval, optlen);
3077 	return sys_getsockopt(fd, level, optname, optval, optlen);
3078 }
3079 
3080 extern void check_pending(int signum);
3081 
sys32_sigaction(int sig,struct old_sigaction32 * act,struct old_sigaction32 * oact)3082 asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
3083 {
3084         struct k_sigaction new_ka, old_ka;
3085         int ret;
3086 
3087 	if(sig < 0) {
3088 		current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
3089 		sig = -sig;
3090 	}
3091 
3092         if (act) {
3093 		old_sigset_t32 mask;
3094 		u32 u_handler, u_restorer;
3095 
3096 		ret = get_user(u_handler, &act->sa_handler);
3097 		new_ka.sa.sa_handler = (void *) (long) u_handler;
3098 		ret |= __get_user(u_restorer, &act->sa_restorer);
3099 		new_ka.sa.sa_restorer = (void *) (long) u_restorer;
3100 		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
3101 		ret |= __get_user(mask, &act->sa_mask);
3102 		if (ret)
3103 			return ret;
3104 		new_ka.ka_restorer = NULL;
3105 		siginitset(&new_ka.sa.sa_mask, mask);
3106         }
3107 
3108         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
3109 
3110 	if (!ret && oact) {
3111 		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
3112 		ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
3113 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
3114 		ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
3115         }
3116 
3117 	return ret;
3118 }
3119 
3120 asmlinkage int
sys32_rt_sigaction(int sig,struct sigaction32 * act,struct sigaction32 * oact,void * restorer,__kernel_size_t32 sigsetsize)3121 sys32_rt_sigaction(int sig, struct sigaction32 *act, struct sigaction32 *oact,
3122 		   void *restorer, __kernel_size_t32 sigsetsize)
3123 {
3124         struct k_sigaction new_ka, old_ka;
3125         int ret;
3126 	sigset_t32 set32;
3127 
3128         /* XXX: Don't preclude handling different sized sigset_t's.  */
3129         if (sigsetsize != sizeof(sigset_t32))
3130                 return -EINVAL;
3131 
3132 	/* All tasks which use RT signals (effectively) use
3133 	 * new style signals.
3134 	 */
3135 	current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
3136 
3137         if (act) {
3138 		u32 u_handler, u_restorer;
3139 
3140 		new_ka.ka_restorer = restorer;
3141 		ret = get_user(u_handler, &act->sa_handler);
3142 		new_ka.sa.sa_handler = (void *) (long) u_handler;
3143 		ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(sigset_t32));
3144 		switch (_NSIG_WORDS) {
3145 		case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
3146 		case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);
3147 		case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32);
3148 		case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32);
3149 		}
3150 		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
3151 		ret |= __get_user(u_restorer, &act->sa_restorer);
3152 		new_ka.sa.sa_restorer = (void *) (long) u_restorer;
3153                 if (ret)
3154                 	return -EFAULT;
3155 	}
3156 
3157 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
3158 
3159 	if (!ret && oact) {
3160 		switch (_NSIG_WORDS) {
3161 		case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3];
3162 		case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2];
3163 		case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];
3164 		case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
3165 		}
3166 		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
3167 		ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset_t32));
3168 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
3169 		ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
3170 		if (ret)
3171 			ret = -EFAULT;
3172         }
3173 
3174         return ret;
3175 }
3176 
3177 
3178 /*
3179  * count32() counts the number of arguments/envelopes
3180  */
count32(u32 * argv,int max)3181 static int count32(u32 * argv, int max)
3182 {
3183 	int i = 0;
3184 
3185 	if (argv != NULL) {
3186 		for (;;) {
3187 			u32 p; int error;
3188 
3189 			error = get_user(p,argv);
3190 			if (error)
3191 				return error;
3192 			if (!p)
3193 				break;
3194 			argv++;
3195 			if (++i > max)
3196 				return -E2BIG;
3197 		}
3198 	}
3199 	return i;
3200 }
3201 
3202 /*
3203  * 'copy_string32()' copies argument/envelope strings from user
3204  * memory to free pages in kernel mem. These are in a format ready
3205  * to be put directly into the top of new user memory.
3206  */
copy_strings32(int argc,u32 * argv,struct linux_binprm * bprm)3207 static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
3208 {
3209 	while (argc-- > 0) {
3210 		u32 str;
3211 		int len;
3212 		unsigned long pos;
3213 
3214 		if (get_user(str, argv + argc) ||
3215 		    !str ||
3216 		    !(len = strnlen_user((char *)A(str), bprm->p)))
3217 			return -EFAULT;
3218 
3219 		if (bprm->p < len)
3220 			return -E2BIG;
3221 
3222 		bprm->p -= len;
3223 
3224 		pos = bprm->p;
3225 		while (len) {
3226 			char *kaddr;
3227 			struct page *page;
3228 			int offset, bytes_to_copy, new, err;
3229 
3230 			offset = pos % PAGE_SIZE;
3231 			page = bprm->page[pos / PAGE_SIZE];
3232 			new = 0;
3233 			if (!page) {
3234 				page = alloc_page(GFP_USER);
3235 				bprm->page[pos / PAGE_SIZE] = page;
3236 				if (!page)
3237 					return -ENOMEM;
3238 				new = 1;
3239 			}
3240 			kaddr = kmap(page);
3241 
3242 			if (new && offset)
3243 				memset(kaddr, 0, offset);
3244 			bytes_to_copy = PAGE_SIZE - offset;
3245 			if (bytes_to_copy > len) {
3246 				bytes_to_copy = len;
3247 				if (new)
3248 					memset(kaddr+offset+len, 0,
3249 					       PAGE_SIZE-offset-len);
3250 			}
3251 
3252 			err = copy_from_user(kaddr + offset, (char *)A(str),
3253 					     bytes_to_copy);
3254 			kunmap(page);
3255 
3256 			if (err)
3257 				return -EFAULT;
3258 
3259 			pos += bytes_to_copy;
3260 			str += bytes_to_copy;
3261 			len -= bytes_to_copy;
3262 		}
3263 	}
3264 	return 0;
3265 }
3266 
3267 /*
3268  * sys32_execve() executes a new program.
3269  */
3270 static inline int
do_execve32(char * filename,u32 * argv,u32 * envp,struct pt_regs * regs)3271 do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
3272 {
3273 	struct linux_binprm bprm;
3274 	struct file * file;
3275 	int retval;
3276 	int i;
3277 
3278 	bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
3279 	memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
3280 
3281 	file = open_exec(filename);
3282 
3283 	retval = PTR_ERR(file);
3284 	if (IS_ERR(file))
3285 		return retval;
3286 
3287 	bprm.file = file;
3288 	bprm.filename = filename;
3289 	bprm.sh_bang = 0;
3290 	bprm.loader = 0;
3291 	bprm.exec = 0;
3292 	if ((bprm.argc = count32(argv, bprm.p / sizeof(u32))) < 0) {
3293 		allow_write_access(file);
3294 		fput(file);
3295 		return bprm.argc;
3296 	}
3297 	if ((bprm.envc = count32(envp, bprm.p / sizeof(u32))) < 0) {
3298 		allow_write_access(file);
3299 		fput(file);
3300 		return bprm.envc;
3301 	}
3302 
3303 	retval = prepare_binprm(&bprm);
3304 	if (retval < 0)
3305 		goto out;
3306 
3307 	retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3308 	if (retval < 0)
3309 		goto out;
3310 
3311 	bprm.exec = bprm.p;
3312 	retval = copy_strings32(bprm.envc, envp, &bprm);
3313 	if (retval < 0)
3314 		goto out;
3315 
3316 	retval = copy_strings32(bprm.argc, argv, &bprm);
3317 	if (retval < 0)
3318 		goto out;
3319 
3320 	retval = search_binary_handler(&bprm, regs);
3321 	if (retval >= 0)
3322 		/* execve success */
3323 		return retval;
3324 
3325 out:
3326 	/* Something went wrong, return the inode and free the argument pages*/
3327 	allow_write_access(bprm.file);
3328 	if (bprm.file)
3329 		fput(bprm.file);
3330 
3331 	for (i=0 ; i<MAX_ARG_PAGES ; i++)
3332 		if (bprm.page[i])
3333 			__free_page(bprm.page[i]);
3334 
3335 	return retval;
3336 }
3337 
3338 /*
3339  * sparc32_execve() executes a new program after the asm stub has set
3340  * things up for us.  This should basically do what I want it to.
3341  */
sparc32_execve(struct pt_regs * regs)3342 asmlinkage int sparc32_execve(struct pt_regs *regs)
3343 {
3344         int error, base = 0;
3345         char *filename;
3346 
3347 	/* User register window flush is done by entry.S */
3348 
3349         /* Check for indirect call. */
3350         if((u32)regs->u_regs[UREG_G1] == 0)
3351                 base = 1;
3352 
3353         filename = getname((char *)AA(regs->u_regs[base + UREG_I0]));
3354 	error = PTR_ERR(filename);
3355         if(IS_ERR(filename))
3356                 goto out;
3357         error = do_execve32(filename,
3358         	(u32 *)AA((u32)regs->u_regs[base + UREG_I1]),
3359         	(u32 *)AA((u32)regs->u_regs[base + UREG_I2]), regs);
3360         putname(filename);
3361 
3362 	if(!error) {
3363 		fprs_write(0);
3364 		current->thread.xfsr[0] = 0;
3365 		current->thread.fpsaved[0] = 0;
3366 		regs->tstate &= ~TSTATE_PEF;
3367 	}
3368 out:
3369         return error;
3370 }
3371 
3372 #ifdef CONFIG_MODULES
3373 
3374 extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
3375 
sys32_create_module(const char * name_user,__kernel_size_t32 size)3376 asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
3377 {
3378 	return sys_create_module(name_user, (size_t)size);
3379 }
3380 
3381 extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
3382 
3383 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
3384  * module structure, even if from 32bit modutils... Why to pollute kernel... :))
3385  */
sys32_init_module(const char * name_user,struct module * mod_user)3386 asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
3387 {
3388 	return sys_init_module(name_user, mod_user);
3389 }
3390 
3391 extern asmlinkage int sys_delete_module(const char *name_user);
3392 
sys32_delete_module(const char * name_user)3393 asmlinkage int sys32_delete_module(const char *name_user)
3394 {
3395 	return sys_delete_module(name_user);
3396 }
3397 
3398 struct module_info32 {
3399 	u32 addr;
3400 	u32 size;
3401 	u32 flags;
3402 	s32 usecount;
3403 };
3404 
3405 /* Query various bits about modules.  */
3406 
3407 static inline long
get_mod_name(const char * user_name,char ** buf)3408 get_mod_name(const char *user_name, char **buf)
3409 {
3410 	unsigned long page;
3411 	long retval;
3412 
3413 	if ((unsigned long)user_name >= TASK_SIZE
3414 	    && !segment_eq(get_fs (), KERNEL_DS))
3415 		return -EFAULT;
3416 
3417 	page = __get_free_page(GFP_KERNEL);
3418 	if (!page)
3419 		return -ENOMEM;
3420 
3421 	retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
3422 	if (retval > 0) {
3423 		if (retval < PAGE_SIZE) {
3424 			*buf = (char *)page;
3425 			return retval;
3426 		}
3427 		retval = -ENAMETOOLONG;
3428 	} else if (!retval)
3429 		retval = -EINVAL;
3430 
3431 	free_page(page);
3432 	return retval;
3433 }
3434 
3435 static inline void
put_mod_name(char * buf)3436 put_mod_name(char *buf)
3437 {
3438 	free_page((unsigned long)buf);
3439 }
3440 
find_module(const char * name)3441 static __inline__ struct module *find_module(const char *name)
3442 {
3443 	struct module *mod;
3444 
3445 	for (mod = module_list; mod ; mod = mod->next) {
3446 		if (mod->flags & MOD_DELETED)
3447 			continue;
3448 		if (!strcmp(mod->name, name))
3449 			break;
3450 	}
3451 
3452 	return mod;
3453 }
3454 
3455 static int
qm_modules(char * buf,size_t bufsize,__kernel_size_t32 * ret)3456 qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
3457 {
3458 	struct module *mod;
3459 	size_t nmod, space, len;
3460 
3461 	nmod = space = 0;
3462 
3463 	for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
3464 		len = strlen(mod->name)+1;
3465 		if (len > bufsize)
3466 			goto calc_space_needed;
3467 		if (copy_to_user(buf, mod->name, len))
3468 			return -EFAULT;
3469 		buf += len;
3470 		bufsize -= len;
3471 		space += len;
3472 	}
3473 
3474 	if (put_user(nmod, ret))
3475 		return -EFAULT;
3476 	else
3477 		return 0;
3478 
3479 calc_space_needed:
3480 	space += len;
3481 	while ((mod = mod->next)->next != NULL)
3482 		space += strlen(mod->name)+1;
3483 
3484 	if (put_user(space, ret))
3485 		return -EFAULT;
3486 	else
3487 		return -ENOSPC;
3488 }
3489 
3490 static int
qm_deps(struct module * mod,char * buf,size_t bufsize,__kernel_size_t32 * ret)3491 qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3492 {
3493 	size_t i, space, len;
3494 
3495 	if (mod->next == NULL)
3496 		return -EINVAL;
3497 	if (!MOD_CAN_QUERY(mod))
3498 		return put_user(0, ret);
3499 
3500 	space = 0;
3501 	for (i = 0; i < mod->ndeps; ++i) {
3502 		const char *dep_name = mod->deps[i].dep->name;
3503 
3504 		len = strlen(dep_name)+1;
3505 		if (len > bufsize)
3506 			goto calc_space_needed;
3507 		if (copy_to_user(buf, dep_name, len))
3508 			return -EFAULT;
3509 		buf += len;
3510 		bufsize -= len;
3511 		space += len;
3512 	}
3513 
3514 	return put_user(i, ret);
3515 
3516 calc_space_needed:
3517 	space += len;
3518 	while (++i < mod->ndeps)
3519 		space += strlen(mod->deps[i].dep->name)+1;
3520 
3521 	if (put_user(space, ret))
3522 		return -EFAULT;
3523 	else
3524 		return -ENOSPC;
3525 }
3526 
3527 static int
qm_refs(struct module * mod,char * buf,size_t bufsize,__kernel_size_t32 * ret)3528 qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3529 {
3530 	size_t nrefs, space, len;
3531 	struct module_ref *ref;
3532 
3533 	if (mod->next == NULL)
3534 		return -EINVAL;
3535 	if (!MOD_CAN_QUERY(mod))
3536 		if (put_user(0, ret))
3537 			return -EFAULT;
3538 		else
3539 			return 0;
3540 
3541 	space = 0;
3542 	for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
3543 		const char *ref_name = ref->ref->name;
3544 
3545 		len = strlen(ref_name)+1;
3546 		if (len > bufsize)
3547 			goto calc_space_needed;
3548 		if (copy_to_user(buf, ref_name, len))
3549 			return -EFAULT;
3550 		buf += len;
3551 		bufsize -= len;
3552 		space += len;
3553 	}
3554 
3555 	if (put_user(nrefs, ret))
3556 		return -EFAULT;
3557 	else
3558 		return 0;
3559 
3560 calc_space_needed:
3561 	space += len;
3562 	while ((ref = ref->next_ref) != NULL)
3563 		space += strlen(ref->ref->name)+1;
3564 
3565 	if (put_user(space, ret))
3566 		return -EFAULT;
3567 	else
3568 		return -ENOSPC;
3569 }
3570 
3571 static inline int
qm_symbols(struct module * mod,char * buf,size_t bufsize,__kernel_size_t32 * ret)3572 qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3573 {
3574 	size_t i, space, len;
3575 	struct module_symbol *s;
3576 	char *strings;
3577 	unsigned *vals;
3578 
3579 	if (!MOD_CAN_QUERY(mod))
3580 		if (put_user(0, ret))
3581 			return -EFAULT;
3582 		else
3583 			return 0;
3584 
3585 	space = mod->nsyms * 2*sizeof(u32);
3586 
3587 	i = len = 0;
3588 	s = mod->syms;
3589 
3590 	if (space > bufsize)
3591 		goto calc_space_needed;
3592 
3593 	if (!access_ok(VERIFY_WRITE, buf, space))
3594 		return -EFAULT;
3595 
3596 	bufsize -= space;
3597 	vals = (unsigned *)buf;
3598 	strings = buf+space;
3599 
3600 	for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
3601 		len = strlen(s->name)+1;
3602 		if (len > bufsize)
3603 			goto calc_space_needed;
3604 
3605 		if (copy_to_user(strings, s->name, len)
3606 		    || __put_user(s->value, vals+0)
3607 		    || __put_user(space, vals+1))
3608 			return -EFAULT;
3609 
3610 		strings += len;
3611 		bufsize -= len;
3612 		space += len;
3613 	}
3614 
3615 	if (put_user(i, ret))
3616 		return -EFAULT;
3617 	else
3618 		return 0;
3619 
3620 calc_space_needed:
3621 	for (; i < mod->nsyms; ++i, ++s)
3622 		space += strlen(s->name)+1;
3623 
3624 	if (put_user(space, ret))
3625 		return -EFAULT;
3626 	else
3627 		return -ENOSPC;
3628 }
3629 
3630 static inline int
qm_info(struct module * mod,char * buf,size_t bufsize,__kernel_size_t32 * ret)3631 qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3632 {
3633 	int error = 0;
3634 
3635 	if (mod->next == NULL)
3636 		return -EINVAL;
3637 
3638 	if (sizeof(struct module_info32) <= bufsize) {
3639 		struct module_info32 info;
3640 		info.addr = (unsigned long)mod;
3641 		info.size = mod->size;
3642 		info.flags = mod->flags;
3643 		info.usecount =
3644 			((mod_member_present(mod, can_unload)
3645 			  && mod->can_unload)
3646 			 ? -1 : atomic_read(&mod->uc.usecount));
3647 
3648 		if (copy_to_user(buf, &info, sizeof(struct module_info32)))
3649 			return -EFAULT;
3650 	} else
3651 		error = -ENOSPC;
3652 
3653 	if (put_user(sizeof(struct module_info32), ret))
3654 		return -EFAULT;
3655 
3656 	return error;
3657 }
3658 
sys32_query_module(char * name_user,int which,char * buf,__kernel_size_t32 bufsize,u32 ret)3659 asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
3660 {
3661 	struct module *mod;
3662 	int err;
3663 
3664 	lock_kernel();
3665 	if (name_user == 0) {
3666 		/* This finds "kernel_module" which is not exported. */
3667 		for(mod = module_list; mod->next != NULL; mod = mod->next)
3668 			;
3669 	} else {
3670 		long namelen;
3671 		char *name;
3672 
3673 		if ((namelen = get_mod_name(name_user, &name)) < 0) {
3674 			err = namelen;
3675 			goto out;
3676 		}
3677 		err = -ENOENT;
3678 		if (namelen == 0) {
3679 			/* This finds "kernel_module" which is not exported. */
3680 			for(mod = module_list; mod->next != NULL; mod = mod->next)
3681 				;
3682 		} else if ((mod = find_module(name)) == NULL) {
3683 			put_mod_name(name);
3684 			goto out;
3685 		}
3686 		put_mod_name(name);
3687 	}
3688 
3689 	switch (which)
3690 	{
3691 	case 0:
3692 		err = 0;
3693 		break;
3694 	case QM_MODULES:
3695 		err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
3696 		break;
3697 	case QM_DEPS:
3698 		err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3699 		break;
3700 	case QM_REFS:
3701 		err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3702 		break;
3703 	case QM_SYMBOLS:
3704 		err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3705 		break;
3706 	case QM_INFO:
3707 		err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3708 		break;
3709 	default:
3710 		err = -EINVAL;
3711 		break;
3712 	}
3713 out:
3714 	unlock_kernel();
3715 	return err;
3716 }
3717 
3718 struct kernel_sym32 {
3719 	u32 value;
3720 	char name[60];
3721 };
3722 
3723 extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
3724 
sys32_get_kernel_syms(struct kernel_sym32 * table)3725 asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
3726 {
3727 	int len, i;
3728 	struct kernel_sym *tbl;
3729 	mm_segment_t old_fs;
3730 
3731 	len = sys_get_kernel_syms(NULL);
3732 	if (!table) return len;
3733 	tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
3734 	if (!tbl) return -ENOMEM;
3735 	old_fs = get_fs();
3736 	set_fs (KERNEL_DS);
3737 	sys_get_kernel_syms(tbl);
3738 	set_fs (old_fs);
3739 	for (i = 0; i < len; i++, table++) {
3740 		if (put_user (tbl[i].value, &table->value) ||
3741 		    copy_to_user (table->name, tbl[i].name, 60))
3742 			break;
3743 	}
3744 	kfree (tbl);
3745 	return i;
3746 }
3747 
3748 #else /* CONFIG_MODULES */
3749 
3750 asmlinkage unsigned long
sys32_create_module(const char * name_user,size_t size)3751 sys32_create_module(const char *name_user, size_t size)
3752 {
3753 	return -ENOSYS;
3754 }
3755 
3756 asmlinkage int
sys32_init_module(const char * name_user,struct module * mod_user)3757 sys32_init_module(const char *name_user, struct module *mod_user)
3758 {
3759 	return -ENOSYS;
3760 }
3761 
3762 asmlinkage int
sys32_delete_module(const char * name_user)3763 sys32_delete_module(const char *name_user)
3764 {
3765 	return -ENOSYS;
3766 }
3767 
3768 asmlinkage int
sys32_query_module(const char * name_user,int which,char * buf,size_t bufsize,size_t * ret)3769 sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
3770 		 size_t *ret)
3771 {
3772 	/* Let the program know about the new interface.  Not that
3773 	   it'll do them much good.  */
3774 	if (which == 0)
3775 		return 0;
3776 
3777 	return -ENOSYS;
3778 }
3779 
3780 asmlinkage int
sys32_get_kernel_syms(struct kernel_sym * table)3781 sys32_get_kernel_syms(struct kernel_sym *table)
3782 {
3783 	return -ENOSYS;
3784 }
3785 
3786 #endif  /* CONFIG_MODULES */
3787 
3788 #if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)
3789 /* Stuff for NFS server syscalls... */
3790 struct nfsctl_svc32 {
3791 	u16			svc32_port;
3792 	s32			svc32_nthreads;
3793 };
3794 
3795 struct nfsctl_client32 {
3796 	s8			cl32_ident[NFSCLNT_IDMAX+1];
3797 	s32			cl32_naddr;
3798 	struct in_addr		cl32_addrlist[NFSCLNT_ADDRMAX];
3799 	s32			cl32_fhkeytype;
3800 	s32			cl32_fhkeylen;
3801 	u8			cl32_fhkey[NFSCLNT_KEYMAX];
3802 };
3803 
3804 struct nfsctl_export32 {
3805 	s8			ex32_client[NFSCLNT_IDMAX+1];
3806 	s8			ex32_path[NFS_MAXPATHLEN+1];
3807 	__kernel_dev_t32	ex32_dev;
3808 	__kernel_ino_t32	ex32_ino;
3809 	s32			ex32_flags;
3810 	__kernel_uid_t32	ex32_anon_uid;
3811 	__kernel_gid_t32	ex32_anon_gid;
3812 };
3813 
3814 struct nfsctl_uidmap32 {
3815 	u32			ug32_ident;   /* char * */
3816 	__kernel_uid_t32	ug32_uidbase;
3817 	s32			ug32_uidlen;
3818 	u32			ug32_udimap;  /* uid_t * */
3819 	__kernel_uid_t32	ug32_gidbase;
3820 	s32			ug32_gidlen;
3821 	u32			ug32_gdimap;  /* gid_t * */
3822 };
3823 
3824 struct nfsctl_fhparm32 {
3825 	struct sockaddr		gf32_addr;
3826 	__kernel_dev_t32	gf32_dev;
3827 	__kernel_ino_t32	gf32_ino;
3828 	s32			gf32_version;
3829 };
3830 
3831 struct nfsctl_fdparm32 {
3832 	struct sockaddr		gd32_addr;
3833 	s8			gd32_path[NFS_MAXPATHLEN+1];
3834 	s32			gd32_version;
3835 };
3836 
3837 struct nfsctl_fsparm32 {
3838 	struct sockaddr		gd32_addr;
3839 	s8			gd32_path[NFS_MAXPATHLEN+1];
3840 	s32			gd32_maxlen;
3841 };
3842 
3843 struct nfsctl_arg32 {
3844 	s32			ca32_version;	/* safeguard */
3845 	union {
3846 		struct nfsctl_svc32	u32_svc;
3847 		struct nfsctl_client32	u32_client;
3848 		struct nfsctl_export32	u32_export;
3849 		struct nfsctl_uidmap32	u32_umap;
3850 		struct nfsctl_fhparm32	u32_getfh;
3851 		struct nfsctl_fdparm32	u32_getfd;
3852 		struct nfsctl_fsparm32	u32_getfs;
3853 	} u;
3854 #define ca32_svc	u.u32_svc
3855 #define ca32_client	u.u32_client
3856 #define ca32_export	u.u32_export
3857 #define ca32_umap	u.u32_umap
3858 #define ca32_getfh	u.u32_getfh
3859 #define ca32_getfd	u.u32_getfd
3860 #define ca32_getfs	u.u32_getfs
3861 #define ca32_authd	u.u32_authd
3862 };
3863 
3864 union nfsctl_res32 {
3865 	__u8			cr32_getfh[NFS_FHSIZE];
3866 	struct knfsd_fh		cr32_getfs;
3867 };
3868 
nfs_svc32_trans(struct nfsctl_arg * karg,struct nfsctl_arg32 * arg32)3869 static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3870 {
3871 	int err;
3872 
3873 	err = __get_user(karg->ca_version, &arg32->ca32_version);
3874 	err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
3875 	err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
3876 	return err;
3877 }
3878 
nfs_clnt32_trans(struct nfsctl_arg * karg,struct nfsctl_arg32 * arg32)3879 static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3880 {
3881 	int err;
3882 
3883 	err = __get_user(karg->ca_version, &arg32->ca32_version);
3884 	err |= copy_from_user(&karg->ca_client.cl_ident[0],
3885 			  &arg32->ca32_client.cl32_ident[0],
3886 			  NFSCLNT_IDMAX);
3887 	err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
3888 	err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
3889 			  &arg32->ca32_client.cl32_addrlist[0],
3890 			  (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
3891 	err |= __get_user(karg->ca_client.cl_fhkeytype,
3892 		      &arg32->ca32_client.cl32_fhkeytype);
3893 	err |= __get_user(karg->ca_client.cl_fhkeylen,
3894 		      &arg32->ca32_client.cl32_fhkeylen);
3895 	err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
3896 			  &arg32->ca32_client.cl32_fhkey[0],
3897 			  NFSCLNT_KEYMAX);
3898 	return (err ? -EFAULT : 0);
3899 }
3900 
nfs_exp32_trans(struct nfsctl_arg * karg,struct nfsctl_arg32 * arg32)3901 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3902 {
3903 	int err;
3904 
3905 	err = __get_user(karg->ca_version, &arg32->ca32_version);
3906 	err |= copy_from_user(&karg->ca_export.ex_client[0],
3907 			  &arg32->ca32_export.ex32_client[0],
3908 			  NFSCLNT_IDMAX);
3909 	err |= copy_from_user(&karg->ca_export.ex_path[0],
3910 			  &arg32->ca32_export.ex32_path[0],
3911 			  NFS_MAXPATHLEN);
3912 	err |= __get_user(karg->ca_export.ex_dev,
3913 		      &arg32->ca32_export.ex32_dev);
3914 	err |= __get_user(karg->ca_export.ex_ino,
3915 		      &arg32->ca32_export.ex32_ino);
3916 	err |= __get_user(karg->ca_export.ex_flags,
3917 		      &arg32->ca32_export.ex32_flags);
3918 	err |= __get_user(karg->ca_export.ex_anon_uid,
3919 		      &arg32->ca32_export.ex32_anon_uid);
3920 	err |= __get_user(karg->ca_export.ex_anon_gid,
3921 		      &arg32->ca32_export.ex32_anon_gid);
3922 	karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
3923 	karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
3924 	return (err ? -EFAULT : 0);
3925 }
3926 
nfs_uud32_trans(struct nfsctl_arg * karg,struct nfsctl_arg32 * arg32)3927 static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3928 {
3929 	u32 uaddr;
3930 	int i;
3931 	int err;
3932 
3933 	memset(karg, 0, sizeof(*karg));
3934 	if(__get_user(karg->ca_version, &arg32->ca32_version))
3935 		return -EFAULT;
3936 	karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
3937 	if(!karg->ca_umap.ug_ident)
3938 		return -ENOMEM;
3939 	err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
3940 	if(strncpy_from_user(karg->ca_umap.ug_ident,
3941 			     (char *)A(uaddr), PAGE_SIZE) <= 0)
3942 		return -EFAULT;
3943 	err |= __get_user(karg->ca_umap.ug_uidbase,
3944 		      &arg32->ca32_umap.ug32_uidbase);
3945 	err |= __get_user(karg->ca_umap.ug_uidlen,
3946 		      &arg32->ca32_umap.ug32_uidlen);
3947 	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
3948 	if (err)
3949 		return -EFAULT;
3950 	karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
3951 					  GFP_USER);
3952 	if(!karg->ca_umap.ug_udimap)
3953 		return -ENOMEM;
3954 	for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
3955 		err |= __get_user(karg->ca_umap.ug_udimap[i],
3956 			      &(((__kernel_uid_t32 *)A(uaddr))[i]));
3957 	err |= __get_user(karg->ca_umap.ug_gidbase,
3958 		      &arg32->ca32_umap.ug32_gidbase);
3959 	err |= __get_user(karg->ca_umap.ug_uidlen,
3960 		      &arg32->ca32_umap.ug32_gidlen);
3961 	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
3962 	if (err)
3963 		return -EFAULT;
3964 	karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
3965 					  GFP_USER);
3966 	if(!karg->ca_umap.ug_gdimap)
3967 		return -ENOMEM;
3968 	for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
3969 		err |= __get_user(karg->ca_umap.ug_gdimap[i],
3970 			      &(((__kernel_gid_t32 *)A(uaddr))[i]));
3971 
3972 	return (err ? -EFAULT : 0);
3973 }
3974 
nfs_getfh32_trans(struct nfsctl_arg * karg,struct nfsctl_arg32 * arg32)3975 static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3976 {
3977 	int err;
3978 
3979 	err = __get_user(karg->ca_version, &arg32->ca32_version);
3980 	err |= copy_from_user(&karg->ca_getfh.gf_addr,
3981 			  &arg32->ca32_getfh.gf32_addr,
3982 			  (sizeof(struct sockaddr)));
3983 	err |= __get_user(karg->ca_getfh.gf_dev,
3984 		      &arg32->ca32_getfh.gf32_dev);
3985 	err |= __get_user(karg->ca_getfh.gf_ino,
3986 		      &arg32->ca32_getfh.gf32_ino);
3987 	err |= __get_user(karg->ca_getfh.gf_version,
3988 		      &arg32->ca32_getfh.gf32_version);
3989 	return (err ? -EFAULT : 0);
3990 }
3991 
nfs_getfd32_trans(struct nfsctl_arg * karg,struct nfsctl_arg32 * arg32)3992 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3993 {
3994 	int err;
3995 
3996 	err = __get_user(karg->ca_version, &arg32->ca32_version);
3997 	err |= copy_from_user(&karg->ca_getfd.gd_addr,
3998 			  &arg32->ca32_getfd.gd32_addr,
3999 			  (sizeof(struct sockaddr)));
4000 	err |= copy_from_user(&karg->ca_getfd.gd_path,
4001 			  &arg32->ca32_getfd.gd32_path,
4002 			  (NFS_MAXPATHLEN+1));
4003 	err |= __get_user(karg->ca_getfd.gd_version,
4004 		      &arg32->ca32_getfd.gd32_version);
4005 	return (err ? -EFAULT : 0);
4006 }
4007 
nfs_getfs32_trans(struct nfsctl_arg * karg,struct nfsctl_arg32 * arg32)4008 static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
4009 {
4010 	int err;
4011 
4012 	err = __get_user(karg->ca_version, &arg32->ca32_version);
4013 	err |= copy_from_user(&karg->ca_getfs.gd_addr,
4014 			  &arg32->ca32_getfs.gd32_addr,
4015 			  (sizeof(struct sockaddr)));
4016 	err |= copy_from_user(&karg->ca_getfs.gd_path,
4017 			  &arg32->ca32_getfs.gd32_path,
4018 			  (NFS_MAXPATHLEN+1));
4019 	err |= __get_user(karg->ca_getfs.gd_maxlen,
4020 		      &arg32->ca32_getfs.gd32_maxlen);
4021 	return (err ? -EFAULT : 0);
4022 }
4023 
4024 /* This really doesn't need translations, we are only passing
4025  * back a union which contains opaque nfs file handle data.
4026  */
nfs_getfh32_res_trans(union nfsctl_res * kres,union nfsctl_res32 * res32)4027 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
4028 {
4029 	return (copy_to_user(res32, kres, sizeof(*res32)) ? -EFAULT : 0);
4030 }
4031 
sys32_nfsservctl(int cmd,struct nfsctl_arg32 * arg32,union nfsctl_res32 * res32)4032 int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
4033 {
4034 	struct nfsctl_arg *karg = NULL;
4035 	union nfsctl_res *kres = NULL;
4036 	mm_segment_t oldfs;
4037 	int err;
4038 
4039 	karg = kmalloc(sizeof(*karg), GFP_USER);
4040 	if(!karg)
4041 		return -ENOMEM;
4042 	if(res32) {
4043 		kres = kmalloc(sizeof(*kres), GFP_USER);
4044 		if(!kres) {
4045 			kfree(karg);
4046 			return -ENOMEM;
4047 		}
4048 	}
4049 	switch(cmd) {
4050 	case NFSCTL_SVC:
4051 		err = nfs_svc32_trans(karg, arg32);
4052 		break;
4053 	case NFSCTL_ADDCLIENT:
4054 		err = nfs_clnt32_trans(karg, arg32);
4055 		break;
4056 	case NFSCTL_DELCLIENT:
4057 		err = nfs_clnt32_trans(karg, arg32);
4058 		break;
4059 	case NFSCTL_EXPORT:
4060 	case NFSCTL_UNEXPORT:
4061 		err = nfs_exp32_trans(karg, arg32);
4062 		break;
4063 	/* This one is unimplemented, be we're ready for it. */
4064 	case NFSCTL_UGIDUPDATE:
4065 		err = nfs_uud32_trans(karg, arg32);
4066 		break;
4067 	case NFSCTL_GETFH:
4068 		err = nfs_getfh32_trans(karg, arg32);
4069 		break;
4070 	case NFSCTL_GETFD:
4071 		err = nfs_getfd32_trans(karg, arg32);
4072 		break;
4073 	case NFSCTL_GETFS:
4074 		err = nfs_getfs32_trans(karg, arg32);
4075 		break;
4076 	default:
4077 		err = -EINVAL;
4078 		break;
4079 	}
4080 	if(err)
4081 		goto done;
4082 	oldfs = get_fs();
4083 	set_fs(KERNEL_DS);
4084 	err = sys_nfsservctl(cmd, karg, kres);
4085 	set_fs(oldfs);
4086 
4087 	if (err)
4088 		goto done;
4089 
4090 	if((cmd == NFSCTL_GETFH) ||
4091 	   (cmd == NFSCTL_GETFD) ||
4092 	   (cmd == NFSCTL_GETFS))
4093 		err = nfs_getfh32_res_trans(kres, res32);
4094 
4095 done:
4096 	if(karg) {
4097 		if(cmd == NFSCTL_UGIDUPDATE) {
4098 			if(karg->ca_umap.ug_ident)
4099 				kfree(karg->ca_umap.ug_ident);
4100 			if(karg->ca_umap.ug_udimap)
4101 				kfree(karg->ca_umap.ug_udimap);
4102 			if(karg->ca_umap.ug_gdimap)
4103 				kfree(karg->ca_umap.ug_gdimap);
4104 		}
4105 		kfree(karg);
4106 	}
4107 	if(kres)
4108 		kfree(kres);
4109 	return err;
4110 }
4111 #else /* !NFSD */
4112 extern asmlinkage long sys_ni_syscall(void);
sys32_nfsservctl(int cmd,void * notused,void * notused2)4113 int asmlinkage sys32_nfsservctl(int cmd, void *notused, void *notused2)
4114 {
4115 	return sys_ni_syscall();
4116 }
4117 #endif
4118 
4119 /* Translations due to time_t size differences.  Which affects all
4120    sorts of things, like timeval and itimerval.  */
4121 
4122 extern struct timezone sys_tz;
4123 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
4124 
sys32_gettimeofday(struct timeval32 * tv,struct timezone * tz)4125 asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
4126 {
4127 	if (tv) {
4128 		struct timeval ktv;
4129 		do_gettimeofday(&ktv);
4130 		if (put_tv32(tv, &ktv))
4131 			return -EFAULT;
4132 	}
4133 	if (tz) {
4134 		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
4135 			return -EFAULT;
4136 	}
4137 	return 0;
4138 }
4139 
sys32_settimeofday(struct timeval32 * tv,struct timezone * tz)4140 asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
4141 {
4142 	struct timeval ktv;
4143 	struct timezone ktz;
4144 
4145  	if (tv) {
4146 		if (get_tv32(&ktv, tv))
4147 			return -EFAULT;
4148 	}
4149 	if (tz) {
4150 		if (copy_from_user(&ktz, tz, sizeof(ktz)))
4151 			return -EFAULT;
4152 	}
4153 
4154 	return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
4155 }
4156 
4157 extern int do_getitimer(int which, struct itimerval *value);
4158 
sys32_getitimer(int which,struct itimerval32 * it)4159 asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
4160 {
4161 	struct itimerval kit;
4162 	int error;
4163 
4164 	error = do_getitimer(which, &kit);
4165 	if (!error && put_it32(it, &kit))
4166 		error = -EFAULT;
4167 
4168 	return error;
4169 }
4170 
4171 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
4172 
sys32_setitimer(int which,struct itimerval32 * in,struct itimerval32 * out)4173 asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
4174 {
4175 	struct itimerval kin, kout;
4176 	int error;
4177 
4178 	if (in) {
4179 		if (get_it32(&kin, in))
4180 			return -EFAULT;
4181 	} else
4182 		memset(&kin, 0, sizeof(kin));
4183 
4184 	error = do_setitimer(which, &kin, out ? &kout : NULL);
4185 	if (error || !out)
4186 		return error;
4187 	if (put_it32(out, &kout))
4188 		return -EFAULT;
4189 
4190 	return 0;
4191 
4192 }
4193 
4194 asmlinkage int sys_utimes(char *, struct timeval *);
4195 
sys32_utimes(char * filename,struct timeval32 * tvs)4196 asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
4197 {
4198 	char *kfilename;
4199 	struct timeval ktvs[2];
4200 	mm_segment_t old_fs;
4201 	int ret;
4202 
4203 	kfilename = getname(filename);
4204 	ret = PTR_ERR(kfilename);
4205 	if (!IS_ERR(kfilename)) {
4206 		if (tvs) {
4207 			if (get_tv32(&ktvs[0], tvs) ||
4208 			    get_tv32(&ktvs[1], 1+tvs))
4209 				return -EFAULT;
4210 		}
4211 
4212 		old_fs = get_fs();
4213 		set_fs(KERNEL_DS);
4214 		ret = sys_utimes(kfilename, (tvs ? &ktvs[0] : NULL));
4215 		set_fs(old_fs);
4216 
4217 		putname(kfilename);
4218 	}
4219 	return ret;
4220 }
4221 
4222 /* These are here just in case some old sparc32 binary calls it. */
sys32_pause(void)4223 asmlinkage int sys32_pause(void)
4224 {
4225 	current->state = TASK_INTERRUPTIBLE;
4226 	schedule();
4227 	return -ERESTARTNOHAND;
4228 }
4229 
4230 /* PCI config space poking. */
4231 extern asmlinkage int sys_pciconfig_read(unsigned long bus,
4232 					 unsigned long dfn,
4233 					 unsigned long off,
4234 					 unsigned long len,
4235 					 unsigned char *buf);
4236 
4237 extern asmlinkage int sys_pciconfig_write(unsigned long bus,
4238 					  unsigned long dfn,
4239 					  unsigned long off,
4240 					  unsigned long len,
4241 					  unsigned char *buf);
4242 
sys32_pciconfig_read(u32 bus,u32 dfn,u32 off,u32 len,u32 ubuf)4243 asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
4244 {
4245 	return sys_pciconfig_read((unsigned long) bus,
4246 				  (unsigned long) dfn,
4247 				  (unsigned long) off,
4248 				  (unsigned long) len,
4249 				  (unsigned char *)AA(ubuf));
4250 }
4251 
sys32_pciconfig_write(u32 bus,u32 dfn,u32 off,u32 len,u32 ubuf)4252 asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
4253 {
4254 	return sys_pciconfig_write((unsigned long) bus,
4255 				   (unsigned long) dfn,
4256 				   (unsigned long) off,
4257 				   (unsigned long) len,
4258 				   (unsigned char *)AA(ubuf));
4259 }
4260 
4261 extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
4262 				unsigned long arg4, unsigned long arg5);
4263 
sys32_prctl(int option,u32 arg2,u32 arg3,u32 arg4,u32 arg5)4264 asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
4265 {
4266 	return sys_prctl(option,
4267 			 (unsigned long) arg2,
4268 			 (unsigned long) arg3,
4269 			 (unsigned long) arg4,
4270 			 (unsigned long) arg5);
4271 }
4272 
4273 
4274 extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
4275 				    size_t count, loff_t pos);
4276 
4277 extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
4278 				     size_t count, loff_t pos);
4279 
4280 typedef __kernel_ssize_t32 ssize_t32;
4281 
sys32_pread(unsigned int fd,char * ubuf,__kernel_size_t32 count,u32 poshi,u32 poslo)4282 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
4283 				 __kernel_size_t32 count, u32 poshi, u32 poslo)
4284 {
4285 	return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4286 }
4287 
sys32_pwrite(unsigned int fd,char * ubuf,__kernel_size_t32 count,u32 poshi,u32 poslo)4288 asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
4289 				  __kernel_size_t32 count, u32 poshi, u32 poslo)
4290 {
4291 	return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4292 }
4293 
4294 extern asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count);
4295 
sys32_readahead(int fd,u32 offhi,u32 offlo,s32 count)4296 asmlinkage ssize_t32 sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count)
4297 {
4298 	return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
4299 }
4300 
4301 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
4302 
sys32_sendfile(int out_fd,int in_fd,__kernel_off_t32 * offset,s32 count)4303 asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
4304 {
4305 	mm_segment_t old_fs = get_fs();
4306 	int ret;
4307 	off_t of;
4308 
4309 	if (offset && get_user(of, offset))
4310 		return -EFAULT;
4311 
4312 	set_fs(KERNEL_DS);
4313 	ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
4314 	set_fs(old_fs);
4315 
4316 	if (offset && put_user(of, offset))
4317 		return -EFAULT;
4318 
4319 	return ret;
4320 }
4321 
4322 /* Handle adjtimex compatability. */
4323 
4324 struct timex32 {
4325 	u32 modes;
4326 	s32 offset, freq, maxerror, esterror;
4327 	s32 status, constant, precision, tolerance;
4328 	struct timeval32 time;
4329 	s32 tick;
4330 	s32 ppsfreq, jitter, shift, stabil;
4331 	s32 jitcnt, calcnt, errcnt, stbcnt;
4332 	s32  :32; s32  :32; s32  :32; s32  :32;
4333 	s32  :32; s32  :32; s32  :32; s32  :32;
4334 	s32  :32; s32  :32; s32  :32; s32  :32;
4335 };
4336 
4337 extern int do_adjtimex(struct timex *);
4338 
sys32_adjtimex(struct timex32 * utp)4339 asmlinkage int sys32_adjtimex(struct timex32 *utp)
4340 {
4341 	struct timex txc;
4342 	int ret;
4343 
4344 	memset(&txc, 0, sizeof(struct timex));
4345 
4346 	if(get_user(txc.modes, &utp->modes) ||
4347 	   __get_user(txc.offset, &utp->offset) ||
4348 	   __get_user(txc.freq, &utp->freq) ||
4349 	   __get_user(txc.maxerror, &utp->maxerror) ||
4350 	   __get_user(txc.esterror, &utp->esterror) ||
4351 	   __get_user(txc.status, &utp->status) ||
4352 	   __get_user(txc.constant, &utp->constant) ||
4353 	   __get_user(txc.precision, &utp->precision) ||
4354 	   __get_user(txc.tolerance, &utp->tolerance) ||
4355 	   __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4356 	   __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4357 	   __get_user(txc.tick, &utp->tick) ||
4358 	   __get_user(txc.ppsfreq, &utp->ppsfreq) ||
4359 	   __get_user(txc.jitter, &utp->jitter) ||
4360 	   __get_user(txc.shift, &utp->shift) ||
4361 	   __get_user(txc.stabil, &utp->stabil) ||
4362 	   __get_user(txc.jitcnt, &utp->jitcnt) ||
4363 	   __get_user(txc.calcnt, &utp->calcnt) ||
4364 	   __get_user(txc.errcnt, &utp->errcnt) ||
4365 	   __get_user(txc.stbcnt, &utp->stbcnt))
4366 		return -EFAULT;
4367 
4368 	ret = do_adjtimex(&txc);
4369 
4370 	if(put_user(txc.modes, &utp->modes) ||
4371 	   __put_user(txc.offset, &utp->offset) ||
4372 	   __put_user(txc.freq, &utp->freq) ||
4373 	   __put_user(txc.maxerror, &utp->maxerror) ||
4374 	   __put_user(txc.esterror, &utp->esterror) ||
4375 	   __put_user(txc.status, &utp->status) ||
4376 	   __put_user(txc.constant, &utp->constant) ||
4377 	   __put_user(txc.precision, &utp->precision) ||
4378 	   __put_user(txc.tolerance, &utp->tolerance) ||
4379 	   __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4380 	   __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4381 	   __put_user(txc.tick, &utp->tick) ||
4382 	   __put_user(txc.ppsfreq, &utp->ppsfreq) ||
4383 	   __put_user(txc.jitter, &utp->jitter) ||
4384 	   __put_user(txc.shift, &utp->shift) ||
4385 	   __put_user(txc.stabil, &utp->stabil) ||
4386 	   __put_user(txc.jitcnt, &utp->jitcnt) ||
4387 	   __put_user(txc.calcnt, &utp->calcnt) ||
4388 	   __put_user(txc.errcnt, &utp->errcnt) ||
4389 	   __put_user(txc.stbcnt, &utp->stbcnt))
4390 		ret = -EFAULT;
4391 
4392 	return ret;
4393 }
4394 
4395 /* This is just a version for 32-bit applications which does
4396  * not force O_LARGEFILE on.
4397  */
4398 
sparc32_open(const char * filename,int flags,int mode)4399 asmlinkage long sparc32_open(const char * filename, int flags, int mode)
4400 {
4401 	char * tmp;
4402 	int fd, error;
4403 
4404 	tmp = getname(filename);
4405 	fd = PTR_ERR(tmp);
4406 	if (!IS_ERR(tmp)) {
4407 		fd = get_unused_fd();
4408 		if (fd >= 0) {
4409 			struct file * f = filp_open(tmp, flags, mode);
4410 			error = PTR_ERR(f);
4411 			if (IS_ERR(f))
4412 				goto out_error;
4413 			fd_install(fd, f);
4414 		}
4415 out:
4416 		putname(tmp);
4417 	}
4418 	return fd;
4419 
4420 out_error:
4421 	put_unused_fd(fd);
4422 	fd = error;
4423 	goto out;
4424 }
4425 
4426 extern unsigned long do_mremap(unsigned long addr,
4427 	unsigned long old_len, unsigned long new_len,
4428 	unsigned long flags, unsigned long new_addr);
4429 
sys32_mremap(unsigned long addr,unsigned long old_len,unsigned long new_len,unsigned long flags,u32 __new_addr)4430 asmlinkage unsigned long sys32_mremap(unsigned long addr,
4431 	unsigned long old_len, unsigned long new_len,
4432 	unsigned long flags, u32 __new_addr)
4433 {
4434 	struct vm_area_struct *vma;
4435 	unsigned long ret = -EINVAL;
4436 	unsigned long new_addr = AA(__new_addr);
4437 
4438 	if (old_len > 0xf0000000UL || new_len > 0xf0000000UL)
4439 		goto out;
4440 	if (addr > 0xf0000000UL - old_len)
4441 		goto out;
4442 	down_write(&current->mm->mmap_sem);
4443 	if (flags & MREMAP_FIXED) {
4444 		if (new_addr > 0xf0000000UL - new_len)
4445 			goto out_sem;
4446 	} else if (addr > 0xf0000000UL - new_len) {
4447 		unsigned long map_flags = 0;
4448 		struct file *file = NULL;
4449 
4450 		ret = -ENOMEM;
4451 		if (!(flags & MREMAP_MAYMOVE))
4452 			goto out_sem;
4453 
4454 		vma = find_vma(current->mm, addr);
4455 		if (vma) {
4456 			if (vma->vm_flags & VM_SHARED)
4457 				map_flags |= MAP_SHARED;
4458 			file = vma->vm_file;
4459 		}
4460 
4461 		/* MREMAP_FIXED checked above. */
4462 		new_addr = get_unmapped_area(file, addr, new_len,
4463 				    vma ? vma->vm_pgoff : 0,
4464 				    map_flags);
4465 		ret = new_addr;
4466 		if (new_addr & ~PAGE_MASK)
4467 			goto out_sem;
4468 		flags |= MREMAP_FIXED;
4469 	}
4470 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
4471 out_sem:
4472 	up_write(&current->mm->mmap_sem);
4473 out:
4474 	return ret;
4475 }
4476 
4477 extern asmlinkage long sys_setpriority(int which, int who, int niceval);
4478 
sys_setpriority32(u32 which,u32 who,u32 niceval)4479 asmlinkage int sys_setpriority32(u32 which, u32 who, u32 niceval)
4480 {
4481 	return sys_setpriority((int) which,
4482 			       (int) who,
4483 			       (int) niceval);
4484 }
4485 
4486 struct __sysctl_args32 {
4487 	u32 name;
4488 	int nlen;
4489 	u32 oldval;
4490 	u32 oldlenp;
4491 	u32 newval;
4492 	u32 newlen;
4493 	u32 __unused[4];
4494 };
4495 
sys32_sysctl(struct __sysctl_args32 * args)4496 extern asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
4497 {
4498 #ifndef CONFIG_SYSCTL
4499 	return -ENOSYS;
4500 #else
4501 	struct __sysctl_args32 tmp;
4502 	int error;
4503 	size_t oldlen, *oldlenp = NULL;
4504 	unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
4505 
4506 	if (copy_from_user(&tmp, args, sizeof(tmp)))
4507 		return -EFAULT;
4508 
4509 	if (tmp.oldval && tmp.oldlenp) {
4510 		/* Duh, this is ugly and might not work if sysctl_args
4511 		   is in read-only memory, but do_sysctl does indirectly
4512 		   a lot of uaccess in both directions and we'd have to
4513 		   basically copy the whole sysctl.c here, and
4514 		   glibc's __sysctl uses rw memory for the structure
4515 		   anyway.  */
4516 		if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
4517 		    put_user(oldlen, (size_t *)addr))
4518 			return -EFAULT;
4519 		oldlenp = (size_t *)addr;
4520 	}
4521 
4522 	lock_kernel();
4523 	error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
4524 			  oldlenp, (void *)A(tmp.newval), tmp.newlen);
4525 	unlock_kernel();
4526 	if (oldlenp) {
4527 		if (!error) {
4528 			if (get_user(oldlen, (size_t *)addr) ||
4529 			    put_user(oldlen, (u32 *)A(tmp.oldlenp)))
4530 				error = -EFAULT;
4531 		}
4532 		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
4533 	}
4534 	return error;
4535 #endif
4536 }
4537