diff --git a/cdr/cdr_custom.c b/cdr/cdr_custom.c
index 4ca6386b946234e85a14707aa0fe8e600dbbe40c..c045241d9711bc9eb4bb3ab748ecffed19f82f3a 100644
--- a/cdr/cdr_custom.c
+++ b/cdr/cdr_custom.c
@@ -115,7 +115,7 @@ static int load_config(void)
 
 static int custom_log(struct ast_cdr *cdr)
 {
-	struct ast_channel dummy;
+	struct ast_channel *dummy;
 	struct ast_str *str;
 	struct cdr_config *config;
 
@@ -124,17 +124,24 @@ static int custom_log(struct ast_cdr *cdr)
 		return -1;
 	}
 
-	/* Quite possibly the first use of a static struct ast_channel, we need it so the var funcs will work */
-	memset(&dummy, 0, sizeof(dummy));
-	dummy.cdr = cdr;
+	dummy = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Substitution/%p", cdr);
+
+	if (!dummy) {
+		ast_log(LOG_ERROR, "Unable to allocate channel for variable subsitution.\n");
+		return -1;
+	}
+
+	/* We need to dup here since the cdr actually belongs to the other channel,
+	   so when we release this channel we don't want the CDR getting cleaned
+	   up prematurely. */
+	dummy->cdr = ast_cdr_dup(cdr);
 
 	AST_RWLIST_RDLOCK(&sinks);
 
 	AST_LIST_TRAVERSE(&sinks, config, list) {
 		FILE *out;
 
-		ast_str_reset(str);
-		ast_str_substitute_variables(&str, 0, &dummy, config->format);
+		ast_str_substitute_variables(&str, 0, dummy, config->format);
 
 		/* Even though we have a lock on the list, we could be being chased by
 		   another thread and this lock ensures that we won't step on anyone's
@@ -158,6 +165,8 @@ static int custom_log(struct ast_cdr *cdr)
 
 	AST_RWLIST_UNLOCK(&sinks);
 
+	ast_channel_release(dummy);
+
 	return 0;
 }