diff --git a/lib/isc/cfgmgr.c b/lib/isc/cfgmgr.c index e1d867a0f1..fd034aece4 100644 --- a/lib/isc/cfgmgr.c +++ b/lib/isc/cfgmgr.c @@ -599,10 +599,15 @@ isc__cfgmgr_getval(const char *name, isc_cfgmgr_val_t *value) { goto out; } - memcpy(value, dbval.mv_data, sizeof(*value)); - if (value->type == ISC_CFGMGR_STRING) { - value->string = ((char *)dbval.mv_data) + sizeof(value->type); + const isc_cfgmgr_type_t strtype = ISC_CFGMGR_STRING; + if (memcmp(dbval.mv_data, &strtype, sizeof(strtype)) == 0) { + value->type = strtype; + value->string = (char *)dbval.mv_data + sizeof(strtype); + } else { + REQUIRE(sizeof(*value) == dbval.mv_size); + memmove(value, dbval.mv_data, sizeof(*value)); } + INSIST(value->type != ISC_CFGMGR_UNDEFINED); out: @@ -652,12 +657,19 @@ isc__cfgmgr_setval(const char *name, const isc_cfgmgr_val_t *value, bool list) { goto out; } + /* + * String is a specific case as it needs an allocation, so the size is + * just the size of the type and the string length + 1. For the other + * cases, in order to keep the flow unconditional and simple there is a + * slight memory waste, i.e. storing a uint32_t will take the size of + * isc_cfgmgr_val_t. + */ if (value->type == ISC_CFGMGR_STRING) { - dbval.mv_size = sizeof(*value) + strlen(value->string) + 1; + dbval.mv_size = sizeof(value->type) + strlen(value->string) + 1; dbval.mv_data = isc_mem_allocate(isc__cfgmgr_mctx, dbval.mv_size); - memcpy(dbval.mv_data, value, sizeof(value->type)); - strcpy(((char *)dbval.mv_data) + sizeof(value->type), + memmove(dbval.mv_data, value, sizeof(value->type)); + strcpy((char *)dbval.mv_data + sizeof(value->type), value->string); } else { dbval = (MDB_val){ .mv_size = sizeof(*value), @@ -671,8 +683,8 @@ isc__cfgmgr_setval(const char *name, const isc_cfgmgr_val_t *value, bool list) { if (list == false) { /* * Can't use MDB_NOOVERWRITE as it would override the - * data if the key/value already exists. Making a - * value copy ahead just in case is likely more + * data if the key/value already exists so it wouldn't work with + * list. Making a value copy ahead just in case is likely more * expensive than an extra lookup */ if (mdb_cursor_get(isc__cfgmgr_ctx.cursor, &dbkey, NULL, diff --git a/lib/isc/include/isc/cfgmgr.h b/lib/isc/include/isc/cfgmgr.h index 424000735d..09fd62d167 100644 --- a/lib/isc/include/isc/cfgmgr.h +++ b/lib/isc/include/isc/cfgmgr.h @@ -26,7 +26,7 @@ typedef enum isc_cfgmgr_type { ISC_CFGMGR_NONE, ISC_CFGMGR_SOCKADDR, ISC_CFGMGR_UINT32 -} isc_cfgmgr_type_t; +} __attribute__ ((__packed__)) isc_cfgmgr_type_t; /* * Generic value holding the actual value and type value for