aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2024-09-06 23:41:12 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2024-09-27 22:13:49 +0000
commitc09ca8f43de12fecf701920675b793cbafba58c5 (patch)
treefe33fa41d634c580e43d1aa84f1c1200cc29d456
parent6828020a6b9a869ccc15c02fa9571357b3bcc2a6 (diff)
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)
-rw-r--r--usr.sbin/mountd/mountd.c44
1 files 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 {