aboutsummaryrefslogtreecommitdiff
path: root/sbin/mount
diff options
context:
space:
mode:
authorDoug Rabson <dfr@FreeBSD.org>2022-11-07 16:56:09 +0000
committerDoug Rabson <dfr@FreeBSD.org>2022-12-19 16:44:54 +0000
commita3f714c4ff8cf3754520f330abe783aa6a06dcdb (patch)
tree33418937f63f9c509c729b84f83c4e892fdc41a6 /sbin/mount
parent5cfacab13291a2551f145ca4a68db42d095e4a9a (diff)
downloadsrc-a3f714c4ff8cf3754520f330abe783aa6a06dcdb.tar.gz
src-a3f714c4ff8cf3754520f330abe783aa6a06dcdb.zip
Diffstat (limited to 'sbin/mount')
-rw-r--r--sbin/mount/getmntopts.c14
-rw-r--r--sbin/mount/mntopts.h1
-rw-r--r--sbin/mount/mount.c23
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;