From: Keith Bostic Date: Sat, 29 Jan 1994 09:18:01 +0000 (-0800) Subject: The change ensures that symbolic links are not used in export paths, X-Git-Tag: BSD-4_4_Lite1-Snapshot-Development~620 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/aab9c17c3a1499f9a32732b076aba0e252fc3ca7 The change ensures that symbolic links are not used in export paths, since the match can never succeed after realpath() converts incoming paths to the "real" one. From Rick Macklem root@snowhite.cis.uoguelph.ca (Charlie Root) SCCS-vsn: sbin/mountd/exports.5 8.2 SCCS-vsn: sbin/mountd/mountd.c 8.6 --- diff --git a/usr/src/sbin/mountd/exports.5 b/usr/src/sbin/mountd/exports.5 index 60d556ec41..aeb1cb1421 100644 --- a/usr/src/sbin/mountd/exports.5 +++ b/usr/src/sbin/mountd/exports.5 @@ -3,7 +3,7 @@ .\" .\" %sccs.include.redist.roff% .\" -.\" @(#)exports.5 8.1 (Berkeley) %G% +.\" @(#)exports.5 8.2 (Berkeley) %G% .\" .Dd .Dt EXPORTS 5 @@ -46,6 +46,8 @@ followed by the .Fl alldirs flag; this form allows the host(s) to mount any directory within the filesystem. +The pathnames must not have any symbolic links in them and should not have +any "." or ".." components. Mount points for a filesystem may appear on multiple lines each with different sets of hosts and export options. .Pp diff --git a/usr/src/sbin/mountd/mountd.c b/usr/src/sbin/mountd/mountd.c index d5d4c1db57..e871fb0696 100644 --- a/usr/src/sbin/mountd/mountd.c +++ b/usr/src/sbin/mountd/mountd.c @@ -15,7 +15,7 @@ static char copyright[] = #endif not lint #ifndef lint -static char sccsid[] = "@(#)mountd.c 8.5 (Berkeley) %G%"; +static char sccsid[] = "@(#)mountd.c 8.6 (Berkeley) %G%"; #endif not lint #include @@ -112,6 +112,7 @@ struct hostlist { /* Global defs */ int mntsrv(), umntall_each(), xdr_fhs(), xdr_mlist(), xdr_dir(), xdr_explist(); +int check_dirpath(); void get_exportlist(), send_umntall(), nextfield(), out_of_mem(); void get_mountlist(), add_mlist(), del_mlist(), free_exp(), free_grp(); void getexp_err(), hang_dirp(), add_dlist(), free_dir(), free_host(); @@ -533,7 +534,6 @@ get_exportlist() register struct grouplist *grp, *tgrp; struct exportlist **epp; struct dirlist *dirhead; - struct stat sb; struct statfs fsb, *fsp; struct hostent *hpe; struct ucred anon; @@ -641,8 +641,7 @@ get_exportlist() } else if (*cp == '/') { savedc = *endcp; *endcp = '\0'; - if (stat(cp, &sb) >= 0 && - (sb.st_mode & S_IFMT) == S_IFDIR && + if (check_dirpath(cp) && statfs(cp, &fsb) >= 0) { if (got_nondir) { syslog(LOG_ERR, "Dirs must be first"); @@ -1981,3 +1980,32 @@ check_options(dp) } return (0); } + +/* + * Check an absolute directory path for any symbolic links. Return true + * if no symbolic links are found. + */ +int +check_dirpath(dirp) + register char *dirp; +{ + register char *cp; + int ret = 1; + struct stat sb; + + cp = dirp + 1; + while (*cp && ret) { + if (*cp == '/') { + *cp = '\0'; + if (lstat(dirp, &sb) < 0 || + (sb.st_mode & S_IFMT) != S_IFDIR) + ret = 0; + *cp = '/'; + } + cp++; + } + if (lstat(dirp, &sb) < 0 || + (sb.st_mode & S_IFMT) != S_IFDIR) + ret = 0; + return (ret); +}