linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: akpm@linux-foundation.org, jiasheng.shi@iluvatar.ai,
	linux-mm@kvack.org, mm-commits@vger.kernel.org,
	sjhuang@iluvatar.ai, torvalds@linux-foundation.org
Subject: [patch 13/16] lib/genalloc: fix the overflow when size is too big
Date: Tue, 29 Dec 2020 15:14:58 -0800	[thread overview]
Message-ID: <20201229231458.Ox75V2Zd-%akpm@linux-foundation.org> (raw)
In-Reply-To: <20201229151349.3285926ec0d1f65a27ac8534@linux-foundation.org>

From: Huang Shijie <sjhuang@iluvatar.ai>
Subject: lib/genalloc: fix the overflow when size is too big

Some graphic card has very big memory on chip, such as 32G bytes.

In the following case, it will cause overflow:
  --------------------------------------------
  pool = gen_pool_create(PAGE_SHIFT, NUMA_NO_NODE);
  ret = gen_pool_add(pool, 0x1000000, SZ_32G, NUMA_NO_NODE);

  va = gen_pool_alloc(pool, SZ_4G);
  --------------------------------------------

The overflow occurs in gen_pool_alloc_algo_owner():

  --------------------------------------------
		....
		size = nbits << order;
		....
  --------------------------------------------

The @nbits is "int" type, so it will overflow.
Then the gen_pool_avail() will return the wrong value.

This patch converts some "int" to "unsigned long", and
changes the compare code in while.

Link: https://lkml.kernel.org/r/20201229060657.3389-1-sjhuang@iluvatar.ai
Signed-off-by: Huang Shijie <sjhuang@iluvatar.ai>
Reported-by: Shi Jiasheng <jiasheng.shi@iluvatar.ai>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 lib/genalloc.c |   25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

--- a/lib/genalloc.c~lib-genalloc-fix-the-overflow-when-size-is-too-big
+++ a/lib/genalloc.c
@@ -81,14 +81,14 @@ static int clear_bits_ll(unsigned long *
  * users set the same bit, one user will return remain bits, otherwise
  * return 0.
  */
-static int bitmap_set_ll(unsigned long *map, int start, int nr)
+static int bitmap_set_ll(unsigned long *map, unsigned long start, unsigned long nr)
 {
 	unsigned long *p = map + BIT_WORD(start);
-	const int size = start + nr;
+	const unsigned long size = start + nr;
 	int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
 	unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
 
-	while (nr - bits_to_set >= 0) {
+	while (nr >= bits_to_set) {
 		if (set_bits_ll(p, mask_to_set))
 			return nr;
 		nr -= bits_to_set;
@@ -116,14 +116,15 @@ static int bitmap_set_ll(unsigned long *
  * users clear the same bit, one user will return remain bits,
  * otherwise return 0.
  */
-static int bitmap_clear_ll(unsigned long *map, int start, int nr)
+static unsigned long
+bitmap_clear_ll(unsigned long *map, unsigned long start, unsigned long nr)
 {
 	unsigned long *p = map + BIT_WORD(start);
-	const int size = start + nr;
+	const unsigned long size = start + nr;
 	int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
 	unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
 
-	while (nr - bits_to_clear >= 0) {
+	while (nr >= bits_to_clear) {
 		if (clear_bits_ll(p, mask_to_clear))
 			return nr;
 		nr -= bits_to_clear;
@@ -183,8 +184,8 @@ int gen_pool_add_owner(struct gen_pool *
 		 size_t size, int nid, void *owner)
 {
 	struct gen_pool_chunk *chunk;
-	int nbits = size >> pool->min_alloc_order;
-	int nbytes = sizeof(struct gen_pool_chunk) +
+	unsigned long nbits = size >> pool->min_alloc_order;
+	unsigned long nbytes = sizeof(struct gen_pool_chunk) +
 				BITS_TO_LONGS(nbits) * sizeof(long);
 
 	chunk = vzalloc_node(nbytes, nid);
@@ -242,7 +243,7 @@ void gen_pool_destroy(struct gen_pool *p
 	struct list_head *_chunk, *_next_chunk;
 	struct gen_pool_chunk *chunk;
 	int order = pool->min_alloc_order;
-	int bit, end_bit;
+	unsigned long bit, end_bit;
 
 	list_for_each_safe(_chunk, _next_chunk, &pool->chunks) {
 		chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
@@ -278,7 +279,7 @@ unsigned long gen_pool_alloc_algo_owner(
 	struct gen_pool_chunk *chunk;
 	unsigned long addr = 0;
 	int order = pool->min_alloc_order;
-	int nbits, start_bit, end_bit, remain;
+	unsigned long nbits, start_bit, end_bit, remain;
 
 #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
 	BUG_ON(in_nmi());
@@ -487,7 +488,7 @@ void gen_pool_free_owner(struct gen_pool
 {
 	struct gen_pool_chunk *chunk;
 	int order = pool->min_alloc_order;
-	int start_bit, nbits, remain;
+	unsigned long start_bit, nbits, remain;
 
 #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
 	BUG_ON(in_nmi());
@@ -755,7 +756,7 @@ unsigned long gen_pool_best_fit(unsigned
 	index = bitmap_find_next_zero_area(map, size, start, nr, 0);
 
 	while (index < size) {
-		int next_bit = find_next_bit(map, size, index + nr);
+		unsigned long next_bit = find_next_bit(map, size, index + nr);
 		if ((next_bit - index) < len) {
 			len = next_bit - index;
 			start_bit = index;
_


  parent reply	other threads:[~2020-12-29 23:15 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-29 23:13 incoming Andrew Morton
2020-12-29 23:14 ` [patch 01/16] selftests/vm: fix building protection keys test Andrew Morton
2020-12-29 23:14 ` [patch 02/16] mm/hugetlb: fix deadlock in hugetlb_cow error path Andrew Morton
2020-12-29 23:14 ` [patch 03/16] Revert "kbuild: avoid static_assert for genksyms" Andrew Morton
2020-12-29 23:14 ` [patch 04/16] checkpatch: prefer strscpy to strlcpy Andrew Morton
2020-12-29 23:14 ` [patch 05/16] mm: add prototype for __add_to_page_cache_locked() Andrew Morton
2020-12-29 23:14 ` [patch 06/16] mm: memmap defer init doesn't work as expected Andrew Morton
2020-12-29 23:14 ` [patch 07/16] mm/mremap.c: fix extent calculation Andrew Morton
2020-12-29 23:14 ` [patch 08/16] mm: generalise COW SMC TLB flushing race comment Andrew Morton
2020-12-29 23:14 ` [patch 09/16] kasan: fix null pointer dereference in kasan_record_aux_stack Andrew Morton
2020-12-29 23:14 ` [patch 10/16] local64.h: make <asm/local64.h> mandatory Andrew Morton
2020-12-29 23:14 ` [patch 11/16] sizes.h: add SZ_8G/SZ_16G/SZ_32G macros Andrew Morton
2020-12-29 23:14 ` [patch 12/16] kdev_t: always inline major/minor helper functions Andrew Morton
2020-12-29 23:14 ` Andrew Morton [this message]
2020-12-29 23:15 ` [patch 14/16] lib/zlib: fix inflating zlib streams on s390 Andrew Morton
2020-12-29 23:15 ` [patch 15/16] zlib: move EXPORT_SYMBOL() and MODULE_LICENSE() out of dfltcc_syms.c Andrew Morton
2020-12-29 23:15 ` [patch 16/16] mm: slub: call account_slab_page() after slab page initialization Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201229231458.Ox75V2Zd-%akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=jiasheng.shi@iluvatar.ai \
    --cc=linux-mm@kvack.org \
    --cc=mm-commits@vger.kernel.org \
    --cc=sjhuang@iluvatar.ai \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).