Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 33808
b: refs/heads/master
c: 3a45975
h: refs/heads/master
v: v3
  • Loading branch information
Kirill Korotaev authored and Linus Torvalds committed Sep 8, 2006
1 parent 31f2642 commit b1c582b
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 43 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 10387e5eb45c6e48d67102b88229f5bc6037461c
refs/heads/master: 3a459756810912d2c2bf188cef566af255936b4d
28 changes: 16 additions & 12 deletions trunk/arch/ia64/kernel/sys_ia64.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,25 @@ sys_pipe (void)
return retval;
}

int ia64_mmap_check(unsigned long addr, unsigned long len,
unsigned long flags)
{
unsigned long roff;

/*
* Don't permit mappings into unmapped space, the virtual page table
* of a region, or across a region boundary. Note: RGN_MAP_LIMIT is
* equal to 2^n-PAGE_SIZE (for some integer n <= 61) and len > 0.
*/
roff = REGION_OFFSET(addr);
if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len)))
return -EINVAL;
return 0;
}

static inline unsigned long
do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff)
{
unsigned long roff;
struct file *file = NULL;

flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
Expand All @@ -188,17 +203,6 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un
goto out;
}

/*
* Don't permit mappings into unmapped space, the virtual page table of a region,
* or across a region boundary. Note: RGN_MAP_LIMIT is equal to 2^n-PAGE_SIZE
* (for some integer n <= 61) and len > 0.
*/
roff = REGION_OFFSET(addr);
if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len))) {
addr = -EINVAL;
goto out;
}

down_write(&current->mm->mmap_sem);
addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(&current->mm->mmap_sem);
Expand Down
27 changes: 15 additions & 12 deletions trunk/arch/sparc/kernel/sys_sparc.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,21 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user
return err;
}

int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
{
if (ARCH_SUN4C_SUN4 &&
(len > 0x20000000 ||
((flags & MAP_FIXED) &&
addr < 0xe0000000 && addr + len > 0x20000000)))
return -EINVAL;

/* See asm-sparc/uaccess.h */
if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
return -EINVAL;

return 0;
}

/* Linux version of mmap */
static unsigned long do_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long fd,
Expand All @@ -233,25 +248,13 @@ static unsigned long do_mmap2(unsigned long addr, unsigned long len,
goto out;
}

retval = -EINVAL;
len = PAGE_ALIGN(len);
if (ARCH_SUN4C_SUN4 &&
(len > 0x20000000 ||
((flags & MAP_FIXED) &&
addr < 0xe0000000 && addr + len > 0x20000000)))
goto out_putf;

/* See asm-sparc/uaccess.h */
if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
goto out_putf;

flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);

down_write(&current->mm->mmap_sem);
retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(&current->mm->mmap_sem);

out_putf:
if (file)
fput(file);
out:
Expand Down
36 changes: 20 additions & 16 deletions trunk/arch/sparc64/kernel/sys_sparc.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,26 @@ asmlinkage long sparc64_personality(unsigned long personality)
return ret;
}

int sparc64_mmap_check(unsigned long addr, unsigned long len,
unsigned long flags)
{
if (test_thread_flag(TIF_32BIT)) {
if (len >= STACK_TOP32)
return -EINVAL;

if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len)
return -EINVAL;
} else {
if (len >= VA_EXCLUDE_START)
return -EINVAL;

if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len))
return -EINVAL;
}

return 0;
}

/* Linux version of mmap */
asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long fd,
Expand All @@ -563,27 +583,11 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
len = PAGE_ALIGN(len);
retval = -EINVAL;

if (test_thread_flag(TIF_32BIT)) {
if (len >= STACK_TOP32)
goto out_putf;

if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len)
goto out_putf;
} else {
if (len >= VA_EXCLUDE_START)
goto out_putf;

if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len))
goto out_putf;
}

down_write(&current->mm->mmap_sem);
retval = do_mmap(file, addr, len, prot, flags, off);
up_write(&current->mm->mmap_sem);

out_putf:
if (file)
fput(file);
out:
Expand Down
8 changes: 8 additions & 0 deletions trunk/include/asm-ia64/mman.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,12 @@
#define MCL_CURRENT 1 /* lock all current mappings */
#define MCL_FUTURE 2 /* lock all future mappings */

#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#define arch_mmap_check ia64_mmap_check
int ia64_mmap_check(unsigned long addr, unsigned long len,
unsigned long flags);
#endif
#endif

#endif /* _ASM_IA64_MMAN_H */
8 changes: 8 additions & 0 deletions trunk/include/asm-sparc/mman.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,12 @@

#define MADV_FREE 0x5 /* (Solaris) contents can be freed */

#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#define arch_mmap_check sparc_mmap_check
int sparc_mmap_check(unsigned long addr, unsigned long len,
unsigned long flags);
#endif
#endif

#endif /* __SPARC_MMAN_H__ */
8 changes: 8 additions & 0 deletions trunk/include/asm-sparc64/mman.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,12 @@

#define MADV_FREE 0x5 /* (Solaris) contents can be freed */

#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#define arch_mmap_check sparc64_mmap_check
int sparc64_mmap_check(unsigned long addr, unsigned long len,
unsigned long flags);
#endif
#endif

#endif /* __SPARC64_MMAN_H__ */
17 changes: 15 additions & 2 deletions trunk/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#include <asm/cacheflush.h>
#include <asm/tlb.h>

#ifndef arch_mmap_check
#define arch_mmap_check(addr, len, flags) (0)
#endif

static void unmap_region(struct mm_struct *mm,
struct vm_area_struct *vma, struct vm_area_struct *prev,
unsigned long start, unsigned long end);
Expand Down Expand Up @@ -913,6 +917,10 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
if (!len)
return -EINVAL;

error = arch_mmap_check(addr, len, flags);
if (error)
return error;

/* Careful about overflows.. */
len = PAGE_ALIGN(len);
if (!len || len > TASK_SIZE)
Expand Down Expand Up @@ -1859,6 +1867,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
unsigned long flags;
struct rb_node ** rb_link, * rb_parent;
pgoff_t pgoff = addr >> PAGE_SHIFT;
int error;

len = PAGE_ALIGN(len);
if (!len)
Expand All @@ -1867,6 +1876,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
if ((addr + len) > TASK_SIZE || (addr + len) < addr)
return -EINVAL;

flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;

error = arch_mmap_check(addr, len, flags);
if (error)
return error;

/*
* mlock MCL_FUTURE?
*/
Expand Down Expand Up @@ -1907,8 +1922,6 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
if (security_vm_enough_memory(len >> PAGE_SHIFT))
return -ENOMEM;

flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;

/* Can we just expand an old private anonymous mapping? */
if (vma_merge(mm, prev, addr, addr + len, flags,
NULL, NULL, pgoff, NULL))
Expand Down

0 comments on commit b1c582b

Please sign in to comment.