>Synopsis: pfctl bad parsing of '\n' following '\' at the end of a
comment line
>Category: system
>Environment:
System : OpenBSD 7.6
Details : OpenBSD 7.6 (GENERIC.MP) #0: Thu Nov 14 13:43:33 CET
2024
[email protected]:
/usr/src/sys/arch/amd64/compile/GENERIC.MP
Architecture: OpenBSD.amd64
Machine : amd64
>Description:
When pfctl reads a file and encouters a line of comment ending by the exact
combination of '\' followed by '\n', it considers the next line as part of
the comment.
Example based on /etc/example/pf.conf :
If I change this part of pf.conf :
===============================
# rdr-to $dns_server port domain
# By default, do not permit remote connections to X11
block return in on ! lo0 proto tcp to port 6000:6010
===============================
by this :
===============================
# rdr-to $dns_server port domain
# By default, do not permit remote connections to X11 \
block return in on ! lo0 proto tcp to port 6000:6010
===============================
The behaviours are the following :
1. Whitout '\' at the end of the comment line :
$ doas pfctl -vnf pf.conf
set skip on { lo }
block return all
pass all flags S/SA
block return in on ! lo0 proto tcp from any to any port 6000:6010
2. With '\' at the end of the comment line :
$ doas pfctl -vnf pf.conf
set skip on { lo }
block return all
pass all flags S/SA
>How-To-Repeat:
My friend Jerome advised me to take a look at other codes that could be
built in a similar way.
He was right. I found this good candidates :
bin/chio/parse.y
sbin/dhcp6leased/parse.y
sbin/dhcpleased/parse.y
sbin/iked/parse.y
sbin/ipsecctl/parse.y
sbin/pfctl/parse.y
sbin/unwind/parse.y
usr.sbin/acme-client/parse.y
usr.sbin/bgpd/parse.y
usr.sbin/dvmrpd/parse.y
usr.sbin/eigrpd/parse.y
usr.sbin/hostapd/parse.y
usr.sbin/httpd/parse.y
usr.sbin/ifstated/parse.y
usr.sbin/iscsictl/parse.y
usr.sbin/ldapd/parse.y
usr.sbin/ldomctl/parse.y
usr.sbin/ldpd/parse.y
usr.sbin/lpd/parse.y
usr.sbin/npppd/npppd/parse.y
usr.sbin/ntpd/parse.y
usr.sbin/ospf6d/parse.y
usr.sbin/ospfd/parse.y
usr.sbin/radiusd/parse.y
usr.sbin/rad/parse.y
usr.sbin/relayd/parse.y
usr.sbin/ripd/parse.y
usr.sbin/smtpd/parse.y
usr.sbin/snmpd/parse.y
usr.sbin/vmd/parse.y
The lgetc function is written in the same way as in the pfctl code.
I tested the patch bellow with ospfd and relayd, but not with the others.
>Fix:
The fix bellow seems to solve the issue for (at least) pfctl, ospfd and
relayd :
--- /usr/src/sbin/pfctl/parse.y Fri Sep 20 22:25:18 2024
+++ parse.y Mon Apr 7 15:23:10 2025
@@ -5143,7 +5143,7 @@
{
int c, next;
- if (quotec) {
+ if (quotec == '"') {
if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing quoted string");
if (file == topfile || popfile() == EOF)
@@ -5155,7 +5155,8 @@
while ((c = igetc()) == '\\') {
next = igetc();
- if (next != '\n') {
+ if (next != '\n' ||
+ (next == '\n' && quotec == '#')) {
c = next;
break;
}
@@ -5231,8 +5232,8 @@
yylval.lineno = file->lineno;
if (c == '#')
- while ((c = lgetc(0)) != '\n' && c != EOF)
- ; /* nothing */
+ while ((c = lgetc('#')) != '\n' && c != EOF)
+ ; /* nothing */
if (c == '$' && !expanding) {
while (1) {
if ((c = lgetc(0)) == EOF)
Best regards,
Olivier