Commit 2d6261583be0 ("lib: rework bitmap_parse()") does not take into account order of halfwords on 64-bit big endian architectures.
Fixes: 2d6261583be0 ("lib: rework bitmap_parse()") Cc: stable@vger.kernel.org Cc: Yury Norov yury.norov@gmail.com Cc: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: Amritha Nambiar amritha.nambiar@intel.com Cc: Arnaldo Carvalho de Melo acme@redhat.com Cc: Chris Wilson chris@chris-wilson.co.uk Cc: Kees Cook keescook@chromium.org Cc: Matthew Wilcox willy@infradead.org Cc: Miklos Szeredi mszeredi@redhat.com Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Steffen Klassert steffen.klassert@secunet.com Cc: "Tobin C . Harding" tobin@kernel.org Cc: Vineet Gupta vineet.gupta1@synopsys.com Cc: Will Deacon will.deacon@arm.com Cc: Willem de Bruijn willemb@google.com Signed-off-by: Alexander Gordeev agordeev@linux.ibm.com --- lib/bitmap.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/lib/bitmap.c b/lib/bitmap.c index 89260aa..a725e46 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -717,6 +717,19 @@ static const char *bitmap_get_x32_reverse(const char *start, return end; }
+#if defined(__BIG_ENDIAN) && defined(CONFIG_64BIT) +static void save_x32_chunk(unsigned long *maskp, u32 chunk, int chunk_idx) +{ + maskp += (chunk_idx / 2); + ((u32 *)maskp)[(chunk_idx & 1) ^ 1] = chunk; +} +#else +static void save_x32_chunk(unsigned long *maskp, u32 chunk, int chunk_idx) +{ + ((u32 *)maskp)[chunk_idx] = chunk; +} +#endif + /** * bitmap_parse - convert an ASCII hex string into a bitmap. * @start: pointer to buffer containing string. @@ -738,7 +751,8 @@ int bitmap_parse(const char *start, unsigned int buflen, { const char *end = strnchrnul(start, buflen, '\n') - 1; int chunks = BITS_TO_U32(nmaskbits); - u32 *bitmap = (u32 *)maskp; + int chunk_idx = 0; + u32 chunk; int unset_bit;
while (1) { @@ -749,9 +763,11 @@ int bitmap_parse(const char *start, unsigned int buflen, if (!chunks--) return -EOVERFLOW;
- end = bitmap_get_x32_reverse(start, end, bitmap++); + end = bitmap_get_x32_reverse(start, end, &chunk); if (IS_ERR(end)) return PTR_ERR(end); + + save_x32_chunk(maskp, chunk, chunk_idx++); }
unset_bit = (BITS_TO_U32(nmaskbits) - chunks) * 32;
On Mon, May 18, 2020 at 1:40 PM Alexander Gordeev agordeev@linux.ibm.com wrote:
Commit 2d6261583be0 ("lib: rework bitmap_parse()") does not take into account order of halfwords on 64-bit big endian architectures.
Thanks for report and the patch!
Did it work before? Can we have a test case for that that we will see the failure?
Fixes: 2d6261583be0 ("lib: rework bitmap_parse()") Cc: stable@vger.kernel.org Cc: Yury Norov yury.norov@gmail.com Cc: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: Amritha Nambiar amritha.nambiar@intel.com Cc: Arnaldo Carvalho de Melo acme@redhat.com Cc: Chris Wilson chris@chris-wilson.co.uk Cc: Kees Cook keescook@chromium.org Cc: Matthew Wilcox willy@infradead.org Cc: Miklos Szeredi mszeredi@redhat.com Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Steffen Klassert steffen.klassert@secunet.com Cc: "Tobin C . Harding" tobin@kernel.org Cc: Vineet Gupta vineet.gupta1@synopsys.com Cc: Will Deacon will.deacon@arm.com Cc: Willem de Bruijn willemb@google.com Signed-off-by: Alexander Gordeev agordeev@linux.ibm.com
lib/bitmap.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/lib/bitmap.c b/lib/bitmap.c index 89260aa..a725e46 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -717,6 +717,19 @@ static const char *bitmap_get_x32_reverse(const char *start, return end; }
+#if defined(__BIG_ENDIAN) && defined(CONFIG_64BIT) +static void save_x32_chunk(unsigned long *maskp, u32 chunk, int chunk_idx) +{
maskp += (chunk_idx / 2);
((u32 *)maskp)[(chunk_idx & 1) ^ 1] = chunk;
+} +#else +static void save_x32_chunk(unsigned long *maskp, u32 chunk, int chunk_idx) +{
((u32 *)maskp)[chunk_idx] = chunk;
+} +#endif
/**
- bitmap_parse - convert an ASCII hex string into a bitmap.
- @start: pointer to buffer containing string.
@@ -738,7 +751,8 @@ int bitmap_parse(const char *start, unsigned int buflen, { const char *end = strnchrnul(start, buflen, '\n') - 1; int chunks = BITS_TO_U32(nmaskbits);
u32 *bitmap = (u32 *)maskp;
int chunk_idx = 0;
u32 chunk; int unset_bit; while (1) {
@@ -749,9 +763,11 @@ int bitmap_parse(const char *start, unsigned int buflen, if (!chunks--) return -EOVERFLOW;
end = bitmap_get_x32_reverse(start, end, bitmap++);
end = bitmap_get_x32_reverse(start, end, &chunk); if (IS_ERR(end)) return PTR_ERR(end);
save_x32_chunk(maskp, chunk, chunk_idx++); } unset_bit = (BITS_TO_U32(nmaskbits) - chunks) * 32;
-- 1.8.3.1
On Mon, May 18, 2020 at 2:33 PM Andy Shevchenko andy.shevchenko@gmail.com wrote:
On Mon, May 18, 2020 at 1:40 PM Alexander Gordeev agordeev@linux.ibm.com wrote:
Commit 2d6261583be0 ("lib: rework bitmap_parse()") does not take into account order of halfwords on 64-bit big endian architectures.
Thanks for report and the patch!
Did it work before? Can we have a test case for that that we will see the failure?
Sorry, I wasn't clear enough. I meant a test case that is arch-independent for this very issue (so, that I can run it on LE 64 machine and see a problem).
On Mon, May 18, 2020 at 02:33:43PM +0300, Andy Shevchenko wrote:
On Mon, May 18, 2020 at 1:40 PM Alexander Gordeev agordeev@linux.ibm.com wrote:
Commit 2d6261583be0 ("lib: rework bitmap_parse()") does not take into account order of halfwords on 64-bit big endian architectures.
Thanks for report and the patch!
Did it work before? Can we have a test case for that that we will see the failure?
The test exists and enabled with CONFIG_TEST_BITMAP. It does not appear ever passed before on 64 BE. It does not fail on 64 LE for me either.
Thanks!
[...]
-- With Best Regards, Andy Shevchenko
On Mon, May 18, 2020 at 01:50:59PM +0200, Alexander Gordeev wrote:
On Mon, May 18, 2020 at 02:33:43PM +0300, Andy Shevchenko wrote:
On Mon, May 18, 2020 at 1:40 PM Alexander Gordeev agordeev@linux.ibm.com wrote:
Commit 2d6261583be0 ("lib: rework bitmap_parse()") does not take into account order of halfwords on 64-bit big endian architectures.
Thanks for report and the patch!
Did it work before? Can we have a test case for that that we will see the failure?
The test exists and enabled with CONFIG_TEST_BITMAP. It does not appear ever passed before on 64 BE. It does not fail on 64 LE for me either.
Hi Andy et al,
Any feedback on the fix? Does it work on 64 LE for you?
Thanks!
Thanks!
[...]
-- With Best Regards, Andy Shevchenko
On Tue, Jun 02, 2020 at 12:24:31PM +0200, Alexander Gordeev wrote:
On Mon, May 18, 2020 at 01:50:59PM +0200, Alexander Gordeev wrote:
On Mon, May 18, 2020 at 02:33:43PM +0300, Andy Shevchenko wrote:
On Mon, May 18, 2020 at 1:40 PM Alexander Gordeev agordeev@linux.ibm.com wrote:
Commit 2d6261583be0 ("lib: rework bitmap_parse()") does not take into account order of halfwords on 64-bit big endian architectures.
Thanks for report and the patch!
Did it work before? Can we have a test case for that that we will see the failure?
The test exists and enabled with CONFIG_TEST_BITMAP. It does not appear ever passed before on 64 BE. It does not fail on 64 LE for me either.
Hi Andy et al,
Any feedback on the fix? Does it work on 64 LE for you?
Test case, please.
Yes, you can simulate BE test case on LE platform and vise versa.
On Fri, Jun 05, 2020 at 04:25:58PM +0300, Andy Shevchenko wrote:
Test case, please.
Hi Andy,
Below is the output of the runtime kernel test "test_bitmap". I resent the patch with Andrew Morton on CC, but did not include the excessive test output:
test_bitmap: parse: 4: input is 1, result is 0x100000000, expected 0x1 test_bitmap: parse: 5: input is deadbeef, result is 0xdeadbeef00000000, expected 0xdeadbeef test_bitmap: parse: 6: input is 1,0, result is 0x1, expected 0x100000000 test_bitmap: parse: 7: input is deadbeef,,0,1, result is 0x1, expected 0xdeadbeef test_bitmap: parse: 8: input is deadbeef,1,0, result is 0x1, expected 0x100000000 test_bitmap: parse: 9: input is baadf00d,deadbeef,1,0, result is 0x1, expected 0x100000000 test_bitmap: parse: 10: input is badf00d,deadbeef,1,0, errno is -75, expected 0 test_bitmap: parse: 11: input is badf00d,deadbeef,1,0, errno is -75, expected 0 test_bitmap: parse: 12: input is badf00d,deadbeef,1,0 , errno is -75, expected 0 test_bitmap: parse: 13: input is , badf00d,deadbeef,1,0 , , errno is -75, expected 0 test_bitmap: parse: 14: input is , badf00d, ,, ,,deadbeef,1,0 , , errno is -75, expected 0 test_bitmap: parse: 16: input is 3,0, errno is 0, expected -75 test_bitmap: parse_user: 4: input is 1, result is 0x100000000, expected 0x1 test_bitmap: parse_user: 5: input is deadbeef, result is 0xdeadbeef00000000, expected 0xdeadbeef test_bitmap: parse_user: 6: input is 1,0, result is 0x1, expected 0x100000000 test_bitmap: parse_user: 7: input is deadbeef,,0,1, result is 0x1, expected 0xdeadbeef test_bitmap: parse_user: 8: input is deadbeef,1,0, result is 0x1, expected 0x100000000 test_bitmap: parse_user: 9: input is baadf00d,deadbeef,1,0, result is 0x1, expected 0x100000000 test_bitmap: parse_user: 10: input is badf00d,deadbeef,1,0, errno is -75, expected 0 test_bitmap: parse_user: 11: input is badf00d,deadbeef,1,0, errno is -75, expected 0 test_bitmap: parse_user: 12: input is badf00d,deadbeef,1,0 , errno is -75, expected 0 test_bitmap: parse_user: 13: input is , badf00d,deadbeef,1,0 , , errno is -75, expected 0 test_bitmap: parse_user: 14: input is , badf00d, ,, ,,deadbeef,1,0 , , errno is -75, expected 0 test_bitmap: parse_user: 16: input is 3,0, errno is 0, expected -75
Thanks!
Yes, you can simulate BE test case on LE platform and vise versa.
-- With Best Regards, Andy Shevchenko
linux-stable-mirror@lists.linaro.org