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, ×->actime) ||
1098 __get_user (t.modtime, ×->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(¤t->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(¤t->blocked, ¤t->blocked, &these);
2193 recalc_sigpending(current);
2194 spin_unlock_irq(¤t->sigmask_lock);
2195
2196 current->state = TASK_INTERRUPTIBLE;
2197 timeout = schedule_timeout(timeout);
2198
2199 spin_lock_irq(¤t->sigmask_lock);
2200 sig = dequeue_signal(&these, &info);
2201 current->blocked = oldblocked;
2202 recalc_sigpending(current);
2203 }
2204 }
2205 spin_unlock_irq(¤t->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(¤t->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(¤t->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