dovecot-1.2: pgsql: Don't write to freed memory if transaction i...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Jan 18 00:21:35 EET 2009
details: http://hg.dovecot.org/dovecot-1.2/rev/81fd92599c7f
changeset: 8650:81fd92599c7f
user: Timo Sirainen <tss at iki.fi>
date: Sat Jan 17 17:21:29 2009 -0500
description:
pgsql: Don't write to freed memory if transaction is aborted while SQL commands are being executed.
diffstat:
1 file changed, 21 insertions(+), 4 deletions(-)
src/lib-sql/driver-pgsql.c | 25 +++++++++++++++++++++----
diffs (97 lines):
diff -r 67c08c386702 -r 81fd92599c7f src/lib-sql/driver-pgsql.c
--- a/src/lib-sql/driver-pgsql.c Sat Jan 17 13:56:24 2009 -0500
+++ b/src/lib-sql/driver-pgsql.c Sat Jan 17 17:21:29 2009 -0500
@@ -70,6 +70,7 @@ struct pgsql_queue {
struct pgsql_transaction_context {
struct sql_transaction_context ctx;
+ int refcount;
sql_commit_callback_t *callback;
void *context;
@@ -845,7 +846,19 @@ driver_pgsql_transaction_begin(struct sq
ctx = i_new(struct pgsql_transaction_context, 1);
ctx->ctx.db = db;
+ ctx->refcount = 1;
return &ctx->ctx;
+}
+
+static void
+driver_pgsql_transaction_unref(struct pgsql_transaction_context *ctx)
+{
+ i_assert(ctx->refcount > 0);
+ if (--ctx->refcount > 0)
+ return;
+
+ i_free(ctx->first_update);
+ i_free(ctx);
}
static void
@@ -871,13 +884,14 @@ driver_pgsql_transaction_commit(struct s
callback(ctx->error, context);
if (ctx->opened)
sql_exec(_ctx->db, "ROLLBACK");
- i_free(ctx);
+ driver_pgsql_transaction_unref(ctx);
return;
}
if (!ctx->opened) {
/* nothing done */
ctx->callback(NULL, ctx->context);
+ driver_pgsql_transaction_unref(ctx);
return;
}
@@ -897,6 +911,7 @@ driver_pgsql_transaction_commit_s(struct
struct sql_result *result;
if (ctx->first_update != NULL) {
+ ctx->refcount++;
sql_query(_ctx->db, ctx->first_update,
transaction_update_callback, ctx);
i_free_and_null(ctx->first_update);
@@ -919,7 +934,7 @@ driver_pgsql_transaction_commit_s(struct
sql_result_free(result);
}
- i_free(ctx);
+ driver_pgsql_transaction_unref(ctx);
return *error_r == NULL ? 0 : -1;
}
@@ -931,8 +946,7 @@ driver_pgsql_transaction_rollback(struct
if (ctx->opened)
sql_exec(_ctx->db, "ROLLBACK");
- i_free(ctx->first_update);
- i_free(ctx);
+ driver_pgsql_transaction_unref(ctx);
}
static void
@@ -944,6 +958,7 @@ transaction_update_callback(struct sql_r
ctx->failed = TRUE;
ctx->error = sql_result_get_error(result);
}
+ driver_pgsql_transaction_unref(ctx);
}
static void
@@ -963,12 +978,14 @@ driver_pgsql_update(struct sql_transacti
return;
}
ctx->opened = TRUE;
+ ctx->refcount += 2;
sql_query(_ctx->db, "BEGIN", transaction_update_callback, ctx);
sql_query(_ctx->db, ctx->first_update,
transaction_update_callback, ctx);
i_free_and_null(ctx->first_update);
}
+ ctx->refcount++;
driver_pgsql_query_full(_ctx->db, query,
transaction_update_callback, ctx, FALSE);
}
More information about the dovecot-cvs
mailing list