lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 06 Feb 2013 19:39:11 -0500
From:	Sasha Levin <sasha.levin@...cle.com>
To:	Michel Lespinasse <walken@...gle.com>
CC:	Andrea Arcangeli <aarcange@...hat.com>,
	Rik van Riel <riel@...hat.com>, Mel Gorman <mgorman@...e.de>,
	Hugh Dickins <hughd@...gle.com>,
	Andrew Morton <akpm@...ux-foundation.org>, linux-mm@...ck.org,
	linux-kernel@...r.kernel.org
Subject: Re: [PATCH 1/3] mm: use long type for page counts in mm_populate()
 and get_user_pages()

Hi Michel,

We're now hitting the VM_BUG_ON() which was added in the last hunk of the
patch:

[  143.217822] ------------[ cut here ]------------
[  143.219938] kernel BUG at mm/mlock.c:424!
[  143.220031] invalid opcode: 0000 [#2] PREEMPT SMP DEBUG_PAGEALLOC
[  143.220031] Modules linked in:
[  143.226691] CPU 3
[  143.226691] Pid: 15435, comm: trinity Tainted: G      D W    3.8.0-rc6-next-20130206-sasha-00029-g95a59cb2 #275
[  143.233222] RIP: 0010:[<ffffffff81242e42>]  [<ffffffff81242e42>] __mm_populate+0x112/0x180
[  143.233222] RSP: 0018:ffff880010061ef8  EFLAGS: 00010246
[  143.233222] RAX: 0000000000000000 RBX: ffff880016329228 RCX: 0000000000000000
[  143.233222] RDX: ffffea0002fe2f80 RSI: 0000000000000000 RDI: ffffea0002fe2f80
[  143.233222] RBP: ffff880010061f48 R08: 0000000000000001 R09: 0000000000000000
[  143.233222] R10: 0000000000000000 R11: ffffea0002fe2f80 R12: 00007ffffffff000
[  143.233222] R13: 00007ff388eb3000 R14: 00007ff388e92000 R15: ffff880009a00000
[  143.233222] FS:  00007ff389085700(0000) GS:ffff88000fc00000(0000) knlGS:0000000000000000
[  143.233222] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  143.233222] CR2: 00007fa6b6aff180 CR3: 000000001002f000 CR4: 00000000000406e0
[  143.303103] can: request_module (can-proto-6) failed.
[  143.233222] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  143.233222] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[  143.321178] Process trinity (pid: 15435, threadinfo ffff880010060000, task ffff8800100a8000)
[  143.321178] Stack:
[  143.321178]  0000000100000001 ffff880009a00098 0000000000000001 00000000100a8000
[  143.321178]  00007ff3890856a8 0000000000000000 0000000000000001 ffff8800100a8000
[  143.321178]  00007ff3890856a8 0000000000000097 ffff880010061f78 ffffffff812431d0
[  143.321178] Call Trace:
[  143.321178]  [<ffffffff812431d0>] sys_mlockall+0x160/0x1a0
[  143.321178]  [<ffffffff83d73d58>] tracesys+0xe1/0xe6
[  143.321178] Code: e8 54 fa ff ff 48 83 f8 00 7d 1e 8b 55 b4 85 d2 75 2f 48 83 f8 f2 bb f4 ff ff ff 74 3e b3 f5 48 83 f8 f4 0f
45 d8 eb 33 90 75 06 <0f> 0b 0f 1f 40 00 48 c1 e0 0c 49 01 c6 eb 0a 0f 1f 80 00 00 00
[  143.392984] RIP  [<ffffffff81242e42>] __mm_populate+0x112/0x180
[  143.392984]  RSP <ffff880010061ef8>
[  143.411359] ---[ end trace a7919e7f17c0a72d ]---


Thanks,
Sasha

On 01/30/2013 07:26 PM, Michel Lespinasse wrote:
> Use long type for page counts in mm_populate() so as to avoid integer
> overflow when running the following test code:
> 
> int main(void) {
>   void *p = mmap(NULL, 0x100000000000, PROT_READ,
>                  MAP_PRIVATE | MAP_ANON, -1, 0);
>   printf("p: %p\n", p);
>   mlockall(MCL_CURRENT);
>   printf("done\n");
>   return 0;
> }
> 
> Signed-off-by: Michel Lespinasse <walken@...gle.com>
> 
> ---
>  include/linux/hugetlb.h |  6 +++---
>  include/linux/mm.h      | 14 +++++++-------
>  mm/hugetlb.c            | 10 +++++-----
>  mm/memory.c             | 14 +++++++-------
>  mm/mlock.c              |  5 +++--
>  5 files changed, 25 insertions(+), 24 deletions(-)
> 
> diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
> index 0c80d3f57a5b..fc6ed17cfd17 100644
> --- a/include/linux/hugetlb.h
> +++ b/include/linux/hugetlb.h
> @@ -43,9 +43,9 @@ int hugetlb_mempolicy_sysctl_handler(struct ctl_table *, int,
>  #endif
>  
>  int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
> -int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *,
> -			struct page **, struct vm_area_struct **,
> -			unsigned long *, int *, int, unsigned int flags);
> +long follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *,
> +			 struct page **, struct vm_area_struct **,
> +			 unsigned long *, long *, long, unsigned int flags);
>  void unmap_hugepage_range(struct vm_area_struct *,
>  			  unsigned long, unsigned long, struct page *);
>  void __unmap_hugepage_range_final(struct mmu_gather *tlb,
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index a224430578f0..d5716094f191 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -1040,13 +1040,13 @@ extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *
>  extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
>  		void *buf, int len, int write);
>  
> -int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
> -		     unsigned long start, int len, unsigned int foll_flags,
> -		     struct page **pages, struct vm_area_struct **vmas,
> -		     int *nonblocking);
> -int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
> -			unsigned long start, int nr_pages, int write, int force,
> -			struct page **pages, struct vm_area_struct **vmas);
> +long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
> +		      unsigned long start, long len, unsigned int foll_flags,
> +		      struct page **pages, struct vm_area_struct **vmas,
> +		      int *nonblocking);
> +long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
> +		    unsigned long start, long nr_pages, int write, int force,
> +		    struct page **pages, struct vm_area_struct **vmas);
>  int get_user_pages_fast(unsigned long start, int nr_pages, int write,
>  			struct page **pages);
>  struct kvec;
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index 4f3ea0b1e57c..4ad07221ce60 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -2924,14 +2924,14 @@ follow_huge_pud(struct mm_struct *mm, unsigned long address,
>  	return NULL;
>  }
>  
> -int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
> -			struct page **pages, struct vm_area_struct **vmas,
> -			unsigned long *position, int *length, int i,
> -			unsigned int flags)
> +long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
> +			 struct page **pages, struct vm_area_struct **vmas,
> +			 unsigned long *position, long *length, long i,
> +			 unsigned int flags)
>  {
>  	unsigned long pfn_offset;
>  	unsigned long vaddr = *position;
> -	int remainder = *length;
> +	long remainder = *length;
>  	struct hstate *h = hstate_vma(vma);
>  
>  	spin_lock(&mm->page_table_lock);
> diff --git a/mm/memory.c b/mm/memory.c
> index f56683208e7f..381b78c20d84 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -1673,12 +1673,12 @@ static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long add
>   * instead of __get_user_pages. __get_user_pages should be used only if
>   * you need some special @gup_flags.
>   */
> -int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
> -		     unsigned long start, int nr_pages, unsigned int gup_flags,
> -		     struct page **pages, struct vm_area_struct **vmas,
> -		     int *nonblocking)
> +long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
> +		unsigned long start, long nr_pages, unsigned int gup_flags,
> +		struct page **pages, struct vm_area_struct **vmas,
> +		int *nonblocking)
>  {
> -	int i;
> +	long i;
>  	unsigned long vm_flags;
>  
>  	if (nr_pages <= 0)
> @@ -1977,8 +1977,8 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
>   *
>   * See also get_user_pages_fast, for performance critical applications.
>   */
> -int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
> -		unsigned long start, int nr_pages, int write, int force,
> +long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
> +		unsigned long start, long nr_pages, int write, int force,
>  		struct page **pages, struct vm_area_struct **vmas)
>  {
>  	int flags = FOLL_TOUCH;
> diff --git a/mm/mlock.c b/mm/mlock.c
> index b1647fbd6bce..e1fa9e4b0a66 100644
> --- a/mm/mlock.c
> +++ b/mm/mlock.c
> @@ -160,7 +160,7 @@ long __mlock_vma_pages_range(struct vm_area_struct *vma,
>  {
>  	struct mm_struct *mm = vma->vm_mm;
>  	unsigned long addr = start;
> -	int nr_pages = (end - start) / PAGE_SIZE;
> +	long nr_pages = (end - start) / PAGE_SIZE;
>  	int gup_flags;
>  
>  	VM_BUG_ON(start & ~PAGE_MASK);
> @@ -378,7 +378,7 @@ int __mm_populate(unsigned long start, unsigned long len, int ignore_errors)
>  	unsigned long end, nstart, nend;
>  	struct vm_area_struct *vma = NULL;
>  	int locked = 0;
> -	int ret = 0;
> +	long ret = 0;
>  
>  	VM_BUG_ON(start & ~PAGE_MASK);
>  	VM_BUG_ON(len != PAGE_ALIGN(len));
> @@ -421,6 +421,7 @@ int __mm_populate(unsigned long start, unsigned long len, int ignore_errors)
>  			ret = __mlock_posix_error_return(ret);
>  			break;
>  		}
> +		VM_BUG_ON(!ret);
>  		nend = nstart + ret * PAGE_SIZE;
>  		ret = 0;
>  	}
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ