FAILED: patch "[PATCH] XArray: Fix xa_find_next for large multi-index entries" failed to apply to 5.6-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From bd40b17ca49d7d110adf456e647701ce74de2241 Mon Sep 17 00:00:00 2001
From: "Matthew Wilcox (Oracle)" <[email protected]>
Date: Fri, 31 Jan 2020 05:07:55 -0500
Subject: [PATCH] XArray: Fix xa_find_next for large multi-index entries
Coverity pointed out that xas_sibling() was shifting xa_offset without promoting it to an unsigned long first, so the shift could cause an overflow and we'd get the wrong answer. The fix is obvious, and the new test-case provokes UBSAN to report an error:
runtime error: shift exponent 60 is too large for 32-bit type 'int'
lib/test_xarray.c +18 -0
@@ -12,6 +12,9 @@static unsigned int tests_run;static unsigned int tests_passed; +static const unsigned int order_limit = +IS_ENABLED (CONFIG_XARRAY_MULTI ) ?BITS_PER_LONG :1 ; +#ifndef XA_DEBUG # ifdef __KERNEL__void xa_dump (const struct xarray *xa) { }
@@ -959,6 +962,20 @@ static noinline void check_multi_find_2(struct xarray *xa) } } +static noinline void check_multi_find_3(struct xarray *xa) +{ +unsigned int order; + +for (order =5 ; order < order_limit; order++) { +unsigned long index =1UL << (order -5 ); + +XA_BUG_ON (xa, !xa_empty (xa)); +xa_store_order (xa,0 , order -4 ,xa_mk_index (0 ),GFP_KERNEL ); +XA_BUG_ON (xa,xa_find_after (xa, &index,ULONG_MAX ,XA_PRESENT )); +xa_erase_index (xa,0 ); + } +} + static noinline void check_find_1(struct xarray *xa) {unsigned long i, j, k;
@@ -1081,6 +1098,7 @@ static noinline void check_find(struct xarray *xa)for (i =2 ; i <10 ; i++)check_multi_find_1 (xa, i);check_multi_find_2 (xa); +check_multi_find_3 (xa); }/* See find_swap_entry() in mm/shmem.c */
lib/xarray.c +2 -1
@@ -1839,7 +1839,8 @@ static bool xas_sibling(struct xa_state *xas)if (!node)return false; mask = (XA_CHUNK_SIZE << node->shift) -1 ; -return (xas->xa_index & mask) > (xas->xa_offset << node->shift); +return (xas->xa_index & mask) > + ((unsigned long )xas->xa_offset << node->shift); }/**