Commit 2b047b97 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

[PATCH] UML: split out arch-specific syscalls from generic ones

This factors out a bunch of non-generic system calls into i386-specific
code.  It also adds the x86_64-specific system calls.
A couple of generic system calls handlers are declared in sysdep-i386 because
x86 has no declarations for them, but x86_64 has incompatible ones.

Also splits out syscalls on behalf on UML/S390 from Bodo Stroesser
Signed-off-by: default avatarBodo Stroesser <bstroesser@fujitsu-siemens.com>
Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent dbe2aba6
...@@ -8,11 +8,70 @@ ...@@ -8,11 +8,70 @@
typedef long syscall_handler_t(struct pt_regs); typedef long syscall_handler_t(struct pt_regs);
/* Not declared on x86, incompatible declarations on x86_64, so these have
* to go here rather than in sys_call_table.c
*/
extern syscall_handler_t sys_ptrace;
extern syscall_handler_t sys_rt_sigaction;
extern syscall_handler_t old_mmap_i386;
#define EXECUTE_SYSCALL(syscall, regs) \ #define EXECUTE_SYSCALL(syscall, regs) \
((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs)) ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
extern long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
#define ARCH_SYSCALLS \ #define ARCH_SYSCALLS \
[ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, \
[ __NR_break ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_oldstat ] = (syscall_handler_t *) sys_stat, \
[ __NR_umount ] = (syscall_handler_t *) sys_oldumount, \
[ __NR_stime ] = um_stime, \
[ __NR_oldfstat ] = (syscall_handler_t *) sys_fstat, \
[ __NR_stty ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_gtty ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_nice ] = (syscall_handler_t *) sys_nice, \
[ __NR_ftime ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_prof ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_signal ] = (syscall_handler_t *) sys_signal, \
[ __NR_lock ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_mpx ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_ulimit ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_oldolduname ] = (syscall_handler_t *) sys_olduname, \
[ __NR_sigaction ] = (syscall_handler_t *) sys_sigaction, \
[ __NR_sgetmask ] = (syscall_handler_t *) sys_sgetmask, \
[ __NR_ssetmask ] = (syscall_handler_t *) sys_ssetmask, \
[ __NR_sigsuspend ] = (syscall_handler_t *) sys_sigsuspend, \
[ __NR_sigpending ] = (syscall_handler_t *) sys_sigpending, \
[ __NR_oldlstat ] = (syscall_handler_t *) sys_lstat, \
[ __NR_readdir ] = old_readdir, \
[ __NR_profil ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_socketcall ] = (syscall_handler_t *) sys_socketcall, \
[ __NR_olduname ] = (syscall_handler_t *) sys_uname, \
[ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_idle ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_ipc ] = (syscall_handler_t *) sys_ipc, \
[ __NR_sigreturn ] = (syscall_handler_t *) sys_sigreturn, \
[ __NR_sigprocmask ] = (syscall_handler_t *) sys_sigprocmask, \
[ __NR_bdflush ] = (syscall_handler_t *) sys_bdflush, \
[ __NR__llseek ] = (syscall_handler_t *) sys_llseek, \
[ __NR__newselect ] = (syscall_handler_t *) sys_select, \
[ __NR_vm86 ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_mmap ] = (syscall_handler_t *) old_mmap_i386, \ [ __NR_mmap ] = (syscall_handler_t *) old_mmap_i386, \
[ __NR_ugetrlimit ] = (syscall_handler_t *) sys_getrlimit, \
[ __NR_mmap2 ] = (syscall_handler_t *) sys_mmap2, \
[ __NR_truncate64 ] = (syscall_handler_t *) sys_truncate64, \
[ __NR_ftruncate64 ] = (syscall_handler_t *) sys_ftruncate64, \
[ __NR_stat64 ] = (syscall_handler_t *) sys_stat64, \
[ __NR_lstat64 ] = (syscall_handler_t *) sys_lstat64, \
[ __NR_fstat64 ] = (syscall_handler_t *) sys_fstat64, \
[ __NR_fcntl64 ] = (syscall_handler_t *) sys_fcntl64, \
[ __NR_sendfile64 ] = (syscall_handler_t *) sys_sendfile64, \
[ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64, \
[ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64, \
[ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64, \
[ __NR_select ] = (syscall_handler_t *) old_select, \ [ __NR_select ] = (syscall_handler_t *) old_select, \
[ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \ [ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \ [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
...@@ -38,11 +97,19 @@ typedef long syscall_handler_t(struct pt_regs); ...@@ -38,11 +97,19 @@ typedef long syscall_handler_t(struct pt_regs);
[ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \ [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
[ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \ [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
[ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \ [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
[ 222 ] = (syscall_handler_t *) sys_ni_syscall, [ 222 ] = (syscall_handler_t *) sys_ni_syscall, \
[ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, \
[ 251 ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, \
[ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
[ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall,
/* 222 doesn't yet have a name in include/asm-i386/unistd.h */ /* 222 doesn't yet have a name in include/asm-i386/unistd.h */
#define LAST_ARCH_SYSCALL 222 #define LAST_ARCH_SYSCALL __NR_vserver
/* /*
* Overrides for Emacs so that we follow Linus's tabbing style. * Overrides for Emacs so that we follow Linus's tabbing style.
......
...@@ -34,9 +34,12 @@ int old_mmap(unsigned long addr, unsigned long len, ...@@ -34,9 +34,12 @@ int old_mmap(unsigned long addr, unsigned long len,
[ __NR_multiplexer ] = sys_ni_syscall, \ [ __NR_multiplexer ] = sys_ni_syscall, \
[ __NR_mmap ] = old_mmap, \ [ __NR_mmap ] = old_mmap, \
[ __NR_madvise ] = sys_madvise, \ [ __NR_madvise ] = sys_madvise, \
[ __NR_mincore ] = sys_mincore, [ __NR_mincore ] = sys_mincore, \
[ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
[ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64,
#define LAST_ARCH_SYSCALL __NR_mincore #define LAST_ARCH_SYSCALL __NR_fadvise64
/* /*
* Overrides for Emacs so that we follow Linus's tabbing style. * Overrides for Emacs so that we follow Linus's tabbing style.
......
/*
* Copyright 2003 PathScale, Inc.
*
* Licensed under the GPL
*/
#ifndef __SYSDEP_X86_64_SYSCALLS_H__
#define __SYSDEP_X86_64_SYSCALLS_H__
#include <linux/msg.h>
#include <linux/shm.h>
typedef long syscall_handler_t(void);
extern syscall_handler_t *ia32_sys_call_table[];
#define EXECUTE_SYSCALL(syscall, regs) \
(((long (*)(long, long, long, long, long, long)) \
(*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(&regs->regs), \
UPT_SYSCALL_ARG2(&regs->regs), \
UPT_SYSCALL_ARG3(&regs->regs), \
UPT_SYSCALL_ARG4(&regs->regs), \
UPT_SYSCALL_ARG5(&regs->regs), \
UPT_SYSCALL_ARG6(&regs->regs)))
extern long old_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
extern syscall_handler_t wrap_sys_shmat;
extern syscall_handler_t sys_modify_ldt;
extern syscall_handler_t sys_arch_prctl;
#define ARCH_SYSCALLS \
[ __NR_mmap ] = (syscall_handler_t *) old_mmap, \
[ __NR_select ] = (syscall_handler_t *) sys_select, \
[ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
[ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
[ __NR_shmget ] = (syscall_handler_t *) sys_shmget, \
[ __NR_shmat ] = (syscall_handler_t *) wrap_sys_shmat, \
[ __NR_shmctl ] = (syscall_handler_t *) sys_shmctl, \
[ __NR_semop ] = (syscall_handler_t *) sys_semop, \
[ __NR_semget ] = (syscall_handler_t *) sys_semget, \
[ __NR_semctl ] = (syscall_handler_t *) sys_semctl, \
[ __NR_shmdt ] = (syscall_handler_t *) sys_shmdt, \
[ __NR_msgget ] = (syscall_handler_t *) sys_msgget, \
[ __NR_msgsnd ] = (syscall_handler_t *) sys_msgsnd, \
[ __NR_msgrcv ] = (syscall_handler_t *) sys_msgrcv, \
[ __NR_msgctl ] = (syscall_handler_t *) sys_msgctl, \
[ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
[ __NR_tuxcall ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_security ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_epoll_ctl_old ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_epoll_wait_old ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
[ __NR_arch_prctl ] = (syscall_handler_t *) sys_arch_prctl, \
[ __NR_socket ] = (syscall_handler_t *) sys_socket, \
[ __NR_connect ] = (syscall_handler_t *) sys_connect, \
[ __NR_accept ] = (syscall_handler_t *) sys_accept, \
[ __NR_recvfrom ] = (syscall_handler_t *) sys_recvfrom, \
[ __NR_recvmsg ] = (syscall_handler_t *) sys_recvmsg, \
[ __NR_sendmsg ] = (syscall_handler_t *) sys_sendmsg, \
[ __NR_bind ] = (syscall_handler_t *) sys_bind, \
[ __NR_listen ] = (syscall_handler_t *) sys_listen, \
[ __NR_getsockname ] = (syscall_handler_t *) sys_getsockname, \
[ __NR_getpeername ] = (syscall_handler_t *) sys_getpeername, \
[ __NR_socketpair ] = (syscall_handler_t *) sys_socketpair, \
[ __NR_sendto ] = (syscall_handler_t *) sys_sendto, \
[ __NR_shutdown ] = (syscall_handler_t *) sys_shutdown, \
[ __NR_setsockopt ] = (syscall_handler_t *) sys_setsockopt, \
[ __NR_getsockopt ] = (syscall_handler_t *) sys_getsockopt, \
[ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, \
[ __NR_semtimedop ] = (syscall_handler_t *) sys_semtimedop, \
[ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, \
[ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
[ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall, \
[ 251 ] = (syscall_handler_t *) sys_ni_syscall,
#define LAST_ARCH_SYSCALL 251
#define NR_syscalls 1024
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
...@@ -194,37 +194,6 @@ long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize) ...@@ -194,37 +194,6 @@ long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
} }
} }
int sys_sigaction(int sig, const struct old_sigaction __user *act,
struct old_sigaction __user *oact)
{
struct k_sigaction new_ka, old_ka;
int ret;
if (act) {
old_sigset_t mask;
if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
__get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
return -EFAULT;
__get_user(new_ka.sa.sa_flags, &act->sa_flags);
__get_user(mask, &act->sa_mask);
siginitset(&new_ka.sa.sa_mask, mask);
}
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) {
if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
__put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
return -EFAULT;
__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
}
return ret;
}
long sys_sigaltstack(const stack_t *uss, stack_t *uoss) long sys_sigaltstack(const stack_t *uss, stack_t *uoss)
{ {
return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs))); return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
......
This diff is collapsed.
...@@ -56,12 +56,11 @@ long sys_vfork(void) ...@@ -56,12 +56,11 @@ long sys_vfork(void)
} }
/* common code for old and new mmaps */ /* common code for old and new mmaps */
static inline long do_mmap2( long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff)
unsigned long fd, unsigned long pgoff)
{ {
int error = -EBADF; long error = -EBADF;
struct file * file = NULL; struct file * file = NULL;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
...@@ -81,38 +80,15 @@ static inline long do_mmap2( ...@@ -81,38 +80,15 @@ static inline long do_mmap2(
return error; return error;
} }
long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
return do_mmap2(addr, len, prot, flags, fd, pgoff);
}
/*
* Perform the select(nd, in, out, ex, tv) and mmap() system
* calls. Linux/i386 didn't use to be able to handle more than
* 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;
unsigned long prot;
unsigned long flags;
unsigned long fd;
unsigned long offset;
};
long old_mmap(unsigned long addr, unsigned long len, long old_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long offset) unsigned long fd, unsigned long offset)
{ {
long err = -EINVAL; long err = -EINVAL;
if (offset & ~PAGE_MASK) if (offset & ~PAGE_MASK)
goto out; goto out;
err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
out: out:
return err; return err;
} }
...@@ -133,90 +109,6 @@ long sys_pipe(unsigned long * fildes) ...@@ -133,90 +109,6 @@ long sys_pipe(unsigned long * fildes)
return error; return error;
} }
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
*
* This is really horribly ugly.
*/
int sys_ipc (uint call, int first, int second,
int third, void *ptr, long fifth)
{
int version, ret;
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
switch (call) {
case SEMOP:
return sys_semtimedop(first, (struct sembuf *) ptr, second,
NULL);
case SEMTIMEDOP:
return sys_semtimedop(first, (struct sembuf *) ptr, second,
(const struct timespec *) fifth);
case SEMGET:
return sys_semget (first, second, third);
case SEMCTL: {
union semun fourth;
if (!ptr)
return -EINVAL;
if (get_user(fourth.__pad, (void **) ptr))
return -EFAULT;
return sys_semctl (first, second, third, fourth);
}
case MSGSND:
return sys_msgsnd (first, (struct msgbuf *) ptr,
second, third);
case MSGRCV:
switch (version) {
case 0: {
struct ipc_kludge tmp;
if (!ptr)
return -EINVAL;
if (copy_from_user(&tmp,
(struct ipc_kludge *) ptr,
sizeof (tmp)))
return -EFAULT;
return sys_msgrcv (first, tmp.msgp, second,
tmp.msgtyp, third);
}
default:
panic("msgrcv with version != 0");
return sys_msgrcv (first,
(struct msgbuf *) ptr,
second, fifth, third);
}
case MSGGET:
return sys_msgget ((key_t) first, second);
case MSGCTL:
return sys_msgctl (first, second, (struct msqid_ds *) ptr);
case SHMAT:
switch (version) {
default: {
ulong raddr;
ret = do_shmat (first, (char *) ptr, second, &raddr);
if (ret)
return ret;
return put_user (raddr, (ulong *) third);
}
case 1: /* iBCS2 emulator entry point */
if (!segment_eq(get_fs(), get_ds()))
return -EINVAL;
return do_shmat (first, (char *) ptr, second, (ulong *) third);
}
case SHMDT:
return sys_shmdt ((char *)ptr);
case SHMGET:
return sys_shmget (first, second, third);
case SHMCTL:
return sys_shmctl (first, second,
(struct shmid_ds *) ptr);
default:
return -ENOSYS;
}
}
long sys_uname(struct old_utsname * name) long sys_uname(struct old_utsname * name)
{ {
......
...@@ -14,95 +14,6 @@ ...@@ -14,95 +14,6 @@
#include "sysdep/syscalls.h" #include "sysdep/syscalls.h"
#include "kern_util.h" #include "kern_util.h"
static inline int check_area(void *ptr, int size)
{
return(verify_area(VERIFY_WRITE, ptr, size));
}
static int check_readlink(struct pt_regs *regs)
{
return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
UPT_SYSCALL_ARG2(&regs->regs)));
}
static int check_utime(struct pt_regs *regs)
{
return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
sizeof(struct utimbuf)));
}
static int check_oldstat(struct pt_regs *regs)
{
return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
sizeof(struct __old_kernel_stat)));
}
static int check_stat(struct pt_regs *regs)
{
return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
sizeof(struct stat)));
}
static int check_stat64(struct pt_regs *regs)
{
return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
sizeof(struct stat64)));
}
struct bogus {
int kernel_ds;
int (*check_params)(struct pt_regs *);
};
struct bogus this_is_bogus[256] = {
[ __NR_mknod ] = { 1, NULL },
[ __NR_mkdir ] = { 1, NULL },
[ __NR_rmdir ] = { 1, NULL },
[ __NR_unlink ] = { 1, NULL },
[ __NR_symlink ] = { 1, NULL },
[ __NR_link ] = { 1, NULL },
[ __NR_rename ] = { 1, NULL },
[ __NR_umount ] = { 1, NULL },
[ __NR_mount ] = { 1, NULL },
[ __NR_pivot_root ] = { 1, NULL },
[ __NR_chdir ] = { 1, NULL },
[ __NR_chroot ] = { 1, NULL },
[ __NR_open ] = { 1, NULL },
[ __NR_quotactl ] = { 1, NULL },
[ __NR_sysfs ] = { 1, NULL },
[ __NR_readlink ] = { 1, check_readlink },
[ __NR_acct ] = { 1, NULL },
[ __NR_execve ] = { 1, NULL },
[ __NR_uselib ] = { 1, NULL },
[ __NR_statfs ] = { 1, NULL },
[ __NR_truncate ] = { 1, NULL },
[ __NR_access ] = { 1, NULL },
[ __NR_chmod ] = { 1, NULL },
[ __NR_chown ] = { 1, NULL },
[ __NR_lchown ] = { 1, NULL },
[ __NR_utime ] = { 1, check_utime },
[ __NR_oldlstat ] = { 1, check_oldstat },
[ __NR_oldstat ] = { 1, check_oldstat },
[ __NR_stat ] = { 1, check_stat },
[ __NR_lstat ] = { 1, check_stat },
[ __NR_stat64 ] = { 1, check_stat64 },
[ __NR_lstat64 ] = { 1, check_stat64 },
[ __NR_chown32 ] = { 1, NULL },
};
/* sys_utimes */
static int check_bogosity(struct pt_regs *regs)
{
struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(&regs->regs)];
if(!bogon->kernel_ds) return(0);
if(bogon->check_params && (*bogon->check_params)(regs))
return(-EFAULT);
set_fs(KERNEL_DS);
return(0);
}
extern syscall_handler_t *sys_call_table[]; extern syscall_handler_t *sys_call_table[];
long execute_syscall_tt(void *r) long execute_syscall_tt(void *r)
...@@ -117,12 +28,8 @@ long execute_syscall_tt(void *r) ...@@ -117,12 +28,8 @@ long execute_syscall_tt(void *r)
if((syscall >= NR_syscalls) || (syscall < 0)) if((syscall >= NR_syscalls) || (syscall < 0))
res = -ENOSYS; res = -ENOSYS;
else if(honeypot && check_bogosity(regs))
res = -EFAULT;
else res = EXECUTE_SYSCALL(syscall, regs); else res = EXECUTE_SYSCALL(syscall, regs);
set_fs(USER_DS);
return(res); return(res);
} }
......
/* /*
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/sched.h" #include "linux/sched.h"
#include "linux/shm.h"
#include "asm/ipc.h"
#include "asm/mman.h" #include "asm/mman.h"
#include "asm/uaccess.h" #include "asm/uaccess.h"
#include "asm/unistd.h" #include "asm/unistd.h"
...@@ -28,7 +30,7 @@ extern int old_mmap(unsigned long addr, unsigned long len, ...@@ -28,7 +30,7 @@ extern int old_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long offset); unsigned long fd, unsigned long offset);
int old_mmap_i386(struct mmap_arg_struct *arg) long old_mmap_i386(struct mmap_arg_struct *arg)
{ {
struct mmap_arg_struct a; struct mmap_arg_struct a;
int err = -EFAULT; int err = -EFAULT;
...@@ -47,7 +49,7 @@ struct sel_arg_struct { ...@@ -47,7 +49,7 @@ struct sel_arg_struct {
struct timeval *tvp; struct timeval *tvp;
}; };
int old_select(struct sel_arg_struct *arg) long old_select(struct sel_arg_struct *arg)
{ {
struct sel_arg_struct a; struct sel_arg_struct a;
...@@ -60,8 +62,8 @@ int old_select(struct sel_arg_struct *arg) ...@@ -60,8 +62,8 @@ int old_select(struct sel_arg_struct *arg)
/* The i386 version skips reading from %esi, the fourth argument. So we must do /* The i386 version skips reading from %esi, the fourth argument. So we must do
* this, too. * this, too.
*/ */
int sys_clone(unsigned long clone_flags, unsigned long newsp, int *parent_tid, long sys_clone(unsigned long clone_flags, unsigned long newsp, int *parent_tid,
int unused, int *child_tid) int unused, int *child_tid)
{ {
long ret; long ret;
...@@ -78,6 +80,122 @@ int sys_clone(unsigned long clone_flags, unsigned long newsp, int *parent_tid, ...@@ -78,6 +80,122 @@ int sys_clone(unsigned long clone_flags, unsigned long newsp, int *parent_tid,
return(ret); return(ret);
} }
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
*
* This is really horribly ugly.
*/
long sys_ipc (uint call, int first, int second,
int third, void *ptr, long fifth)
{
int version, ret;
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
switch (call) {
case SEMOP:
return sys_semtimedop(first, (struct sembuf *) ptr, second,
NULL);
case SEMTIMEDOP:
return sys_semtimedop(first, (struct sembuf *) ptr, second,
(const struct timespec *) fifth);
case SEMGET:
return sys_semget (first, second, third);
case SEMCTL: {
union semun fourth;
if (!ptr)
return -EINVAL;
if (get_user(fourth.__pad, (void **) ptr))
return -EFAULT;
return sys_semctl (first, second, third, fourth);
}
case MSGSND:
return sys_msgsnd (first, (struct msgbuf *) ptr,
second, third);
case MSGRCV:
switch (version) {
case 0: {
struct ipc_kludge tmp;
if (!ptr)
return -EINVAL;
if (copy_from_user(&tmp,
(struct ipc_kludge *) ptr,
sizeof (tmp)))
return -EFAULT;
return sys_msgrcv (first, tmp.msgp, second,
tmp.msgtyp, third);
}
default:
panic("msgrcv with version != 0");
return sys_msgrcv (first,
(struct msgbuf *) ptr,
second, fifth, third);
}
case MSGGET:
return sys_msgget ((key_t) first, second);
case MSGCTL:
return sys_msgctl (first, second, (struct msqid_ds *) ptr);
case SHMAT:
switch (version) {
default: {
ulong raddr;
ret = do_shmat (first, (char *) ptr, second, &raddr);
if (ret)
return ret;
return put_user (raddr, (ulong *) third);
}
case 1: /* iBCS2 emulator entry point */
if (!segment_eq(get_fs(), get_ds()))
return -EINVAL;
return do_shmat (first, (char *) ptr, second, (ulong *) third);
}
case SHMDT:
return sys_shmdt ((char *)ptr);
case SHMGET:
return sys_shmget (first, second, third);
case SHMCTL:
return sys_shmctl (first, second,
(struct shmid_ds *) ptr);
default:
return -ENOSYS;
}
}
long sys_sigaction(int sig, const struct old_sigaction __user *act,
struct old_sigaction __user *oact)
{
struct k_sigaction new_ka, old_ka;
int ret;
if (act) {
old_sigset_t mask;
if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
__get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
return -EFAULT;
__get_user(new_ka.sa.sa_flags, &act->sa_flags);
__get_user(mask, &act->sa_mask);
siginitset(&new_ka.sa.sa_mask, mask);
}
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) {
if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
__put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
return -EFAULT;
__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
}
return ret;
}
/* /*
* Overrides for Emacs so that we follow Linus's tabbing style. * Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically * Emacs will notice this stuff at the end of the file and automatically
......
/*
* Copyright 2003 PathScale, Inc.
*
* Licensed under the GPL
*/
#include "linux/linkage.h"
#include "linux/slab.h"
#include "linux/shm.h"
#include "asm/uaccess.h"
#define __FRAME_OFFSETS
#include "asm/ptrace.h"
#include "asm/unistd.h"
#include "asm/prctl.h" /* XXX This should get the constants from libc */
#include "choose-mode.h"
asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg)
{
unsigned long raddr;
return do_shmat(shmid, shmaddr, shmflg, &raddr) ?: (long) raddr;
}
#ifdef CONFIG_MODE_TT
extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
{
/* XXX This should check VERIFY_WRITE depending on func, check this
* in i386 as well.
*/
if(verify_area(VERIFY_READ, ptr, bytecount))
return(-EFAULT);
return(modify_ldt(func, ptr, bytecount));
}
#endif
#ifdef CONFIG_MODE_SKAS
extern int userspace_pid;
#ifndef __NR_mm_indirect
#define __NR_mm_indirect 241
#endif
long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
{
unsigned long args[6];
void *buf;
int res, n;
buf = kmalloc(bytecount, GFP_KERNEL);
if(buf == NULL)
return(-ENOMEM);
res = 0;
switch(func){
case 1:
case 0x11:
res = copy_from_user(buf, ptr, bytecount);
break;
}
if(res != 0){
res = -EFAULT;
goto out;
}
args[0] = func;
args[1] = (unsigned long) buf;
args[2] = bytecount;
res = syscall(__NR_mm_indirect, &current->mm->context.u,
__NR_modify_ldt, args);
if(res < 0)
goto out;
switch(func){
case 0:
case 2:
n = res;
res = copy_to_user(ptr, buf, n);
if(res != 0)
res = -EFAULT;
else
res = n;
break;
}
out:
kfree(buf);
return(res);
}
#endif
long sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
{
return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
ptr, bytecount));
}
#ifdef CONFIG_MODE_TT
extern long arch_prctl(int code, unsigned long addr);
static long arch_prctl_tt(int code, unsigned long addr)
{
unsigned long tmp;
long ret;
switch(code){
case ARCH_SET_GS:
case ARCH_SET_FS:
ret = arch_prctl(code, addr);
break;
case ARCH_GET_FS:
case ARCH_GET_GS:
ret = arch_prctl(code, (unsigned long) &tmp);
if(!ret)
ret = put_user(tmp, &addr);
break;
default:
ret = -EINVAL;
break;
}
return(ret);
}
#endif
#ifdef CONFIG_MODE_SKAS
static long arch_prctl_skas(int code, unsigned long addr)
{
long ret = 0;
switch(code){
case ARCH_SET_GS:
current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
break;
case ARCH_SET_FS:
current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr;
break;
case ARCH_GET_FS:
ret = put_user(current->thread.regs.regs.skas.regs[GS / sizeof(unsigned long)], &addr);
break;
case ARCH_GET_GS:
ret = put_user(current->thread.regs.regs.skas.regs[FS / sizeof(unsigned \
long)], &addr);
break;
default:
ret = -EINVAL;
break;
}
return(ret);
}
#endif
long sys_arch_prctl(int code, unsigned long addr)
{
return(CHOOSE_MODE_PROC(arch_prctl_tt, arch_prctl_skas, code, addr));
}
long sys_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tid, void __user *child_tid)
{
long ret;
/* XXX: normal arch do here this pass, and also pass the regs to
* do_fork, instead of NULL. Currently the arch-independent code
* ignores these values, while the UML code (actually it's
* copy_thread) does the right thing. But this should change,
probably. */
/*if (!newsp)
newsp = UPT_SP(current->thread.regs);*/
current->thread.forking = 1;
ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
current->thread.forking = 0;
return(ret);
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment