>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

Reply via email to