| From 93f7463d35a06cdb3866cc614bf3909d236f7390 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 18 May 2022 13:52:23 -0700 |
| Subject: nodemask: Fix return values to be unsigned |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Kees Cook <keescook@chromium.org> |
| |
| [ Upstream commit 0dfe54071d7c828a02917b595456bfde1afdddc9 ] |
| |
| 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> |
| Signed-off-by: Yury Norov <yury.norov@gmail.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/linux/nodemask.h | 38 +++++++++++++++++++------------------- |
| lib/nodemask.c | 4 ++-- |
| 2 files changed, 21 insertions(+), 21 deletions(-) |
| |
| diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h |
| index 7b7155a6c984..3cc98ded3373 100644 |
| --- a/include/linux/nodemask.h |
| +++ b/include/linux/nodemask.h |
| @@ -41,11 +41,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 |
| @@ -143,7 +143,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); |
| } |
| @@ -190,7 +190,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); |
| @@ -198,7 +198,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); |
| @@ -206,20 +206,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); |
| } |
| @@ -250,15 +250,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)); |
| } |
| |
| /* |
| @@ -266,7 +266,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) |
| { |
| @@ -286,9 +286,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)); |
| } |
| |
| @@ -428,11 +428,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 e42a5bf44d33..f6ad9c2775a8 100644 |
| --- a/lib/nodemask.c |
| +++ b/lib/nodemask.c |
| @@ -2,9 +2,9 @@ |
| #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); |
| + unsigned int ret = __next_node(node, srcp); |
| |
| if (ret == MAX_NUMNODES) |
| ret = __first_node(srcp); |
| -- |
| 2.35.1 |
| |