291 lines
7.7 KiB
C
291 lines
7.7 KiB
C
/* linux/arch/e2k/kernel/sys_32.c 1.10 08/21/2001.
|
|
*
|
|
* Copyright (C) 2001 MCST
|
|
*/
|
|
|
|
/**************************** DEBUG DEFINES *****************************/
|
|
|
|
#define DEBUG_TRAP_CELLAR 0 /* DEBUG_TRAP_CELLAR */
|
|
#define DbgTC(...) DebugPrint(DEBUG_TRAP_CELLAR ,##__VA_ARGS__)
|
|
#define DEBUG_SIG_MODE 0 /* Signal handling */
|
|
#define DebugSig(...) DebugPrint(DEBUG_SIG_MODE ,##__VA_ARGS__)
|
|
#define DEBUG_32 0 /* processes */
|
|
#define DebugP_32(...) DebugPrint(DEBUG_32 ,##__VA_ARGS__)
|
|
|
|
#undef DEBUG_EXECVE_MODE
|
|
#undef DebugEX
|
|
#define DEBUG_EXECVE_MODE 0 /* execve and exit */
|
|
#define DebugEX(...) DebugPrint(DEBUG_EXECVE_MODE ,##__VA_ARGS__)
|
|
|
|
#include <linux/sched.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/signal.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/highmem.h>
|
|
#include <linux/time.h>
|
|
#include <linux/security.h>
|
|
#include <linux/syscalls.h>
|
|
#include <linux/compat.h>
|
|
#include <linux/sysctl.h>
|
|
|
|
#include <asm/uaccess.h>
|
|
#include <asm/siginfo.h>
|
|
#include <asm/process.h>
|
|
|
|
#include <linux/unistd.h>
|
|
#include <asm/mmu_context.h>
|
|
#include <asm/lms.h>
|
|
|
|
|
|
long
|
|
sys_rt_sigaction32(int sig, const struct sigaction *act, struct sigaction *oact,
|
|
size_t sigsetsize)
|
|
{
|
|
struct k_sigaction new_sa, old_sa;
|
|
struct k_sigaction32 new_sa32, old_sa32;
|
|
int ret = -EINVAL;
|
|
|
|
DebugSig("start (%d, %p, %p, %ld)\n",
|
|
sig, act, oact, sigsetsize);
|
|
DebugSig("sz sa_mask %ld sz sa_mask32 %ld\n",
|
|
sizeof(new_sa.sa.sa_mask), sizeof(new_sa32.sa.sa_mask));
|
|
/* XXX: Don't preclude handling different sized sigset_t's. */
|
|
if (sigsetsize != sizeof(sigset_t))
|
|
goto out;
|
|
|
|
if (act) {
|
|
if (copy_from_user(&new_sa32.sa, act, sizeof(new_sa32.sa)))
|
|
return -EFAULT;
|
|
}
|
|
DebugSig("sa_handler 0x%lx\n",
|
|
(u64)new_sa32.sa.sa_handler);
|
|
new_sa.sa.sa_handler = (__sighandler_t)(u64)new_sa32.sa.sa_handler;
|
|
new_sa.sa.sa_restorer = (__sigrestore_t)(u64)new_sa32.sa.sa_restorer;
|
|
new_sa.sa.sa_flags = new_sa32.sa.sa_flags;
|
|
new_sa.sa.sa_mask.sig[0] = (int)new_sa32.sa.sa_mask.sig[0];
|
|
|
|
ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
|
|
if (ret) return ret;
|
|
if (!oact) return ret;
|
|
|
|
old_sa32.sa.sa_handler = (u64)(old_sa.sa.sa_handler) & 0xFFFFFFFF;
|
|
old_sa32.sa.sa_restorer = (u64)(old_sa.sa.sa_restorer) & 0xFFFFFFFF;
|
|
old_sa32.sa.sa_flags = (u32)old_sa.sa.sa_flags;
|
|
old_sa32.sa.sa_mask.sig[0] = old_sa.sa.sa_mask.sig[0];
|
|
|
|
if (copy_to_user(oact, &old_sa32.sa, sizeof(old_sa32.sa)))
|
|
return -EFAULT;
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
struct timeval32 {
|
|
int tv_sec; /* seconds */
|
|
int tv_usec; /* microseconds */
|
|
};
|
|
|
|
extern struct timezone sys_tz;
|
|
|
|
asmlinkage long sys_gettimeofday32(struct timeval *tv, struct timezone *tz)
|
|
{
|
|
|
|
if (tv) {
|
|
struct timeval ktv;
|
|
struct timeval32 tv32;
|
|
do_gettimeofday(&ktv);
|
|
tv32.tv_sec = ktv.tv_sec & 0xffffffff;
|
|
tv32.tv_usec = ktv.tv_usec & 0xffffffff;
|
|
if (copy_to_user(tv, &tv32, sizeof(tv32)))
|
|
return -EFAULT;
|
|
}
|
|
if (tz) {
|
|
if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
|
|
return -EFAULT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
asmlinkage long sys_settimeofday32(struct timeval *tv, struct timezone *tz)
|
|
{
|
|
|
|
struct timeval32 new_tv32;
|
|
struct timezone new_tz;
|
|
struct timespec new_tv;
|
|
|
|
if (tv) {
|
|
if (copy_from_user(&new_tv32, tv, sizeof(new_tv32)))
|
|
return -EFAULT;
|
|
|
|
}
|
|
if (tz) {
|
|
if (copy_from_user(&new_tz, tz, sizeof(*tz)))
|
|
return -EFAULT;
|
|
}
|
|
new_tv.tv_sec = new_tv32.tv_sec;
|
|
new_tv.tv_nsec = new_tv32.tv_usec * 1000;
|
|
return do_sys_settimeofday(tv ? &new_tv : NULL, tz ? &new_tz : NULL);
|
|
return 0;
|
|
}
|
|
|
|
#ifdef CONFIG_COMPAT
|
|
int copy_siginfo_to_user32(struct compat_siginfo __user *to,
|
|
const siginfo_t *from)
|
|
{
|
|
int err = 0;
|
|
|
|
if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
|
|
return -EFAULT;
|
|
|
|
BEGIN_USR_PFAULT("lbl_copy_siginfo_to_user32", "0f");
|
|
/*
|
|
* If you change siginfo_t structure, please make sure that
|
|
* this code is fixed accordingly.
|
|
* It should never copy any pad contained in the structure
|
|
* to avoid security leaks, but must copy the generic
|
|
* 3 ints plus the relevant union member.
|
|
*/
|
|
to->si_signo = from->si_signo;
|
|
to->si_errno = from->si_errno;
|
|
to->si_code = (short) from->si_code;
|
|
|
|
if (from->si_code < 0) {
|
|
to->si_pid = from->si_pid;
|
|
to->si_uid = from->si_uid;
|
|
to->si_ptr = ptr_to_compat(from->si_ptr);
|
|
} else {
|
|
/*
|
|
* First 32bits of unions are always present:
|
|
* si_pid === si_band === si_tid === si_addr(LS half)
|
|
*/
|
|
to->_sifields._pad[0] = from->_sifields._pad[0];
|
|
switch (from->si_code >> 16) {
|
|
case __SI_FAULT >> 16:
|
|
break;
|
|
case __SI_SYS >> 16:
|
|
to->si_syscall = from->si_syscall;
|
|
to->si_arch = from->si_arch;
|
|
break;
|
|
case __SI_CHLD >> 16:
|
|
to->si_utime = from->si_utime;
|
|
to->si_stime = from->si_stime;
|
|
to->si_status = from->si_status;
|
|
/* FALL THROUGH */
|
|
default:
|
|
case __SI_KILL >> 16:
|
|
to->si_uid = from->si_uid;
|
|
break;
|
|
case __SI_POLL >> 16:
|
|
to->si_fd = from->si_fd;
|
|
break;
|
|
case __SI_TIMER >> 16:
|
|
to->si_overrun = from->si_overrun;
|
|
to->si_ptr = ptr_to_compat(from->si_ptr);
|
|
break;
|
|
/* This is not generated by the kernel as of now. */
|
|
case __SI_RT >> 16:
|
|
case __SI_MESGQ >> 16:
|
|
to->si_uid = from->si_uid;
|
|
to->si_int = from->si_int;
|
|
break;
|
|
}
|
|
}
|
|
LBL_USR_PFAULT("lbl_copy_siginfo_to_user32", "0:");
|
|
if (END_USR_PFAULT)
|
|
err = -EFAULT;
|
|
|
|
return err;
|
|
}
|
|
|
|
int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
|
|
{
|
|
int err = 0;
|
|
|
|
if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
|
|
return -EFAULT;
|
|
|
|
BEGIN_USR_PFAULT("lbl_copy_siginfo_from_user32", "1f");
|
|
to->si_signo = from->si_signo;
|
|
to->si_errno = from->si_errno;
|
|
to->si_code = from->si_code;
|
|
|
|
to->si_pid = from->si_pid;
|
|
to->si_uid = from->si_uid;
|
|
to->si_ptr = compat_ptr(from->si_ptr);
|
|
LBL_USR_PFAULT("lbl_copy_siginfo_from_user32", "1:");
|
|
if (END_USR_PFAULT)
|
|
err = -EFAULT;
|
|
|
|
return err;
|
|
}
|
|
#endif
|
|
|
|
/* warning: next two assume little endian */
|
|
asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
|
|
compat_size_t count, unsigned long poslo, unsigned long poshi)
|
|
{
|
|
return sys_pread64(fd, ubuf, count, (poshi << 32) | poslo);
|
|
}
|
|
|
|
asmlinkage long sys32_pwrite64(unsigned int fd, char __user *ubuf,
|
|
compat_size_t count, unsigned long poslo, unsigned long poshi)
|
|
{
|
|
return sys_pwrite64(fd, ubuf, count, (poshi << 32) | poslo);
|
|
}
|
|
|
|
asmlinkage long sys32_readahead(int fd, unsigned long offlo,
|
|
unsigned long offhi, compat_size_t count)
|
|
{
|
|
return sys_readahead(fd, (offhi << 32) | offlo, count);
|
|
}
|
|
|
|
asmlinkage long sys32_fadvise64(int fd, unsigned long offlo,
|
|
unsigned long offhi, compat_size_t len, int advice)
|
|
{
|
|
return sys_fadvise64_64(fd, (offhi << 32) | offlo, len, advice);
|
|
}
|
|
|
|
asmlinkage long sys32_fadvise64_64(int fd,
|
|
unsigned long offlo, unsigned long offhi,
|
|
unsigned long lenlo, unsigned long lenhi, int advice)
|
|
{
|
|
return sys_fadvise64_64(fd, (offhi << 32) | offlo,
|
|
(lenhi << 32) | lenlo, advice);
|
|
}
|
|
|
|
asmlinkage long sys32_sync_file_range(int fd,
|
|
unsigned long off_low, unsigned long off_high,
|
|
unsigned long nb_low, unsigned long nb_high, int flags)
|
|
{
|
|
return sys_sync_file_range(fd, (off_high << 32) | off_low,
|
|
(nb_high << 32) | nb_low, flags);
|
|
}
|
|
|
|
asmlinkage long sys32_fallocate(int fd, int mode,
|
|
unsigned long offlo, unsigned long offhi,
|
|
unsigned long lenlo, unsigned long lenhi)
|
|
{
|
|
return sys_fallocate(fd, mode, (offhi << 32) | offlo,
|
|
(lenhi << 32) | lenlo);
|
|
}
|
|
|
|
asmlinkage long sys32_truncate64(const char __user * path,
|
|
unsigned long low, unsigned long high)
|
|
{
|
|
return sys_truncate(path, (high << 32) | low);
|
|
}
|
|
|
|
asmlinkage long sys32_ftruncate64(unsigned int fd,
|
|
unsigned long low, unsigned long high)
|
|
{
|
|
return sys_ftruncate(fd, (high << 32) | low);
|
|
}
|
|
|
|
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
|
compat_ulong_t caddr, compat_ulong_t cdata)
|
|
{
|
|
return arch_ptrace(child, (long)request, (long)caddr, (long)cdata);
|
|
}
|
|
|
|
|