Commit c3a5950a authored by Arun Sharma's avatar Arun Sharma Committed by Tony Luck

[IA64] sparse annotations and cleanups for ia32 subsystem

+ Add sparse annotations to ia32 subsystem so it checks out cleanly.
+ Add set_fs(KERNEL_DS) in elfcore32.h
+ Use compat_ptr() instead of P()
+ Fix a bug in ia32_sigsuspend() by introducing __ia32_rt_sigsuspend()
Signed-off-by: default avatarDavid Mosberger-Tang <davidm@hpl.hp.com>
Signed-off-by: default avatarArun Sharma <arun.sharma@intel.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 795fff87
...@@ -103,11 +103,15 @@ static inline int ...@@ -103,11 +103,15 @@ static inline int
elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu) elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu)
{ {
struct ia32_user_i387_struct *fpstate = (void*)fpu; struct ia32_user_i387_struct *fpstate = (void*)fpu;
mm_segment_t old_fs;
if (!tsk->used_math) if (!tsk->used_math)
return 0; return 0;
save_ia32_fpstate(tsk, fpstate); old_fs = get_fs();
set_fs(KERNEL_DS);
save_ia32_fpstate(tsk, (struct ia32_user_i387_struct __user *) fpstate);
set_fs(old_fs);
return 1; return 1;
} }
...@@ -117,11 +121,15 @@ static inline int ...@@ -117,11 +121,15 @@ static inline int
elf_core_copy_task_xfpregs(struct task_struct *tsk, elf_fpxregset_t *xfpu) elf_core_copy_task_xfpregs(struct task_struct *tsk, elf_fpxregset_t *xfpu)
{ {
struct ia32_user_fxsr_struct *fpxstate = (void*) xfpu; struct ia32_user_fxsr_struct *fpxstate = (void*) xfpu;
mm_segment_t old_fs;
if (!tsk->used_math) if (!tsk->used_math)
return 0; return 0;
save_ia32_fpxstate(tsk, fpxstate); old_fs = get_fs();
set_fs(KERNEL_DS);
save_ia32_fpxstate(tsk, (struct ia32_user_fxsr_struct __user *) fpxstate);
set_fs(old_fs);
return 1; return 1;
} }
......
/* /*
* Copyright (C) 2001 Hewlett-Packard Co * Copyright (C) 2001, 2004 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
* *
* Adapted from arch/i386/kernel/ldt.c * Adapted from arch/i386/kernel/ldt.c
...@@ -17,25 +17,24 @@ ...@@ -17,25 +17,24 @@
#include "ia32priv.h" #include "ia32priv.h"
#define P(p) ((void *) (unsigned long) (p))
/* /*
* read_ldt() is not really atomic - this is not a problem since synchronization of reads * read_ldt() is not really atomic - this is not a problem since synchronization of reads
* and writes done to the LDT has to be assured by user-space anyway. Writes are atomic, * and writes done to the LDT has to be assured by user-space anyway. Writes are atomic,
* to protect the security checks done on new descriptors. * to protect the security checks done on new descriptors.
*/ */
static int static int
read_ldt (void *ptr, unsigned long bytecount) read_ldt (void __user *ptr, unsigned long bytecount)
{ {
char *src, *dst, buf[256]; /* temporary buffer (don't overflow kernel stack!) */
unsigned long bytes_left, n; unsigned long bytes_left, n;
char __user *src, *dst;
char buf[256]; /* temporary buffer (don't overflow kernel stack!) */
if (bytecount > IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE) if (bytecount > IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE)
bytecount = IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE; bytecount = IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE;
bytes_left = bytecount; bytes_left = bytecount;
src = (void *) IA32_LDT_OFFSET; src = (void __user *) IA32_LDT_OFFSET;
dst = ptr; dst = ptr;
while (bytes_left) { while (bytes_left) {
...@@ -61,7 +60,7 @@ read_ldt (void *ptr, unsigned long bytecount) ...@@ -61,7 +60,7 @@ read_ldt (void *ptr, unsigned long bytecount)
} }
static int static int
read_default_ldt (void * ptr, unsigned long bytecount) read_default_ldt (void __user * ptr, unsigned long bytecount)
{ {
unsigned long size; unsigned long size;
int err; int err;
...@@ -80,7 +79,7 @@ read_default_ldt (void * ptr, unsigned long bytecount) ...@@ -80,7 +79,7 @@ read_default_ldt (void * ptr, unsigned long bytecount)
} }
static int static int
write_ldt (void * ptr, unsigned long bytecount, int oldmode) write_ldt (void __user * ptr, unsigned long bytecount, int oldmode)
{ {
struct ia32_user_desc ldt_info; struct ia32_user_desc ldt_info;
__u64 entry; __u64 entry;
...@@ -120,7 +119,7 @@ write_ldt (void * ptr, unsigned long bytecount, int oldmode) ...@@ -120,7 +119,7 @@ write_ldt (void * ptr, unsigned long bytecount, int oldmode)
* memory, but we still need to guard against out-of-memory, hence we must use * memory, but we still need to guard against out-of-memory, hence we must use
* put_user(). * put_user().
*/ */
ret = __put_user(entry, (__u64 *) IA32_LDT_OFFSET + ldt_info.entry_number); ret = __put_user(entry, (__u64 __user *) IA32_LDT_OFFSET + ldt_info.entry_number);
ia32_load_segment_descriptors(current); ia32_load_segment_descriptors(current);
return ret; return ret;
} }
...@@ -132,16 +131,16 @@ sys32_modify_ldt (int func, unsigned int ptr, unsigned int bytecount) ...@@ -132,16 +131,16 @@ sys32_modify_ldt (int func, unsigned int ptr, unsigned int bytecount)
switch (func) { switch (func) {
case 0: case 0:
ret = read_ldt(P(ptr), bytecount); ret = read_ldt(compat_ptr(ptr), bytecount);
break; break;
case 1: case 1:
ret = write_ldt(P(ptr), bytecount, 1); ret = write_ldt(compat_ptr(ptr), bytecount, 1);
break; break;
case 2: case 2:
ret = read_default_ldt(P(ptr), bytecount); ret = read_default_ldt(compat_ptr(ptr), bytecount);
break; break;
case 0x11: case 0x11:
ret = write_ldt(P(ptr), bytecount, 0); ret = write_ldt(compat_ptr(ptr), bytecount, 0);
break; break;
} }
return ret; return ret;
......
...@@ -66,7 +66,7 @@ struct rt_sigframe_ia32 ...@@ -66,7 +66,7 @@ struct rt_sigframe_ia32
}; };
int int
copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 *from) copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 __user *from)
{ {
unsigned long tmp; unsigned long tmp;
int err; int err;
...@@ -92,7 +92,7 @@ copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 *from) ...@@ -92,7 +92,7 @@ copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 *from)
break; break;
case __SI_FAULT >> 16: case __SI_FAULT >> 16:
err |= __get_user(tmp, &from->si_addr); err |= __get_user(tmp, &from->si_addr);
to->si_addr = (void *) tmp; to->si_addr = (void __user *) tmp;
break; break;
case __SI_POLL >> 16: case __SI_POLL >> 16:
err |= __get_user(to->si_band, &from->si_band); err |= __get_user(to->si_band, &from->si_band);
...@@ -110,7 +110,7 @@ copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 *from) ...@@ -110,7 +110,7 @@ copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 *from)
} }
int int
copy_siginfo_to_user32 (siginfo_t32 *to, siginfo_t *from) copy_siginfo_to_user32 (siginfo_t32 __user *to, siginfo_t *from)
{ {
unsigned int addr; unsigned int addr;
int err; int err;
...@@ -141,7 +141,8 @@ copy_siginfo_to_user32 (siginfo_t32 *to, siginfo_t *from) ...@@ -141,7 +141,8 @@ copy_siginfo_to_user32 (siginfo_t32 *to, siginfo_t *from)
err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_uid, &to->si_uid);
break; break;
case __SI_FAULT >> 16: case __SI_FAULT >> 16:
err |= __put_user((long)from->si_addr, &to->si_addr); /* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */
err |= __put_user(from->_sifields._pad[0], &to->si_addr);
break; break;
case __SI_POLL >> 16: case __SI_POLL >> 16:
err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_band, &to->si_band);
...@@ -202,7 +203,7 @@ copy_siginfo_to_user32 (siginfo_t32 *to, siginfo_t *from) ...@@ -202,7 +203,7 @@ copy_siginfo_to_user32 (siginfo_t32 *to, siginfo_t *from)
*/ */
static int static int
save_ia32_fpstate_live (struct _fpstate_ia32 *save) save_ia32_fpstate_live (struct _fpstate_ia32 __user *save)
{ {
struct task_struct *tsk = current; struct task_struct *tsk = current;
struct pt_regs *ptp; struct pt_regs *ptp;
...@@ -310,7 +311,7 @@ save_ia32_fpstate_live (struct _fpstate_ia32 *save) ...@@ -310,7 +311,7 @@ save_ia32_fpstate_live (struct _fpstate_ia32 *save)
} }
static int static int
restore_ia32_fpstate_live (struct _fpstate_ia32 *save) restore_ia32_fpstate_live (struct _fpstate_ia32 __user *save)
{ {
struct task_struct *tsk = current; struct task_struct *tsk = current;
struct pt_regs *ptp; struct pt_regs *ptp;
...@@ -339,34 +340,34 @@ restore_ia32_fpstate_live (struct _fpstate_ia32 *save) ...@@ -339,34 +340,34 @@ restore_ia32_fpstate_live (struct _fpstate_ia32 *save)
fir = ia64_getreg(_IA64_REG_AR_FIR); fir = ia64_getreg(_IA64_REG_AR_FIR);
fdr = ia64_getreg(_IA64_REG_AR_FDR); fdr = ia64_getreg(_IA64_REG_AR_FDR);
__get_user(mxcsr, (unsigned int *)&save->mxcsr); __get_user(mxcsr, (unsigned int __user *)&save->mxcsr);
/* setting bits 0..5 8..12 with cw and 39..47 from mxcsr */ /* setting bits 0..5 8..12 with cw and 39..47 from mxcsr */
__get_user(lo, (unsigned int *)&save->cw); __get_user(lo, (unsigned int __user *)&save->cw);
num64 = mxcsr & 0xff10; num64 = mxcsr & 0xff10;
num64 = (num64 << 32) | (lo & 0x1f3f); num64 = (num64 << 32) | (lo & 0x1f3f);
fcr = (fcr & (~0xff1000001f3fUL)) | num64; fcr = (fcr & (~0xff1000001f3fUL)) | num64;
/* setting bits 0..31 with sw and tag and 32..37 from mxcsr */ /* setting bits 0..31 with sw and tag and 32..37 from mxcsr */
__get_user(lo, (unsigned int *)&save->sw); __get_user(lo, (unsigned int __user *)&save->sw);
/* set bits 15,7 (fsw.b, fsw.es) to reflect the current error status */ /* set bits 15,7 (fsw.b, fsw.es) to reflect the current error status */
if ( !(lo & 0x7f) ) if ( !(lo & 0x7f) )
lo &= (~0x8080); lo &= (~0x8080);
__get_user(hi, (unsigned int *)&save->tag); __get_user(hi, (unsigned int __user *)&save->tag);
num64 = mxcsr & 0x3f; num64 = mxcsr & 0x3f;
num64 = (num64 << 16) | (hi & 0xffff); num64 = (num64 << 16) | (hi & 0xffff);
num64 = (num64 << 16) | (lo & 0xffff); num64 = (num64 << 16) | (lo & 0xffff);
fsr = (fsr & (~0x3fffffffffUL)) | num64; fsr = (fsr & (~0x3fffffffffUL)) | num64;
/* setting bits 0..47 with cssel and ipoff */ /* setting bits 0..47 with cssel and ipoff */
__get_user(lo, (unsigned int *)&save->ipoff); __get_user(lo, (unsigned int __user *)&save->ipoff);
__get_user(hi, (unsigned int *)&save->cssel); __get_user(hi, (unsigned int __user *)&save->cssel);
num64 = hi & 0xffff; num64 = hi & 0xffff;
num64 = (num64 << 32) | lo; num64 = (num64 << 32) | lo;
fir = (fir & (~0xffffffffffffUL)) | num64; fir = (fir & (~0xffffffffffffUL)) | num64;
/* setting bits 0..47 with datasel and dataoff */ /* setting bits 0..47 with datasel and dataoff */
__get_user(lo, (unsigned int *)&save->dataoff); __get_user(lo, (unsigned int __user *)&save->dataoff);
__get_user(hi, (unsigned int *)&save->datasel); __get_user(hi, (unsigned int __user *)&save->datasel);
num64 = hi & 0xffff; num64 = hi & 0xffff;
num64 = (num64 << 32) | lo; num64 = (num64 << 32) | lo;
fdr = (fdr & (~0xffffffffffffUL)) | num64; fdr = (fdr & (~0xffffffffffffUL)) | num64;
...@@ -452,8 +453,8 @@ sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int r ...@@ -452,8 +453,8 @@ sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int r
sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler); sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler);
} }
asmlinkage long long
ia32_rt_sigsuspend (compat_sigset_t *uset, unsigned int sigsetsize, struct sigscratch *scr) __ia32_rt_sigsuspend (compat_sigset_t *sset, unsigned int sigsetsize, struct sigscratch *scr)
{ {
extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall); extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall);
sigset_t oldset, set; sigset_t oldset, set;
...@@ -461,10 +462,7 @@ ia32_rt_sigsuspend (compat_sigset_t *uset, unsigned int sigsetsize, struct sigsc ...@@ -461,10 +462,7 @@ ia32_rt_sigsuspend (compat_sigset_t *uset, unsigned int sigsetsize, struct sigsc
scr->scratch_unat = 0; /* avoid leaking kernel bits to user level */ scr->scratch_unat = 0; /* avoid leaking kernel bits to user level */
memset(&set, 0, sizeof(&set)); memset(&set, 0, sizeof(&set));
if (sigsetsize > sizeof(sigset_t)) if (memcpy(&set.sig, &sset->sig, sigsetsize))
return -EINVAL;
if (copy_from_user(&set.sig, &uset->sig, sigsetsize))
return -EFAULT; return -EFAULT;
sigdelsetmask(&set, ~_BLOCKABLE); sigdelsetmask(&set, ~_BLOCKABLE);
...@@ -491,10 +489,24 @@ ia32_rt_sigsuspend (compat_sigset_t *uset, unsigned int sigsetsize, struct sigsc ...@@ -491,10 +489,24 @@ ia32_rt_sigsuspend (compat_sigset_t *uset, unsigned int sigsetsize, struct sigsc
} }
} }
asmlinkage long
ia32_rt_sigsuspend (compat_sigset_t __user *uset, unsigned int sigsetsize, struct sigscratch *scr)
{
compat_sigset_t set;
if (sigsetsize > sizeof(compat_sigset_t))
return -EINVAL;
if (copy_from_user(&set.sig, &uset->sig, sigsetsize))
return -EFAULT;
return __ia32_rt_sigsuspend(&set, sigsetsize, scr);
}
asmlinkage long asmlinkage long
ia32_sigsuspend (unsigned int mask, struct sigscratch *scr) ia32_sigsuspend (unsigned int mask, struct sigscratch *scr)
{ {
return ia32_rt_sigsuspend((compat_sigset_t *)&mask, sizeof(mask), scr); return __ia32_rt_sigsuspend((compat_sigset_t *) &mask, sizeof(mask), scr);
} }
asmlinkage long asmlinkage long
...@@ -512,8 +524,8 @@ sys32_signal (int sig, unsigned int handler) ...@@ -512,8 +524,8 @@ sys32_signal (int sig, unsigned int handler)
} }
asmlinkage long asmlinkage long
sys32_rt_sigaction (int sig, struct sigaction32 *act, sys32_rt_sigaction (int sig, struct sigaction32 __user *act,
struct sigaction32 *oact, unsigned int sigsetsize) struct sigaction32 __user *oact, unsigned int sigsetsize)
{ {
struct k_sigaction new_ka, old_ka; struct k_sigaction new_ka, old_ka;
unsigned int handler, restorer; unsigned int handler, restorer;
...@@ -547,7 +559,8 @@ sys32_rt_sigaction (int sig, struct sigaction32 *act, ...@@ -547,7 +559,8 @@ sys32_rt_sigaction (int sig, struct sigaction32 *act,
asmlinkage long asmlinkage long
sys32_rt_sigprocmask (int how, compat_sigset_t *set, compat_sigset_t *oset, unsigned int sigsetsize) sys32_rt_sigprocmask (int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
unsigned int sigsetsize)
{ {
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
sigset_t s; sigset_t s;
...@@ -562,7 +575,9 @@ sys32_rt_sigprocmask (int how, compat_sigset_t *set, compat_sigset_t *oset, unsi ...@@ -562,7 +575,9 @@ sys32_rt_sigprocmask (int how, compat_sigset_t *set, compat_sigset_t *oset, unsi
return -EFAULT; return -EFAULT;
} }
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sizeof(s)); ret = sys_rt_sigprocmask(how,
set ? (sigset_t __user *) &s : NULL,
oset ? (sigset_t __user *) &s : NULL, sizeof(s));
set_fs(old_fs); set_fs(old_fs);
if (ret) if (ret)
return ret; return ret;
...@@ -574,10 +589,9 @@ sys32_rt_sigprocmask (int how, compat_sigset_t *set, compat_sigset_t *oset, unsi ...@@ -574,10 +589,9 @@ sys32_rt_sigprocmask (int how, compat_sigset_t *set, compat_sigset_t *oset, unsi
} }
asmlinkage long asmlinkage long
sys32_rt_sigtimedwait (compat_sigset_t *uthese, siginfo_t32 *uinfo, sys32_rt_sigtimedwait (compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo,
struct compat_timespec *uts, unsigned int sigsetsize) struct compat_timespec __user *uts, unsigned int sigsetsize)
{ {
extern int copy_siginfo_to_user32 (siginfo_t32 *, siginfo_t *);
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
struct timespec t; struct timespec t;
siginfo_t info; siginfo_t info;
...@@ -589,8 +603,10 @@ sys32_rt_sigtimedwait (compat_sigset_t *uthese, siginfo_t32 *uinfo, ...@@ -589,8 +603,10 @@ sys32_rt_sigtimedwait (compat_sigset_t *uthese, siginfo_t32 *uinfo,
if (uts && get_compat_timespec(&t, uts)) if (uts && get_compat_timespec(&t, uts))
return -EFAULT; return -EFAULT;
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL, ret = sys_rt_sigtimedwait((sigset_t __user *) &s,
sigsetsize); uinfo ? (siginfo_t __user *) &info : NULL,
uts ? (struct timespec __user *) &t : NULL,
sigsetsize);
set_fs(old_fs); set_fs(old_fs);
if (ret >= 0 && uinfo) { if (ret >= 0 && uinfo) {
if (copy_siginfo_to_user32(uinfo, &info)) if (copy_siginfo_to_user32(uinfo, &info))
...@@ -600,7 +616,7 @@ sys32_rt_sigtimedwait (compat_sigset_t *uthese, siginfo_t32 *uinfo, ...@@ -600,7 +616,7 @@ sys32_rt_sigtimedwait (compat_sigset_t *uthese, siginfo_t32 *uinfo,
} }
asmlinkage long asmlinkage long
sys32_rt_sigqueueinfo (int pid, int sig, siginfo_t32 *uinfo) sys32_rt_sigqueueinfo (int pid, int sig, siginfo_t32 __user *uinfo)
{ {
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
siginfo_t info; siginfo_t info;
...@@ -609,13 +625,13 @@ sys32_rt_sigqueueinfo (int pid, int sig, siginfo_t32 *uinfo) ...@@ -609,13 +625,13 @@ sys32_rt_sigqueueinfo (int pid, int sig, siginfo_t32 *uinfo)
if (copy_siginfo_from_user32(&info, uinfo)) if (copy_siginfo_from_user32(&info, uinfo))
return -EFAULT; return -EFAULT;
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_rt_sigqueueinfo(pid, sig, &info); ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
set_fs(old_fs); set_fs(old_fs);
return ret; return ret;
} }
asmlinkage long asmlinkage long
sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact) sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact)
{ {
struct k_sigaction new_ka, old_ka; struct k_sigaction new_ka, old_ka;
unsigned int handler, restorer; unsigned int handler, restorer;
...@@ -648,7 +664,7 @@ sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *o ...@@ -648,7 +664,7 @@ sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *o
} }
static int static int
setup_sigcontext_ia32 (struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate, setup_sigcontext_ia32 (struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate,
struct pt_regs *regs, unsigned long mask) struct pt_regs *regs, unsigned long mask)
{ {
int err = 0; int err = 0;
...@@ -657,10 +673,10 @@ setup_sigcontext_ia32 (struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate ...@@ -657,10 +673,10 @@ setup_sigcontext_ia32 (struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate
if (!access_ok(VERIFY_WRITE, sc, sizeof(*sc))) if (!access_ok(VERIFY_WRITE, sc, sizeof(*sc)))
return -EFAULT; return -EFAULT;
err |= __put_user((regs->r16 >> 32) & 0xffff, (unsigned int *)&sc->fs); err |= __put_user((regs->r16 >> 32) & 0xffff, (unsigned int __user *)&sc->fs);
err |= __put_user((regs->r16 >> 48) & 0xffff, (unsigned int *)&sc->gs); err |= __put_user((regs->r16 >> 48) & 0xffff, (unsigned int __user *)&sc->gs);
err |= __put_user((regs->r16 >> 16) & 0xffff, (unsigned int *)&sc->es); err |= __put_user((regs->r16 >> 16) & 0xffff, (unsigned int __user *)&sc->es);
err |= __put_user(regs->r16 & 0xffff, (unsigned int *)&sc->ds); err |= __put_user(regs->r16 & 0xffff, (unsigned int __user *)&sc->ds);
err |= __put_user(regs->r15, &sc->edi); err |= __put_user(regs->r15, &sc->edi);
err |= __put_user(regs->r14, &sc->esi); err |= __put_user(regs->r14, &sc->esi);
err |= __put_user(regs->r13, &sc->ebp); err |= __put_user(regs->r13, &sc->ebp);
...@@ -674,14 +690,14 @@ setup_sigcontext_ia32 (struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate ...@@ -674,14 +690,14 @@ setup_sigcontext_ia32 (struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate
err |= __put_user(current->tss.error_code, &sc->err); err |= __put_user(current->tss.error_code, &sc->err);
#endif #endif
err |= __put_user(regs->cr_iip, &sc->eip); err |= __put_user(regs->cr_iip, &sc->eip);
err |= __put_user(regs->r17 & 0xffff, (unsigned int *)&sc->cs); err |= __put_user(regs->r17 & 0xffff, (unsigned int __user *)&sc->cs);
/* /*
* `eflags' is in an ar register for this context * `eflags' is in an ar register for this context
*/ */
flag = ia64_getreg(_IA64_REG_AR_EFLAG); flag = ia64_getreg(_IA64_REG_AR_EFLAG);
err |= __put_user((unsigned int)flag, &sc->eflags); err |= __put_user((unsigned int)flag, &sc->eflags);
err |= __put_user(regs->r12, &sc->esp_at_signal); err |= __put_user(regs->r12, &sc->esp_at_signal);
err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int *)&sc->ss); err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int __user *)&sc->ss);
if ( save_ia32_fpstate_live(fpstate) < 0 ) if ( save_ia32_fpstate_live(fpstate) < 0 )
err = -EFAULT; err = -EFAULT;
...@@ -705,7 +721,7 @@ setup_sigcontext_ia32 (struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate ...@@ -705,7 +721,7 @@ setup_sigcontext_ia32 (struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate
} }
static int static int
restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 *sc, int *peax) restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 __user *sc, int *peax)
{ {
unsigned int err = 0; unsigned int err = 0;
...@@ -775,10 +791,10 @@ restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 *sc, int * ...@@ -775,10 +791,10 @@ restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 *sc, int *
} }
{ {
struct _fpstate_ia32 *buf = NULL; struct _fpstate_ia32 __user *buf = NULL;
u32 fpstate_ptr; u32 fpstate_ptr;
err |= get_user(fpstate_ptr, &(sc->fpstate)); err |= get_user(fpstate_ptr, &(sc->fpstate));
buf = (struct _fpstate_ia32 *)(u64)fpstate_ptr; buf = compat_ptr(fpstate_ptr);
if (buf) { if (buf) {
err |= restore_ia32_fpstate_live(buf); err |= restore_ia32_fpstate_live(buf);
} }
...@@ -808,7 +824,7 @@ restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 *sc, int * ...@@ -808,7 +824,7 @@ restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 *sc, int *
/* /*
* Determine which stack to use.. * Determine which stack to use..
*/ */
static inline void * static inline void __user *
get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
{ {
unsigned long esp; unsigned long esp;
...@@ -823,14 +839,14 @@ get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) ...@@ -823,14 +839,14 @@ get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
} }
/* Legacy stack switching not supported */ /* Legacy stack switching not supported */
return (void *)((esp - frame_size) & -8ul); return (void __user *)((esp - frame_size) & -8ul);
} }
static int static int
setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
{ {
struct exec_domain *ed = current_thread_info()->exec_domain; struct exec_domain *ed = current_thread_info()->exec_domain;
struct sigframe_ia32 *frame; struct sigframe_ia32 __user *frame;
int err = 0; int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame)); frame = get_sigframe(ka, regs, sizeof(*frame));
...@@ -862,9 +878,9 @@ setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs ...@@ -862,9 +878,9 @@ setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs
* See arch/i386/kernel/signal.c * See arch/i386/kernel/signal.c
*/ */
err |= __put_user(0xb858, (short *)(frame->retcode+0)); err |= __put_user(0xb858, (short __user *)(frame->retcode+0));
err |= __put_user(__IA32_NR_sigreturn, (int *)(frame->retcode+2)); err |= __put_user(__IA32_NR_sigreturn, (int __user *)(frame->retcode+2));
err |= __put_user(0x80cd, (short *)(frame->retcode+6)); err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
if (err) if (err)
goto give_sigsegv; goto give_sigsegv;
...@@ -896,7 +912,8 @@ setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -896,7 +912,8 @@ setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs * regs) sigset_t *set, struct pt_regs * regs)
{ {
struct exec_domain *ed = current_thread_info()->exec_domain; struct exec_domain *ed = current_thread_info()->exec_domain;
struct rt_sigframe_ia32 *frame; compat_uptr_t pinfo, puc;
struct rt_sigframe_ia32 __user *frame;
int err = 0; int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame)); frame = get_sigframe(ka, regs, sizeof(*frame));
...@@ -906,8 +923,11 @@ setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -906,8 +923,11 @@ setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user((ed && ed->signal_invmap err |= __put_user((ed && ed->signal_invmap
&& sig < 32 ? ed->signal_invmap[sig] : sig), &frame->sig); && sig < 32 ? ed->signal_invmap[sig] : sig), &frame->sig);
err |= __put_user((long)&frame->info, &frame->pinfo);
err |= __put_user((long)&frame->uc, &frame->puc); pinfo = (long __user) &frame->info;
puc = (long __user) &frame->uc;
err |= __put_user(pinfo, &frame->pinfo);
err |= __put_user(puc, &frame->puc);
err |= copy_siginfo_to_user32(&frame->info, info); err |= copy_siginfo_to_user32(&frame->info, info);
/* Create the ucontext. */ /* Create the ucontext. */
...@@ -936,9 +956,9 @@ setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -936,9 +956,9 @@ setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info,
* See arch/i386/kernel/signal.c * See arch/i386/kernel/signal.c
*/ */
err |= __put_user(0xb8, (char *)(frame->retcode+0)); err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
err |= __put_user(__IA32_NR_rt_sigreturn, (int *)(frame->retcode+1)); err |= __put_user(__IA32_NR_rt_sigreturn, (int __user *)(frame->retcode+1));
err |= __put_user(0x80cd, (short *)(frame->retcode+5)); err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
if (err) if (err)
goto give_sigsegv; goto give_sigsegv;
...@@ -982,7 +1002,7 @@ sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int ...@@ -982,7 +1002,7 @@ sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int
{ {
struct pt_regs *regs = (struct pt_regs *) &stack; struct pt_regs *regs = (struct pt_regs *) &stack;
unsigned long esp = (unsigned int) regs->r12; unsigned long esp = (unsigned int) regs->r12;
struct sigframe_ia32 *frame = (struct sigframe_ia32 *)(esp - 8); struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(esp - 8);
sigset_t set; sigset_t set;
int eax; int eax;
...@@ -996,7 +1016,7 @@ sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int ...@@ -996,7 +1016,7 @@ sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int
sigdelsetmask(&set, ~_BLOCKABLE); sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
current->blocked = (sigset_t) set; current->blocked = set;
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
...@@ -1015,9 +1035,8 @@ sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, ...@@ -1015,9 +1035,8 @@ sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
{ {
struct pt_regs *regs = (struct pt_regs *) &stack; struct pt_regs *regs = (struct pt_regs *) &stack;
unsigned long esp = (unsigned int) regs->r12; unsigned long esp = (unsigned int) regs->r12;
struct rt_sigframe_ia32 *frame = (struct rt_sigframe_ia32 *)(esp - 4); struct rt_sigframe_ia32 __user *frame = (struct rt_sigframe_ia32 __user *)(esp - 4);
sigset_t set; sigset_t set;
stack_t st;
int eax; int eax;
if (verify_area(VERIFY_READ, frame, sizeof(*frame))) if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
...@@ -1034,11 +1053,9 @@ sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, ...@@ -1034,11 +1053,9 @@ sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
if (restore_sigcontext_ia32(regs, &frame->uc.uc_mcontext, &eax)) if (restore_sigcontext_ia32(regs, &frame->uc.uc_mcontext, &eax))
goto badframe; goto badframe;
if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
goto badframe;
/* It is more difficult to avoid calling this function than to /* It is more difficult to avoid calling this function than to
call it and ignore errors. */ call it and ignore errors. */
do_sigaltstack(&st, NULL, esp); do_sigaltstack((stack_t __user *) &frame->uc.uc_stack, NULL, esp);
return eax; return eax;
......
...@@ -76,7 +76,7 @@ ia32_clone_tls (struct task_struct *child, struct pt_regs *childregs) ...@@ -76,7 +76,7 @@ ia32_clone_tls (struct task_struct *child, struct pt_regs *childregs)
struct ia32_user_desc info; struct ia32_user_desc info;
int idx; int idx;
if (copy_from_user(&info, (void *)(childregs->r14 & 0xffffffff), sizeof(info))) if (copy_from_user(&info, (void __user *)(childregs->r14 & 0xffffffff), sizeof(info)))
return -EFAULT; return -EFAULT;
if (LDT_empty(&info)) if (LDT_empty(&info))
return -EINVAL; return -EINVAL;
......
...@@ -556,8 +556,8 @@ struct user_regs_struct32 { ...@@ -556,8 +556,8 @@ struct user_regs_struct32 {
}; };
/* Prototypes for use in elfcore32.h */ /* Prototypes for use in elfcore32.h */
extern int save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *save); extern int save_ia32_fpstate (struct task_struct *, struct ia32_user_i387_struct __user *);
extern int save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save); extern int save_ia32_fpxstate (struct task_struct *, struct ia32_user_fxsr_struct __user *);
#endif /* !CONFIG_IA32_SUPPORT */ #endif /* !CONFIG_IA32_SUPPORT */
......
...@@ -70,10 +70,7 @@ ...@@ -70,10 +70,7 @@
# define DBG(fmt...) # define DBG(fmt...)
#endif #endif
#define A(__x) ((unsigned long)(__x))
#define AA(__x) ((unsigned long)(__x))
#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1))) #define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define OFFSET4K(a) ((a) & 0xfff) #define OFFSET4K(a) ((a) & 0xfff)
#define PAGE_START(addr) ((addr) & PAGE_MASK) #define PAGE_START(addr) ((addr) & PAGE_MASK)
...@@ -82,9 +79,6 @@ ...@@ -82,9 +79,6 @@
#define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid)) #define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid))
#define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid)) #define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid))
extern unsigned long arch_get_unmapped_area (struct file *, unsigned long, unsigned long,
unsigned long, unsigned long);
/* /*
* Anything that modifies or inspects ia32 user virtual memory must hold this semaphore * Anything that modifies or inspects ia32 user virtual memory must hold this semaphore
* while doing so. * while doing so.
...@@ -93,7 +87,8 @@ extern unsigned long arch_get_unmapped_area (struct file *, unsigned long, unsig ...@@ -93,7 +87,8 @@ extern unsigned long arch_get_unmapped_area (struct file *, unsigned long, unsig
static DECLARE_MUTEX(ia32_mmap_sem); static DECLARE_MUTEX(ia32_mmap_sem);
asmlinkage long asmlinkage long
sys32_execve (char *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp, struct pt_regs *regs) sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp,
struct pt_regs *regs)
{ {
long error; long error;
char *filename; char *filename;
...@@ -128,7 +123,7 @@ sys32_execve (char *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp ...@@ -128,7 +123,7 @@ sys32_execve (char *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp
return error; return error;
} }
int cp_compat_stat(struct kstat *stat, struct compat_stat *ubuf) int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
{ {
int err; int err;
...@@ -199,7 +194,7 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro ...@@ -199,7 +194,7 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro
/* Optimize the case where the old mmap and the new mmap are both anonymous */ /* Optimize the case where the old mmap and the new mmap are both anonymous */
if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) { if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) {
if (clear_user((void *) start, end - start)) { if (clear_user((void __user *) start, end - start)) {
ret = -EFAULT; ret = -EFAULT;
goto out; goto out;
} }
...@@ -211,7 +206,7 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro ...@@ -211,7 +206,7 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro
return -ENOMEM; return -ENOMEM;
if (old_prot) if (old_prot)
copy_from_user(page, (void *) PAGE_START(start), PAGE_SIZE); copy_from_user(page, (void __user *) PAGE_START(start), PAGE_SIZE);
down_write(&current->mm->mmap_sem); down_write(&current->mm->mmap_sem);
{ {
...@@ -226,9 +221,10 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro ...@@ -226,9 +221,10 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro
if (old_prot) { if (old_prot) {
/* copy back the old page contents. */ /* copy back the old page contents. */
if (offset_in_page(start)) if (offset_in_page(start))
copy_to_user((void *) PAGE_START(start), page, offset_in_page(start)); copy_to_user((void __user *) PAGE_START(start), page,
offset_in_page(start));
if (offset_in_page(end)) if (offset_in_page(end))
copy_to_user((void *) end, page + offset_in_page(end), copy_to_user((void __user *) end, page + offset_in_page(end),
PAGE_SIZE - offset_in_page(end)); PAGE_SIZE - offset_in_page(end));
} }
...@@ -236,7 +232,7 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro ...@@ -236,7 +232,7 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro
/* read the file contents */ /* read the file contents */
inode = file->f_dentry->d_inode; inode = file->f_dentry->d_inode;
if (!inode->i_fop || !file->f_op->read if (!inode->i_fop || !file->f_op->read
|| ((*file->f_op->read)(file, (char *) start, end - start, &off) < 0)) || ((*file->f_op->read)(file, (char __user *) start, end - start, &off) < 0))
{ {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
...@@ -838,7 +834,8 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro ...@@ -838,7 +834,8 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro
/* read the file contents */ /* read the file contents */
inode = file->f_dentry->d_inode; inode = file->f_dentry->d_inode;
if (!inode->i_fop || !file->f_op->read if (!inode->i_fop || !file->f_op->read
|| ((*file->f_op->read)(file, (char *) pstart, pend - pstart, &poff) < 0)) || ((*file->f_op->read)(file, (char __user *) pstart, pend - pstart, &poff)
< 0))
{ {
sys_munmap(pstart, pend - pstart); sys_munmap(pstart, pend - pstart);
return -EINVAL; return -EINVAL;
...@@ -927,7 +924,7 @@ struct mmap_arg_struct { ...@@ -927,7 +924,7 @@ struct mmap_arg_struct {
}; };
asmlinkage long asmlinkage long
sys32_mmap (struct mmap_arg_struct *arg) sys32_mmap (struct mmap_arg_struct __user *arg)
{ {
struct mmap_arg_struct a; struct mmap_arg_struct a;
struct file *file = NULL; struct file *file = NULL;
...@@ -1140,7 +1137,7 @@ sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len, ...@@ -1140,7 +1137,7 @@ sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len,
} }
asmlinkage long asmlinkage long
sys32_pipe (int *fd) sys32_pipe (int __user *fd)
{ {
int retval; int retval;
int fds[2]; int fds[2];
...@@ -1155,14 +1152,14 @@ sys32_pipe (int *fd) ...@@ -1155,14 +1152,14 @@ sys32_pipe (int *fd)
} }
static inline long static inline long
get_tv32 (struct timeval *o, struct compat_timeval *i) get_tv32 (struct timeval *o, struct compat_timeval __user *i)
{ {
return (!access_ok(VERIFY_READ, i, sizeof(*i)) || return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
(__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec))); (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec)));
} }
static inline long static inline long
put_tv32 (struct compat_timeval *o, struct timeval *i) put_tv32 (struct compat_timeval __user *o, struct timeval *i)
{ {
return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
(__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec))); (__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec)));
...@@ -1192,7 +1189,7 @@ sys32_alarm (unsigned int seconds) ...@@ -1192,7 +1189,7 @@ sys32_alarm (unsigned int seconds)
extern struct timezone sys_tz; extern struct timezone sys_tz;
asmlinkage long asmlinkage long
sys32_gettimeofday (struct compat_timeval *tv, struct timezone *tz) sys32_gettimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
{ {
if (tv) { if (tv) {
struct timeval ktv; struct timeval ktv;
...@@ -1208,7 +1205,7 @@ sys32_gettimeofday (struct compat_timeval *tv, struct timezone *tz) ...@@ -1208,7 +1205,7 @@ sys32_gettimeofday (struct compat_timeval *tv, struct timezone *tz)
} }
asmlinkage long asmlinkage long
sys32_settimeofday (struct compat_timeval *tv, struct timezone *tz) sys32_settimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
{ {
struct timeval ktv; struct timeval ktv;
struct timespec kts; struct timespec kts;
...@@ -1229,14 +1226,14 @@ sys32_settimeofday (struct compat_timeval *tv, struct timezone *tz) ...@@ -1229,14 +1226,14 @@ sys32_settimeofday (struct compat_timeval *tv, struct timezone *tz)
} }
struct getdents32_callback { struct getdents32_callback {
struct compat_dirent * current_dir; struct compat_dirent __user *current_dir;
struct compat_dirent * previous; struct compat_dirent __user *previous;
int count; int count;
int error; int error;
}; };
struct readdir32_callback { struct readdir32_callback {
struct old_linux32_dirent * dirent; struct old_linux32_dirent __user * dirent;
int count; int count;
}; };
...@@ -1244,9 +1241,9 @@ static int ...@@ -1244,9 +1241,9 @@ static int
filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
unsigned int d_type) unsigned int d_type)
{ {
struct compat_dirent * dirent; struct compat_dirent __user * dirent;
struct getdents32_callback * buf = (struct getdents32_callback *) __buf; struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4);
buf->error = -EINVAL; /* only used if we fail.. */ buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count) if (reclen > buf->count)
...@@ -1263,17 +1260,17 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, ...@@ -1263,17 +1260,17 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
|| copy_to_user(dirent->d_name, name, namlen) || copy_to_user(dirent->d_name, name, namlen)
|| put_user(0, dirent->d_name + namlen)) || put_user(0, dirent->d_name + namlen))
return -EFAULT; return -EFAULT;
dirent = (struct compat_dirent *) ((char *) dirent + reclen); dirent = (struct compat_dirent __user *) ((char __user *) dirent + reclen);
buf->current_dir = dirent; buf->current_dir = dirent;
buf->count -= reclen; buf->count -= reclen;
return 0; return 0;
} }
asmlinkage long asmlinkage long
sys32_getdents (unsigned int fd, struct compat_dirent *dirent, unsigned int count) sys32_getdents (unsigned int fd, struct compat_dirent __user *dirent, unsigned int count)
{ {
struct file * file; struct file * file;
struct compat_dirent * lastdirent; struct compat_dirent __user * lastdirent;
struct getdents32_callback buf; struct getdents32_callback buf;
int error; int error;
...@@ -1310,7 +1307,7 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ...@@ -1310,7 +1307,7 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t
unsigned int d_type) unsigned int d_type)
{ {
struct readdir32_callback * buf = (struct readdir32_callback *) __buf; struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
struct old_linux32_dirent * dirent; struct old_linux32_dirent __user * dirent;
if (buf->count) if (buf->count)
return -EINVAL; return -EINVAL;
...@@ -1326,7 +1323,7 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ...@@ -1326,7 +1323,7 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t
} }
asmlinkage long asmlinkage long
sys32_readdir (unsigned int fd, void *dirent, unsigned int count) sys32_readdir (unsigned int fd, void __user *dirent, unsigned int count)
{ {
int error; int error;
struct file * file; struct file * file;
...@@ -1357,7 +1354,7 @@ struct sel_arg_struct { ...@@ -1357,7 +1354,7 @@ struct sel_arg_struct {
}; };
asmlinkage long asmlinkage long
sys32_old_select (struct sel_arg_struct *arg) sys32_old_select (struct sel_arg_struct __user *arg)
{ {
struct sel_arg_struct a; struct sel_arg_struct a;
...@@ -1434,7 +1431,7 @@ sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth) ...@@ -1434,7 +1431,7 @@ sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
* so we have to implement this system call here. * so we have to implement this system call here.
*/ */
asmlinkage long asmlinkage long
sys32_time (int *tloc) sys32_time (int __user *tloc)
{ {
int i; int i;
struct timeval tv; struct timeval tv;
...@@ -1564,8 +1561,8 @@ putreg (struct task_struct *child, int regno, unsigned int value) ...@@ -1564,8 +1561,8 @@ putreg (struct task_struct *child, int regno, unsigned int value)
} }
static void static void
put_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp, put_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
int tos) struct switch_stack *swp, int tos)
{ {
struct _fpreg_ia32 *f; struct _fpreg_ia32 *f;
char buf[32]; char buf[32];
...@@ -1597,8 +1594,8 @@ put_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switc ...@@ -1597,8 +1594,8 @@ put_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switc
} }
static void static void
get_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp, get_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
int tos) struct switch_stack *swp, int tos)
{ {
if ((regno += tos) >= 8) if ((regno += tos) >= 8)
...@@ -1627,7 +1624,7 @@ get_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switc ...@@ -1627,7 +1624,7 @@ get_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switc
} }
int int
save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *save) save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
{ {
struct switch_stack *swp; struct switch_stack *swp;
struct pt_regs *ptp; struct pt_regs *ptp;
...@@ -1656,7 +1653,7 @@ save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *save) ...@@ -1656,7 +1653,7 @@ save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *save)
} }
static int static int
restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *save) restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
{ {
struct switch_stack *swp; struct switch_stack *swp;
struct pt_regs *ptp; struct pt_regs *ptp;
...@@ -1666,15 +1663,15 @@ restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *sav ...@@ -1666,15 +1663,15 @@ restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *sav
if (!access_ok(VERIFY_READ, save, sizeof(*save))) if (!access_ok(VERIFY_READ, save, sizeof(*save)))
return(-EFAULT); return(-EFAULT);
__get_user(num32, (unsigned int *)&save->cwd); __get_user(num32, (unsigned int __user *)&save->cwd);
tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f); tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
__get_user(fsrlo, (unsigned int *)&save->swd); __get_user(fsrlo, (unsigned int __user *)&save->swd);
__get_user(fsrhi, (unsigned int *)&save->twd); __get_user(fsrhi, (unsigned int __user *)&save->twd);
num32 = (fsrhi << 16) | fsrlo; num32 = (fsrhi << 16) | fsrlo;
tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32; tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
__get_user(num32, (unsigned int *)&save->fip); __get_user(num32, (unsigned int __user *)&save->fip);
tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32; tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
__get_user(num32, (unsigned int *)&save->foo); __get_user(num32, (unsigned int __user *)&save->foo);
tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32; tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
/* /*
...@@ -1689,7 +1686,7 @@ restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *sav ...@@ -1689,7 +1686,7 @@ restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *sav
} }
int int
save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save) save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
{ {
struct switch_stack *swp; struct switch_stack *swp;
struct pt_regs *ptp; struct pt_regs *ptp;
...@@ -1715,7 +1712,7 @@ save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save) ...@@ -1715,7 +1712,7 @@ save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save)
ptp = ia64_task_regs(tsk); ptp = ia64_task_regs(tsk);
tos = (tsk->thread.fsr >> 11) & 7; tos = (tsk->thread.fsr >> 11) & 7;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
put_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos); put_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
mxcsr = ((tsk->thread.fcr>>32) & 0xff80) | ((tsk->thread.fsr>>32) & 0x3f); mxcsr = ((tsk->thread.fcr>>32) & 0xff80) | ((tsk->thread.fsr>>32) & 0x3f);
__put_user(mxcsr & 0xffff, &save->mxcsr); __put_user(mxcsr & 0xffff, &save->mxcsr);
...@@ -1728,7 +1725,7 @@ save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save) ...@@ -1728,7 +1725,7 @@ save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save)
} }
static int static int
restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save) restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
{ {
struct switch_stack *swp; struct switch_stack *swp;
struct pt_regs *ptp; struct pt_regs *ptp;
...@@ -1741,15 +1738,15 @@ restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *sa ...@@ -1741,15 +1738,15 @@ restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *sa
if (!access_ok(VERIFY_READ, save, sizeof(*save))) if (!access_ok(VERIFY_READ, save, sizeof(*save)))
return(-EFAULT); return(-EFAULT);
__get_user(num32, (unsigned int *)&save->cwd); __get_user(num32, (unsigned int __user *)&save->cwd);
tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f); tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
__get_user(fsrlo, (unsigned int *)&save->swd); __get_user(fsrlo, (unsigned int __user *)&save->swd);
__get_user(fsrhi, (unsigned int *)&save->twd); __get_user(fsrhi, (unsigned int __user *)&save->twd);
num32 = (fsrhi << 16) | fsrlo; num32 = (fsrhi << 16) | fsrlo;
tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32; tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
__get_user(num32, (unsigned int *)&save->fip); __get_user(num32, (unsigned int __user *)&save->fip);
tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32; tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
__get_user(num32, (unsigned int *)&save->foo); __get_user(num32, (unsigned int __user *)&save->foo);
tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32; tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
/* /*
...@@ -1759,9 +1756,9 @@ restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *sa ...@@ -1759,9 +1756,9 @@ restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *sa
ptp = ia64_task_regs(tsk); ptp = ia64_task_regs(tsk);
tos = (tsk->thread.fsr >> 11) & 7; tos = (tsk->thread.fsr >> 11) & 7;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
get_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos); get_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
__get_user(mxcsr, (unsigned int *)&save->mxcsr); __get_user(mxcsr, (unsigned int __user *)&save->mxcsr);
num64 = mxcsr & 0xff10; num64 = mxcsr & 0xff10;
tsk->thread.fcr = (tsk->thread.fcr & (~0xff1000000000UL)) | (num64<<32); tsk->thread.fcr = (tsk->thread.fcr & (~0xff1000000000UL)) | (num64<<32);
num64 = mxcsr & 0x3f; num64 = mxcsr & 0x3f;
...@@ -1823,7 +1820,7 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data, ...@@ -1823,7 +1820,7 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data,
case PTRACE_PEEKDATA: /* read word at location addr */ case PTRACE_PEEKDATA: /* read word at location addr */
ret = ia32_peek(regs, child, addr, &value); ret = ia32_peek(regs, child, addr, &value);
if (ret == 0) if (ret == 0)
ret = put_user(value, (unsigned int *) A(data)); ret = put_user(value, (unsigned int __user *) compat_ptr(data));
else else
ret = -EIO; ret = -EIO;
goto out_tsk; goto out_tsk;
...@@ -1839,7 +1836,7 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data, ...@@ -1839,7 +1836,7 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data,
break; break;
tmp = getreg(child, addr); tmp = getreg(child, addr);
if (!put_user(tmp, (unsigned int *) A(data))) if (!put_user(tmp, (unsigned int __user *) compat_ptr(data)))
ret = 0; ret = 0;
break; break;
...@@ -1853,24 +1850,24 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data, ...@@ -1853,24 +1850,24 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data,
break; break;
case IA32_PTRACE_GETREGS: case IA32_PTRACE_GETREGS:
if (!access_ok(VERIFY_WRITE, (int *) A(data), 17*sizeof(int))) { if (!access_ok(VERIFY_WRITE, compat_ptr(data), 17*sizeof(int))) {
ret = -EIO; ret = -EIO;
break; break;
} }
for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) { for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
put_user(getreg(child, i), (unsigned int *) A(data)); put_user(getreg(child, i), (unsigned int __user *) compat_ptr(data));
data += sizeof(int); data += sizeof(int);
} }
ret = 0; ret = 0;
break; break;
case IA32_PTRACE_SETREGS: case IA32_PTRACE_SETREGS:
if (!access_ok(VERIFY_READ, (int *) A(data), 17*sizeof(int))) { if (!access_ok(VERIFY_READ, compat_ptr(data), 17*sizeof(int))) {
ret = -EIO; ret = -EIO;
break; break;
} }
for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) { for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
get_user(tmp, (unsigned int *) A(data)); get_user(tmp, (unsigned int __user *) compat_ptr(data));
putreg(child, i, tmp); putreg(child, i, tmp);
data += sizeof(int); data += sizeof(int);
} }
...@@ -1878,19 +1875,23 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data, ...@@ -1878,19 +1875,23 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data,
break; break;
case IA32_PTRACE_GETFPREGS: case IA32_PTRACE_GETFPREGS:
ret = save_ia32_fpstate(child, (struct ia32_user_i387_struct *) A(data)); ret = save_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
compat_ptr(data));
break; break;
case IA32_PTRACE_GETFPXREGS: case IA32_PTRACE_GETFPXREGS:
ret = save_ia32_fpxstate(child, (struct ia32_user_fxsr_struct *) A(data)); ret = save_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
compat_ptr(data));
break; break;
case IA32_PTRACE_SETFPREGS: case IA32_PTRACE_SETFPREGS:
ret = restore_ia32_fpstate(child, (struct ia32_user_i387_struct *) A(data)); ret = restore_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
compat_ptr(data));
break; break;
case IA32_PTRACE_SETFPXREGS: case IA32_PTRACE_SETFPXREGS:
ret = restore_ia32_fpxstate(child, (struct ia32_user_fxsr_struct *) A(data)); ret = restore_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
compat_ptr(data));
break; break;
case PTRACE_SYSCALL: /* continue, stop after next syscall */ case PTRACE_SYSCALL: /* continue, stop after next syscall */
...@@ -1920,7 +1921,7 @@ typedef struct { ...@@ -1920,7 +1921,7 @@ typedef struct {
} ia32_stack_t; } ia32_stack_t;
asmlinkage long asmlinkage long
sys32_sigaltstack (ia32_stack_t *uss32, ia32_stack_t *uoss32, sys32_sigaltstack (ia32_stack_t __user *uss32, ia32_stack_t __user *uoss32,
long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long stack) long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long stack)
{ {
struct pt_regs *pt = (struct pt_regs *) &stack; struct pt_regs *pt = (struct pt_regs *) &stack;
...@@ -1932,9 +1933,9 @@ sys32_sigaltstack (ia32_stack_t *uss32, ia32_stack_t *uoss32, ...@@ -1932,9 +1933,9 @@ sys32_sigaltstack (ia32_stack_t *uss32, ia32_stack_t *uoss32,
if (uss32) { if (uss32) {
if (copy_from_user(&buf32, uss32, sizeof(ia32_stack_t))) if (copy_from_user(&buf32, uss32, sizeof(ia32_stack_t)))
return -EFAULT; return -EFAULT;
uss.ss_sp = (void *) (long) buf32.ss_sp; uss.ss_sp = (void __user *) (long) buf32.ss_sp;
uss.ss_flags = buf32.ss_flags; uss.ss_flags = buf32.ss_flags;
/* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the /* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the
check and set it to the user requested value later */ check and set it to the user requested value later */
if ((buf32.ss_flags != SS_DISABLE) && (buf32.ss_size < MINSIGSTKSZ_IA32)) { if ((buf32.ss_flags != SS_DISABLE) && (buf32.ss_size < MINSIGSTKSZ_IA32)) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -1943,14 +1944,15 @@ sys32_sigaltstack (ia32_stack_t *uss32, ia32_stack_t *uoss32, ...@@ -1943,14 +1944,15 @@ sys32_sigaltstack (ia32_stack_t *uss32, ia32_stack_t *uoss32,
uss.ss_size = MINSIGSTKSZ; uss.ss_size = MINSIGSTKSZ;
} }
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12); ret = do_sigaltstack(uss32 ? (stack_t __user *) &uss : NULL,
current->sas_ss_size = buf32.ss_size; (stack_t __user *) &uoss, pt->r12);
current->sas_ss_size = buf32.ss_size;
set_fs(old_fs); set_fs(old_fs);
out: out:
if (ret < 0) if (ret < 0)
return(ret); return(ret);
if (uoss32) { if (uoss32) {
buf32.ss_sp = (long) uoss.ss_sp; buf32.ss_sp = (long __user) uoss.ss_sp;
buf32.ss_flags = uoss.ss_flags; buf32.ss_flags = uoss.ss_flags;
buf32.ss_size = uoss.ss_size; buf32.ss_size = uoss.ss_size;
if (copy_to_user(uoss32, &buf32, sizeof(ia32_stack_t))) if (copy_to_user(uoss32, &buf32, sizeof(ia32_stack_t)))
...@@ -1989,14 +1991,14 @@ struct sysctl32 { ...@@ -1989,14 +1991,14 @@ struct sysctl32 {
}; };
asmlinkage long asmlinkage long
sys32_sysctl (struct sysctl32 *args) sys32_sysctl (struct sysctl32 __user *args)
{ {
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
struct sysctl32 a32; struct sysctl32 a32;
mm_segment_t old_fs = get_fs (); mm_segment_t old_fs = get_fs ();
void *oldvalp, *newvalp; void __user *oldvalp, *newvalp;
size_t oldlen; size_t oldlen;
int *namep; int __user *namep;
long ret; long ret;
if (copy_from_user(&a32, args, sizeof(a32))) if (copy_from_user(&a32, args, sizeof(a32)))
...@@ -2009,11 +2011,11 @@ sys32_sysctl (struct sysctl32 *args) ...@@ -2009,11 +2011,11 @@ sys32_sysctl (struct sysctl32 *args)
* addresses, we KNOW that access_ok() will always succeed, so this is an * addresses, we KNOW that access_ok() will always succeed, so this is an
* expensive NOP, but so what... * expensive NOP, but so what...
*/ */
namep = (int *) A(a32.name); namep = (int __user *) compat_ptr(a32.name);
oldvalp = (void *) A(a32.oldval); oldvalp = compat_ptr(a32.oldval);
newvalp = (void *) A(a32.newval); newvalp = compat_ptr(a32.newval);
if ((oldvalp && get_user(oldlen, (int *) A(a32.oldlenp))) if ((oldvalp && get_user(oldlen, (int __user *) compat_ptr(a32.oldlenp)))
|| !access_ok(VERIFY_WRITE, namep, 0) || !access_ok(VERIFY_WRITE, namep, 0)
|| !access_ok(VERIFY_WRITE, oldvalp, 0) || !access_ok(VERIFY_WRITE, oldvalp, 0)
|| !access_ok(VERIFY_WRITE, newvalp, 0)) || !access_ok(VERIFY_WRITE, newvalp, 0))
...@@ -2021,11 +2023,12 @@ sys32_sysctl (struct sysctl32 *args) ...@@ -2021,11 +2023,12 @@ sys32_sysctl (struct sysctl32 *args)
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
lock_kernel(); lock_kernel();
ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen); ret = do_sysctl(namep, a32.nlen, oldvalp, (size_t __user *) &oldlen,
newvalp, (size_t) a32.newlen);
unlock_kernel(); unlock_kernel();
set_fs(old_fs); set_fs(old_fs);
if (oldvalp && put_user (oldlen, (int *) A(a32.oldlenp))) if (oldvalp && put_user (oldlen, (int __user *) compat_ptr(a32.oldlenp)))
return -EFAULT; return -EFAULT;
return ret; return ret;
...@@ -2035,7 +2038,7 @@ sys32_sysctl (struct sysctl32 *args) ...@@ -2035,7 +2038,7 @@ sys32_sysctl (struct sysctl32 *args)
} }
asmlinkage long asmlinkage long
sys32_newuname (struct new_utsname *name) sys32_newuname (struct new_utsname __user *name)
{ {
int ret = sys_newuname(name); int ret = sys_newuname(name);
...@@ -2046,14 +2049,14 @@ sys32_newuname (struct new_utsname *name) ...@@ -2046,14 +2049,14 @@ sys32_newuname (struct new_utsname *name)
} }
asmlinkage long asmlinkage long
sys32_getresuid16 (u16 *ruid, u16 *euid, u16 *suid) sys32_getresuid16 (u16 __user *ruid, u16 __user *euid, u16 __user *suid)
{ {
uid_t a, b, c; uid_t a, b, c;
int ret; int ret;
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_getresuid(&a, &b, &c); ret = sys_getresuid((uid_t __user *) &a, (uid_t __user *) &b, (uid_t __user *) &c);
set_fs(old_fs); set_fs(old_fs);
if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid)) if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid))
...@@ -2062,14 +2065,14 @@ sys32_getresuid16 (u16 *ruid, u16 *euid, u16 *suid) ...@@ -2062,14 +2065,14 @@ sys32_getresuid16 (u16 *ruid, u16 *euid, u16 *suid)
} }
asmlinkage long asmlinkage long
sys32_getresgid16 (u16 *rgid, u16 *egid, u16 *sgid) sys32_getresgid16 (u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
{ {
gid_t a, b, c; gid_t a, b, c;
int ret; int ret;
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_getresgid(&a, &b, &c); ret = sys_getresgid((gid_t __user *) &a, (gid_t __user *) &b, (gid_t __user *) &c);
set_fs(old_fs); set_fs(old_fs);
if (ret) if (ret)
...@@ -2086,7 +2089,7 @@ sys32_lseek (unsigned int fd, int offset, unsigned int whence) ...@@ -2086,7 +2089,7 @@ sys32_lseek (unsigned int fd, int offset, unsigned int whence)
} }
static int static int
groups16_to_user(short *grouplist, struct group_info *group_info) groups16_to_user(short __user *grouplist, struct group_info *group_info)
{ {
int i; int i;
short group; short group;
...@@ -2101,7 +2104,7 @@ groups16_to_user(short *grouplist, struct group_info *group_info) ...@@ -2101,7 +2104,7 @@ groups16_to_user(short *grouplist, struct group_info *group_info)
} }
static int static int
groups16_from_user(struct group_info *group_info, short *grouplist) groups16_from_user(struct group_info *group_info, short __user *grouplist)
{ {
int i; int i;
short group; short group;
...@@ -2116,7 +2119,7 @@ groups16_from_user(struct group_info *group_info, short *grouplist) ...@@ -2116,7 +2119,7 @@ groups16_from_user(struct group_info *group_info, short *grouplist)
} }
asmlinkage long asmlinkage long
sys32_getgroups16 (int gidsetsize, short *grouplist) sys32_getgroups16 (int gidsetsize, short __user *grouplist)
{ {
int i; int i;
...@@ -2141,7 +2144,7 @@ sys32_getgroups16 (int gidsetsize, short *grouplist) ...@@ -2141,7 +2144,7 @@ sys32_getgroups16 (int gidsetsize, short *grouplist)
} }
asmlinkage long asmlinkage long
sys32_setgroups16 (int gidsetsize, short *grouplist) sys32_setgroups16 (int gidsetsize, short __user *grouplist)
{ {
struct group_info *group_info; struct group_info *group_info;
int retval; int retval;
...@@ -2169,7 +2172,7 @@ sys32_setgroups16 (int gidsetsize, short *grouplist) ...@@ -2169,7 +2172,7 @@ sys32_setgroups16 (int gidsetsize, short *grouplist)
asmlinkage long asmlinkage long
sys32_truncate64 (unsigned int path, unsigned int len_lo, unsigned int len_hi) sys32_truncate64 (unsigned int path, unsigned int len_lo, unsigned int len_hi)
{ {
return sys_truncate((const char *) A(path), ((unsigned long) len_hi << 32) | len_lo); return sys_truncate(compat_ptr(path), ((unsigned long) len_hi << 32) | len_lo);
} }
asmlinkage long asmlinkage long
...@@ -2179,7 +2182,7 @@ sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi) ...@@ -2179,7 +2182,7 @@ sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi)
} }
static int static int
putstat64 (struct stat64 *ubuf, struct kstat *kbuf) putstat64 (struct stat64 __user *ubuf, struct kstat *kbuf)
{ {
int err; int err;
u64 hdev; u64 hdev;
...@@ -2188,8 +2191,8 @@ putstat64 (struct stat64 *ubuf, struct kstat *kbuf) ...@@ -2188,8 +2191,8 @@ putstat64 (struct stat64 *ubuf, struct kstat *kbuf)
return -EFAULT; return -EFAULT;
hdev = huge_encode_dev(kbuf->dev); hdev = huge_encode_dev(kbuf->dev);
err = __put_user(hdev, (u32*)&ubuf->st_dev); err = __put_user(hdev, (u32 __user*)&ubuf->st_dev);
err |= __put_user(hdev >> 32, ((u32*)&ubuf->st_dev) + 1); err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_dev) + 1);
err |= __put_user(kbuf->ino, &ubuf->__st_ino); err |= __put_user(kbuf->ino, &ubuf->__st_ino);
err |= __put_user(kbuf->ino, &ubuf->st_ino_lo); err |= __put_user(kbuf->ino, &ubuf->st_ino_lo);
err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi); err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi);
...@@ -2198,8 +2201,8 @@ putstat64 (struct stat64 *ubuf, struct kstat *kbuf) ...@@ -2198,8 +2201,8 @@ putstat64 (struct stat64 *ubuf, struct kstat *kbuf)
err |= __put_user(kbuf->uid, &ubuf->st_uid); err |= __put_user(kbuf->uid, &ubuf->st_uid);
err |= __put_user(kbuf->gid, &ubuf->st_gid); err |= __put_user(kbuf->gid, &ubuf->st_gid);
hdev = huge_encode_dev(kbuf->rdev); hdev = huge_encode_dev(kbuf->rdev);
err = __put_user(hdev, (u32*)&ubuf->st_rdev); err = __put_user(hdev, (u32 __user*)&ubuf->st_rdev);
err |= __put_user(hdev >> 32, ((u32*)&ubuf->st_rdev) + 1); err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_rdev) + 1);
err |= __put_user(kbuf->size, &ubuf->st_size_lo); err |= __put_user(kbuf->size, &ubuf->st_size_lo);
err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi); err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi);
err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime); err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime);
...@@ -2214,7 +2217,7 @@ putstat64 (struct stat64 *ubuf, struct kstat *kbuf) ...@@ -2214,7 +2217,7 @@ putstat64 (struct stat64 *ubuf, struct kstat *kbuf)
} }
asmlinkage long asmlinkage long
sys32_stat64 (char *filename, struct stat64 *statbuf) sys32_stat64 (char __user *filename, struct stat64 __user *statbuf)
{ {
struct kstat s; struct kstat s;
long ret = vfs_stat(filename, &s); long ret = vfs_stat(filename, &s);
...@@ -2224,7 +2227,7 @@ sys32_stat64 (char *filename, struct stat64 *statbuf) ...@@ -2224,7 +2227,7 @@ sys32_stat64 (char *filename, struct stat64 *statbuf)
} }
asmlinkage long asmlinkage long
sys32_lstat64 (char *filename, struct stat64 *statbuf) sys32_lstat64 (char __user *filename, struct stat64 __user *statbuf)
{ {
struct kstat s; struct kstat s;
long ret = vfs_lstat(filename, &s); long ret = vfs_lstat(filename, &s);
...@@ -2234,7 +2237,7 @@ sys32_lstat64 (char *filename, struct stat64 *statbuf) ...@@ -2234,7 +2237,7 @@ sys32_lstat64 (char *filename, struct stat64 *statbuf)
} }
asmlinkage long asmlinkage long
sys32_fstat64 (unsigned int fd, struct stat64 *statbuf) sys32_fstat64 (unsigned int fd, struct stat64 __user *statbuf)
{ {
struct kstat s; struct kstat s;
long ret = vfs_fstat(fd, &s); long ret = vfs_fstat(fd, &s);
...@@ -2261,7 +2264,7 @@ struct sysinfo32 { ...@@ -2261,7 +2264,7 @@ struct sysinfo32 {
}; };
asmlinkage long asmlinkage long
sys32_sysinfo (struct sysinfo32 *info) sys32_sysinfo (struct sysinfo32 __user *info)
{ {
struct sysinfo s; struct sysinfo s;
long ret, err; long ret, err;
...@@ -2269,7 +2272,7 @@ sys32_sysinfo (struct sysinfo32 *info) ...@@ -2269,7 +2272,7 @@ sys32_sysinfo (struct sysinfo32 *info)
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_sysinfo(&s); ret = sys_sysinfo((struct sysinfo __user *) &s);
set_fs(old_fs); set_fs(old_fs);
/* Check to see if any memory value is too large for 32-bit and /* Check to see if any memory value is too large for 32-bit and
* scale down if needed. * scale down if needed.
...@@ -2312,14 +2315,14 @@ sys32_sysinfo (struct sysinfo32 *info) ...@@ -2312,14 +2315,14 @@ sys32_sysinfo (struct sysinfo32 *info)
} }
asmlinkage long asmlinkage long
sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec *interval) sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec __user *interval)
{ {
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
struct timespec t; struct timespec t;
long ret; long ret;
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_sched_rr_get_interval(pid, &t); ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t);
set_fs(old_fs); set_fs(old_fs);
if (put_compat_timespec(&t, interval)) if (put_compat_timespec(&t, interval))
return -EFAULT; return -EFAULT;
...@@ -2327,19 +2330,19 @@ sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec *interval) ...@@ -2327,19 +2330,19 @@ sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec *interval)
} }
asmlinkage long asmlinkage long
sys32_pread (unsigned int fd, void *buf, unsigned int count, u32 pos_lo, u32 pos_hi) sys32_pread (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
{ {
return sys_pread64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo); return sys_pread64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
} }
asmlinkage long asmlinkage long
sys32_pwrite (unsigned int fd, void *buf, unsigned int count, u32 pos_lo, u32 pos_hi) sys32_pwrite (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
{ {
return sys_pwrite64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo); return sys_pwrite64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
} }
asmlinkage long asmlinkage long
sys32_sendfile (int out_fd, int in_fd, int *offset, unsigned int count) sys32_sendfile (int out_fd, int in_fd, int __user *offset, unsigned int count)
{ {
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
long ret; long ret;
...@@ -2349,7 +2352,7 @@ sys32_sendfile (int out_fd, int in_fd, int *offset, unsigned int count) ...@@ -2349,7 +2352,7 @@ sys32_sendfile (int out_fd, int in_fd, int *offset, unsigned int count)
return -EFAULT; return -EFAULT;
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *) &of : NULL, count);
set_fs(old_fs); set_fs(old_fs);
if (!ret && offset && put_user(of, offset)) if (!ret && offset && put_user(of, offset))
...@@ -2380,7 +2383,7 @@ sys32_brk (unsigned int brk) ...@@ -2380,7 +2383,7 @@ sys32_brk (unsigned int brk)
obrk = mm->brk; obrk = mm->brk;
ret = sys_brk(brk); ret = sys_brk(brk);
if (ret < obrk) if (ret < obrk)
clear_user((void *) ret, PAGE_ALIGN(ret) - ret); clear_user(compat_ptr(ret), PAGE_ALIGN(ret) - ret);
return ret; return ret;
} }
...@@ -2388,7 +2391,7 @@ sys32_brk (unsigned int brk) ...@@ -2388,7 +2391,7 @@ sys32_brk (unsigned int brk)
* Exactly like fs/open.c:sys_open(), except that it doesn't set the O_LARGEFILE flag. * Exactly like fs/open.c:sys_open(), except that it doesn't set the O_LARGEFILE flag.
*/ */
asmlinkage long asmlinkage long
sys32_open (const char * filename, int flags, int mode) sys32_open (const char __user * filename, int flags, int mode)
{ {
char * tmp; char * tmp;
int fd, error; int fd, error;
...@@ -2420,10 +2423,10 @@ struct epoll_event32 ...@@ -2420,10 +2423,10 @@ struct epoll_event32
{ {
u32 events; u32 events;
u32 data[2]; u32 data[2];
}; };
asmlinkage long asmlinkage long
sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 *event) sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 __user *event)
{ {
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
struct epoll_event event64; struct epoll_event event64;
...@@ -2441,14 +2444,14 @@ sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 *event) ...@@ -2441,14 +2444,14 @@ sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 *event)
event64.data |= (u64)data_halfword << 32; event64.data |= (u64)data_halfword << 32;
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
error = sys_epoll_ctl(epfd, op, fd, &event64); error = sys_epoll_ctl(epfd, op, fd, (struct epoll_event __user *) &event64);
set_fs(old_fs); set_fs(old_fs);
return error; return error;
} }
asmlinkage long asmlinkage long
sys32_epoll_wait(int epfd, struct epoll_event32 *events, int maxevents, sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents,
int timeout) int timeout)
{ {
struct epoll_event *events64 = NULL; struct epoll_event *events64 = NULL;
...@@ -2466,8 +2469,8 @@ sys32_epoll_wait(int epfd, struct epoll_event32 *events, int maxevents, ...@@ -2466,8 +2469,8 @@ sys32_epoll_wait(int epfd, struct epoll_event32 *events, int maxevents,
maxevents * sizeof(struct epoll_event32)))) maxevents * sizeof(struct epoll_event32))))
return error; return error;
/* /*
* Allocate space for the intermediate copy. If the space needed * Allocate space for the intermediate copy. If the space needed
* is large enough to cause kmalloc to fail, then try again with * is large enough to cause kmalloc to fail, then try again with
* __get_free_pages. * __get_free_pages.
*/ */
...@@ -2476,14 +2479,15 @@ sys32_epoll_wait(int epfd, struct epoll_event32 *events, int maxevents, ...@@ -2476,14 +2479,15 @@ sys32_epoll_wait(int epfd, struct epoll_event32 *events, int maxevents,
if (events64 == NULL) { if (events64 == NULL) {
events64 = (struct epoll_event *) events64 = (struct epoll_event *)
__get_free_pages(GFP_KERNEL, get_order(size)); __get_free_pages(GFP_KERNEL, get_order(size));
if (events64 == NULL) if (events64 == NULL)
return -ENOMEM; return -ENOMEM;
do_free_pages = 1; do_free_pages = 1;
} }
/* Do the system call */ /* Do the system call */
set_fs(KERNEL_DS); /* copy_to/from_user should work on kernel mem*/ set_fs(KERNEL_DS); /* copy_to/from_user should work on kernel mem*/
numevents = sys_epoll_wait(epfd, events64, maxevents, timeout); numevents = sys_epoll_wait(epfd, (struct epoll_event __user *) events64,
maxevents, timeout);
set_fs(old_fs); set_fs(old_fs);
/* Don't modify userspace memory if we're returning an error */ /* Don't modify userspace memory if we're returning an error */
...@@ -2526,7 +2530,7 @@ get_free_idx (void) ...@@ -2526,7 +2530,7 @@ get_free_idx (void)
* Set a given TLS descriptor: * Set a given TLS descriptor:
*/ */
asmlinkage int asmlinkage int
sys32_set_thread_area (struct ia32_user_desc *u_info) sys32_set_thread_area (struct ia32_user_desc __user *u_info)
{ {
struct thread_struct *t = &current->thread; struct thread_struct *t = &current->thread;
struct ia32_user_desc info; struct ia32_user_desc info;
...@@ -2587,7 +2591,7 @@ sys32_set_thread_area (struct ia32_user_desc *u_info) ...@@ -2587,7 +2591,7 @@ sys32_set_thread_area (struct ia32_user_desc *u_info)
#define GET_USEABLE(desc) (((desc)->b >> 20) & 1) #define GET_USEABLE(desc) (((desc)->b >> 20) & 1)
asmlinkage int asmlinkage int
sys32_get_thread_area (struct ia32_user_desc *u_info) sys32_get_thread_area (struct ia32_user_desc __user *u_info)
{ {
struct ia32_user_desc info; struct ia32_user_desc info;
struct desc_struct *desc; struct desc_struct *desc;
...@@ -2615,12 +2619,8 @@ sys32_get_thread_area (struct ia32_user_desc *u_info) ...@@ -2615,12 +2619,8 @@ sys32_get_thread_area (struct ia32_user_desc *u_info)
return 0; return 0;
} }
extern asmlinkage long
sys_timer_create(clockid_t which_clock, struct sigevent *timer_event_spec,
timer_t * created_timer_id);
asmlinkage long asmlinkage long
sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id) sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id)
{ {
struct sigevent se; struct sigevent se;
mm_segment_t oldfs; mm_segment_t oldfs;
...@@ -2643,7 +2643,7 @@ sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id) ...@@ -2643,7 +2643,7 @@ sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id)
oldfs = get_fs(); oldfs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
err = sys_timer_create(clock, &se, &t); err = sys_timer_create(clock, (struct sigevent __user *) &se, (timer_t __user *) &t);
set_fs(oldfs); set_fs(oldfs);
if (!err) if (!err)
......
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