From 4afbe3ba97a0cb880e6f459e059f561a519bd307 Mon Sep 17 00:00:00 2001 From: Ilias Aberkane Date: Thu, 17 Sep 2026 12:01:57 +0200 Subject: [PATCH 1/3] if-options: fix NULL dereference on missing variable name strskipwhite() returns NULL when the remainder of a define/define6/ definend line is empty or whitespace-only (e.g. a trailing escaped space protected from the config trim). parse_option() then called strcasecmp(NULL, "reserved") and crashed. Treat a NULL variable name the same as an absent one: error out for types that require a name and accept np == NULL for OT_OPTION. Reproducer: a config line 'define 119 string=x\\ ' (escaped trailing space) segfaults at strcasecmp in parse_option (if-options.c:2120). Fixes #731. --- src/if-options.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/if-options.c b/src/if-options.c index 7b445f45..7616c8f5 100644 --- a/src/if-options.c +++ b/src/if-options.c @@ -2117,7 +2117,13 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, fp = strwhite(arg); if (fp) *fp++ = '\0'; - if (strcasecmp(arg, "reserved")) { + if (arg == NULL) { + if (!(t & OT_OPTION)) { + logerrx("type requires a variable name"); + return -1; + } + np = NULL; + } else if (strcasecmp(arg, "reserved")) { np = strdup(arg); if (np == NULL) { logerr(__func__); From 1cbccb4f990225655514f91962fcff8e8cdc3314 Mon Sep 17 00:00:00 2001 From: Ilias Aberkane Date: Thu, 17 Sep 2026 13:54:51 +0200 Subject: [PATCH 2/3] if-options: restrict nameless option defines to encap Nameless OT_OPTION entries are only meaningful inside an encap block; a nameless top-level define/embed is unreferenceable and leaves opt->var NULL, which later crashes print_option (%s) and the embedded lookup (strcmp). Require a variable name outside O_ENCAP for both the absent-name and empty-name cases. --- src/if-options.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/if-options.c b/src/if-options.c index 7616c8f5..833bc0eb 100644 --- a/src/if-options.c +++ b/src/if-options.c @@ -2106,7 +2106,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, } /* variable */ if (!fp) { - if (!(t & OT_OPTION)) { + if (!(t & OT_OPTION) || opt != O_ENCAP) { logerrx("type %s requires a variable name", arg); return -1; @@ -2118,7 +2118,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, if (fp) *fp++ = '\0'; if (arg == NULL) { - if (!(t & OT_OPTION)) { + if (!(t & OT_OPTION) || opt != O_ENCAP) { logerrx("type requires a variable name"); return -1; } From 963d2c8cb242b8d4149794f0d9714c749321d9d0 Mon Sep 17 00:00:00 2001 From: Ilias Aberkane Date: Tue, 22 Sep 2026 23:31:56 +0200 Subject: [PATCH 3/3] if-options: fix clang-format violation in nameless-option guard The guard added in the previous commit exceeds the column limit, which the clang-format CI check rejects. Wrap the logerrx() call. --- src/if-options.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/if-options.c b/src/if-options.c index 833bc0eb..0ec71a43 100644 --- a/src/if-options.c +++ b/src/if-options.c @@ -2119,7 +2119,8 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, *fp++ = '\0'; if (arg == NULL) { if (!(t & OT_OPTION) || opt != O_ENCAP) { - logerrx("type requires a variable name"); + logerrx( + "type requires a variable name"); return -1; } np = NULL;