diff --git a/ChangeLog.txt b/ChangeLog.txt index 24f79e5d..231e4c3a 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -2,6 +2,7 @@ Security: - Broker will now reject Will messages that attempt to publish to $CONTROL/. - Broker now validates usernames provided in a TLS certificate or TLS-PSK identity are valid UTF-8. +- Fix potential crash when loading invalid persitence file. Broker: - Fix $SYS messages being expired after 60 seconds and hence unchanged values diff --git a/src/persist_write.c b/src/persist_write.c index f0949f8a..954e36a4 100644 --- a/src/persist_write.c +++ b/src/persist_write.c @@ -47,8 +47,6 @@ static int persist__client_messages_save(FILE *db_fptr, struct mosquitto *contex assert(db_fptr); assert(context); - memset(&chunk, 0, sizeof(struct P_client_msg)); - cmsg = queue; while(cmsg){ if(!strncmp(cmsg->store->topic, "$SYS", 4) @@ -61,6 +59,8 @@ static int persist__client_messages_save(FILE *db_fptr, struct mosquitto *contex continue; } + memset(&chunk, 0, sizeof(struct P_client_msg)); + chunk.F.store_id = cmsg->store->db_id; chunk.F.mid = cmsg->mid; chunk.F.id_len = (uint16_t)strlen(context->id); @@ -91,8 +91,6 @@ static int persist__message_store_save(FILE *db_fptr) assert(db_fptr); - memset(&chunk, 0, sizeof(struct P_msg_store)); - stored = db.msg_store; while(stored){ if(stored->ref_count < 1 || stored->topic == NULL){ @@ -100,6 +98,8 @@ static int persist__message_store_save(FILE *db_fptr) continue; } + memset(&chunk, 0, sizeof(struct P_msg_store)); + if(!strncmp(stored->topic, "$SYS", 4)){ if(stored->ref_count <= 1 && stored->dest_id_count == 0){ /* $SYS messages that are only retained shouldn't be persisted. */ @@ -164,9 +164,9 @@ static int persist__client_save(FILE *db_fptr) assert(db_fptr); - memset(&chunk, 0, sizeof(struct P_client)); - HASH_ITER(hh_id, db.contexts_by_id, context, ctxt_tmp){ + memset(&chunk, 0, sizeof(struct P_client)); + if(context && #ifdef WITH_BRIDGE ((!context->bridge && context->clean_start == false) @@ -224,8 +224,6 @@ static int persist__subs_save(FILE *db_fptr, struct mosquitto__subhier *node, co size_t slen; int rc; - memset(&sub_chunk, 0, sizeof(struct P_sub)); - slen = strlen(topic) + node->topic_len + 2; thistopic = mosquitto__malloc(sizeof(char)*slen); if(!thistopic) return MOSQ_ERR_NOMEM; @@ -238,6 +236,8 @@ static int persist__subs_save(FILE *db_fptr, struct mosquitto__subhier *node, co sub = node->subs; while(sub){ if(sub->context->clean_start == false && sub->context->id){ + memset(&sub_chunk, 0, sizeof(struct P_sub)); + sub_chunk.F.identifier = sub->identifier; sub_chunk.F.id_len = (uint16_t)strlen(sub->context->id); sub_chunk.F.topic_len = (uint16_t)strlen(thistopic); @@ -281,10 +281,10 @@ static int persist__retain_save(FILE *db_fptr, struct mosquitto__retainhier *nod struct P_retain retain_chunk; int rc; - memset(&retain_chunk, 0, sizeof(struct P_retain)); - if(node->retained && strncmp(node->retained->topic, "$SYS", 4)){ /* Don't save $SYS messages. */ + memset(&retain_chunk, 0, sizeof(struct P_retain)); + retain_chunk.F.store_id = node->retained->db_id; rc = persist__chunk_retain_write_v6(db_fptr, &retain_chunk); if(rc){