From f87a401c87ea98f25b0644ba70815cb4616a53f8 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Thu, 18 Aug 2022 18:29:23 +0200 Subject: [PATCH 1/2] pkg/littlefs: fix unaligned memory access Previously `tests/pkg_littlefs` crashed on the `samr21-xpro`. This now aligns the buffers in `littlefs_desc_t` to the alignment requirement of `uint32_t`. Specifically the issue causing the crash at hand was that `lfs_free_t::buffer` is of type `uint32_t *`, so access are expected to be aligned to `uint32_t`. After this commit, this assumption is fulfilled. --- sys/include/fs/littlefs_fs.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/sys/include/fs/littlefs_fs.h b/sys/include/fs/littlefs_fs.h index 0d1eecd927eb..7c458d5c2736 100644 --- a/sys/include/fs/littlefs_fs.h +++ b/sys/include/fs/littlefs_fs.h @@ -22,15 +22,18 @@ #ifndef FS_LITTLEFS_FS_H #define FS_LITTLEFS_FS_H -#ifdef __cplusplus -extern "C" { -#endif +#include #include "vfs.h" #include "lfs.h" #include "mtd.h" #include "mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + /** * @name littlefs configuration * @{ @@ -79,21 +82,21 @@ typedef struct { * total number of block is defined in @p config. * if set to 0, the total number of sectors from the mtd is used */ uint32_t base_addr; - uint16_t sectors_per_block; /**< number of sectors per block */ #if LITTLEFS_FILE_BUFFER_SIZE || DOXYGEN /** file buffer to use internally if LITTLEFS_FILE_BUFFER_SIZE is set */ - uint8_t file_buf[LITTLEFS_FILE_BUFFER_SIZE]; + alignas(uint32_t) uint8_t file_buf[LITTLEFS_FILE_BUFFER_SIZE]; #endif #if LITTLEFS_READ_BUFFER_SIZE || DOXYGEN /** read buffer to use internally if LITTLEFS_READ_BUFFER_SIZE is set */ - uint8_t read_buf[LITTLEFS_READ_BUFFER_SIZE]; + alignas(uint32_t) uint8_t read_buf[LITTLEFS_READ_BUFFER_SIZE]; #endif #if LITTLEFS_PROG_BUFFER_SIZE || DOXYGEN /** prog buffer to use internally if LITTLEFS_PROG_BUFFER_SIZE is set */ - uint8_t prog_buf[LITTLEFS_PROG_BUFFER_SIZE]; + alignas(uint32_t) uint8_t prog_buf[LITTLEFS_PROG_BUFFER_SIZE]; #endif /** lookahead buffer to use internally */ - uint8_t lookahead_buf[LITTLEFS_LOOKAHEAD_SIZE / 8]; + alignas(uint32_t) uint8_t lookahead_buf[LITTLEFS_LOOKAHEAD_SIZE / 8]; + uint16_t sectors_per_block; /**< number of sectors per block */ } littlefs_desc_t; /** The littlefs vfs driver */ From ca4afc4053c453f3bd0c0c15c9f12377213b299e Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Thu, 18 Aug 2022 18:36:05 +0200 Subject: [PATCH 2/2] pkg/littlefs2: fix unaligned memory access Previously `tests/pkg_littlefs2` crashed on the `samr21-xpro`. This now aligns the buffers in `littlefs2_desc_t` to the alignment requirement of `uint32_t`. Specifically the issue causing the crash at hand was that `struct lfs_free::buffer` is of type `uint32_t *`, so access are expected to be aligned to `uint32_t`. After this commit, this assumption is fulfilled. --- sys/include/fs/littlefs2_fs.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/sys/include/fs/littlefs2_fs.h b/sys/include/fs/littlefs2_fs.h index 78fff4b74acd..17da92515585 100644 --- a/sys/include/fs/littlefs2_fs.h +++ b/sys/include/fs/littlefs2_fs.h @@ -24,15 +24,17 @@ #ifndef FS_LITTLEFS2_FS_H #define FS_LITTLEFS2_FS_H -#ifdef __cplusplus -extern "C" { -#endif +#include #include "vfs.h" #include "lfs.h" #include "mtd.h" #include "mutex.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @name littlefs configuration * @ingroup config @@ -95,24 +97,24 @@ typedef struct { * total number of block is defined in @p config. * if set to 0, the total number of sectors from the mtd is used */ uint32_t base_addr; - uint16_t sectors_per_block; /**< number of sectors per block */ #if CONFIG_LITTLEFS2_FILE_BUFFER_SIZE || DOXYGEN /** file buffer to use internally if CONFIG_LITTLEFS2_FILE_BUFFER_SIZE * is set */ - uint8_t file_buf[CONFIG_LITTLEFS2_FILE_BUFFER_SIZE]; + alignas(uint32_t) uint8_t file_buf[CONFIG_LITTLEFS2_FILE_BUFFER_SIZE]; #endif #if CONFIG_LITTLEFS2_READ_BUFFER_SIZE || DOXYGEN /** read buffer to use internally if CONFIG_LITTLEFS2_READ_BUFFER_SIZE * is set */ - uint8_t read_buf[CONFIG_LITTLEFS2_READ_BUFFER_SIZE]; + alignas(uint32_t) uint8_t read_buf[CONFIG_LITTLEFS2_READ_BUFFER_SIZE]; #endif #if CONFIG_LITTLEFS2_PROG_BUFFER_SIZE || DOXYGEN /** prog buffer to use internally if CONFIG_LITTLEFS2_PROG_BUFFER_SIZE * is set */ - uint8_t prog_buf[CONFIG_LITTLEFS2_PROG_BUFFER_SIZE]; + alignas(uint32_t) uint8_t prog_buf[CONFIG_LITTLEFS2_PROG_BUFFER_SIZE]; #endif /** lookahead buffer to use internally */ - uint8_t lookahead_buf[CONFIG_LITTLEFS2_LOOKAHEAD_SIZE]; + alignas(uint32_t) uint8_t lookahead_buf[CONFIG_LITTLEFS2_LOOKAHEAD_SIZE]; + uint16_t sectors_per_block; /**< number of sectors per block */ } littlefs2_desc_t; /** The littlefs vfs driver */