diff --git a/head/sbin/mount/mntopts.h b/head/sbin/mount/mntopts.h --- a/head/sbin/mount/mntopts.h +++ b/head/sbin/mount/mntopts.h @@ -45,6 +45,7 @@ #define MOPT_NOEXEC { "exec", 1, MNT_NOEXEC, 0 } #define MOPT_NOSUID { "suid", 1, MNT_NOSUID, 0 } #define MOPT_NOSYMFOLLOW { "symfollow", 1, MNT_NOSYMFOLLOW, 0 } +#define MOPT_NOSOCKBIND { "sockbind", 1, MNT_NOSOCKBIND, 0 } #define MOPT_RDONLY { "rdonly", 0, MNT_RDONLY, 0 } #define MOPT_SYNC { "sync", 0, MNT_SYNCHRONOUS, 0 } #define MOPT_UNION { "union", 0, MNT_UNION, 0 } @@ -88,6 +89,7 @@ MOPT_SUIDDIR, /* must be before MOPT_NOSUID */ \ MOPT_NOSUID, \ MOPT_NOSYMFOLLOW, \ + MOPT_NOSOCKBIND, \ MOPT_RDONLY, \ MOPT_UNION, \ MOPT_NOCLUSTERR, \ diff --git a/head/sbin/mount/mount.c b/head/sbin/mount/mount.c --- a/head/sbin/mount/mount.c +++ b/head/sbin/mount/mount.c @@ -999,6 +999,7 @@ if (flags & MNT_UNTRUSTED) res = catopt(res, "untrusted"); if (flags & MNT_NOCOVER) res = catopt(res, "nocover"); if (flags & MNT_EMPTYDIR) res = catopt(res, "emptydir"); + if (flags & MNT_NOSOCKBIND) res = catopt(res, "nosockbind"); return (res); } diff --git a/head/sys/fs/nullfs/null_vfsops.c b/head/sys/fs/nullfs/null_vfsops.c --- a/head/sys/fs/nullfs/null_vfsops.c +++ b/head/sys/fs/nullfs/null_vfsops.c @@ -351,8 +351,9 @@ /* now copy across the "interesting" information and fake the rest */ sbp->f_type = mstat->f_type; sbp->f_flags = (sbp->f_flags & (MNT_RDONLY | MNT_NOEXEC | MNT_NOSUID | - MNT_UNION | MNT_NOSYMFOLLOW | MNT_AUTOMOUNTED)) | - (mstat->f_flags & ~(MNT_ROOTFS | MNT_AUTOMOUNTED)); + MNT_UNION | MNT_NOSYMFOLLOW | MNT_AUTOMOUNTED | MNT_NOSOCKBIND)) | + (mstat->f_flags & ~(MNT_ROOTFS | MNT_AUTOMOUNTED | + MNT_NOSOCKBIND)); sbp->f_bsize = mstat->f_bsize; sbp->f_iosize = mstat->f_iosize; sbp->f_blocks = mstat->f_blocks; diff --git a/head/sys/kern/uipc_usrreq.c b/head/sys/kern/uipc_usrreq.c --- a/head/sys/kern/uipc_usrreq.c +++ b/head/sys/kern/uipc_usrreq.c @@ -592,7 +592,7 @@ struct nameidata nd; struct unpcb *unp; struct vnode *vp; - struct mount *mp; + struct mount *mp, *mp0; cap_rights_t rights; char *buf; @@ -664,6 +664,13 @@ error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); #endif + if (error == 0) { + mp0 = nd.ni_dvp->v_mount; + if (mp0 == NULL) + error = ENOENT; + else if((mp0->mnt_flag & MNT_NOSOCKBIND) != 0) + error = EPERM; + } if (error == 0) error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); NDFREE(&nd, NDF_ONLY_PNBUF); diff --git a/head/sys/kern/vfs_mount.c b/head/sys/kern/vfs_mount.c --- a/head/sys/kern/vfs_mount.c +++ b/head/sys/kern/vfs_mount.c @@ -148,6 +148,7 @@ "rw", "nosuid", "noexec", + "nosockbind", NULL }; @@ -907,6 +908,12 @@ free(opt->name, M_MOUNT); opt->name = strdup("nonosymfollow", M_MOUNT); } + else if (strcmp(opt->name, "nosockbind") == 0) + fsflags |= MNT_NOSOCKBIND; + else if (strcmp(opt->name, "sockbind") == 0) { + free(opt->name, M_MOUNT); + opt->name = strdup("nonosockbind", M_MOUNT); + } else if (strcmp(opt->name, "noro") == 0) { fsflags &= ~MNT_RDONLY; autoro = false; diff --git a/head/sys/kern/vfs_subr.c b/head/sys/kern/vfs_subr.c --- a/head/sys/kern/vfs_subr.c +++ b/head/sys/kern/vfs_subr.c @@ -4313,6 +4313,7 @@ MNT_FLAG(MNT_FORCE); MNT_FLAG(MNT_SNAPSHOT); MNT_FLAG(MNT_BYFSID); + MNT_FLAG(MNT_NOSOCKBIND); #undef MNT_FLAG if (mflags != 0) { if (buf[0] != '\0') diff --git a/head/sys/sys/mount.h b/head/sys/sys/mount.h --- a/head/sys/sys/mount.h +++ b/head/sys/sys/mount.h @@ -336,6 +336,7 @@ { MNT_NOEXEC, "noexec" }, \ { MNT_NOSUID, "nosuid" }, \ { MNT_NOSYMFOLLOW, "nosymfollow" }, \ + { MNT_NOSOCKBIND, "nosockbind" }, \ { MNT_QUOTA, "with quotas" }, \ { MNT_RDONLY, "read-only" }, \ { MNT_SYNCHRONOUS, "synchronous" }, \ @@ -384,6 +385,7 @@ #define MNT_SUJ 0x0000000100000000ULL /* using journaled soft updates */ #define MNT_AUTOMOUNTED 0x0000000200000000ULL /* mounted by automountd(8) */ #define MNT_UNTRUSTED 0x0000000800000000ULL /* filesys metadata untrusted */ +#define MNT_NOSOCKBIND 0x0000020000000000ULL /* disallow UNIX domain bind() */ /* * NFS export related mount flags. @@ -423,7 +425,7 @@ MNT_IGNORE | MNT_EXPUBLIC | MNT_NOSYMFOLLOW | \ MNT_GJOURNAL | MNT_MULTILABEL | MNT_ACLS | \ MNT_NFS4ACLS | MNT_AUTOMOUNTED | MNT_VERIFIED | \ - MNT_UNTRUSTED) + MNT_UNTRUSTED | MNT_NOSOCKBIND) /* Mask of flags that can be updated. */ #define MNT_UPDATEMASK (MNT_NOSUID | MNT_NOEXEC | \ @@ -432,7 +434,7 @@ MNT_NOSYMFOLLOW | MNT_IGNORE | \ MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR | \ MNT_ACLS | MNT_USER | MNT_NFS4ACLS | \ - MNT_AUTOMOUNTED | MNT_UNTRUSTED) + MNT_AUTOMOUNTED | MNT_UNTRUSTED | MNT_NOSOCKBIND) /* * External filesystem command modifier flags.