From 51eda38249eb525f9e508e1516d322513062ea72 Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Sun, 6 Sep 2015 07:40:06 -0700 Subject: [PATCH] Fix use after free of ctx->last_tag. (closes #3775) When using imap to access gmail, tagging and saving messages to "all mail" and pressing can result in the call path: mx_check_mailbox() imap_check_mailbox() imap_cmd_finish() imap_expunge_mailbox() mx_update_tables() followed by: mx_sync_mailbox() The HEADER pointed to by ctx->last_tag will be removed and FREE'ed in mx_update_tables(), but will subsequently be accessed in mx_sync_mailbox(). This patch simply sets ctx->last_tag=NULL if it is freed inside mx_update_tables(). Thanks to Peter Lekensteyn for the bug report and ASAN report. --- mx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mx.c b/mx.c index 4c5cb07de..62a5d5f3c 100644 --- a/mx.c +++ b/mx.c @@ -1058,6 +1058,13 @@ void mx_update_tables(CONTEXT *ctx, int committing) hash_delete (ctx->subj_hash, ctx->hdrs[i]->env->real_subj, ctx->hdrs[i], NULL); if (ctx->id_hash && ctx->hdrs[i]->env->message_id) hash_delete (ctx->id_hash, ctx->hdrs[i]->env->message_id, ctx->hdrs[i], NULL); + /* The path mx_check_mailbox() -> imap_check_mailbox() -> + * imap_expunge_mailbox() -> mx_update_tables() + * can occur before a call to mx_sync_mailbox(), resulting in + * last_tag being stale if it's not reset here. + */ + if (ctx->last_tag == ctx->hdrs[i]) + ctx->last_tag = NULL; mutt_free_header (&ctx->hdrs[i]); } } -- 2.49.0