[PATCH] can_hardlink sysctl ported from FreeBSD

Matthias Schmidt schmidtm at mathematik.uni-marburg.de
Mon Sep 26 02:11:39 PDT 2005


Hi,

I ported the two FreeBSD sysctl's

- security.bsd.hardlink_check_uid
- security.bsd.hardlink_check_gid
to DragonFly.  If this sysctls are active unprivileged users cannot 
create hard links to files owned by other users/groups.  I added the 
sysctl's under kern, not security.bsd ...

Greets

	Matthias

diff -urN sys.orig/kern/vfs_syscalls.c sys/kern/vfs_syscalls.c
--- sys.orig/kern/vfs_syscalls.c	2005-09-17 09:43:00.000000000 +0200
+++ sys/kern/vfs_syscalls.c	2005-09-26 10:39:39.000000000 +0200
@@ -1569,6 +1569,46 @@
 	return (error);
 }
 
+static int hardlink_check_uid = 0;
+SYSCTL_INT(_kern, OID_AUTO, hardlink_check_uid, CTLFLAG_RW,
+    &hardlink_check_uid, 0, 
+    "Unprivileged processes cannot create hard links to files owned by other "
+    "users");
+static int hardlink_check_gid = 0;
+SYSCTL_INT(_kern, OID_AUTO, hardlink_check_gid, CTLFLAG_RW,
+    &hardlink_check_gid, 0,
+    "Unprivileged processes cannot create hard links to files owned by other "
+    "groups");
+
+static int
+can_hardlink(struct vnode *vp, struct thread *td, struct ucred *cred)
+{
+	struct vattr va;
+	int error;
+
+	if (suser_cred(cred, PRISON_ROOT) == 0)
+		return (0);
+	
+	if (!hardlink_check_uid)
+		return (0);
+	
+	error = VOP_GETATTR(vp, &va, td);
+	if (error != 0)
+		return (error);
+	
+	if (hardlink_check_uid) {
+		if (cred->cr_uid != va.va_uid)
+			return (EPERM);
+	}
+	
+	if (hardlink_check_gid) {
+		if (!groupmember(va.va_gid, cred))
+			return (EPERM);
+	}
+
+	return (0);
+}
+
 int
 kern_link(struct nlookupdata *nd, struct nlookupdata *linknd)
 {
@@ -1613,7 +1653,9 @@
 	/*
 	 * Finally run the new API VOP.
 	 */
-	error = VOP_NLINK(linknd->nl_ncp, vp, linknd->nl_cred);
+	error = can_hardlink(vp, td, td->td_proc->p_ucred);
+	if (error == 0)
+		error = VOP_NLINK(linknd->nl_ncp, vp, linknd->nl_cred);
 	vput(vp);
 	return (error);
 }




More information about the Submit mailing list