Move the "no (hard) linking directories" and "no cross-mount links"
authorguenther <guenther@openbsd.org>
Mon, 25 Mar 2024 17:57:07 +0000 (17:57 +0000)
committerguenther <guenther@openbsd.org>
Mon, 25 Mar 2024 17:57:07 +0000 (17:57 +0000)
checks from all the filesystems that support hardlinks at all into
the VFS layer.  Simplify, EPERM description in link(2).

ok miod@ mpi@

lib/libc/sys/link.2
sys/kern/vfs_syscalls.c
sys/miscfs/fuse/fuse_vnops.c
sys/nfs/nfs_serv.c
sys/nfs/nfs_vnops.c
sys/tmpfs/tmpfs_vnops.c
sys/ufs/ext2fs/ext2fs_vnops.c
sys/ufs/ufs/ufs_vnops.c

index a9c241a..4d6f9f1 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: link.2,v 1.29 2015/09/10 17:55:21 schwarze Exp $
+.\"    $OpenBSD: link.2,v 1.30 2024/03/25 17:57:07 guenther Exp $
 .\"    $NetBSD: link.2,v 1.7 1995/02/27 12:34:01 cgd Exp $
 .\"
 .\" Copyright (c) 1980, 1991, 1993
@@ -30,7 +30,7 @@
 .\"
 .\"     @(#)link.2     8.3 (Berkeley) 1/12/94
 .\"
-.Dd $Mdocdate: September 10 2015 $
+.Dd $Mdocdate: March 25 2024 $
 .Dt LINK 2
 .Os
 .Sh NAME
@@ -172,11 +172,7 @@ does exist.
 .It Bq Er EPERM
 The file named by
 .Fa name1
-is a directory and the effective
-user ID is not superuser,
-or the file system containing the file does not permit the use of
-.Fn link
-on a directory.
+is a directory.
 .It Bq Er EPERM
 The file named by
 .Fa name1
index 6eb0796..40445f2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vfs_syscalls.c,v 1.363 2024/02/03 18:51:58 beck Exp $ */
+/*     $OpenBSD: vfs_syscalls.c,v 1.364 2024/03/25 17:57:07 guenther Exp $     */
 /*     $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $        */
 
 /*
@@ -1703,7 +1703,6 @@ dolinkat(struct proc *p, int fd1, const char *path1, int fd2,
        struct vnode *vp;
        struct nameidata nd;
        int error, follow;
-       int flags;
 
        if (flag & ~AT_SYMLINK_FOLLOW)
                return (EINVAL);
@@ -1716,12 +1715,12 @@ dolinkat(struct proc *p, int fd1, const char *path1, int fd2,
                return (error);
        vp = nd.ni_vp;
 
-       flags = LOCKPARENT;
        if (vp->v_type == VDIR) {
-               flags |= STRIPSLASHES;
+               error = EPERM;
+               goto out;
        }
 
-       NDINITAT(&nd, CREATE, flags, UIO_USERSPACE, fd2, path2, p);
+       NDINITAT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, fd2, path2, p);
        nd.ni_pledge = PLEDGE_CPATH;
        nd.ni_unveil = UNVEIL_CREATE;
        if ((error = namei(&nd)) != 0)
@@ -1736,6 +1735,15 @@ dolinkat(struct proc *p, int fd1, const char *path1, int fd2,
                error = EEXIST;
                goto out;
        }
+
+       /* No cross-mount links! */
+       if (nd.ni_dvp->v_mount != vp->v_mount) {
+               VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+               vput(nd.ni_dvp);
+               error = EXDEV;
+               goto out;
+       }
+
        error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
 out:
        vrele(vp);
index c3c06c8..173d705 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_vnops.c,v 1.67 2023/09/08 20:00:28 mvs Exp $ */
+/* $OpenBSD: fuse_vnops.c,v 1.68 2024/03/25 17:57:07 guenther Exp $ */
 /*
  * Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
  *
@@ -646,16 +646,6 @@ fusefs_link(void *v)
                error = ENOSYS;
                goto out2;
        }
-       if (vp->v_type == VDIR) {
-               VOP_ABORTOP(dvp, cnp);
-               error = EPERM;
-               goto out2;
-       }
-       if (dvp->v_mount != vp->v_mount) {
-               VOP_ABORTOP(dvp, cnp);
-               error = EXDEV;
-               goto out2;
-       }
        if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) {
                VOP_ABORTOP(dvp, cnp);
                goto out2;
index 421c402..2f4624c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nfs_serv.c,v 1.122 2023/03/08 04:43:09 guenther Exp $ */
+/*     $OpenBSD: nfs_serv.c,v 1.123 2024/03/25 17:57:07 guenther Exp $ */
 /*     $NetBSD: nfs_serv.c,v 1.34 1997/05/12 23:37:12 fvdl Exp $       */
 
 /*
@@ -1598,7 +1598,7 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                error = 0;
                goto nfsmout;
        }
-       if (vp->v_type == VDIR && (error = suser_ucred(cred)) != 0)
+       if (vp->v_type == VDIR)
                goto out1;
 
        NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, NULL, procp);
index d61f0a4..bda27cd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nfs_vnops.c,v 1.193 2023/04/26 10:00:37 beck Exp $    */
+/*     $OpenBSD: nfs_vnops.c,v 1.194 2024/03/25 17:57:07 guenther Exp $        */
 /*     $NetBSD: nfs_vnops.c,v 1.62.4.1 1996/07/08 20:26:52 jtc Exp $   */
 
 /*
@@ -1769,11 +1769,6 @@ nfs_link(void *v)
 
        info.nmi_v3 = NFS_ISV3(vp);
 
-       if (dvp->v_mount != vp->v_mount) {
-               pool_put(&namei_pool, cnp->cn_pnbuf);
-               vput(dvp);
-               return (EXDEV);
-       }
        error = vn_lock(vp, LK_EXCLUSIVE);
        if (error != 0) {
                VOP_ABORTOP(dvp, cnp);
index d910b15..b1c68fd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tmpfs_vnops.c,v 1.53 2023/09/08 20:00:28 mvs Exp $    */
+/*     $OpenBSD: tmpfs_vnops.c,v 1.54 2024/03/25 17:57:07 guenther Exp $       */
 /*     $NetBSD: tmpfs_vnops.c,v 1.100 2012/11/05 17:27:39 dholland Exp $       */
 
 /*
@@ -771,21 +771,8 @@ tmpfs_link(void *v)
        int error;
 
        KASSERT(VOP_ISLOCKED(dvp));
-
-       if (vp->v_type == VDIR) {
-               VOP_ABORTOP(dvp, cnp);
-               vput(dvp);
-               return EPERM;
-       }
-
        KASSERT(dvp != vp);
 
-       if (dvp->v_mount != vp->v_mount) {
-               VOP_ABORTOP(dvp, cnp);
-               vput(dvp);
-               return EXDEV;
-       }
-
        dnode = VP_TO_TMPFS_DIR(dvp);
        node = VP_TO_TMPFS_NODE(vp);
 
index 235590d..eee8e11 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ext2fs_vnops.c,v 1.91 2023/03/08 04:43:09 guenther Exp $      */
+/*     $OpenBSD: ext2fs_vnops.c,v 1.92 2024/03/25 17:57:07 guenther Exp $      */
 /*     $NetBSD: ext2fs_vnops.c,v 1.1 1997/06/11 09:34:09 bouyer Exp $  */
 
 /*
@@ -435,16 +435,6 @@ ext2fs_link(void *v)
        if ((cnp->cn_flags & HASBUF) == 0)
                panic("ext2fs_link: no name");
 #endif
-       if (vp->v_type == VDIR) {
-               VOP_ABORTOP(dvp, cnp);
-               error = EISDIR;
-               goto out2;
-       }
-       if (dvp->v_mount != vp->v_mount) {
-               VOP_ABORTOP(dvp, cnp);
-               error = EXDEV;
-               goto out2;
-       }
        if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) {
                VOP_ABORTOP(dvp, cnp);
                goto out2;
index d6cee35..d329284 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ufs_vnops.c,v 1.160 2024/02/03 18:51:59 beck Exp $    */
+/*     $OpenBSD: ufs_vnops.c,v 1.161 2024/03/25 17:57:07 guenther Exp $        */
 /*     $NetBSD: ufs_vnops.c,v 1.18 1996/05/11 18:28:04 mycroft Exp $   */
 
 /*
@@ -621,16 +621,6 @@ ufs_link(void *v)
        if ((cnp->cn_flags & HASBUF) == 0)
                panic("ufs_link: no name");
 #endif
-       if (vp->v_type == VDIR) {
-               VOP_ABORTOP(dvp, cnp);
-               error = EPERM;
-               goto out2;
-       }
-       if (dvp->v_mount != vp->v_mount) {
-               VOP_ABORTOP(dvp, cnp);
-               error = EXDEV;
-               goto out2;
-       }
        if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) {
                VOP_ABORTOP(dvp, cnp);
                goto out2;