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