linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] bitmap: Fix return values to be unsigned
@ 2022-05-17 21:22 Kees Cook
  2022-05-17 21:22 ` [PATCH v2 1/2] " Kees Cook
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Kees Cook @ 2022-05-17 21:22 UTC (permalink / raw)
  To: Yury Norov
  Cc: Kees Cook, Christophe de Dinechin, Rasmus Villemoes,
	Alexey Dobriyan, Andy Shevchenko, Andrew Morton, Zhen Lei,
	linux-kernel, linux-hardening

Hi,

As mentioned in the last patch:

Both nodemask and bitmap routines had mixed return values that provided
potentially signed results that could never happen. This was leading to
the compiler getting confusing about the range of possible return values
(it was thinking things could be negative where they could not be). Fix
all the nodemask and bitmap routines that should be returning unsigned
(or bool) values. Silences GCC 12 warnings:

 mm/swapfile.c: In function ‘setup_swap_info’:
 mm/swapfile.c:2291:47: error: array subscript -1 is below array bounds of ‘struct plist_node[]’ [-Werror=array-bounds]
  2291 |                                 p->avail_lists[i].prio = 1;
       |                                 ~~~~~~~~~~~~~~^~~
 In file included from mm/swapfile.c:16:
 ./include/linux/swap.h:292:27: note: while referencing ‘avail_lists’
   292 |         struct plist_node avail_lists[]; /*
       |                           ^~~~~~~~~~~

This splits up the patch into the bitmap and nodemask halves, and drops
a needless change to the random node helper.

I note that Alexey and Rasmus touched on this area in the past, fixing
up node ids to be unsigned:

ce0725f78a56 ("numa: make "nr_online_nodes" unsigned int")
b9726c26dc21 ("numa: make "nr_node_ids" unsigned int")
33c4fa8c6763 ("linux/nodemask.h: update bitmap wrappers to take unsigned int")

If anyone else would like to carry this, please let me know. I'm happy
to carry it in my tree.

-Kees

Kees Cook (2):
  bitmap: Fix return values to be unsigned
  nodemask: Fix return values to be unsigned

 include/linux/bitmap.h   | 14 +++++++-------
 include/linux/nodemask.h | 38 +++++++++++++++++++-------------------
 lib/bitmap.c             | 28 ++++++++++++++--------------
 lib/nodemask.c           |  2 +-
 4 files changed, 41 insertions(+), 41 deletions(-)

-- 
2.32.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/2] bitmap: Fix return values to be unsigned
  2022-05-17 21:22 [PATCH v2 0/2] bitmap: Fix return values to be unsigned Kees Cook
@ 2022-05-17 21:22 ` Kees Cook
  2022-05-17 21:22 ` [PATCH v2 2/2] nodemask: " Kees Cook
  2022-05-17 22:21 ` [PATCH v2 0/2] bitmap: " Yury Norov
  2 siblings, 0 replies; 6+ messages in thread
From: Kees Cook @ 2022-05-17 21:22 UTC (permalink / raw)
  To: Yury Norov
  Cc: Kees Cook, Rasmus Villemoes, Christophe de Dinechin,
	Alexey Dobriyan, Andy Shevchenko, Andrew Morton, Zhen Lei,
	linux-kernel, linux-hardening

Both nodemask and bitmap routines had mixed return values that provided
potentially signed return values that could never happen. This was
leading to the compiler getting confusing about the range of possible
return values (it was thinking things could be negative where they could
not be). In preparation for fixing nodemask, fix all the bitmap routines
that should be returning unsigned (or bool) values.

Cc: Yury Norov <yury.norov@gmail.com>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Christophe de Dinechin <dinechin@redhat.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Zhen Lei <thunder.leizhen@huawei.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 include/linux/bitmap.h | 14 +++++++-------
 lib/bitmap.c           | 28 ++++++++++++++--------------
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 7dba0847510c..381735c2f2f1 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -132,8 +132,8 @@ unsigned long *devm_bitmap_zalloc(struct device *dev,
  * lib/bitmap.c provides these functions:
  */
 
-int __bitmap_equal(const unsigned long *bitmap1,
-		   const unsigned long *bitmap2, unsigned int nbits);
+bool __bitmap_equal(const unsigned long *bitmap1,
+		    const unsigned long *bitmap2, unsigned int nbits);
 bool __pure __bitmap_or_equal(const unsigned long *src1,
 			      const unsigned long *src2,
 			      const unsigned long *src3,
@@ -157,10 +157,10 @@ int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
 void __bitmap_replace(unsigned long *dst,
 		      const unsigned long *old, const unsigned long *new,
 		      const unsigned long *mask, unsigned int nbits);
-int __bitmap_intersects(const unsigned long *bitmap1,
-			const unsigned long *bitmap2, unsigned int nbits);
-int __bitmap_subset(const unsigned long *bitmap1,
-		    const unsigned long *bitmap2, unsigned int nbits);
+bool __bitmap_intersects(const unsigned long *bitmap1,
+			 const unsigned long *bitmap2, unsigned int nbits);
+bool __bitmap_subset(const unsigned long *bitmap1,
+		     const unsigned long *bitmap2, unsigned int nbits);
 int __bitmap_weight(const unsigned long *bitmap, unsigned int nbits);
 void __bitmap_set(unsigned long *map, unsigned int start, int len);
 void __bitmap_clear(unsigned long *map, unsigned int start, int len);
@@ -331,7 +331,7 @@ static inline void bitmap_complement(unsigned long *dst, const unsigned long *sr
 #endif
 #define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1)
 
-static inline int bitmap_equal(const unsigned long *src1,
+static inline bool bitmap_equal(const unsigned long *src1,
 			const unsigned long *src2, unsigned int nbits)
 {
 	if (small_const_nbits(nbits))
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 0d5c2ece0bcb..b57dafe13eec 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -45,19 +45,19 @@
  * for the best explanations of this ordering.
  */
 
-int __bitmap_equal(const unsigned long *bitmap1,
+bool __bitmap_equal(const unsigned long *bitmap1,
 		const unsigned long *bitmap2, unsigned int bits)
 {
 	unsigned int k, lim = bits/BITS_PER_LONG;
 	for (k = 0; k < lim; ++k)
 		if (bitmap1[k] != bitmap2[k])
-			return 0;
+			return false;
 
 	if (bits % BITS_PER_LONG)
 		if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
-			return 0;
+			return false;
 
-	return 1;
+	return true;
 }
 EXPORT_SYMBOL(__bitmap_equal);
 
@@ -303,33 +303,33 @@ void __bitmap_replace(unsigned long *dst,
 }
 EXPORT_SYMBOL(__bitmap_replace);
 
-int __bitmap_intersects(const unsigned long *bitmap1,
-			const unsigned long *bitmap2, unsigned int bits)
+bool __bitmap_intersects(const unsigned long *bitmap1,
+			 const unsigned long *bitmap2, unsigned int bits)
 {
 	unsigned int k, lim = bits/BITS_PER_LONG;
 	for (k = 0; k < lim; ++k)
 		if (bitmap1[k] & bitmap2[k])
-			return 1;
+			return true;
 
 	if (bits % BITS_PER_LONG)
 		if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
-			return 1;
-	return 0;
+			return true;
+	return false;
 }
 EXPORT_SYMBOL(__bitmap_intersects);
 
-int __bitmap_subset(const unsigned long *bitmap1,
-		    const unsigned long *bitmap2, unsigned int bits)
+bool __bitmap_subset(const unsigned long *bitmap1,
+		     const unsigned long *bitmap2, unsigned int bits)
 {
 	unsigned int k, lim = bits/BITS_PER_LONG;
 	for (k = 0; k < lim; ++k)
 		if (bitmap1[k] & ~bitmap2[k])
-			return 0;
+			return false;
 
 	if (bits % BITS_PER_LONG)
 		if ((bitmap1[k] & ~bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
-			return 0;
-	return 1;
+			return false;
+	return true;
 }
 EXPORT_SYMBOL(__bitmap_subset);
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] nodemask: Fix return values to be unsigned
  2022-05-17 21:22 [PATCH v2 0/2] bitmap: Fix return values to be unsigned Kees Cook
  2022-05-17 21:22 ` [PATCH v2 1/2] " Kees Cook
@ 2022-05-17 21:22 ` Kees Cook
  2022-05-17 22:15   ` Yury Norov
  2022-05-17 22:21 ` [PATCH v2 0/2] bitmap: " Yury Norov
  2 siblings, 1 reply; 6+ messages in thread
From: Kees Cook @ 2022-05-17 21:22 UTC (permalink / raw)
  To: Yury Norov
  Cc: Kees Cook, Christophe de Dinechin, Alexey Dobriyan,
	Andy Shevchenko, Rasmus Villemoes, Andrew Morton, Zhen Lei,
	linux-kernel, linux-hardening

The nodemask routines had mixed return values that provided potentially
signed return values that could never happen. This was leading to the
compiler getting confusing about the range of possible return values
(it was thinking things could be negative where they could not be). Fix
all the nodemask routines that should be returning unsigned
(or bool) values. Silences:

 mm/swapfile.c: In function ‘setup_swap_info’:
 mm/swapfile.c:2291:47: error: array subscript -1 is below array bounds of ‘struct plist_node[]’ [-Werror=array-bounds]
  2291 |                                 p->avail_lists[i].prio = 1;
       |                                 ~~~~~~~~~~~~~~^~~
 In file included from mm/swapfile.c:16:
 ./include/linux/swap.h:292:27: note: while referencing ‘avail_lists’
   292 |         struct plist_node avail_lists[]; /*
       |                           ^~~~~~~~~~~

Reported-by: Christophe de Dinechin <dinechin@redhat.com>
Link: https://lore.kernel.org/lkml/20220414150855.2407137-3-dinechin@redhat.com/
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Yury Norov <yury.norov@gmail.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Zhen Lei <thunder.leizhen@huawei.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 include/linux/nodemask.h | 38 +++++++++++++++++++-------------------
 lib/nodemask.c           |  2 +-
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 567c3ddba2c4..2c39663c3407 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -42,11 +42,11 @@
  * void nodes_shift_right(dst, src, n)	Shift right
  * void nodes_shift_left(dst, src, n)	Shift left
  *
- * int first_node(mask)			Number lowest set bit, or MAX_NUMNODES
- * int next_node(node, mask)		Next node past 'node', or MAX_NUMNODES
- * int next_node_in(node, mask)		Next node past 'node', or wrap to first,
+ * unsigned int first_node(mask)	Number lowest set bit, or MAX_NUMNODES
+ * unsigend int next_node(node, mask)	Next node past 'node', or MAX_NUMNODES
+ * unsigned int next_node_in(node, mask) Next node past 'node', or wrap to first,
  *					or MAX_NUMNODES
- * int first_unset_node(mask)		First node not set in mask, or 
+ * unsigned int first_unset_node(mask)	First node not set in mask, or
  *					MAX_NUMNODES
  *
  * nodemask_t nodemask_of_node(node)	Return nodemask with bit 'node' set
@@ -153,7 +153,7 @@ static inline void __nodes_clear(nodemask_t *dstp, unsigned int nbits)
 
 #define node_test_and_set(node, nodemask) \
 			__node_test_and_set((node), &(nodemask))
-static inline int __node_test_and_set(int node, nodemask_t *addr)
+static inline bool __node_test_and_set(int node, nodemask_t *addr)
 {
 	return test_and_set_bit(node, addr->bits);
 }
@@ -200,7 +200,7 @@ static inline void __nodes_complement(nodemask_t *dstp,
 
 #define nodes_equal(src1, src2) \
 			__nodes_equal(&(src1), &(src2), MAX_NUMNODES)
-static inline int __nodes_equal(const nodemask_t *src1p,
+static inline bool __nodes_equal(const nodemask_t *src1p,
 					const nodemask_t *src2p, unsigned int nbits)
 {
 	return bitmap_equal(src1p->bits, src2p->bits, nbits);
@@ -208,7 +208,7 @@ static inline int __nodes_equal(const nodemask_t *src1p,
 
 #define nodes_intersects(src1, src2) \
 			__nodes_intersects(&(src1), &(src2), MAX_NUMNODES)
-static inline int __nodes_intersects(const nodemask_t *src1p,
+static inline bool __nodes_intersects(const nodemask_t *src1p,
 					const nodemask_t *src2p, unsigned int nbits)
 {
 	return bitmap_intersects(src1p->bits, src2p->bits, nbits);
@@ -216,20 +216,20 @@ static inline int __nodes_intersects(const nodemask_t *src1p,
 
 #define nodes_subset(src1, src2) \
 			__nodes_subset(&(src1), &(src2), MAX_NUMNODES)
-static inline int __nodes_subset(const nodemask_t *src1p,
+static inline bool __nodes_subset(const nodemask_t *src1p,
 					const nodemask_t *src2p, unsigned int nbits)
 {
 	return bitmap_subset(src1p->bits, src2p->bits, nbits);
 }
 
 #define nodes_empty(src) __nodes_empty(&(src), MAX_NUMNODES)
-static inline int __nodes_empty(const nodemask_t *srcp, unsigned int nbits)
+static inline bool __nodes_empty(const nodemask_t *srcp, unsigned int nbits)
 {
 	return bitmap_empty(srcp->bits, nbits);
 }
 
 #define nodes_full(nodemask) __nodes_full(&(nodemask), MAX_NUMNODES)
-static inline int __nodes_full(const nodemask_t *srcp, unsigned int nbits)
+static inline bool __nodes_full(const nodemask_t *srcp, unsigned int nbits)
 {
 	return bitmap_full(srcp->bits, nbits);
 }
@@ -260,15 +260,15 @@ static inline void __nodes_shift_left(nodemask_t *dstp,
           > MAX_NUMNODES, then the silly min_ts could be dropped. */
 
 #define first_node(src) __first_node(&(src))
-static inline int __first_node(const nodemask_t *srcp)
+static inline unsigned int __first_node(const nodemask_t *srcp)
 {
-	return min_t(int, MAX_NUMNODES, find_first_bit(srcp->bits, MAX_NUMNODES));
+	return min_t(unsigned int, MAX_NUMNODES, find_first_bit(srcp->bits, MAX_NUMNODES));
 }
 
 #define next_node(n, src) __next_node((n), &(src))
-static inline int __next_node(int n, const nodemask_t *srcp)
+static inline unsigned int __next_node(int n, const nodemask_t *srcp)
 {
-	return min_t(int,MAX_NUMNODES,find_next_bit(srcp->bits, MAX_NUMNODES, n+1));
+	return min_t(unsigned int, MAX_NUMNODES, find_next_bit(srcp->bits, MAX_NUMNODES, n+1));
 }
 
 /*
@@ -276,7 +276,7 @@ static inline int __next_node(int n, const nodemask_t *srcp)
  * the first node in src if needed.  Returns MAX_NUMNODES if src is empty.
  */
 #define next_node_in(n, src) __next_node_in((n), &(src))
-int __next_node_in(int node, const nodemask_t *srcp);
+unsigned int __next_node_in(int node, const nodemask_t *srcp);
 
 static inline void init_nodemask_of_node(nodemask_t *mask, int node)
 {
@@ -296,9 +296,9 @@ static inline void init_nodemask_of_node(nodemask_t *mask, int node)
 })
 
 #define first_unset_node(mask) __first_unset_node(&(mask))
-static inline int __first_unset_node(const nodemask_t *maskp)
+static inline unsigned int __first_unset_node(const nodemask_t *maskp)
 {
-	return min_t(int,MAX_NUMNODES,
+	return min_t(unsigned int, MAX_NUMNODES,
 			find_first_zero_bit(maskp->bits, MAX_NUMNODES));
 }
 
@@ -436,11 +436,11 @@ static inline int num_node_state(enum node_states state)
 
 #define first_online_node	first_node(node_states[N_ONLINE])
 #define first_memory_node	first_node(node_states[N_MEMORY])
-static inline int next_online_node(int nid)
+static inline unsigned int next_online_node(int nid)
 {
 	return next_node(nid, node_states[N_ONLINE]);
 }
-static inline int next_memory_node(int nid)
+static inline unsigned int next_memory_node(int nid)
 {
 	return next_node(nid, node_states[N_MEMORY]);
 }
diff --git a/lib/nodemask.c b/lib/nodemask.c
index 3aa454c54c0d..a334cf722189 100644
--- a/lib/nodemask.c
+++ b/lib/nodemask.c
@@ -3,7 +3,7 @@
 #include <linux/module.h>
 #include <linux/random.h>
 
-int __next_node_in(int node, const nodemask_t *srcp)
+unsigned int __next_node_in(int node, const nodemask_t *srcp)
 {
 	int ret = __next_node(node, srcp);
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] nodemask: Fix return values to be unsigned
  2022-05-17 21:22 ` [PATCH v2 2/2] nodemask: " Kees Cook
@ 2022-05-17 22:15   ` Yury Norov
  0 siblings, 0 replies; 6+ messages in thread
From: Yury Norov @ 2022-05-17 22:15 UTC (permalink / raw)
  To: Kees Cook
  Cc: Christophe de Dinechin, Alexey Dobriyan, Andy Shevchenko,
	Rasmus Villemoes, Andrew Morton, Zhen Lei, linux-kernel,
	linux-hardening

On Tue, May 17, 2022 at 02:22:34PM -0700, Kees Cook wrote:
> The nodemask routines had mixed return values that provided potentially
> signed return values that could never happen. This was leading to the
> compiler getting confusing about the range of possible return values
> (it was thinking things could be negative where they could not be). Fix
> all the nodemask routines that should be returning unsigned
> (or bool) values. Silences:
> 
>  mm/swapfile.c: In function ‘setup_swap_info’:
>  mm/swapfile.c:2291:47: error: array subscript -1 is below array bounds of ‘struct plist_node[]’ [-Werror=array-bounds]
>   2291 |                                 p->avail_lists[i].prio = 1;
>        |                                 ~~~~~~~~~~~~~~^~~
>  In file included from mm/swapfile.c:16:
>  ./include/linux/swap.h:292:27: note: while referencing ‘avail_lists’
>    292 |         struct plist_node avail_lists[]; /*
>        |                           ^~~~~~~~~~~
> 
> Reported-by: Christophe de Dinechin <dinechin@redhat.com>
> Link: https://lore.kernel.org/lkml/20220414150855.2407137-3-dinechin@redhat.com/
> Cc: Alexey Dobriyan <adobriyan@gmail.com>
> Cc: Yury Norov <yury.norov@gmail.com>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Zhen Lei <thunder.leizhen@huawei.com>
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  include/linux/nodemask.h | 38 +++++++++++++++++++-------------------
>  lib/nodemask.c           |  2 +-
>  2 files changed, 20 insertions(+), 20 deletions(-)
> 
> diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
> index 567c3ddba2c4..2c39663c3407 100644
> --- a/include/linux/nodemask.h
> +++ b/include/linux/nodemask.h
> @@ -42,11 +42,11 @@
>   * void nodes_shift_right(dst, src, n)	Shift right
>   * void nodes_shift_left(dst, src, n)	Shift left
>   *
> - * int first_node(mask)			Number lowest set bit, or MAX_NUMNODES
> - * int next_node(node, mask)		Next node past 'node', or MAX_NUMNODES
> - * int next_node_in(node, mask)		Next node past 'node', or wrap to first,
> + * unsigned int first_node(mask)	Number lowest set bit, or MAX_NUMNODES
> + * unsigend int next_node(node, mask)	Next node past 'node', or MAX_NUMNODES
> + * unsigned int next_node_in(node, mask) Next node past 'node', or wrap to first,
>   *					or MAX_NUMNODES
> - * int first_unset_node(mask)		First node not set in mask, or 
> + * unsigned int first_unset_node(mask)	First node not set in mask, or
>   *					MAX_NUMNODES
>   *
>   * nodemask_t nodemask_of_node(node)	Return nodemask with bit 'node' set
> @@ -153,7 +153,7 @@ static inline void __nodes_clear(nodemask_t *dstp, unsigned int nbits)
>  
>  #define node_test_and_set(node, nodemask) \
>  			__node_test_and_set((node), &(nodemask))
> -static inline int __node_test_and_set(int node, nodemask_t *addr)
> +static inline bool __node_test_and_set(int node, nodemask_t *addr)
>  {
>  	return test_and_set_bit(node, addr->bits);
>  }
> @@ -200,7 +200,7 @@ static inline void __nodes_complement(nodemask_t *dstp,
>  
>  #define nodes_equal(src1, src2) \
>  			__nodes_equal(&(src1), &(src2), MAX_NUMNODES)
> -static inline int __nodes_equal(const nodemask_t *src1p,
> +static inline bool __nodes_equal(const nodemask_t *src1p,
>  					const nodemask_t *src2p, unsigned int nbits)
>  {
>  	return bitmap_equal(src1p->bits, src2p->bits, nbits);
> @@ -208,7 +208,7 @@ static inline int __nodes_equal(const nodemask_t *src1p,
>  
>  #define nodes_intersects(src1, src2) \
>  			__nodes_intersects(&(src1), &(src2), MAX_NUMNODES)
> -static inline int __nodes_intersects(const nodemask_t *src1p,
> +static inline bool __nodes_intersects(const nodemask_t *src1p,
>  					const nodemask_t *src2p, unsigned int nbits)
>  {
>  	return bitmap_intersects(src1p->bits, src2p->bits, nbits);
> @@ -216,20 +216,20 @@ static inline int __nodes_intersects(const nodemask_t *src1p,
>  
>  #define nodes_subset(src1, src2) \
>  			__nodes_subset(&(src1), &(src2), MAX_NUMNODES)
> -static inline int __nodes_subset(const nodemask_t *src1p,
> +static inline bool __nodes_subset(const nodemask_t *src1p,
>  					const nodemask_t *src2p, unsigned int nbits)
>  {
>  	return bitmap_subset(src1p->bits, src2p->bits, nbits);
>  }
>  
>  #define nodes_empty(src) __nodes_empty(&(src), MAX_NUMNODES)
> -static inline int __nodes_empty(const nodemask_t *srcp, unsigned int nbits)
> +static inline bool __nodes_empty(const nodemask_t *srcp, unsigned int nbits)
>  {
>  	return bitmap_empty(srcp->bits, nbits);
>  }
>  
>  #define nodes_full(nodemask) __nodes_full(&(nodemask), MAX_NUMNODES)
> -static inline int __nodes_full(const nodemask_t *srcp, unsigned int nbits)
> +static inline bool __nodes_full(const nodemask_t *srcp, unsigned int nbits)
>  {
>  	return bitmap_full(srcp->bits, nbits);
>  }
> @@ -260,15 +260,15 @@ static inline void __nodes_shift_left(nodemask_t *dstp,
>            > MAX_NUMNODES, then the silly min_ts could be dropped. */
>  
>  #define first_node(src) __first_node(&(src))
> -static inline int __first_node(const nodemask_t *srcp)
> +static inline unsigned int __first_node(const nodemask_t *srcp)
>  {
> -	return min_t(int, MAX_NUMNODES, find_first_bit(srcp->bits, MAX_NUMNODES));
> +	return min_t(unsigned int, MAX_NUMNODES, find_first_bit(srcp->bits, MAX_NUMNODES));
>  }
>  
>  #define next_node(n, src) __next_node((n), &(src))
> -static inline int __next_node(int n, const nodemask_t *srcp)
> +static inline unsigned int __next_node(int n, const nodemask_t *srcp)
>  {
> -	return min_t(int,MAX_NUMNODES,find_next_bit(srcp->bits, MAX_NUMNODES, n+1));
> +	return min_t(unsigned int, MAX_NUMNODES, find_next_bit(srcp->bits, MAX_NUMNODES, n+1));
>  }
>  
>  /*
> @@ -276,7 +276,7 @@ static inline int __next_node(int n, const nodemask_t *srcp)
>   * the first node in src if needed.  Returns MAX_NUMNODES if src is empty.
>   */
>  #define next_node_in(n, src) __next_node_in((n), &(src))
> -int __next_node_in(int node, const nodemask_t *srcp);
> +unsigned int __next_node_in(int node, const nodemask_t *srcp);
>  
>  static inline void init_nodemask_of_node(nodemask_t *mask, int node)
>  {
> @@ -296,9 +296,9 @@ static inline void init_nodemask_of_node(nodemask_t *mask, int node)
>  })
>  
>  #define first_unset_node(mask) __first_unset_node(&(mask))
> -static inline int __first_unset_node(const nodemask_t *maskp)
> +static inline unsigned int __first_unset_node(const nodemask_t *maskp)
>  {
> -	return min_t(int,MAX_NUMNODES,
> +	return min_t(unsigned int, MAX_NUMNODES,
>  			find_first_zero_bit(maskp->bits, MAX_NUMNODES));
>  }
>  
> @@ -436,11 +436,11 @@ static inline int num_node_state(enum node_states state)
>  
>  #define first_online_node	first_node(node_states[N_ONLINE])
>  #define first_memory_node	first_node(node_states[N_MEMORY])
> -static inline int next_online_node(int nid)
> +static inline unsigned int next_online_node(int nid)
>  {
>  	return next_node(nid, node_states[N_ONLINE]);
>  }
> -static inline int next_memory_node(int nid)
> +static inline unsigned int next_memory_node(int nid)
>  {
>  	return next_node(nid, node_states[N_MEMORY]);
>  }
> diff --git a/lib/nodemask.c b/lib/nodemask.c
> index 3aa454c54c0d..a334cf722189 100644
> --- a/lib/nodemask.c
> +++ b/lib/nodemask.c
> @@ -3,7 +3,7 @@
>  #include <linux/module.h>
>  #include <linux/random.h>
>  
> -int __next_node_in(int node, const nodemask_t *srcp)
> +unsigned int __next_node_in(int node, const nodemask_t *srcp)
>  {
>  	int ret = __next_node(node, srcp);

Now this should be unsigned int, right?
  
> -- 
> 2.32.0

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/2] bitmap: Fix return values to be unsigned
  2022-05-17 21:22 [PATCH v2 0/2] bitmap: Fix return values to be unsigned Kees Cook
  2022-05-17 21:22 ` [PATCH v2 1/2] " Kees Cook
  2022-05-17 21:22 ` [PATCH v2 2/2] nodemask: " Kees Cook
@ 2022-05-17 22:21 ` Yury Norov
  2022-05-18  0:56   ` Kees Cook
  2 siblings, 1 reply; 6+ messages in thread
From: Yury Norov @ 2022-05-17 22:21 UTC (permalink / raw)
  To: Kees Cook
  Cc: Christophe de Dinechin, Rasmus Villemoes, Alexey Dobriyan,
	Andy Shevchenko, Andrew Morton, Zhen Lei, linux-kernel,
	linux-hardening

On Tue, May 17, 2022 at 02:22:32PM -0700, Kees Cook wrote:
> Hi,
> 
> As mentioned in the last patch:
> 
> Both nodemask and bitmap routines had mixed return values that provided
> potentially signed results that could never happen. This was leading to
> the compiler getting confusing about the range of possible return values
> (it was thinking things could be negative where they could not be). Fix
> all the nodemask and bitmap routines that should be returning unsigned
> (or bool) values. Silences GCC 12 warnings:
> 
>  mm/swapfile.c: In function ‘setup_swap_info’:
>  mm/swapfile.c:2291:47: error: array subscript -1 is below array bounds of ‘struct plist_node[]’ [-Werror=array-bounds]
>   2291 |                                 p->avail_lists[i].prio = 1;
>        |                                 ~~~~~~~~~~~~~~^~~
>  In file included from mm/swapfile.c:16:
>  ./include/linux/swap.h:292:27: note: while referencing ‘avail_lists’
>    292 |         struct plist_node avail_lists[]; /*
>        |                           ^~~~~~~~~~~
> 
> This splits up the patch into the bitmap and nodemask halves, and drops
> a needless change to the random node helper.
> 
> I note that Alexey and Rasmus touched on this area in the past, fixing
> up node ids to be unsigned:
> 
> ce0725f78a56 ("numa: make "nr_online_nodes" unsigned int")
> b9726c26dc21 ("numa: make "nr_node_ids" unsigned int")
> 33c4fa8c6763 ("linux/nodemask.h: update bitmap wrappers to take unsigned int")
> 
> If anyone else would like to carry this, please let me know. I'm happy
> to carry it in my tree.

I think it should go thru my tree, if no objections.
 
> -Kees
> 
> Kees Cook (2):
>   bitmap: Fix return values to be unsigned
>   nodemask: Fix return values to be unsigned

Can you please also add patch for tools?

Thanks,
Yury

>  include/linux/bitmap.h   | 14 +++++++-------
>  include/linux/nodemask.h | 38 +++++++++++++++++++-------------------
>  lib/bitmap.c             | 28 ++++++++++++++--------------
>  lib/nodemask.c           |  2 +-
>  4 files changed, 41 insertions(+), 41 deletions(-)
> 
> -- 
> 2.32.0

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/2] bitmap: Fix return values to be unsigned
  2022-05-17 22:21 ` [PATCH v2 0/2] bitmap: " Yury Norov
@ 2022-05-18  0:56   ` Kees Cook
  0 siblings, 0 replies; 6+ messages in thread
From: Kees Cook @ 2022-05-18  0:56 UTC (permalink / raw)
  To: Yury Norov
  Cc: Christophe de Dinechin, Rasmus Villemoes, Alexey Dobriyan,
	Andy Shevchenko, Andrew Morton, Zhen Lei, linux-kernel,
	linux-hardening



On May 17, 2022 3:21:00 PM PDT, Yury Norov <yury.norov@gmail.com> wrote:
>On Tue, May 17, 2022 at 02:22:32PM -0700, Kees Cook wrote:
>> Hi,
>> 
>> As mentioned in the last patch:
>> 
>> Both nodemask and bitmap routines had mixed return values that provided
>> potentially signed results that could never happen. This was leading to
>> the compiler getting confusing about the range of possible return values
>> (it was thinking things could be negative where they could not be). Fix
>> all the nodemask and bitmap routines that should be returning unsigned
>> (or bool) values. Silences GCC 12 warnings:
>> 
>>  mm/swapfile.c: In function ‘setup_swap_info’:
>>  mm/swapfile.c:2291:47: error: array subscript -1 is below array bounds of ‘struct plist_node[]’ [-Werror=array-bounds]
>>   2291 |                                 p->avail_lists[i].prio = 1;
>>        |                                 ~~~~~~~~~~~~~~^~~
>>  In file included from mm/swapfile.c:16:
>>  ./include/linux/swap.h:292:27: note: while referencing ‘avail_lists’
>>    292 |         struct plist_node avail_lists[]; /*
>>        |                           ^~~~~~~~~~~
>> 
>> This splits up the patch into the bitmap and nodemask halves, and drops
>> a needless change to the random node helper.
>> 
>> I note that Alexey and Rasmus touched on this area in the past, fixing
>> up node ids to be unsigned:
>> 
>> ce0725f78a56 ("numa: make "nr_online_nodes" unsigned int")
>> b9726c26dc21 ("numa: make "nr_node_ids" unsigned int")
>> 33c4fa8c6763 ("linux/nodemask.h: update bitmap wrappers to take unsigned int")
>> 
>> If anyone else would like to carry this, please let me know. I'm happy
>> to carry it in my tree.
>
>I think it should go thru my tree, if no objections.

Sure thing! Thanks for the review. I'll send a v3 with the variable updated and tools/ refreshed.

-Kees


-- 
Kees Cook

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-05-18  0:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-17 21:22 [PATCH v2 0/2] bitmap: Fix return values to be unsigned Kees Cook
2022-05-17 21:22 ` [PATCH v2 1/2] " Kees Cook
2022-05-17 21:22 ` [PATCH v2 2/2] nodemask: " Kees Cook
2022-05-17 22:15   ` Yury Norov
2022-05-17 22:21 ` [PATCH v2 0/2] bitmap: " Yury Norov
2022-05-18  0:56   ` Kees Cook

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).