Commit c6e2227e authored by Eddie C. Dost's avatar Eddie C. Dost Committed by David S. Miller

[SPARC64]: Missing user access return value checks in fs/binfmt_elf.c and fs/compat.c

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bd24a6bd
......@@ -106,15 +106,17 @@ static int set_brk(unsigned long start, unsigned long end)
be in memory */
static void padzero(unsigned long elf_bss)
static int padzero(unsigned long elf_bss)
{
unsigned long nbyte;
nbyte = ELF_PAGEOFFSET(elf_bss);
if (nbyte) {
nbyte = ELF_MIN_ALIGN - nbyte;
clear_user((void __user *) elf_bss, nbyte);
if (clear_user((void __user *) elf_bss, nbyte))
return -EFAULT;
}
return 0;
}
/* Let's use some macros to make this stack manipulation a litle clearer */
......@@ -130,7 +132,7 @@ static void padzero(unsigned long elf_bss)
#define STACK_ALLOC(sp, len) ({ sp -= len ; sp; })
#endif
static void
static int
create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
int interp_aout, unsigned long load_addr,
unsigned long interp_load_addr)
......@@ -175,7 +177,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
STACK_ALLOC(p, ((current->pid % 64) << 7));
#endif
u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
__copy_to_user(u_platform, k_platform, len);
if (__copy_to_user(u_platform, k_platform, len))
return -EFAULT;
}
/* Create the ELF interpreter info */
......@@ -237,7 +240,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
#endif
/* Now, let's put argc (and argv, envp if appropriate) on the stack */
__put_user(argc, sp++);
if (__put_user(argc, sp++))
return -EFAULT;
if (interp_aout) {
argv = sp + 2;
envp = argv + argc + 1;
......@@ -255,25 +259,29 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
__put_user((elf_addr_t)p, argv++);
len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES);
if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
return;
return 0;
p += len;
}
__put_user(0, argv);
if (__put_user(0, argv))
return -EFAULT;
current->mm->arg_end = current->mm->env_start = p;
while (envc-- > 0) {
size_t len;
__put_user((elf_addr_t)p, envp++);
len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES);
if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
return;
return 0;
p += len;
}
__put_user(0, envp);
if (__put_user(0, envp))
return -EFAULT;
current->mm->env_end = p;
/* Put the elf_info on the stack in the right place. */
sp = (elf_addr_t __user *)envp + 1;
copy_to_user(sp, elf_info, ei_index * sizeof(elf_addr_t));
if (copy_to_user(sp, elf_info, ei_index * sizeof(elf_addr_t)))
return -EFAULT;
return 0;
}
#ifndef elf_map
......@@ -407,7 +415,11 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
* that there are zero-mapped pages up to and including the
* last bss page.
*/
padzero(elf_bss);
if (padzero(elf_bss)) {
error = -EFAULT;
goto out_close;
}
elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); /* What we have mapped so far */
/* Map the last of the bss segment */
......@@ -787,7 +799,11 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
nbyte = ELF_MIN_ALIGN - nbyte;
if (nbyte > elf_brk - elf_bss)
nbyte = elf_brk - elf_bss;
clear_user((void __user *) elf_bss + load_bias, nbyte);
if (clear_user((void __user *) elf_bss + load_bias, nbyte)) {
retval = -EFAULT;
send_sig(SIGKILL, current, 0);
goto out_free_dentry;
}
}
}
......@@ -871,7 +887,11 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
send_sig(SIGKILL, current, 0);
goto out_free_dentry;
}
padzero(elf_bss);
if (padzero(elf_bss)) {
send_sig(SIGSEGV, current, 0);
retval = -EFAULT; /* Nobody gets to see this, but.. */
goto out_free_dentry;
}
if (elf_interpreter) {
if (interpreter_type == INTERPRETER_AOUT)
......@@ -1035,7 +1055,10 @@ static int load_elf_library(struct file *file)
goto out_free_ph;
elf_bss = elf_phdata->p_vaddr + elf_phdata->p_filesz;
padzero(elf_bss);
if (padzero(elf_bss)) {
error = -EFAULT;
goto out_free_ph;
}
len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_MIN_ALIGN - 1);
bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
......@@ -1242,8 +1265,8 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
cputime_to_timeval(p->signal->cstime, &prstatus->pr_cstime);
}
static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
struct mm_struct *mm)
static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
struct mm_struct *mm)
{
int i, len;
......@@ -1253,8 +1276,9 @@ static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
len = mm->arg_end - mm->arg_start;
if (len >= ELF_PRARGSZ)
len = ELF_PRARGSZ-1;
copy_from_user(&psinfo->pr_psargs,
(const char __user *)mm->arg_start, len);
if (copy_from_user(&psinfo->pr_psargs,
(const char __user *)mm->arg_start, len))
return -EFAULT;
for(i = 0; i < len; i++)
if (psinfo->pr_psargs[i] == 0)
psinfo->pr_psargs[i] = ' ';
......@@ -1275,7 +1299,7 @@ static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
SET_GID(psinfo->pr_gid, p->gid);
strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
return;
return 0;
}
/* Here is the structure in which status of each thread is captured. */
......
......@@ -645,8 +645,11 @@ int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
/* Don't check these user accesses, just let that get trapped
* in the ioctl handler instead.
*/
copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], IFNAMSIZ);
__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data);
if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
IFNAMSIZ))
return -EFAULT;
if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
return -EFAULT;
return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64);
}
......@@ -2343,7 +2346,9 @@ put_dirent32 (struct dirent *d, struct compat_dirent __user *d32)
__put_user(d->d_ino, &d32->d_ino);
__put_user(d->d_off, &d32->d_off);
__put_user(d->d_reclen, &d32->d_reclen);
__copy_to_user(d32->d_name, d->d_name, d->d_reclen);
if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
return -EFAULT;
return ret;
}
......@@ -2486,7 +2491,8 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
if (cmd == TIOCSSERIAL) {
if (verify_area(VERIFY_READ, ss32, sizeof(SS32)))
return -EFAULT;
__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base));
if (__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base)))
return -EFAULT;
__get_user(udata, &ss32->iomem_base);
ss.iomem_base = compat_ptr(udata);
__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift);
......@@ -2499,7 +2505,8 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
if (cmd == TIOCGSERIAL && err >= 0) {
if (verify_area(VERIFY_WRITE, ss32, sizeof(SS32)))
return -EFAULT;
__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base));
if (__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base)))
return -EFAULT;
__put_user((unsigned long)ss.iomem_base >> 32 ?
0xffffffff : (unsigned)(unsigned long)ss.iomem_base,
&ss32->iomem_base);
......
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