git: 07cd69e272da - main - mountd.c: Define a new -a command line option
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 28 Dec 2024 21:26:07 UTC
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=07cd69e272da2f116950f2bde6dfcc404f869f0c commit 07cd69e272da2f116950f2bde6dfcc404f869f0c Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2024-12-28 21:24:51 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2024-12-28 21:24:51 +0000 mountd.c: Define a new -a command line option Bugzilla PR#282995 reported that, when a file system was exported with the "-alldirs" flag, the export succeeded even if the directory path was not a server file system mount point. This behaviour for "-alldirs" was only documented in the Example section of exports(5) and had not been enforced since FreeBSD2. (A patch applied between FreeBSD1 and FreeBSD2 broke the check for file system mount point.) Since the behaviour of allowing the export has existed since FreeBSD2, the concensus on a mailing list was that it would be a POLA violation to change it now. Therefore, this patch adds a new "-a" mountd command line option to enforce a check for the exported directory being a server file system mount point. PR: 282995 MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D48137 --- usr.sbin/mountd/mountd.c | 51 +++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index cb87535f6c3b..4457a925c2ed 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -215,7 +215,8 @@ static int do_export_mount(struct exportlist *, struct statfs *); static int do_mount(struct exportlist *, struct grouplist *, uint64_t, struct expcred *, char *, int, struct statfs *, int, int *); static int do_opt(char **, char **, struct exportlist *, - struct grouplist *, int *, uint64_t *, struct expcred *); + struct grouplist *, int *, uint64_t *, struct expcred *, + char *); static struct exportlist *ex_search(fsid_t *, struct exportlisthead *); static struct exportlist *get_exp(void); static void free_dir(struct dirlist *); @@ -292,6 +293,7 @@ static int sock_fdpos; static int suspend_nfsd = 0; static int nofork = 0; static int skiplocalhost = 0; +static int alldirs_fail = 0; static int opt_flags; static int have_v6 = 1; @@ -320,6 +322,7 @@ static gid_t *tmp_groups = NULL; #define OP_MASKLEN 0x200 #define OP_SEC 0x400 #define OP_CLASSMASK 0x800 /* mask not specified, is Class A/B/C default */ +#define OP_NOTROOT 0x1000 /* Mark the the mount path is not a fs root */ #ifdef DEBUG static int debug = 1; @@ -458,7 +461,7 @@ main(int argc, char **argv) else close(s); - while ((c = getopt(argc, argv, "2Adeh:lNnp:RrSs")) != -1) + while ((c = getopt(argc, argv, "2Aadeh:lNnp:RrSs")) != -1) switch (c) { case '2': force_v2 = 1; @@ -466,6 +469,9 @@ main(int argc, char **argv) case 'A': warn_admin = 0; break; + case 'a': + alldirs_fail = 1; + break; case 'e': /* now a no-op, since this is the default */ break; @@ -1590,6 +1596,7 @@ get_exportlist_one(int passno) v4root_phase = 0; dirhead = (struct dirlist *)NULL; unvis_dir[0] = '\0'; + fsb.f_mntonname[0] = '\0'; while (get_line()) { if (debug) @@ -1650,7 +1657,7 @@ get_exportlist_one(int passno) warnx("doing opt %s", cp); got_nondir = 1; if (do_opt(&cp, &endcp, ep, grp, &has_host, - &exflags, &anon)) { + &exflags, &anon, unvis_dir)) { getexp_err(ep, tgrp, NULL); goto nextline; } @@ -1731,19 +1738,9 @@ get_exportlist_one(int passno) fsb.f_fsid.val[1]); } - if (warn_admin != 0 && - (ep->ex_flag & EX_ADMINWARN) == 0 && - strcmp(unvis_dir, fsb.f_mntonname) != - 0) { - if (debug) - warnx("exporting %s exports entire " - "%s file system", unvis_dir, - fsb.f_mntonname); - syslog(LOG_ERR, "Warning: exporting %s " - "exports entire %s file system", - unvis_dir, fsb.f_mntonname); - ep->ex_flag |= EX_ADMINWARN; - } + if (strcmp(unvis_dir, fsb.f_mntonname) != + 0) + opt_flags |= OP_NOTROOT; /* * Add dirpath to export mount point. @@ -1813,6 +1810,17 @@ get_exportlist_one(int passno) "WARNING: No mask specified for %s, " "using out-of-date default", (&grp->gr_ptr.gt_net)->nt_name); + if ((opt_flags & OP_NOTROOT) != 0 && warn_admin != 0 && + (ep->ex_flag & EX_ADMINWARN) == 0 && unvis_dir[0] != '\0' && + fsb.f_mntonname[0] != '\0') { + if (debug) + warnx("exporting %s exports entire %s file " + "system", unvis_dir, fsb.f_mntonname); + syslog(LOG_ERR, "Warning: exporting %s exports " + "entire %s file system", unvis_dir, + fsb.f_mntonname); + ep->ex_flag |= EX_ADMINWARN; + } if (check_options(dirhead)) { getexp_err(ep, tgrp, NULL); goto nextline; @@ -2836,7 +2844,7 @@ parsesec(char *seclist, struct exportlist *ep) */ static int do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp, - int *has_hostp, uint64_t *exflagsp, struct expcred *cr) + int *has_hostp, uint64_t *exflagsp, struct expcred *cr, char *unvis_dir) { char *cpoptarg, *cpoptend; char *cp, *endcp, *cpopt, savedc, savedc2; @@ -2921,6 +2929,12 @@ do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp, syslog(LOG_ERR, "= after op: %s", cpopt); return (1); } + if ((opt_flags & OP_NOTROOT) != 0) { + syslog(LOG_ERR, "%s: path %s not mount point", + cpopt, unvis_dir); + if (alldirs_fail != 0) + return (1); + } opt_flags |= OP_ALLDIRS; } else if (!strcmp(cpopt, "public")) { if (fnd_equal == 1) { @@ -3317,7 +3331,8 @@ do_mount(struct exportlist *ep, struct grouplist *grp, uint64_t exflags, ret = 1; goto error_exit; } - if (opt_flags & OP_ALLDIRS) { + if ((opt_flags & OP_ALLDIRS) && + alldirs_fail != 0) { if (errno == EINVAL) syslog(LOG_ERR, "-alldirs requested but %s is not a filesystem mountpoint",