From df9215be9011b8724cc6ef6c76c5869aa6f0fd7c Mon Sep 17 00:00:00 2001 From: Taylor R Campbell <riastradh@NetBSD.org> Date: Sat, 26 Mar 2022 20:13:04 +0000 Subject: [PATCH] link(2): Require caller to own file and be in file's group. --- sys/kern/vfs_syscalls.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 695010d1da0a..54b22a6fda6f 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -2566,9 +2566,10 @@ do_sys_mkfifoat(struct lwp *l, int fdat, const char *path, mode_t mode) /* ARGSUSED */ int do_sys_linkat(struct lwp *l, int fdpath, const char *path, int fdlink, - const char *link, int follow, register_t *retval) + const char *link, int follow, register_t *retval) { struct vnode *vp; + struct vattr vattr; struct pathbuf *linkpb; struct nameidata nd; namei_simple_flags_t ns_flags; @@ -2603,6 +2604,28 @@ do_sys_linkat(struct lwp *l, int fdpath, const char *path, int fdlink, error = EXDEV; goto abortop; } + /* + * Prevent hard-linking files you don't own, or in a group that + * you're not in. + */ + error = VOP_GETATTR(vp, &vattr, l->l_cred); + if (error) + goto abortop; + if (vattr.va_uid != kauth_cred_geteuid(l->l_cred)) { + error = EPERM; + goto abortop; + } + if (vattr.va_gid != kauth_cred_getegid(l->l_cred)) { + int groupmember; + error = kauth_cred_ismember_gid(l->l_cred, vattr.va_gid, + &groupmember); + if (error) + goto abortop; + if (!groupmember) { + error = EPERM; + goto abortop; + } + } error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); VOP_UNLOCK(nd.ni_dvp); vrele(nd.ni_dvp);