mm/iob: limit the alignment length of IOB to no less than sizeof(uinptr_t)

avoid crashes caused by four-byte alignment issues.

Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu
2025-05-13 10:35:37 +08:00
committed by Alan C. Assis
parent 776a6a5d0b
commit 48e9b4fc7a
6 changed files with 14 additions and 15 deletions
+1
View File
@@ -25,6 +25,7 @@
****************************************************************************/
#include <nuttx/net/dns.h>
#include <nuttx/net/net.h>
#include <nuttx/rpmsg/rpmsg.h>
#include <nuttx/semaphore.h>
#include <nuttx/usrsock/usrsock_rpmsg.h>
+2 -3
View File
@@ -31,6 +31,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <sys/param.h>
#ifdef CONFIG_IOB_NOTIFIER
# include <nuttx/wqueue.h>
@@ -74,9 +75,7 @@
/* Default config of alignment and head padding size */
#if !defined(CONFIG_IOB_ALIGNMENT)
# define CONFIG_IOB_ALIGNMENT 1
#endif
#define IOB_ALIGNMENT MAX(CONFIG_IOB_ALIGNMENT, sizeof(uintptr_t))
/* IOB helpers */
-1
View File
@@ -46,7 +46,6 @@
#include <nuttx/queue.h>
#include <nuttx/wdog.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include <nuttx/mm/map.h>
#include <nuttx/tls.h>
#include <nuttx/spinlock_type.h>
+4 -4
View File
@@ -335,9 +335,9 @@ FAR struct iob_s *iob_alloc_dynamic(uint16_t size)
FAR struct iob_s *iob;
size_t alignsize;
alignsize = ALIGN_UP(sizeof(struct iob_s), CONFIG_IOB_ALIGNMENT) + size;
alignsize = ALIGN_UP(sizeof(struct iob_s), IOB_ALIGNMENT) + size;
iob = kmm_memalign(CONFIG_IOB_ALIGNMENT, alignsize);
iob = kmm_memalign(IOB_ALIGNMENT, alignsize);
if (iob)
{
iob->io_flink = NULL; /* Not in a chain */
@@ -347,7 +347,7 @@ FAR struct iob_s *iob_alloc_dynamic(uint16_t size)
iob->io_pktlen = 0; /* Total length of the packet */
iob->io_free = iob_free_dynamic; /* Customer free callback */
iob->io_data = (FAR uint8_t *)ALIGN_UP((uintptr_t)(iob + 1),
CONFIG_IOB_ALIGNMENT);
IOB_ALIGNMENT);
}
return iob;
@@ -432,7 +432,7 @@ FAR struct iob_s *iob_init_with_data(FAR void *data, uint16_t size,
iob->io_pktlen = 0; /* Total length of the packet */
iob->io_free = free_cb; /* Customer free callback */
iob->io_data = (FAR uint8_t *)ALIGN_UP((uintptr_t)(iob + 1),
CONFIG_IOB_ALIGNMENT);
IOB_ALIGNMENT);
iob->io_bufsize = ((FAR uint8_t *)data + size) - iob->io_data;
return iob;
+1 -1
View File
@@ -122,7 +122,7 @@ FAR struct iob_s *iob_free(FAR struct iob_s *iob)
if (iob->io_free != NULL)
{
FAR uint8_t *io_data = (FAR uint8_t *)ALIGN_UP((uintptr_t)(iob + 1),
CONFIG_IOB_ALIGNMENT);
IOB_ALIGNMENT);
if (iob->io_data == io_data)
{
iob->io_free(iob);
+6 -6
View File
@@ -41,13 +41,13 @@
#ifdef CONFIG_IOB_ALLOC
# define IOB_ALIGN_SIZE ALIGN_UP(sizeof(struct iob_s) + CONFIG_IOB_BUFSIZE, \
CONFIG_IOB_ALIGNMENT)
IOB_ALIGNMENT)
#else
# define IOB_ALIGN_SIZE ALIGN_UP(sizeof(struct iob_s), CONFIG_IOB_ALIGNMENT)
# define IOB_ALIGN_SIZE ALIGN_UP(sizeof(struct iob_s), IOB_ALIGNMENT)
#endif
#define IOB_BUFFER_SIZE (IOB_ALIGN_SIZE * CONFIG_IOB_NBUFFERS + \
CONFIG_IOB_ALIGNMENT - 1)
IOB_ALIGNMENT - 1)
/****************************************************************************
* Private Data
@@ -55,7 +55,7 @@
/* Following raw buffer will be divided into iob_s instances, the initial
* procedure will ensure that the member io_data of each iob_s is aligned
* to the CONFIG_IOB_ALIGNMENT memory boundary.
* to the IOB_ALIGNMENT memory boundary.
*/
#ifdef IOB_SECTION
@@ -135,11 +135,11 @@ void iob_initialize(void)
uintptr_t buf;
/* Get a start address which plus offsetof(struct iob_s, io_data) is
* aligned to the CONFIG_IOB_ALIGNMENT memory boundary
* aligned to the IOB_ALIGNMENT memory boundary
*/
buf = ALIGN_UP((uintptr_t)g_iob_buffer + offsetof(struct iob_s, io_data),
CONFIG_IOB_ALIGNMENT) - offsetof(struct iob_s, io_data);
IOB_ALIGNMENT) - offsetof(struct iob_s, io_data);
/* Get I/O buffer instance from the start address and add each I/O buffer
* to the free list