diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2023-12-13 17:46:16 +0100 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2023-12-13 17:46:16 +0100 |
commit | 7d2c7d59a363e690995eb958959f0bc12445355c (patch) | |
tree | 135fcbfb1790f6aeef2d05ab368932ff25b2608c | |
parent | 2c7555cf2ac8439713dd9148b348128c57222a38 (diff) |
Nest: Fix memory alignment in attribute cache
In attribute cache, adata structures were stored densely in one memory
block, without regard to alignment. Let's force at least u32 alignment.
-rw-r--r-- | nest/route.h | 1 | ||||
-rw-r--r-- | nest/rt-attr.c | 7 |
2 files changed, 5 insertions, 3 deletions
diff --git a/nest/route.h b/nest/route.h index 3e1340fa..d26a4b8c 100644 --- a/nest/route.h +++ b/nest/route.h @@ -542,6 +542,7 @@ const char *ea_custom_name(uint ea); #define EA_ALLOW_UNDEF 0x10000 /* ea_find: allow EAF_TYPE_UNDEF */ #define EA_BIT(n) ((n) << 24) /* Used in bitfield accessors */ #define EA_BIT_GET(ea) ((ea) >> 24) +#define EA_DATA_ALIGN 4 /* Alignment of adata in attribute cache */ #define EAF_TYPE_MASK 0x1f /* Mask with this to get type */ #define EAF_TYPE_INT 0x01 /* 32-bit unsigned integer number */ diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 25936d81..7f3645ee 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -766,7 +766,7 @@ ea_list_copy(ea_list *o) { eattr *a = &o->attrs[i]; if (!(a->type & EAF_EMBEDDED)) - elen += sizeof(struct adata) + a->u.ptr->length; + elen += BIRD_ALIGN(sizeof(struct adata) + a->u.ptr->length, EA_DATA_ALIGN); } n = mb_alloc(rta_pool, elen); @@ -777,11 +777,12 @@ ea_list_copy(ea_list *o) eattr *a = &n->attrs[i]; if (!(a->type & EAF_EMBEDDED)) { - unsigned size = sizeof(struct adata) + a->u.ptr->length; + uint size_u = sizeof(struct adata) + a->u.ptr->length; + uint size = BIRD_ALIGN(size_u, EA_DATA_ALIGN); ASSERT_DIE(adpos + size <= elen); struct adata *d = ((void *) n) + adpos; - memcpy(d, a->u.ptr, size); + memcpy(d, a->u.ptr, size_u); a->u.ptr = d; adpos += size; |