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 /nest | |
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.
Diffstat (limited to 'nest')
-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; |