diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-04-29 21:13:14 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1997-04-29 21:13:14 +0000 |
commit | 19c9bba94152148523ba0f7ef7cffe3d45656b11 (patch) | |
tree | 40b1cb534496a7f1ca0f5c314a523c69f1fee464 /arch/i386/kernel/sys_i386.c | |
parent | 7206675c40394c78a90e74812bbdbf8cf3cca1be (diff) |
Import of Linux/MIPS 2.1.36
Diffstat (limited to 'arch/i386/kernel/sys_i386.c')
-rw-r--r-- | arch/i386/kernel/sys_i386.c | 128 |
1 files changed, 76 insertions, 52 deletions
diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c index 619b372d8..b1eb2911d 100644 --- a/arch/i386/kernel/sys_i386.c +++ b/arch/i386/kernel/sys_i386.c @@ -9,6 +9,8 @@ #include <linux/errno.h> #include <linux/sched.h> #include <linux/mm.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> #include <linux/sem.h> #include <linux/msg.h> #include <linux/shm.h> @@ -28,15 +30,14 @@ asmlinkage int sys_pipe(unsigned long * fildes) int fd[2]; int error; - error = verify_area(VERIFY_WRITE,fildes,8); - if (error) - return error; + lock_kernel(); error = do_pipe(fd); - if (error) - return error; - put_user(fd[0],0+fildes); - put_user(fd[1],1+fildes); - return 0; + unlock_kernel(); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; } /* @@ -45,6 +46,7 @@ asmlinkage int sys_pipe(unsigned long * fildes) * 4 system call parameters, so these system calls used a memory * block for parameter passing.. */ + struct mmap_arg_struct { unsigned long addr; unsigned long len; @@ -56,20 +58,22 @@ struct mmap_arg_struct { asmlinkage int old_mmap(struct mmap_arg_struct *arg) { - int error; + int error = -EFAULT; struct file * file = NULL; struct mmap_arg_struct a; - error = verify_area(VERIFY_READ, arg, sizeof(*arg)); - if (error) - return error; - copy_from_user(&a, arg, sizeof(a)); + lock_kernel(); + if (copy_from_user(&a, arg, sizeof(a))) + goto out; if (!(a.flags & MAP_ANONYMOUS)) { + error = -EBADF; if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd])) - return -EBADF; + goto out; } a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset); +out: + unlock_kernel(); return error; } @@ -87,6 +91,7 @@ asmlinkage int old_select(struct sel_arg_struct *arg) if (copy_from_user(&a, arg, sizeof(a))) return -EFAULT; + /* sys_select() does the appropriate kernel locking */ return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); } @@ -97,56 +102,68 @@ asmlinkage int old_select(struct sel_arg_struct *arg) */ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth) { - int version; + int version, ret; + lock_kernel(); version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; if (call <= SEMCTL) switch (call) { case SEMOP: - return sys_semop (first, (struct sembuf *)ptr, second); + ret = sys_semop (first, (struct sembuf *)ptr, second); + goto out; case SEMGET: - return sys_semget (first, second, third); + ret = sys_semget (first, second, third); + goto out; case SEMCTL: { union semun fourth; - int err; + ret = -EINVAL; if (!ptr) - return -EINVAL; - if ((err = verify_area (VERIFY_READ, ptr, sizeof(long)))) - return err; - get_user(fourth.__pad, (void **) ptr); - return sys_semctl (first, second, third, fourth); + goto out; + ret = -EFAULT; + if (get_user(fourth.__pad, (void **) ptr)) + goto out; + ret = sys_semctl (first, second, third, fourth); + goto out; } default: - return -EINVAL; + ret = -EINVAL; + goto out; } if (call <= MSGCTL) switch (call) { case MSGSND: - return sys_msgsnd (first, (struct msgbuf *) ptr, - second, third); + ret = sys_msgsnd (first, (struct msgbuf *) ptr, + second, third); + goto out; case MSGRCV: switch (version) { case 0: { struct ipc_kludge tmp; - int err; + ret = -EINVAL; if (!ptr) - return -EINVAL; - if ((err = verify_area (VERIFY_READ, ptr, sizeof(tmp)))) - return err; - copy_from_user(&tmp,(struct ipc_kludge *) ptr, sizeof (tmp)); - return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third); + goto out; + ret = -EFAULT; + if (copy_from_user(&tmp,(struct ipc_kludge *) ptr, + sizeof (tmp))) + goto out; + ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third); + goto out; } case 1: default: - return sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third); + ret = sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third); + goto out; } case MSGGET: - return sys_msgget ((key_t) first, second); + ret = sys_msgget ((key_t) first, second); + goto out; case MSGCTL: - return sys_msgctl (first, second, (struct msqid_ds *) ptr); + ret = sys_msgctl (first, second, (struct msqid_ds *) ptr); + goto out; default: - return -EINVAL; + ret = -EINVAL; + goto out; } if (call <= SHMCTL) switch (call) { @@ -154,28 +171,35 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, switch (version) { case 0: default: { ulong raddr; - int err; - if ((err = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong)))) - return err; - err = sys_shmat (first, (char *) ptr, second, &raddr); - if (err) - return err; - put_user (raddr, (ulong *) third); - return 0; - } + ret = sys_shmat (first, (char *) ptr, second, &raddr); + if (ret) + goto out; + ret = put_user (raddr, (ulong *) third); + goto out; + } case 1: /* iBCS2 emulator entry point */ + ret = -EINVAL; if (get_fs() != get_ds()) - return -EINVAL; - return sys_shmat (first, (char *) ptr, second, (ulong *) third); + goto out; + ret = sys_shmat (first, (char *) ptr, second, (ulong *) third); + goto out; } case SHMDT: - return sys_shmdt ((char *)ptr); + ret = sys_shmdt ((char *)ptr); + goto out; case SHMGET: - return sys_shmget (first, second, third); + ret = sys_shmget (first, second, third); + goto out; case SHMCTL: - return sys_shmctl (first, second, (struct shmid_ds *) ptr); + ret = sys_shmctl (first, second, (struct shmid_ds *) ptr); + goto out; default: - return -EINVAL; + ret = -EINVAL; + goto out; } - return -EINVAL; + else + ret = -EINVAL; +out: + unlock_kernel(); + return ret; } |