git » libjio » commit 867ea33

If malloc() fails inside jtrans_add(), we leave ts->lock locked, which will cause a deadlock if we try to do almost any other operation with the transaction (in fact, freeing it will also make pthread_mutex_destroy() fail).

author Alberto Bertogli
2004-08-29 00:22:55 UTC
committer Alberto Bertogli
2007-07-15 13:17:16 UTC
parent c736bd43dc442ce22ca4e416a584a9f8b1686bba

If malloc() fails inside jtrans_add(), we leave ts->lock locked, which will cause a deadlock if we try to do almost any other operation with the transaction (in fact, freeing it will also make pthread_mutex_destroy() fail).

If malloc() fails inside jtrans_add(), we leave ts->lock locked, which will
cause a deadlock if we try to do almost any other operation with the
transaction (in fact, freeing it will also make pthread_mutex_destroy() fail).

This patch fixes it by unlocking before returning in those cases.

Thanks to Shehjar Tikoo for the report.

trans.c +6 -2

diff --git a/trans.c b/trans.c
index 3f7e40e..13d4494 100644
--- a/trans.c
+++ b/trans.c
@@ -140,16 +140,20 @@ int jtrans_add(struct jtrans *ts, const void *buf, size_t count, off_t offset)
 	pthread_mutex_lock(&(ts->lock));
 	if (ts->op == NULL) {
 		ts->op = malloc(sizeof(struct joper));
-		if (ts->op == NULL)
+		if (ts->op == NULL) {
+			pthread_mutex_unlock(&(ts->lock));
 			return 0;
+		}
 		jop = ts->op;
 		jop->prev = NULL;
 	} else {
 		for (tmpop = ts->op; tmpop->next != NULL; tmpop = tmpop->next)
 			;
 		tmpop->next = malloc(sizeof(struct joper));
-		if (tmpop->next == NULL)
+		if (tmpop->next == NULL) {
+			pthread_mutex_unlock(&(ts->lock));
 			return 0;
+		}
 		tmpop->next->prev = tmpop;
 		jop = tmpop->next;
 	}