aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorGuillermo Julián Moreno <guillermo.julian@naudit.es>2016-06-03 17:55:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-06-03 18:06:22 -0400
commit65ee03c4b9f89e1b088defd97273be6da169d798 (patch)
treeca5bd05b3bc29cf2a5a07f083fd80221049aa06e /mm
parent4340fa55298d17049e71c7a34e04647379c269f3 (diff)
mm: fix overflow in vm_map_ram()
When remapping pages accounting for 4G or more memory space, the operation 'count << PAGE_SHIFT' overflows as it is performed on an integer. Solution: cast before doing the bitshift. [akpm@linux-foundation.org: fix vm_unmap_ram() also] [akpm@linux-foundation.org: fix vmap() as well, per Guillermo] Link: http://lkml.kernel.org/r/etPan.57175fb3.7a271c6b.2bd@naudit.es Signed-off-by: Guillermo Julián Moreno <guillermo.julian@naudit.es> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/vmalloc.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index cf7ad1a53be0..e11475cdeb7a 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1105,7 +1105,7 @@ EXPORT_SYMBOL_GPL(vm_unmap_aliases);
1105 */ 1105 */
1106void vm_unmap_ram(const void *mem, unsigned int count) 1106void vm_unmap_ram(const void *mem, unsigned int count)
1107{ 1107{
1108 unsigned long size = count << PAGE_SHIFT; 1108 unsigned long size = (unsigned long)count << PAGE_SHIFT;
1109 unsigned long addr = (unsigned long)mem; 1109 unsigned long addr = (unsigned long)mem;
1110 1110
1111 BUG_ON(!addr); 1111 BUG_ON(!addr);
@@ -1140,7 +1140,7 @@ EXPORT_SYMBOL(vm_unmap_ram);
1140 */ 1140 */
1141void *vm_map_ram(struct page **pages, unsigned int count, int node, pgprot_t prot) 1141void *vm_map_ram(struct page **pages, unsigned int count, int node, pgprot_t prot)
1142{ 1142{
1143 unsigned long size = count << PAGE_SHIFT; 1143 unsigned long size = (unsigned long)count << PAGE_SHIFT;
1144 unsigned long addr; 1144 unsigned long addr;
1145 void *mem; 1145 void *mem;
1146 1146
@@ -1574,14 +1574,15 @@ void *vmap(struct page **pages, unsigned int count,
1574 unsigned long flags, pgprot_t prot) 1574 unsigned long flags, pgprot_t prot)
1575{ 1575{
1576 struct vm_struct *area; 1576 struct vm_struct *area;
1577 unsigned long size; /* In bytes */
1577 1578
1578 might_sleep(); 1579 might_sleep();
1579 1580
1580 if (count > totalram_pages) 1581 if (count > totalram_pages)
1581 return NULL; 1582 return NULL;
1582 1583
1583 area = get_vm_area_caller((count << PAGE_SHIFT), flags, 1584 size = (unsigned long)count << PAGE_SHIFT;
1584 __builtin_return_address(0)); 1585 area = get_vm_area_caller(size, flags, __builtin_return_address(0));
1585 if (!area) 1586 if (!area)
1586 return NULL; 1587 return NULL;
1587 1588