| From 21c9fb611c25d5cd038f6fe485232e7884bb0b3d Mon Sep 17 00:00:00 2001 |
| From: Arnd Bergmann <arnd@arndb.de> |
| Date: Fri, 5 Apr 2024 16:30:04 +0200 |
| Subject: mtd: diskonchip: work around ubsan link failure |
| |
| From: Arnd Bergmann <arnd@arndb.de> |
| |
| commit 21c9fb611c25d5cd038f6fe485232e7884bb0b3d upstream. |
| |
| I ran into a randconfig build failure with UBSAN using gcc-13.2: |
| |
| arm-linux-gnueabi-ld: error: unplaced orphan section `.bss..Lubsan_data31' from `drivers/mtd/nand/raw/diskonchip.o' |
| |
| I'm not entirely sure what is going on here, but I suspect this has something |
| to do with the check for the end of the doc_locations[] array that contains |
| an (unsigned long)0xffffffff element, which is compared against the signed |
| (int)0xffffffff. If this is the case, we should get a runtime check for |
| undefined behavior, but we instead get an unexpected build-time error. |
| |
| I would have expected this to work fine on 32-bit architectures despite the |
| signed integer overflow, though on 64-bit architectures this likely won't |
| ever work. |
| |
| Changing the contition to instead check for the size of the array makes the |
| code safe everywhere and avoids the ubsan check that leads to the link |
| error. The loop code goes back to before 2.6.12. |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Arnd Bergmann <arnd@arndb.de> |
| Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> |
| Link: https://lore.kernel.org/linux-mtd/20240405143015.717429-1-arnd@kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/mtd/nand/raw/diskonchip.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/mtd/nand/raw/diskonchip.c |
| +++ b/drivers/mtd/nand/raw/diskonchip.c |
| @@ -52,7 +52,7 @@ static unsigned long doc_locations[] __i |
| 0xe8000, 0xea000, 0xec000, 0xee000, |
| #endif |
| #endif |
| - 0xffffffff }; |
| +}; |
| |
| static struct mtd_info *doclist = NULL; |
| |
| @@ -1678,7 +1678,7 @@ static int __init init_nanddoc(void) |
| if (ret < 0) |
| return ret; |
| } else { |
| - for (i = 0; (doc_locations[i] != 0xffffffff); i++) { |
| + for (i = 0; i < ARRAY_SIZE(doc_locations); i++) { |
| doc_probe(doc_locations[i]); |
| } |
| } |