Skip to content

Commit

Permalink
mm: The alignment length in mm is consistent with Kasan
Browse files Browse the repository at this point in the history
preceding will cause the mm alignment to be inconsistent with the kasan alignment

Signed-off-by: wangmingrong1 <wangmingrong1@xiaomi.com>
  • Loading branch information
W-M-R committed Jan 6, 2025
1 parent 3e66498 commit 5b16eae
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 18 deletions.
18 changes: 10 additions & 8 deletions mm/kasan/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
****************************************************************************/

#include <nuttx/nuttx.h>
#include <nuttx/mm/mm.h>
#include <nuttx/mm/kasan.h>
#include <nuttx/compiler.h>
#include <nuttx/spinlock.h>
Expand All @@ -44,10 +45,8 @@
#define KASAN_LAST_WORD_MASK(end) \
(UINTPTR_MAX >> (-(end) & (KASAN_BITS_PER_WORD - 1)))

#define KASAN_SHADOW_SCALE (sizeof(uintptr_t))

#define KASAN_SHADOW_SIZE(size) \
(KASAN_BYTES_PER_WORD * ((size) / KASAN_SHADOW_SCALE / KASAN_BITS_PER_WORD))
(KASAN_BYTES_PER_WORD * ((size) / MM_ALIGN / KASAN_BITS_PER_WORD))
#define KASAN_REGION_SIZE(size) \
(sizeof(struct kasan_region_s) + KASAN_SHADOW_SIZE(size))

Expand Down Expand Up @@ -87,7 +86,7 @@ kasan_mem_to_shadow(FAR const void *ptr, size_t size,
{
DEBUGASSERT(addr + size <= g_region[i]->end);
addr -= g_region[i]->begin;
addr /= KASAN_SHADOW_SCALE;
addr /= MM_ALIGN;
*bit = addr % KASAN_BITS_PER_WORD;
return &g_region[i]->shadow[addr / KASAN_BITS_PER_WORD];
}
Expand All @@ -110,15 +109,15 @@ kasan_is_poisoned(FAR const void *addr, size_t size)
return kasan_global_is_poisoned(addr, size);
}

if (size <= KASAN_SHADOW_SCALE)
if (size <= MM_ALIGN)
{
return ((*p >> bit) & 1);
}

nbit = KASAN_BITS_PER_WORD - bit % KASAN_BITS_PER_WORD;
mask = KASAN_FIRST_WORD_MASK(bit);
size = ALIGN_UP(size, KASAN_SHADOW_SCALE);
size /= KASAN_SHADOW_SCALE;
size = ALIGN_UP(size, MM_ALIGN);
size /= MM_ALIGN;

while (size >= nbit)
{
Expand Down Expand Up @@ -155,6 +154,9 @@ static void kasan_set_poison(FAR const void *addr, size_t size,
unsigned int nbit;
uintptr_t mask;

DEBUGASSERT((uintptr_t)addr % MM_ALIGN == 0);
DEBUGASSERT(size % MM_ALIGN == 0);

p = kasan_mem_to_shadow(addr, size, &bit);
if (p == NULL)
{
Expand All @@ -163,7 +165,7 @@ static void kasan_set_poison(FAR const void *addr, size_t size,

nbit = KASAN_BITS_PER_WORD - bit % KASAN_BITS_PER_WORD;
mask = KASAN_FIRST_WORD_MASK(bit);
size /= KASAN_SHADOW_SCALE;
size /= MM_ALIGN;

flags = spin_lock_irqsave(&g_lock);
while (size >= nbit)
Expand Down
10 changes: 6 additions & 4 deletions mm/kasan/sw_tags.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* Included Files
****************************************************************************/

#include <nuttx/mm/mm.h>
#include <nuttx/mm/kasan.h>
#include <nuttx/compiler.h>
#include <nuttx/spinlock.h>
Expand All @@ -45,10 +46,8 @@

#define kasan_random_tag() (1 + rand() % ((1 << (64 - KASAN_TAG_SHIFT)) - 2))

#define KASAN_SHADOW_SCALE (sizeof(uintptr_t))

#define KASAN_SHADOW_SIZE(size) \
((size) + KASAN_SHADOW_SCALE - 1) / KASAN_SHADOW_SCALE
((size) + MM_ALIGN - 1) / MM_ALIGN
#define KASAN_REGION_SIZE(size) \
(sizeof(struct kasan_region_s) + KASAN_SHADOW_SIZE(size))

Expand Down Expand Up @@ -89,7 +88,7 @@ kasan_mem_to_shadow(FAR const void *ptr, size_t size)
{
DEBUGASSERT(addr + size <= g_region[i]->end);
addr -= g_region[i]->begin;
return &g_region[i]->shadow[addr / KASAN_SHADOW_SCALE];
return &g_region[i]->shadow[addr / MM_ALIGN];
}
}

Expand Down Expand Up @@ -135,6 +134,9 @@ static void kasan_set_poison(FAR const void *addr,
irqstate_t flags;
FAR uint8_t *p;

DEBUGASSERT((uintptr_t)addr % MM_ALIGN == 0);
DEBUGASSERT(size % MM_ALIGN == 0);

p = kasan_mem_to_shadow(addr, size);
if (p == NULL)
{
Expand Down
22 changes: 17 additions & 5 deletions mm/mm_heap/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
* previous freenode
*/

#define MM_ALLOCNODE_OVERHEAD (MM_SIZEOF_ALLOCNODE - sizeof(mmsize_t))
#define MM_ALLOCNODE_OVERHEAD (MM_SIZEOF_ALLOCNODE - MM_ALIGN)

/* Get the node size */

Expand Down Expand Up @@ -173,7 +173,12 @@ typedef size_t mmsize_t;

struct mm_allocnode_s
{
mmsize_t preceding; /* Physical preceding chunk size */
union
{
mmsize_t preceding; /* Physical preceding chunk size */
uint8_t align[MM_ALIGN];
};

mmsize_t size; /* Size of this chunk */
#if CONFIG_MM_BACKTRACE >= 0
pid_t pid; /* The pid for caller */
Expand All @@ -182,13 +187,19 @@ struct mm_allocnode_s
FAR void *backtrace[CONFIG_MM_BACKTRACE]; /* The backtrace buffer for caller */
# endif
#endif
};
}
aligned_data(MM_ALIGN);

/* This describes a free chunk */

struct mm_freenode_s
{
mmsize_t preceding; /* Physical preceding chunk size */
union
{
mmsize_t preceding; /* Physical preceding chunk size */
uint8_t align[MM_ALIGN];
};

mmsize_t size; /* Size of this chunk */
#if CONFIG_MM_BACKTRACE >= 0
pid_t pid; /* The pid for caller */
Expand All @@ -199,7 +210,8 @@ struct mm_freenode_s
#endif
FAR struct mm_freenode_s *flink; /* Supports a doubly linked list */
FAR struct mm_freenode_s *blink;
};
}
aligned_data(MM_ALIGN);

static_assert(MM_SIZEOF_ALLOCNODE <= MM_MIN_CHUNK,
"Error size for struct mm_allocnode_s\n");
Expand Down
2 changes: 1 addition & 1 deletion mm/mm_heap/mm_initialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart,

heapbase = MM_ALIGN_UP((uintptr_t)heapstart + 2 * MM_SIZEOF_ALLOCNODE) -
2 * MM_SIZEOF_ALLOCNODE;
heapsize = heapsize - (heapbase - (uintptr_t)heapstart);
heapsize = MM_ALIGN_DOWN(heapsize - (heapbase - (uintptr_t)heapstart));

/* Register KASan for access rights check. We need to register after
* address alignment.
Expand Down

0 comments on commit 5b16eae

Please sign in to comment.