Download raw body.
relayd 2/3: add set and append keyword sanity check
This adds a sanity to check "set" and "append" to avoid config errors.
Configs with a matching keyword together with set or append, no longer
parse.
OK?
commit 115dee3b4923a9c1b6c9e253ef7926de2251e1eb
Author: Rafael Sadowski <rafael@sizeofvoid.org>
Date: Fri Oct 9 13:45:15 2026 +0200
relayd: add set and append keyword sanity check
"set" and "append" write a literal key and value, so a matching keyword
had no effect there. Reject it instead of ignoring it.
diff --git a/parse.y b/parse.y
index a317f84..765ee90 100644
--- a/parse.y
+++ b/parse.y
@@ -145,6 +145,7 @@ struct relay *relay_inherit(struct relay *, struct relay *);
int getservice(char *);
int is_if_in_group(const char *, const char *);
static struct keyname *proto_keyname(char *);
+static int rule_kv_sanity_check(enum key_option);
static void rule_kv_setvalue(struct kv *, const char *, u_int16_t);
typedef struct {
@@ -1603,6 +1604,11 @@ ruleopts : METHOD STRING {
free($2);
}
| COOKIE key_option optpattern STRING value {
+ if (rule_kv_sanity_check($2) == -1) {
+ free($4);
+ free($5);
+ YYERROR;
+ }
keytype = KEY_TYPE_COOKIE;
rule->rule_kv[keytype].kv_key = strdup($4);
rule->rule_kv[keytype].kv_option = $2;
@@ -1627,6 +1633,11 @@ ruleopts : METHOD STRING {
rule->rule_kv[keytype].kv_type = keytype;
}
| HEADER key_option optpattern STRING value {
+ if (rule_kv_sanity_check($2) == -1) {
+ free($4);
+ free($5);
+ YYERROR;
+ }
keytype = KEY_TYPE_HEADER;
rule->rule_kv[keytype].kv_option = $2;
rule->rule_kv[keytype].kv_key = strdup($4);
@@ -1659,6 +1670,11 @@ ruleopts : METHOD STRING {
rule->rule_kv[keytype].kv_type = keytype;
}
| PATH key_option optpattern STRING value {
+ if (rule_kv_sanity_check($2) == -1) {
+ free($4);
+ free($5);
+ YYERROR;
+ }
keytype = KEY_TYPE_PATH;
rule->rule_kv[keytype].kv_option = $2;
/* default: path matching is case-sensitive. */
@@ -1698,6 +1714,11 @@ ruleopts : METHOD STRING {
rule->rule_kv[keytype].kv_type = keytype;
}
| QUERYSTR key_option optpattern STRING value {
+ if (rule_kv_sanity_check($2) == -1) {
+ free($4);
+ free($5);
+ YYERROR;
+ }
switch ($2) {
case KEY_OPTION_APPEND:
case KEY_OPTION_SET:
@@ -1744,6 +1765,11 @@ ruleopts : METHOD STRING {
rule->rule_kv[keytype].kv_type = keytype;
}
| URL key_option optpattern optdigest value {
+ if (rule_kv_sanity_check($2) == -1) {
+ free($4.digest);
+ free($5);
+ YYERROR;
+ }
switch ($2) {
case KEY_OPTION_APPEND:
case KEY_OPTION_SET:
@@ -3822,6 +3848,18 @@ proto_keyname(char *name)
return kname;
}
+static int
+rule_kv_sanity_check(enum key_option opt)
+{
+ if ((opt == KEY_OPTION_SET || opt == KEY_OPTION_APPEND) &&
+ (key_flag != 0 || val_flag != 0)) {
+ yyerror("matching keyword not allowed with %s",
+ opt == KEY_OPTION_SET ? "set" : "append");
+ return (-1);
+ }
+ return (0);
+}
+
/*
* Set the value of a rule kv. An omitted value matches anything,
* otherwise use the matching keyword or the per-type default.
relayd 2/3: add set and append keyword sanity check