diff options
Diffstat (limited to 'sbin/mount')
-rw-r--r-- | sbin/mount/getmntopts.c | 14 | ||||
-rw-r--r-- | sbin/mount/mntopts.h | 1 | ||||
-rw-r--r-- | sbin/mount/mount.c | 23 |
3 files changed, 35 insertions, 3 deletions
diff --git a/sbin/mount/getmntopts.c b/sbin/mount/getmntopts.c index fb739c6406ae..0ee6d99ed8b9 100644 --- a/sbin/mount/getmntopts.c +++ b/sbin/mount/getmntopts.c @@ -139,6 +139,20 @@ checkpath(const char *path, char *resolved) return (0); } +int +checkpath_allow_file(const char *path, char *resolved) +{ + struct stat sb; + + if (realpath(path, resolved) == NULL || stat(resolved, &sb) != 0) + return (1); + if (!S_ISDIR(sb.st_mode) && !S_ISREG(sb.st_mode)) { + errno = ENOTDIR; + return (1); + } + return (0); +} + void build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val, size_t len) diff --git a/sbin/mount/mntopts.h b/sbin/mount/mntopts.h index 183d6d9e501d..1d8b80069355 100644 --- a/sbin/mount/mntopts.h +++ b/sbin/mount/mntopts.h @@ -103,6 +103,7 @@ struct mntopt { void getmntopts(const char *, const struct mntopt *, int *, int *); void rmslashes(char *, char *); int checkpath(const char *, char resolved_path[]); +int checkpath_allow_file(const char *, char resolved_path[]); extern int getmnt_silent; void build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val, size_t len); void build_iovec_argf(struct iovec **iov, int *iovlen, const char *name, const char *fmt, ...); diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c index 6c986907bcda..7ac5cd965a8f 100644 --- a/sbin/mount/mount.c +++ b/sbin/mount/mount.c @@ -89,6 +89,7 @@ struct statfs *getmntpt(const char *); int hasopt(const char *, const char *); int ismounted(struct fstab *, struct statfs *, int); int isremountable(const char *); +int allow_file_mount(const char *); void mangle(char *, struct cpa *); char *update_options(char *, char *, int); int mountfs(const char *, const char *, const char *, @@ -503,6 +504,15 @@ isremountable(const char *vfsname) } int +allow_file_mount(const char *vfsname) +{ + + if (strcmp(vfsname, "nullfs") == 0) + return (1); + return (0); +} + +int hasopt(const char *mntopts, const char *option) { int negative, found; @@ -548,9 +558,16 @@ mountfs(const char *vfstype, const char *spec, const char *name, int flags, static struct cpa mnt_argv; /* resolve the mountpoint with realpath(3) */ - if (checkpath(name, mntpath) != 0) { - xo_warn("%s", mntpath); - return (1); + if (allow_file_mount(vfstype)) { + if (checkpath_allow_file(name, mntpath) != 0) { + xo_warn("%s", mntpath); + return (1); + } + } else { + if (checkpath(name, mntpath) != 0) { + xo_warn("%s", mntpath); + return (1); + } } name = mntpath; |