Browse code

core: fix end-script commands in expr. leaks

When having commands that end the script immediately in
assignments (e.g. $foo = { drop; }) or in expressions
(e.g. if ($v + { drop; } > 0)), the script was terminated
immediately via longjmp. However this might leave some un-freed
variables.
This fix introduces a safe version of run_actions()
(run_actions_safe()) that will not use longjmp() to immediately
end the whole script on drop, returning instead to its caller.
(cherry picked from commit 28a882873f8a69a189d790e33bcd2017c253a66a)

Andrei Pelinescu-Onciul authored on 29/09/2010 14:30:40
Showing 5 changed files
... ...
@@ -1331,7 +1331,8 @@ int run_actions(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
1331 1331
 	h->rec_lev--;
1332 1332
 end:
1333 1333
 	/* process module onbreak handlers if present */
1334
-	if (h->rec_lev==0 && ret==0)
1334
+	if (unlikely(h->rec_lev==0 && ret==0 &&
1335
+					!(h->run_flags & IGNORE_ON_BREAK_R_F)))
1335 1336
 		for (mod=modules;mod;mod=mod->next)
1336 1337
 			if ((mod->mod_interface_ver==0) && mod->exports && 
1337 1338
 					mod->exports->v0.onbreak_f) {
... ...
@@ -1348,6 +1349,33 @@ error:
1348 1348
 }
1349 1349
 
1350 1350
 
1351
+
1352
+#ifdef USE_LONGJMP
1353
+/** safe version of run_actions().
1354
+ * It always return (it doesn't longjmp on forced script end).
1355
+ * @returns 0, or 1 on success, <0 on error
1356
+ * (0 if drop or break encountered, 1 if not ) */
1357
+int run_actions_safe(struct run_act_ctx* h, struct action* a,
1358
+						struct sip_msg* msg)
1359
+{
1360
+	struct run_act_ctx ctx;
1361
+	int ret;
1362
+	int ign_on_break;
1363
+	
1364
+	/* start with a fresh action context */
1365
+	init_run_actions_ctx(&ctx);
1366
+	ctx.last_retcode = h->last_retcode;
1367
+	ign_on_break = h->run_flags & IGNORE_ON_BREAK_R_F;
1368
+	ctx.run_flags = h->run_flags | IGNORE_ON_BREAK_R_F;
1369
+	ret = run_actions(&ctx, a, msg);
1370
+	h->last_retcode = ctx.last_retcode;
1371
+	h->run_flags = (ctx.run_flags & ~IGNORE_ON_BREAK_R_F) | ign_on_break;
1372
+	return ret;
1373
+}
1374
+#endif /* USE_LONGJMP */
1375
+
1376
+
1377
+
1351 1378
 int run_top_route(struct action* a, sip_msg_t* msg, struct run_act_ctx *c)
1352 1379
 {
1353 1380
 	struct run_act_ctx ctx;
... ...
@@ -61,4 +61,12 @@ int run_actions(struct run_act_ctx* c, struct action* a, struct sip_msg* msg);
61 61
 
62 62
 int run_top_route(struct action* a, sip_msg_t* msg, struct run_act_ctx* c);
63 63
 
64
+
65
+#ifdef USE_LONGJMP
66
+int run_actions_safe(struct run_act_ctx* c, struct action* a,
67
+						struct sip_msg* msg);
68
+#else /*! USE_LONGJMP */
69
+#define run_actions_safe(c, a, m) run_actions(c, a, m)
70
+#endif /* USE_LONGJMP */
71
+
64 72
 #endif
... ...
@@ -101,7 +101,7 @@ inline static int lval_avp_assign(struct run_act_ctx* h, struct sip_msg* msg,
101 101
 		case RV_ACTION_ST:
102 102
 			flags=avp->type & ~AVP_VAL_STR;
103 103
 			if (rv->v.action)
104
-				value.n=run_actions(h, rv->v.action, msg);
104
+				value.n=run_actions_safe(h, rv->v.action, msg);
105 105
 			else
106 106
 				value.n=-1;
107 107
 			ret=value.n;
... ...
@@ -276,7 +276,7 @@ inline static int lval_pvar_assign(struct run_act_ctx* h, struct sip_msg* msg,
276 276
 		case RV_ACTION_ST:
277 277
 			pval.flags=PV_TYPE_INT|PV_VAL_INT;
278 278
 			if (rv->v.action)
279
-				pval.ri=run_actions(h, rv->v.action, msg);
279
+				pval.ri=run_actions_safe(h, rv->v.action, msg);
280 280
 			else
281 281
 				pval.ri=0;
282 282
 			ret=pval.ri;
... ...
@@ -134,6 +134,7 @@ typedef enum _operand_subtype action_param_type;
134 134
 #define RETURN_R_F 2
135 135
 #define BREAK_R_F  4
136 136
 #define DROP_R_F   8
137
+#define IGNORE_ON_BREAK_R_F 256
137 138
 
138 139
 
139 140
 struct cfg_pos{
... ...
@@ -894,7 +894,7 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
894 894
 			break;
895 895
 		case RV_ACTION_ST:
896 896
 			if (rv->v.action)
897
-				*i=(run_actions(h, rv->v.action, msg)>0);
897
+				*i=(run_actions_safe(h, rv->v.action, msg)>0);
898 898
 			else
899 899
 				*i=0;
900 900
 			break;
... ...
@@ -1089,7 +1089,7 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
1089 1089
 			break;
1090 1090
 		case RV_ACTION_ST:
1091 1091
 			if (rv->v.action)
1092
-				i=(run_actions(h, rv->v.action, msg)>0);
1092
+				i=(run_actions_safe(h, rv->v.action, msg)>0);
1093 1093
 			else
1094 1094
 				i=0;
1095 1095
 			tmpv->s=int2str(i, &tmpv->len);