kasan: fix realloc memcpy tags check error
When the size of the new realloc is larger than the old one and can be expanded forward and backward, the tag of oldmem needs to be set to the same as newmem, otherwise memcpy will report a kasan error. Signed-off-by: wangmingrong1 <wangmingrong1@xiaomi.com>
This commit is contained in:
parent
c6da553788
commit
448ace4761
4 changed files with 53 additions and 4 deletions
|
|
@ -41,6 +41,8 @@
|
|||
# define kasan_unpoison(addr, size) addr
|
||||
# define kasan_register(addr, size)
|
||||
# define kasan_unregister(addr)
|
||||
# define kasan_get_tag(addr) 0
|
||||
# define kasan_set_tag(addr, tag) addr
|
||||
# define kasan_clear_tag(addr) addr
|
||||
# define kasan_start()
|
||||
# define kasan_stop()
|
||||
|
|
@ -132,6 +134,12 @@ void kasan_register(FAR void *addr, FAR size_t *size);
|
|||
|
||||
void kasan_unregister(FAR void *addr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: kasan_set_tag
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *kasan_set_tag(FAR const void *addr, uint8_t tag);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: kasan_clear_tag
|
||||
*
|
||||
|
|
@ -145,6 +153,19 @@ void kasan_unregister(FAR void *addr);
|
|||
|
||||
FAR void *kasan_clear_tag(FAR const void *addr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: kasan_get_tag
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - The address of the memory to get the tag.
|
||||
*
|
||||
* Returned Value:
|
||||
* address tag
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t kasan_get_tag(FAR const void *addr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: kasan_start
|
||||
*
|
||||
|
|
|
|||
|
|
@ -204,6 +204,16 @@ static void kasan_set_poison(FAR const void *addr, size_t size,
|
|||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t kasan_get_tag(FAR const void *addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
FAR void *kasan_set_tag(FAR const void *addr, uint8_t tag)
|
||||
{
|
||||
return (FAR void *)addr;
|
||||
}
|
||||
|
||||
FAR void *kasan_clear_tag(FAR const void *addr)
|
||||
{
|
||||
return (FAR void *)addr;
|
||||
|
|
|
|||
|
|
@ -156,10 +156,10 @@ static void kasan_set_poison(FAR const void *addr,
|
|||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *kasan_clear_tag(FAR const void *addr)
|
||||
FAR void *kasan_set_tag(FAR const void *addr, uint8_t tag)
|
||||
{
|
||||
return (FAR void *)
|
||||
(((uint64_t)(addr)) & ~((uint64_t)0xff << KASAN_TAG_SHIFT));
|
||||
return (FAR void *)((uint64_t)kasan_clear_tag(addr) |
|
||||
(((uint64_t)tag) << KASAN_TAG_SHIFT));
|
||||
}
|
||||
|
||||
void kasan_poison(FAR const void *addr, size_t size)
|
||||
|
|
@ -167,6 +167,22 @@ void kasan_poison(FAR const void *addr, size_t size)
|
|||
kasan_set_poison(addr, size, 0xff);
|
||||
}
|
||||
|
||||
FAR void *kasan_clear_tag(FAR const void *addr)
|
||||
{
|
||||
return (FAR void *)
|
||||
(((uint64_t)addr) & ~((uint64_t)0xff << KASAN_TAG_SHIFT));
|
||||
}
|
||||
|
||||
uint8_t kasan_get_tag(FAR const void *addr)
|
||||
{
|
||||
return (uint8_t)((uint64_t)addr >> KASAN_TAG_SHIFT);
|
||||
}
|
||||
|
||||
bool kasan_bypass(bool state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FAR void *kasan_unpoison(FAR const void *addr, size_t size)
|
||||
{
|
||||
uint8_t tag = kasan_random_tag();
|
||||
|
|
|
|||
|
|
@ -393,7 +393,9 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
|
|||
|
||||
newmem = kasan_unpoison(newmem, MM_SIZEOF_NODE(oldnode) -
|
||||
MM_ALLOCNODE_OVERHEAD);
|
||||
if (kasan_reset_tag(newmem) != kasan_reset_tag(oldmem))
|
||||
|
||||
oldmem = kasan_set_tag(oldmem, kasan_get_tag(newmem));
|
||||
if (newmem != oldmem)
|
||||
{
|
||||
/* Now we have to move the user contents 'down' in memory. memcpy
|
||||
* should be safe for this.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue