git: c09ca8f43de1 - stable/14 - mountd: Add check for "=" after exports(5) options

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Fri, 27 Sep 2024 22:15:19 UTC
The branch stable/14 has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=c09ca8f43de12fecf701920675b793cbafba58c5

commit c09ca8f43de12fecf701920675b793cbafba58c5
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2024-09-06 23:41:12 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2024-09-27 22:13:49 +0000

    mountd: Add check for "=" after exports(5) options
    
    Some exports(5) options take a "=arg" component that provides an
    argument value for the option.  Others do not.
    Without this patch, if "=arg" was provided for an option that did
    not take an argument value, the "=arg" was simply ignored.
    This could result in confusion w.r.t. what was being exported,
    as noted by the Problem Report.
    
    This patch adds a check for "=arg" for the options that do not
    take an argument value and fails the exports line if one is found.
    
    PR:     281003
    (cherry picked from commit 3df987c99d1194a0e43a84853e934aa0c0ab09db)
---
 usr.sbin/mountd/mountd.c | 44 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c
index 6583bfbc0ffb..fa270f3a42d4 100644
--- a/usr.sbin/mountd/mountd.c
+++ b/usr.sbin/mountd/mountd.c
@@ -2827,7 +2827,7 @@ do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp,
 {
 	char *cpoptarg, *cpoptend;
 	char *cp, *endcp, *cpopt, savedc, savedc2;
-	int allflag, usedarg;
+	int allflag, usedarg, fnd_equal;
 
 	savedc2 = '\0';
 	cpopt = *cpp;
@@ -2838,14 +2838,18 @@ do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp,
 	while (cpopt && *cpopt) {
 		allflag = 1;
 		usedarg = -2;
+		fnd_equal = 0;
 		if ((cpoptend = strchr(cpopt, ','))) {
 			*cpoptend++ = '\0';
-			if ((cpoptarg = strchr(cpopt, '=')))
+			if ((cpoptarg = strchr(cpopt, '='))) {
 				*cpoptarg++ = '\0';
+				fnd_equal = 1;
+			}
 		} else {
-			if ((cpoptarg = strchr(cpopt, '=')))
+			if ((cpoptarg = strchr(cpopt, '='))) {
 				*cpoptarg++ = '\0';
-			else {
+				fnd_equal = 1;
+			} else {
 				*cp = savedc;
 				nextfield(&cp, &endcp);
 				**endcpp = '\0';
@@ -2858,6 +2862,10 @@ do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp,
 			}
 		}
 		if (!strcmp(cpopt, "ro") || !strcmp(cpopt, "o")) {
+			if (fnd_equal == 1) {
+				syslog(LOG_ERR, "= after op: %s", cpopt);
+				return (1);
+			}
 			*exflagsp |= MNT_EXRDONLY;
 		} else if (cpoptarg && (!strcmp(cpopt, "maproot") ||
 		    !(allflag = strcmp(cpopt, "mapall")) ||
@@ -2896,15 +2904,31 @@ do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp,
 			usedarg++;
 			opt_flags |= OP_NET;
 		} else if (!strcmp(cpopt, "alldirs")) {
+			if (fnd_equal == 1) {
+				syslog(LOG_ERR, "= after op: %s", cpopt);
+				return (1);
+			}
 			opt_flags |= OP_ALLDIRS;
 		} else if (!strcmp(cpopt, "public")) {
+			if (fnd_equal == 1) {
+				syslog(LOG_ERR, "= after op: %s", cpopt);
+				return (1);
+			}
 			*exflagsp |= MNT_EXPUBLIC;
 		} else if (!strcmp(cpopt, "webnfs")) {
+			if (fnd_equal == 1) {
+				syslog(LOG_ERR, "= after op: %s", cpopt);
+				return (1);
+			}
 			*exflagsp |= (MNT_EXPUBLIC|MNT_EXRDONLY|MNT_EXPORTANON);
 			opt_flags |= OP_MAPALL;
 		} else if (cpoptarg && !strcmp(cpopt, "index")) {
 			ep->ex_indexfile = strdup(cpoptarg);
 		} else if (!strcmp(cpopt, "quiet")) {
+			if (fnd_equal == 1) {
+				syslog(LOG_ERR, "= after op: %s", cpopt);
+				return (1);
+			}
 			opt_flags |= OP_QUIET;
 		} else if (cpoptarg && !strcmp(cpopt, "sec")) {
 			if (parsesec(cpoptarg, ep))
@@ -2912,10 +2936,22 @@ do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp,
 			opt_flags |= OP_SEC;
 			usedarg++;
 		} else if (!strcmp(cpopt, "tls")) {
+			if (fnd_equal == 1) {
+				syslog(LOG_ERR, "= after op: %s", cpopt);
+				return (1);
+			}
 			*exflagsp |= MNT_EXTLS;
 		} else if (!strcmp(cpopt, "tlscert")) {
+			if (fnd_equal == 1) {
+				syslog(LOG_ERR, "= after op: %s", cpopt);
+				return (1);
+			}
 			*exflagsp |= (MNT_EXTLS | MNT_EXTLSCERT);
 		} else if (!strcmp(cpopt, "tlscertuser")) {
+			if (fnd_equal == 1) {
+				syslog(LOG_ERR, "= after op: %s", cpopt);
+				return (1);
+			}
 			*exflagsp |= (MNT_EXTLS | MNT_EXTLSCERT |
 			    MNT_EXTLSCERTUSER);
 		} else {