summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2017-08-25 13:17:32 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2017-08-28 17:18:50 +0200
commit79c09386549472ecea72c60850ee33f7a4e49e9c (patch)
tree1ce54452c107bfbeb971f4f33384ea7063112357
parentd3d56d0fe1856b7fe27584eb90e8349e883cd56b (diff)
parser: Fix memleaks for STRING token (and derived ones)
The common paradigm here is that all parser rules converting string tokens into symbols must free the string token if it's not used anymore. This is unrelated to the %destructor directive, since that will apply only if the parser discards the token, which is not the case then. While being at it, simplify error handling in parser rule for listing conntrack helpers (error() won't return NULL) and drop the unused extra parameter passed to error() in level_type rule. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--src/parser_bison.y46
-rw-r--r--src/rule.c1
2 files changed, 37 insertions, 10 deletions
diff --git a/src/parser_bison.y b/src/parser_bison.y
index d149178c..d4b29029 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -724,6 +724,7 @@ common_block : INCLUDE QUOTED_STRING stmt_separator
if (symbol_lookup(scope, $2) != NULL) {
erec_queue(error(&@2, "redefinition of symbol '%s'", $2),
state->msgs);
+ xfree($2);
YYERROR;
}
@@ -860,6 +861,7 @@ add_cmd : TABLE table_spec
int type;
erec = ct_objtype_parse(&@$, $2, &type);
+ xfree($2);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -939,6 +941,7 @@ create_cmd : TABLE table_spec
int type;
erec = ct_objtype_parse(&@$, $2, &type);
+ xfree($2);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -992,6 +995,7 @@ delete_cmd : TABLE table_spec
int type;
erec = ct_objtype_parse(&@$, $2, &type);
+ xfree($2);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -1079,6 +1083,7 @@ list_cmd : TABLE table_spec
int type;
erec = ct_objtype_parse(&@$, $2, &type);
+ xfree($2);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -1093,16 +1098,12 @@ list_cmd : TABLE table_spec
if (strcmp($2, "helpers") == 0) {
cmd = CMD_OBJ_CT_HELPERS;
} else {
- struct error_record *erec;
-
- erec = error(&@$, "unknown ct class '%s', want 'helpers'", $2);
-
- if (erec != NULL) {
- erec_queue(erec, state->msgs);
- YYERROR;
- } else
- YYERROR;
+ erec_queue(error(&@$, "unknown ct class '%s', want 'helpers'", $2),
+ state->msgs);
+ xfree($2);
+ YYERROR;
}
+ xfree($2);
$$ = cmd_alloc(CMD_LIST, cmd, &$4, &@$, NULL);
}
@@ -1231,9 +1232,11 @@ table_options : FLAGS STRING
{
if (strcmp($2, "dormant") == 0) {
$<table>0->flags = TABLE_F_DORMANT;
+ xfree($2);
} else {
erec_queue(error(&@2, "unknown table option %s", $2),
state->msgs);
+ xfree($2);
YYERROR;
}
}
@@ -1302,6 +1305,7 @@ table_block : /* empty */ { $$ = $<table>-1; }
int type;
erec = ct_objtype_parse(&@$, $3, &type);
+ xfree($3);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -1478,8 +1482,10 @@ type_identifier_list : type_identifier
if (dtype == NULL) {
erec_queue(error(&@3, "unknown datatype %s", $3),
state->msgs);
+ xfree($3);
YYERROR;
}
+ xfree($3);
$$ = concat_subtype_add($$, dtype->type);
}
;
@@ -1533,6 +1539,7 @@ hook_spec : TYPE STRING HOOK STRING dev_spec PRIORITY prio_spec
if (chain_type == NULL) {
erec_queue(error(&@2, "unknown chain type %s", $2),
state->msgs);
+ xfree($2);
YYERROR;
}
$<chain>0->type = xstrdup(chain_type);
@@ -1542,6 +1549,7 @@ hook_spec : TYPE STRING HOOK STRING dev_spec PRIORITY prio_spec
if ($<chain>0->hookstr == NULL) {
erec_queue(error(&@4, "unknown chain hook %s", $4),
state->msgs);
+ xfree($4);
YYERROR;
}
xfree($4);
@@ -1589,6 +1597,7 @@ time_spec : STRING
uint64_t res;
erec = time_parse(&@1, $1, &res);
+ xfree($1);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -1919,10 +1928,12 @@ level_type : string
else if (!strcmp("debug", $1))
$$ = LOG_DEBUG;
else {
- erec_queue(error(&@1, "invalid log level", $1),
+ erec_queue(error(&@1, "invalid log level"),
state->msgs);
+ xfree($1);
YYERROR;
}
+ xfree($1);
}
;
@@ -1980,6 +1991,7 @@ limit_stmt : LIMIT RATE limit_mode NUM SLASH time_unit limit_burst
uint64_t rate, unit;
erec = rate_parse(&@$, $5, &rate, &unit);
+ xfree($5);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -2010,6 +2022,7 @@ quota_used : /* empty */ { $$ = 0; }
uint64_t rate;
erec = data_unit_parse(&@$, $3, &rate);
+ xfree($3);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -2024,6 +2037,7 @@ quota_stmt : QUOTA quota_mode NUM quota_unit quota_used
uint64_t rate;
erec = data_unit_parse(&@$, $4, &rate);
+ xfree($4);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -2055,6 +2069,7 @@ limit_burst : /* empty */ { $$ = 0; }
uint64_t rate;
erec = data_unit_parse(&@$, $3, &rate);
+ xfree($3);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -2093,6 +2108,7 @@ reject_opts : /* empty */
current_scope(state),
$4);
$<stmt>0->reject.expr->dtype = &icmp_code_type;
+ xfree($4);
}
| WITH ICMP6 TYPE STRING
{
@@ -2103,6 +2119,7 @@ reject_opts : /* empty */
current_scope(state),
$4);
$<stmt>0->reject.expr->dtype = &icmpv6_code_type;
+ xfree($4);
}
| WITH ICMPX TYPE STRING
{
@@ -2112,6 +2129,7 @@ reject_opts : /* empty */
current_scope(state),
$4);
$<stmt>0->reject.expr->dtype = &icmpx_code_type;
+ xfree($4);
}
| WITH TCP RESET
{
@@ -2392,6 +2410,7 @@ variable_expr : '$' identifier
if (symbol_lookup(scope, $2) == NULL) {
erec_queue(error(&@2, "unknown identifier '%s'", $2),
state->msgs);
+ xfree($2);
YYERROR;
}
@@ -2692,6 +2711,7 @@ quota_config : quota_mode NUM quota_unit quota_used
uint64_t rate;
erec = data_unit_parse(&@$, $3, &rate);
+ xfree($3);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -2994,6 +3014,7 @@ meta_expr : META meta_key
unsigned int key;
erec = meta_key_parse(&@$, $2, &key);
+ xfree($2);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -3046,6 +3067,7 @@ meta_stmt : META meta_key SET expr
unsigned int key;
erec = meta_key_parse(&@$, $2, &key);
+ xfree($2);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -3110,6 +3132,7 @@ ct_expr : CT ct_key
unsigned int key;
erec = ct_key_parse(&@$, $2, &key);
+ xfree($2);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -3123,6 +3146,7 @@ ct_expr : CT ct_key
int8_t direction;
erec = ct_dir_parse(&@$, $2, &direction);
+ xfree($2);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -3180,6 +3204,7 @@ ct_stmt : CT ct_key SET expr
unsigned int key;
erec = ct_key_parse(&@$, $2, &key);
+ xfree($2);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
@@ -3202,6 +3227,7 @@ ct_stmt : CT ct_key SET expr
int8_t direction;
erec = ct_dir_parse(&@$, $2, &direction);
+ xfree($2);
if (erec != NULL) {
erec_queue(erec, state->msgs);
YYERROR;
diff --git a/src/rule.c b/src/rule.c
index 140855f5..44d36c16 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -926,6 +926,7 @@ struct monitor *monitor_alloc(uint32_t format, uint32_t type, const char *event)
void monitor_free(struct monitor *m)
{
+ xfree(m->event);
xfree(m);
}