DragonFly BSD
DragonFly submit List (threaded) for 2005-09
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: [PATCH] can_hardlink sysctl ported from FreeBSD


From: Matthias Schmidt <schmidtm@xxxxxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 28 Sep 2005 17:03:38 +0200

Hi,

Matthew Dillon wrote:
I like the concept, but the (FreeBSD) implementation does not look
quite correct.

The FreeBSD implementation is correct, I made a typo :)


    I'm thinking we want something like this.  Notice the change I made
    to the hardlink_check_gid code?

	if (suser_cred(cred, PRISON_ROOT) == 0)
		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 (cred->cr_uid != va.va_uid && !groupmember(va.va_gid, cred))
			return (EPERM);
	}

I changed the code, tested it and generated a new diff (attached).


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-28 16:51:23.000000000 +0200
@@ -1569,6 +1569,43 @@
 	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);
+	
+	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 (cred->cr_uid != va.va_uid && !groupmember(va.va_gid, cred))
+			return (EPERM);
+	}
+
+	return (0);
+}
+
 int
 kern_link(struct nlookupdata *nd, struct nlookupdata *linknd)
 {
@@ -1613,7 +1650,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);
 }


[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]