aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/ia32/sys_ia32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/ia32/sys_ia32.c')
-rw-r--r--arch/x86/ia32/sys_ia32.c176
1 files changed, 5 insertions, 171 deletions
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index 9f5527198825..626be156d88d 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -40,6 +40,7 @@
40#include <linux/ptrace.h> 40#include <linux/ptrace.h>
41#include <linux/highuid.h> 41#include <linux/highuid.h>
42#include <linux/sysctl.h> 42#include <linux/sysctl.h>
43#include <linux/slab.h>
43#include <asm/mman.h> 44#include <asm/mman.h>
44#include <asm/types.h> 45#include <asm/types.h>
45#include <asm/uaccess.h> 46#include <asm/uaccess.h>
@@ -143,7 +144,7 @@ asmlinkage long sys32_fstatat(unsigned int dfd, char __user *filename,
143 * block for parameter passing.. 144 * block for parameter passing..
144 */ 145 */
145 146
146struct mmap_arg_struct { 147struct mmap_arg_struct32 {
147 unsigned int addr; 148 unsigned int addr;
148 unsigned int len; 149 unsigned int len;
149 unsigned int prot; 150 unsigned int prot;
@@ -152,12 +153,9 @@ struct mmap_arg_struct {
152 unsigned int offset; 153 unsigned int offset;
153}; 154};
154 155
155asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg) 156asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *arg)
156{ 157{
157 struct mmap_arg_struct a; 158 struct mmap_arg_struct32 a;
158 struct file *file = NULL;
159 unsigned long retval;
160 struct mm_struct *mm ;
161 159
162 if (copy_from_user(&a, arg, sizeof(a))) 160 if (copy_from_user(&a, arg, sizeof(a)))
163 return -EFAULT; 161 return -EFAULT;
@@ -165,22 +163,8 @@ asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg)
165 if (a.offset & ~PAGE_MASK) 163 if (a.offset & ~PAGE_MASK)
166 return -EINVAL; 164 return -EINVAL;
167 165
168 if (!(a.flags & MAP_ANONYMOUS)) { 166 return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
169 file = fget(a.fd);
170 if (!file)
171 return -EBADF;
172 }
173
174 mm = current->mm;
175 down_write(&mm->mmap_sem);
176 retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags,
177 a.offset>>PAGE_SHIFT); 167 a.offset>>PAGE_SHIFT);
178 if (file)
179 fput(file);
180
181 up_write(&mm->mmap_sem);
182
183 return retval;
184} 168}
185 169
186asmlinkage long sys32_mprotect(unsigned long start, size_t len, 170asmlinkage long sys32_mprotect(unsigned long start, size_t len,
@@ -349,24 +333,6 @@ asmlinkage long sys32_alarm(unsigned int seconds)
349 return alarm_setitimer(seconds); 333 return alarm_setitimer(seconds);
350} 334}
351 335
352struct sel_arg_struct {
353 unsigned int n;
354 unsigned int inp;
355 unsigned int outp;
356 unsigned int exp;
357 unsigned int tvp;
358};
359
360asmlinkage long sys32_old_select(struct sel_arg_struct __user *arg)
361{
362 struct sel_arg_struct a;
363
364 if (copy_from_user(&a, arg, sizeof(a)))
365 return -EFAULT;
366 return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
367 compat_ptr(a.exp), compat_ptr(a.tvp));
368}
369
370asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, 336asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr,
371 int options) 337 int options)
372{ 338{
@@ -434,62 +400,6 @@ asmlinkage long sys32_rt_sigqueueinfo(int pid, int sig,
434 return ret; 400 return ret;
435} 401}
436 402
437#ifdef CONFIG_SYSCTL_SYSCALL
438struct sysctl_ia32 {
439 unsigned int name;
440 int nlen;
441 unsigned int oldval;
442 unsigned int oldlenp;
443 unsigned int newval;
444 unsigned int newlen;
445 unsigned int __unused[4];
446};
447
448
449asmlinkage long sys32_sysctl(struct sysctl_ia32 __user *args32)
450{
451 struct sysctl_ia32 a32;
452 mm_segment_t old_fs = get_fs();
453 void __user *oldvalp, *newvalp;
454 size_t oldlen;
455 int __user *namep;
456 long ret;
457
458 if (copy_from_user(&a32, args32, sizeof(a32)))
459 return -EFAULT;
460
461 /*
462 * We need to pre-validate these because we have to disable
463 * address checking before calling do_sysctl() because of
464 * OLDLEN but we can't run the risk of the user specifying bad
465 * addresses here. Well, since we're dealing with 32 bit
466 * addresses, we KNOW that access_ok() will always succeed, so
467 * this is an expensive NOP, but so what...
468 */
469 namep = compat_ptr(a32.name);
470 oldvalp = compat_ptr(a32.oldval);
471 newvalp = compat_ptr(a32.newval);
472
473 if ((oldvalp && get_user(oldlen, (int __user *)compat_ptr(a32.oldlenp)))
474 || !access_ok(VERIFY_WRITE, namep, 0)
475 || !access_ok(VERIFY_WRITE, oldvalp, 0)
476 || !access_ok(VERIFY_WRITE, newvalp, 0))
477 return -EFAULT;
478
479 set_fs(KERNEL_DS);
480 lock_kernel();
481 ret = do_sysctl(namep, a32.nlen, oldvalp, (size_t __user *)&oldlen,
482 newvalp, (size_t) a32.newlen);
483 unlock_kernel();
484 set_fs(old_fs);
485
486 if (oldvalp && put_user(oldlen, (int __user *)compat_ptr(a32.oldlenp)))
487 return -EFAULT;
488
489 return ret;
490}
491#endif
492
493/* warning: next two assume little endian */ 403/* warning: next two assume little endian */
494asmlinkage long sys32_pread(unsigned int fd, char __user *ubuf, u32 count, 404asmlinkage long sys32_pread(unsigned int fd, char __user *ubuf, u32 count,
495 u32 poslo, u32 poshi) 405 u32 poslo, u32 poshi)
@@ -539,82 +449,6 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd,
539 return ret; 449 return ret;
540} 450}
541 451
542asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
543 unsigned long prot, unsigned long flags,
544 unsigned long fd, unsigned long pgoff)
545{
546 struct mm_struct *mm = current->mm;
547 unsigned long error;
548 struct file *file = NULL;
549
550 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
551 if (!(flags & MAP_ANONYMOUS)) {
552 file = fget(fd);
553 if (!file)
554 return -EBADF;
555 }
556
557 down_write(&mm->mmap_sem);
558 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
559 up_write(&mm->mmap_sem);
560
561 if (file)
562 fput(file);
563 return error;
564}
565
566asmlinkage long sys32_olduname(struct oldold_utsname __user *name)
567{
568 char *arch = "x86_64";
569 int err;
570
571 if (!name)
572 return -EFAULT;
573 if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
574 return -EFAULT;
575
576 down_read(&uts_sem);
577
578 err = __copy_to_user(&name->sysname, &utsname()->sysname,
579 __OLD_UTS_LEN);
580 err |= __put_user(0, name->sysname+__OLD_UTS_LEN);
581 err |= __copy_to_user(&name->nodename, &utsname()->nodename,
582 __OLD_UTS_LEN);
583 err |= __put_user(0, name->nodename+__OLD_UTS_LEN);
584 err |= __copy_to_user(&name->release, &utsname()->release,
585 __OLD_UTS_LEN);
586 err |= __put_user(0, name->release+__OLD_UTS_LEN);
587 err |= __copy_to_user(&name->version, &utsname()->version,
588 __OLD_UTS_LEN);
589 err |= __put_user(0, name->version+__OLD_UTS_LEN);
590
591 if (personality(current->personality) == PER_LINUX32)
592 arch = "i686";
593
594 err |= __copy_to_user(&name->machine, arch, strlen(arch) + 1);
595
596 up_read(&uts_sem);
597
598 err = err ? -EFAULT : 0;
599
600 return err;
601}
602
603long sys32_uname(struct old_utsname __user *name)
604{
605 int err;
606
607 if (!name)
608 return -EFAULT;
609 down_read(&uts_sem);
610 err = copy_to_user(name, utsname(), sizeof(*name));
611 up_read(&uts_sem);
612 if (personality(current->personality) == PER_LINUX32)
613 err |= copy_to_user(&name->machine, "i686", 5);
614
615 return err ? -EFAULT : 0;
616}
617
618asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv, 452asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv,
619 compat_uptr_t __user *envp, struct pt_regs *regs) 453 compat_uptr_t __user *envp, struct pt_regs *regs)
620{ 454{