[PATCH] can_hardlink sysctl ported from FreeBSD
Matthias Schmidt
schmidtm at mathematik.uni-marburg.de
Wed Sep 28 08:07:58 PDT 2005
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);
}
More information about the Submit
mailing list