diff --git a/sbin/i386/mount_msdos/mount_msdos.c b/sbin/i386/mount_msdos/mount_msdos.c index dfb15df9a23e..ebb646adbacc 100644 --- a/sbin/i386/mount_msdos/mount_msdos.c +++ b/sbin/i386/mount_msdos/mount_msdos.c @@ -87,7 +87,7 @@ main(argc, argv) struct msdosfs_args args; struct stat sb; int c, error, mntflags, set_gid, set_uid, set_mask; - char *dev, *dir, ndir[MAXPATHLEN+1]; + char *dev, *dir, mntpath[MAXPATHLEN]; struct vfsconf vfc; mntflags = set_gid = set_uid = set_mask = 0; @@ -145,15 +145,13 @@ main(argc, argv) dev = argv[optind]; dir = argv[optind + 1]; - if (dir[0] != '/') { - warnx("\"%s\" is a relative path", dir); - if (getcwd(ndir, sizeof(ndir)) == NULL) - err(EX_OSERR, "getcwd"); - strncat(ndir, "/", sizeof(ndir) - strlen(ndir) - 1); - strncat(ndir, dir, sizeof(ndir) - strlen(ndir) - 1); - dir = ndir; - warnx("using \"%s\" instead", dir); - } + + /* + * Resolve the mountpoint with realpath(3) and remove unnecessary + * slashes from the devicename if there are any. + */ + (void)checkpath(dir, mntpath); + (void)rmslashes(dev, dev); args.fspec = dev; args.export.ex_root = -2; /* unchecked anyway on DOS fs */ @@ -162,8 +160,8 @@ main(argc, argv) else args.export.ex_flags = 0; if (!set_gid || !set_uid || !set_mask) { - if (stat(dir, &sb) == -1) - err(EX_OSERR, "stat %s", dir); + if (stat(mntpath, &sb) == -1) + err(EX_OSERR, "stat %s", mntpath); if (!set_uid) args.uid = sb.st_uid; @@ -183,7 +181,7 @@ main(argc, argv) if (error) errx(EX_OSERR, "msdos filesystem is not available"); - if (mount(vfc.vfc_name, dir, mntflags, &args) < 0) + if (mount(vfc.vfc_name, mntpath, mntflags, &args) < 0) err(EX_OSERR, "%s", dev); exit (0); diff --git a/sbin/mount/getmntopts.c b/sbin/mount/getmntopts.c index c80c26281fb6..ffc18bfac219 100644 --- a/sbin/mount/getmntopts.c +++ b/sbin/mount/getmntopts.c @@ -41,10 +41,13 @@ static const char rcsid[] = #endif /* not lint */ #include +#include #include +#include #include #include +#include #include "mntopts.h" @@ -106,3 +109,39 @@ getmntopts(options, m0, flagp, altflagp) free(optbuf); } + +void +rmslashes(rrpin, rrpout) + char *rrpin; + char *rrpout; +{ + char *rrpoutstart; + + *rrpout = *rrpin; + for (rrpoutstart = rrpout; *rrpin != '\0'; *rrpout++ = *rrpin++) { + + /* skip all double slashes */ + while (*rrpin == '/' && *(rrpin + 1) == '/') + rrpin++; + } + + /* remove trailing slash if necessary */ + if (rrpout - rrpoutstart > 1 && *(rrpout - 1) == '/') + *(rrpout - 1) = '\0'; + else + *rrpout = '\0'; +} + +void +checkpath(path, resolved) + const char *path; + char *resolved; +{ + struct stat sb; + + if (realpath(path, resolved) != NULL && stat(resolved, &sb) == 0) { + if (!S_ISDIR(sb.st_mode)) + errx(EX_USAGE, "%s: not a directory", resolved); + } else + errx(EX_USAGE, "%s: %s", resolved, strerror(errno)); +} diff --git a/sbin/mount/mntopts.h b/sbin/mount/mntopts.h index dd98298dba62..73c3c15a838f 100644 --- a/sbin/mount/mntopts.h +++ b/sbin/mount/mntopts.h @@ -88,4 +88,6 @@ struct mntopt { MOPT_NOCLUSTERW void getmntopts __P((const char *, const struct mntopt *, int *, int *)); +void rmslashes __P((char *, char *)); +void checkpath __P((const char *, char resolved_path[])); extern int getmnt_silent; diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c index 039ee9542e07..b84696a2944d 100644 --- a/sbin/mount/mount.c +++ b/sbin/mount/mount.c @@ -61,6 +61,7 @@ static const char rcsid[] = #include #include "extern.h" +#include "mntopts.h" #include "pathnames.h" /* `meta' options */ @@ -354,7 +355,6 @@ mountfs(vfstype, spec, name, flags, options, mntopts) NULL }; const char *argv[100], **edir; - struct stat sb; struct statfs sf; pid_t pid; int argc, i, status; @@ -365,16 +365,8 @@ mountfs(vfstype, spec, name, flags, options, mntopts) (void)&name; #endif - if (realpath(name, mntpath) != NULL && stat(mntpath, &sb) == 0) { - if (!S_ISDIR(sb.st_mode)) { - warnx("%s: not a directory", mntpath); - return (1); - } - } else { - warn("%s", mntpath); - return (1); - } - + /* resolve the mountpoint with realpath(3) */ + (void)checkpath(name, mntpath); name = mntpath; if (mntopts == NULL) diff --git a/sbin/mount_cd9660/mount_cd9660.c b/sbin/mount_cd9660/mount_cd9660.c index a3185d7f9f3c..665d22f64787 100644 --- a/sbin/mount_cd9660/mount_cd9660.c +++ b/sbin/mount_cd9660/mount_cd9660.c @@ -85,7 +85,7 @@ main(int argc, char **argv) { struct iso_args args; int ch, mntflags, opts; - char *dev, *dir; + char *dev, *dir, mntpath[MAXPATHLEN]; struct vfsconf vfc; int error, verbose; @@ -128,6 +128,13 @@ main(int argc, char **argv) dev = argv[0]; dir = argv[1]; + /* + * Resolve the mountpoint with realpath(3) and remove unnecessary + * slashes from the devicename if there are any. + */ + (void)checkpath(dir, mntpath); + (void)rmslashes(dev, dev); + #define DEFAULT_ROOTUID -2 /* * ISO 9660 filesystems are not writeable. @@ -168,7 +175,7 @@ main(int argc, char **argv) if (error) errx(1, "cd9660 filesystem is not available"); - if (mount(vfc.vfc_name, dir, mntflags, &args) < 0) + if (mount(vfc.vfc_name, mntpath, mntflags, &args) < 0) err(1, NULL); exit(0); } diff --git a/sbin/mount_ext2fs/mount_ext2fs.c b/sbin/mount_ext2fs/mount_ext2fs.c index 00a20246f499..ded01952a936 100644 --- a/sbin/mount_ext2fs/mount_ext2fs.c +++ b/sbin/mount_ext2fs/mount_ext2fs.c @@ -76,7 +76,7 @@ main(argc, argv) { struct ufs_args args; int ch, mntflags; - char *fs_name, *options; + char *fs_name, *options, mntpath[MAXPATHLEN]; struct vfsconf vfc; int error; @@ -100,6 +100,13 @@ main(argc, argv) args.fspec = argv[0]; /* the name of the device file */ fs_name = argv[1]; /* the mount point */ + /* + * Resolve the mountpoint with realpath(3) and remove unnecessary + * slashes from the devicename if there are any. + */ + (void)checkpath(fs_name, mntpath); + (void)rmslashes(args.fspec, args.fspec); + #define DEFAULT_ROOTUID -2 args.export.ex_root = DEFAULT_ROOTUID; if (mntflags & MNT_RDONLY) @@ -118,7 +125,7 @@ main(argc, argv) if (error) errx(EX_OSERR, "ext2fs filesystem is not available"); - if (mount(vfc.vfc_name, fs_name, mntflags, &args) < 0) + if (mount(vfc.vfc_name, mntpath, mntflags, &args) < 0) err(EX_OSERR, "%s", args.fspec); exit(0); } diff --git a/sbin/mount_ifs/getmntopts.c b/sbin/mount_ifs/getmntopts.c index c80c26281fb6..ffc18bfac219 100644 --- a/sbin/mount_ifs/getmntopts.c +++ b/sbin/mount_ifs/getmntopts.c @@ -41,10 +41,13 @@ static const char rcsid[] = #endif /* not lint */ #include +#include #include +#include #include #include +#include #include "mntopts.h" @@ -106,3 +109,39 @@ getmntopts(options, m0, flagp, altflagp) free(optbuf); } + +void +rmslashes(rrpin, rrpout) + char *rrpin; + char *rrpout; +{ + char *rrpoutstart; + + *rrpout = *rrpin; + for (rrpoutstart = rrpout; *rrpin != '\0'; *rrpout++ = *rrpin++) { + + /* skip all double slashes */ + while (*rrpin == '/' && *(rrpin + 1) == '/') + rrpin++; + } + + /* remove trailing slash if necessary */ + if (rrpout - rrpoutstart > 1 && *(rrpout - 1) == '/') + *(rrpout - 1) = '\0'; + else + *rrpout = '\0'; +} + +void +checkpath(path, resolved) + const char *path; + char *resolved; +{ + struct stat sb; + + if (realpath(path, resolved) != NULL && stat(resolved, &sb) == 0) { + if (!S_ISDIR(sb.st_mode)) + errx(EX_USAGE, "%s: not a directory", resolved); + } else + errx(EX_USAGE, "%s: %s", resolved, strerror(errno)); +} diff --git a/sbin/mount_ifs/mntopts.h b/sbin/mount_ifs/mntopts.h index dd98298dba62..73c3c15a838f 100644 --- a/sbin/mount_ifs/mntopts.h +++ b/sbin/mount_ifs/mntopts.h @@ -88,4 +88,6 @@ struct mntopt { MOPT_NOCLUSTERW void getmntopts __P((const char *, const struct mntopt *, int *, int *)); +void rmslashes __P((char *, char *)); +void checkpath __P((const char *, char resolved_path[])); extern int getmnt_silent; diff --git a/sbin/mount_ifs/mount.c b/sbin/mount_ifs/mount.c index 039ee9542e07..b84696a2944d 100644 --- a/sbin/mount_ifs/mount.c +++ b/sbin/mount_ifs/mount.c @@ -61,6 +61,7 @@ static const char rcsid[] = #include #include "extern.h" +#include "mntopts.h" #include "pathnames.h" /* `meta' options */ @@ -354,7 +355,6 @@ mountfs(vfstype, spec, name, flags, options, mntopts) NULL }; const char *argv[100], **edir; - struct stat sb; struct statfs sf; pid_t pid; int argc, i, status; @@ -365,16 +365,8 @@ mountfs(vfstype, spec, name, flags, options, mntopts) (void)&name; #endif - if (realpath(name, mntpath) != NULL && stat(mntpath, &sb) == 0) { - if (!S_ISDIR(sb.st_mode)) { - warnx("%s: not a directory", mntpath); - return (1); - } - } else { - warn("%s", mntpath); - return (1); - } - + /* resolve the mountpoint with realpath(3) */ + (void)checkpath(name, mntpath); name = mntpath; if (mntopts == NULL) diff --git a/sbin/mount_msdos/mount_msdos.c b/sbin/mount_msdos/mount_msdos.c index dfb15df9a23e..ebb646adbacc 100644 --- a/sbin/mount_msdos/mount_msdos.c +++ b/sbin/mount_msdos/mount_msdos.c @@ -87,7 +87,7 @@ main(argc, argv) struct msdosfs_args args; struct stat sb; int c, error, mntflags, set_gid, set_uid, set_mask; - char *dev, *dir, ndir[MAXPATHLEN+1]; + char *dev, *dir, mntpath[MAXPATHLEN]; struct vfsconf vfc; mntflags = set_gid = set_uid = set_mask = 0; @@ -145,15 +145,13 @@ main(argc, argv) dev = argv[optind]; dir = argv[optind + 1]; - if (dir[0] != '/') { - warnx("\"%s\" is a relative path", dir); - if (getcwd(ndir, sizeof(ndir)) == NULL) - err(EX_OSERR, "getcwd"); - strncat(ndir, "/", sizeof(ndir) - strlen(ndir) - 1); - strncat(ndir, dir, sizeof(ndir) - strlen(ndir) - 1); - dir = ndir; - warnx("using \"%s\" instead", dir); - } + + /* + * Resolve the mountpoint with realpath(3) and remove unnecessary + * slashes from the devicename if there are any. + */ + (void)checkpath(dir, mntpath); + (void)rmslashes(dev, dev); args.fspec = dev; args.export.ex_root = -2; /* unchecked anyway on DOS fs */ @@ -162,8 +160,8 @@ main(argc, argv) else args.export.ex_flags = 0; if (!set_gid || !set_uid || !set_mask) { - if (stat(dir, &sb) == -1) - err(EX_OSERR, "stat %s", dir); + if (stat(mntpath, &sb) == -1) + err(EX_OSERR, "stat %s", mntpath); if (!set_uid) args.uid = sb.st_uid; @@ -183,7 +181,7 @@ main(argc, argv) if (error) errx(EX_OSERR, "msdos filesystem is not available"); - if (mount(vfc.vfc_name, dir, mntflags, &args) < 0) + if (mount(vfc.vfc_name, mntpath, mntflags, &args) < 0) err(EX_OSERR, "%s", dev); exit (0); diff --git a/sbin/mount_msdosfs/mount_msdosfs.c b/sbin/mount_msdosfs/mount_msdosfs.c index dfb15df9a23e..ebb646adbacc 100644 --- a/sbin/mount_msdosfs/mount_msdosfs.c +++ b/sbin/mount_msdosfs/mount_msdosfs.c @@ -87,7 +87,7 @@ main(argc, argv) struct msdosfs_args args; struct stat sb; int c, error, mntflags, set_gid, set_uid, set_mask; - char *dev, *dir, ndir[MAXPATHLEN+1]; + char *dev, *dir, mntpath[MAXPATHLEN]; struct vfsconf vfc; mntflags = set_gid = set_uid = set_mask = 0; @@ -145,15 +145,13 @@ main(argc, argv) dev = argv[optind]; dir = argv[optind + 1]; - if (dir[0] != '/') { - warnx("\"%s\" is a relative path", dir); - if (getcwd(ndir, sizeof(ndir)) == NULL) - err(EX_OSERR, "getcwd"); - strncat(ndir, "/", sizeof(ndir) - strlen(ndir) - 1); - strncat(ndir, dir, sizeof(ndir) - strlen(ndir) - 1); - dir = ndir; - warnx("using \"%s\" instead", dir); - } + + /* + * Resolve the mountpoint with realpath(3) and remove unnecessary + * slashes from the devicename if there are any. + */ + (void)checkpath(dir, mntpath); + (void)rmslashes(dev, dev); args.fspec = dev; args.export.ex_root = -2; /* unchecked anyway on DOS fs */ @@ -162,8 +160,8 @@ main(argc, argv) else args.export.ex_flags = 0; if (!set_gid || !set_uid || !set_mask) { - if (stat(dir, &sb) == -1) - err(EX_OSERR, "stat %s", dir); + if (stat(mntpath, &sb) == -1) + err(EX_OSERR, "stat %s", mntpath); if (!set_uid) args.uid = sb.st_uid; @@ -183,7 +181,7 @@ main(argc, argv) if (error) errx(EX_OSERR, "msdos filesystem is not available"); - if (mount(vfc.vfc_name, dir, mntflags, &args) < 0) + if (mount(vfc.vfc_name, mntpath, mntflags, &args) < 0) err(EX_OSERR, "%s", dev); exit (0); diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c index 7e04cd62f312..588f14d0bfb3 100644 --- a/sbin/mount_nfs/mount_nfs.c +++ b/sbin/mount_nfs/mount_nfs.c @@ -256,6 +256,7 @@ main(argc, argv) struct nfsd_cargs ncd; int mntflags, altflags, i, nfssvc_flag, num; char *name, *p, *spec; + char mntpath[MAXPATHLEN]; struct vfsconf vfc; int error = 0; #ifdef NFSKERB @@ -470,6 +471,9 @@ main(argc, argv) if (!getnfsargs(spec, nfsargsp)) exit(1); + /* resolve the mountpoint with realpath(3) */ + (void)checkpath(name, mntpath); + #ifdef __FreeBSD__ error = getvfsbyname("nfs", &vfc); if (error && vfsisloadable("nfs")) { @@ -481,11 +485,11 @@ main(argc, argv) if (error) errx(EX_OSERR, "nfs filesystem is not available"); - if (mount(vfc.vfc_name, name, mntflags, nfsargsp)) - err(1, "%s", name); + if (mount(vfc.vfc_name, mntpath, mntflags, nfsargsp)) + err(1, "%s", mntpath); #else - if (mount("nfs", name, mntflags, nfsargsp)) - err(1, "%s", name); + if (mount("nfs", mntpath, mntflags, nfsargsp)) + err(1, "%s", mntpath); #endif if (nfsargsp->flags & (NFSMNT_NQNFS | NFSMNT_KERB)) { if ((opflags & ISBGRND) == 0) { @@ -502,7 +506,7 @@ main(argc, argv) } openlog("mount_nfs:", LOG_PID, LOG_DAEMON); nfssvc_flag = NFSSVC_MNTD; - ncd.ncd_dirp = name; + ncd.ncd_dirp = mntpath; while (nfssvc(nfssvc_flag, (caddr_t)&ncd) < 0) { if (errno != ENEEDAUTH) { syslog(LOG_ERR, "nfssvc err %m"); @@ -652,27 +656,50 @@ getnfsargs(spec, nfsargsp) #endif struct timeval pertry, try; enum clnt_stat clnt_stat; - int so = RPC_ANYSOCK, i, nfsvers, mntvers, orgcnt; + int so = RPC_ANYSOCK, i, nfsvers, mntvers, orgcnt, speclen; char *hostp, *delimp; #ifdef NFSKERB char *cp; #endif - u_short tport = 0; + u_short tport; static struct nfhret nfhret; static char nam[MNAMELEN + 1]; - strncpy(nam, spec, MNAMELEN); - nam[MNAMELEN] = '\0'; - if ((delimp = strchr(spec, '@')) != NULL) { - hostp = delimp + 1; - } else if ((delimp = strchr(spec, ':')) != NULL) { + tport = 0; + + if ((delimp = strchr(spec, ':')) != NULL) { hostp = spec; spec = delimp + 1; + } else if ((delimp = strrchr(spec, '@')) != NULL) { + warnx("path@server syntax is deprecated, use server:path"); + hostp = delimp + 1; } else { - warnx("no : or @ spec"); + warnx("no : nfs-name"); return (0); } + *delimp = '\0'; + + /* + * If there has been a trailing slash at mounttime it seems + * that some mountd implementations fail to remove the mount + * entries from their mountlist while unmounting. + */ + speclen = strlen(spec); + while (speclen > 1 && spec[speclen - 1] == '/') { + spec[speclen - 1] = '\0'; + speclen--; + } + if (strlen(hostp) + strlen(spec) + 1 > MNAMELEN) { + warnx("%s:%s: %s", hostp, spec, strerror(ENAMETOOLONG)); + return (0); + } + + /* Make both '@' and ':' notations equal */ + strcat(nam, hostp); + strcat(nam, ":"); + strcat(nam, spec); + /* * DUMB!! Until the mount protocol works on iso transport, we must * supply both an iso and an inet address for the host. diff --git a/sbin/mount_ntfs/mount_ntfs.c b/sbin/mount_ntfs/mount_ntfs.c index add62a1dd1d3..95b86c22a9cf 100644 --- a/sbin/mount_ntfs/mount_ntfs.c +++ b/sbin/mount_ntfs/mount_ntfs.c @@ -67,8 +67,8 @@ main(argc, argv) { struct ntfs_args args; struct stat sb; - int c, mntflags, set_gid, set_uid, set_mask,error; - char *dev, *dir, ndir[MAXPATHLEN+1]; + int c, mntflags, set_gid, set_uid, set_mask, error; + char *dev, *dir, ndir[MAXPATHLEN+1], mntpath[MAXPATHLEN]; #if __FreeBSD_version >= 300000 struct vfsconf vfc; #else @@ -113,15 +113,13 @@ main(argc, argv) dev = argv[optind]; dir = argv[optind + 1]; - if (dir[0] != '/') { - warnx("\"%s\" is a relative path", dir); - if (getcwd(ndir, sizeof(ndir)) == NULL) - err(EX_OSERR, "getcwd"); - strncat(ndir, "/", sizeof(ndir) - strlen(ndir) - 1); - strncat(ndir, dir, sizeof(ndir) - strlen(ndir) - 1); - dir = ndir; - warnx("using \"%s\" instead", dir); - } + + /* + * Resolve the mountpoint with realpath(3) and remove unnecessary + * slashes from the devicename if there are any. + */ + (void)checkpath(dir, mntpath); + (void)rmslashes(dev, dev); args.fspec = dev; args.export.ex_root = 65534; /* unchecked anyway on DOS fs */ @@ -130,8 +128,8 @@ main(argc, argv) else args.export.ex_flags = 0; if (!set_gid || !set_uid || !set_mask) { - if (stat(dir, &sb) == -1) - err(EX_OSERR, "stat %s", dir); + if (stat(mntpath, &sb) == -1) + err(EX_OSERR, "stat %s", mntpath); if (!set_uid) args.uid = sb.st_uid; @@ -166,9 +164,9 @@ main(argc, argv) errx(EX_OSERR, "ntfs filesystem is not available"); #if __FreeBSD_version >= 300000 - if (mount(vfc.vfc_name, dir, mntflags, &args) < 0) + if (mount(vfc.vfc_name, mntpath, mntflags, &args) < 0) #else - if (mount(vfc->vfc_index, dir, mntflags, &args) < 0) + if (mount(vfc->vfc_index, mntpath, mntflags, &args) < 0) #endif err(EX_OSERR, "%s", dev); diff --git a/sbin/mount_null/mount_null.c b/sbin/mount_null/mount_null.c index a866e385f9fa..cf6120863bac 100644 --- a/sbin/mount_null/mount_null.c +++ b/sbin/mount_null/mount_null.c @@ -97,11 +97,9 @@ main(argc, argv) if (argc != 2) usage(); - if (realpath(argv[0], target) == 0) - err(EX_OSERR, "%s", target); - - if (realpath(argv[1], source) == 0) - err(EX_OSERR, "%s", source); + /* resolve target and source with realpath(3) */ + (void)checkpath(argv[0], target); + (void)checkpath(argv[1], source); if (subdir(target, source) || subdir(source, target)) errx(EX_USAGE, "%s (%s) and %s are not distinct paths", diff --git a/sbin/mount_nullfs/mount_nullfs.c b/sbin/mount_nullfs/mount_nullfs.c index a866e385f9fa..cf6120863bac 100644 --- a/sbin/mount_nullfs/mount_nullfs.c +++ b/sbin/mount_nullfs/mount_nullfs.c @@ -97,11 +97,9 @@ main(argc, argv) if (argc != 2) usage(); - if (realpath(argv[0], target) == 0) - err(EX_OSERR, "%s", target); - - if (realpath(argv[1], source) == 0) - err(EX_OSERR, "%s", source); + /* resolve target and source with realpath(3) */ + (void)checkpath(argv[0], target); + (void)checkpath(argv[1], source); if (subdir(target, source) || subdir(source, target)) errx(EX_USAGE, "%s (%s) and %s are not distinct paths", diff --git a/sbin/mount_portal/mount_portal.c b/sbin/mount_portal/mount_portal.c index c0b1852a44b3..48cf609df74e 100644 --- a/sbin/mount_portal/mount_portal.c +++ b/sbin/mount_portal/mount_portal.c @@ -105,7 +105,7 @@ main(argc, argv) struct portal_args args; struct sockaddr_un un; char *conf; - char *mountpt; + char mountpt[MAXPATHLEN]; int mntflags = 0; char tag[32]; struct vfsconf vfc; @@ -142,7 +142,9 @@ main(argc, argv) * Get config file and mount point */ conf = argv[optind]; - mountpt = argv[optind+1]; + + /* resolve the mountpoint with realpath(3) */ + (void)checkpath(argv[optind+1], mountpt); /* * Construct the listening socket diff --git a/sbin/mount_portalfs/mount_portalfs.c b/sbin/mount_portalfs/mount_portalfs.c index c0b1852a44b3..48cf609df74e 100644 --- a/sbin/mount_portalfs/mount_portalfs.c +++ b/sbin/mount_portalfs/mount_portalfs.c @@ -105,7 +105,7 @@ main(argc, argv) struct portal_args args; struct sockaddr_un un; char *conf; - char *mountpt; + char mountpt[MAXPATHLEN]; int mntflags = 0; char tag[32]; struct vfsconf vfc; @@ -142,7 +142,9 @@ main(argc, argv) * Get config file and mount point */ conf = argv[optind]; - mountpt = argv[optind+1]; + + /* resolve the mountpoint with realpath(3) */ + (void)checkpath(argv[optind+1], mountpt); /* * Construct the listening socket diff --git a/sbin/mount_std/mount_std.c b/sbin/mount_std/mount_std.c index 2d2c5a2670f3..2a95764d8542 100644 --- a/sbin/mount_std/mount_std.c +++ b/sbin/mount_std/mount_std.c @@ -71,6 +71,7 @@ main(argc, argv) char *argv[]; { int ch, mntflags; + char mntpath[MAXPATHLEN]; struct vfsconf vfc; int error; @@ -116,7 +117,10 @@ main(argc, argv) if (error) errx(EX_OSERR, "%s filesystem not available", fsname); - if (mount(vfc.vfc_name, argv[1], mntflags, NULL)) + /* resolve the mountpoint with realpath(3) */ + (void)checkpath(argv[1], mntpath); + + if (mount(vfc.vfc_name, mntpath, mntflags, NULL)) err(EX_OSERR, NULL); exit(0); } diff --git a/sbin/mount_umap/mount_umap.c b/sbin/mount_umap/mount_umap.c index 888682c3b98e..0aa7b8c075a3 100644 --- a/sbin/mount_umap/mount_umap.c +++ b/sbin/mount_umap/mount_umap.c @@ -98,7 +98,8 @@ main(argc, argv) FILE *fp, *gfp; u_long gmapdata[GMAPFILEENTRIES][2], mapdata[MAPFILEENTRIES][2]; int ch, count, gnentries, mntflags, nentries; - char *gmapfile, *mapfile, *source, *target, buf[20]; + char *gmapfile, *mapfile, buf[20]; + char source[MAXPATHLEN], target[MAXPATHLEN]; struct vfsconf vfc; int error; @@ -125,8 +126,9 @@ main(argc, argv) if (argc != 2 || mapfile == NULL || gmapfile == NULL) usage(); - source = argv[0]; - target = argv[1]; + /* resolve both target and source with realpath(3) */ + (void)checkpath(argv[0], source); + (void)checkpath(argv[1], target); /* Read in uid mapping data. */ if ((fp = fopen(mapfile, "r")) == NULL) diff --git a/sbin/mount_umapfs/mount_umapfs.c b/sbin/mount_umapfs/mount_umapfs.c index 888682c3b98e..0aa7b8c075a3 100644 --- a/sbin/mount_umapfs/mount_umapfs.c +++ b/sbin/mount_umapfs/mount_umapfs.c @@ -98,7 +98,8 @@ main(argc, argv) FILE *fp, *gfp; u_long gmapdata[GMAPFILEENTRIES][2], mapdata[MAPFILEENTRIES][2]; int ch, count, gnentries, mntflags, nentries; - char *gmapfile, *mapfile, *source, *target, buf[20]; + char *gmapfile, *mapfile, buf[20]; + char source[MAXPATHLEN], target[MAXPATHLEN]; struct vfsconf vfc; int error; @@ -125,8 +126,9 @@ main(argc, argv) if (argc != 2 || mapfile == NULL || gmapfile == NULL) usage(); - source = argv[0]; - target = argv[1]; + /* resolve both target and source with realpath(3) */ + (void)checkpath(argv[0], source); + (void)checkpath(argv[1], target); /* Read in uid mapping data. */ if ((fp = fopen(mapfile, "r")) == NULL) diff --git a/sbin/mount_union/mount_union.c b/sbin/mount_union/mount_union.c index 4222ede4baad..1d5d3ebc504c 100644 --- a/sbin/mount_union/mount_union.c +++ b/sbin/mount_union/mount_union.c @@ -109,11 +109,9 @@ main(argc, argv) if (argc != 2) usage(); - if (realpath(argv[0], target) == 0) - err(EX_OSERR, "%s", target); - - if (realpath(argv[1], source) == 0) - err(EX_OSERR, "%s", source); + /* resolve both target and source with realpath(3) */ + (void)checkpath(argv[0], target); + (void)checkpath(argv[1], source); if (subdir(target, source) || subdir(source, target)) errx(EX_USAGE, "%s (%s) and %s (%s) are not distinct paths", diff --git a/sbin/mount_unionfs/mount_unionfs.c b/sbin/mount_unionfs/mount_unionfs.c index 4222ede4baad..1d5d3ebc504c 100644 --- a/sbin/mount_unionfs/mount_unionfs.c +++ b/sbin/mount_unionfs/mount_unionfs.c @@ -109,11 +109,9 @@ main(argc, argv) if (argc != 2) usage(); - if (realpath(argv[0], target) == 0) - err(EX_OSERR, "%s", target); - - if (realpath(argv[1], source) == 0) - err(EX_OSERR, "%s", source); + /* resolve both target and source with realpath(3) */ + (void)checkpath(argv[0], target); + (void)checkpath(argv[1], source); if (subdir(target, source) || subdir(source, target)) errx(EX_USAGE, "%s (%s) and %s (%s) are not distinct paths", diff --git a/usr.sbin/mount_portalfs/mount_portalfs.c b/usr.sbin/mount_portalfs/mount_portalfs.c index c0b1852a44b3..48cf609df74e 100644 --- a/usr.sbin/mount_portalfs/mount_portalfs.c +++ b/usr.sbin/mount_portalfs/mount_portalfs.c @@ -105,7 +105,7 @@ main(argc, argv) struct portal_args args; struct sockaddr_un un; char *conf; - char *mountpt; + char mountpt[MAXPATHLEN]; int mntflags = 0; char tag[32]; struct vfsconf vfc; @@ -142,7 +142,9 @@ main(argc, argv) * Get config file and mount point */ conf = argv[optind]; - mountpt = argv[optind+1]; + + /* resolve the mountpoint with realpath(3) */ + (void)checkpath(argv[optind+1], mountpt); /* * Construct the listening socket