Browse code

tm: t_save_lumps() verifies the route type

Even though the t_save_lumps() function is registered only for
request route, in some corner case, the function might be called
from failure_route. (For example a failure route executes a request
route block which calls this function.)
This scenario resulted in overwriting the already cloned lump list
which is not allowed because of the lockless read, and also
resulted in a memory leak.
An extra check is also added to save_msg_lumps() to catch this bug.
(cherry picked from commit a7bbaf7cd83b5d044ff8c7fff7b19c7ff392da74)

Miklos Tirpak authored on 30/09/2010 08:42:57 • Andrei Pelinescu-Onciul committed on 11/10/2010 09:30:29
Showing 2 changed files
... ...
@@ -116,6 +116,14 @@ int save_msg_lumps( struct sip_msg *shm_msg, struct sip_msg *pkg_msg)
116 116
 		return -1;
117 117
 	}
118 118
 
119
+#ifdef EXTRA_DEBUG
120
+	membar_depends();
121
+	if (shm_msg->add_rm || shm_msg->body_lumps || shm_msg->reply_lump) {
122
+		LOG(L_ERR, "ERROR: save_msg_lumps: BUG, trying to overwrite the already cloned lumps\n");
123
+		return -1;
124
+	}
125
+#endif
126
+
119 127
 	/* needless to clone the lumps for ACK, they will not be used again */
120 128
 	if (shm_msg->REQ_METHOD == METHOD_ACK)
121 129
 		return 0;
... ...
@@ -1811,17 +1811,19 @@ static int w_t_save_lumps(struct sip_msg* msg, char* foo, char* bar)
1811 1811
 #ifdef POSTPONE_MSG_CLONING
1812 1812
 	struct cell *t;
1813 1813
 
1814
-	t=get_t();
1815
-	if (!t || t==T_UNDEFINED) {
1816
-		LOG(L_ERR, "ERROR: w_t_save_lumps: transaction has not been created yet\n");
1817
-		return -1;
1818
-	}
1814
+	if (is_route_type(REQUEST_ROUTE)) {
1815
+		t=get_t();
1816
+		if (!t || t==T_UNDEFINED) {
1817
+			LOG(L_ERR, "ERROR: w_t_save_lumps: transaction has not been created yet\n");
1818
+			return -1;
1819
+		}
1819 1820
 
1820
-	if (save_msg_lumps(t->uas.request, msg)) {
1821
-		LOG(L_ERR, "ERROR: w_t_save_lumps: "
1822
-			"failed to save the message lumps\n");
1823
-		return -1;
1824
-	}
1821
+		if (save_msg_lumps(t->uas.request, msg)) {
1822
+			LOG(L_ERR, "ERROR: w_t_save_lumps: "
1823
+				"failed to save the message lumps\n");
1824
+			return -1;
1825
+		}
1826
+	} /* else nothing to do, the lumps have already been saved */
1825 1827
 	return 1;
1826 1828
 #else
1827 1829
 	LOG(L_ERR, "ERROR: w_t_save_lumps: POSTPONE_MSG_CLONING is not defined,"