Subject: Re: sysctl knob to let sugid processes dump core (pr 15994)
To: None <tech-security@NetBSD.org>
From: Elad Efrat <elad@NetBSD.org>
List: tech-kern
Date: 01/23/2006 19:35:01
This is a multi-part message in MIME format.
--------------010205040606050002070706
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Okay here's a newer patch..

phyre:elad {47} sysctl security.setid_core
security.setid_core.dump = 0
security.setid_core.path = /var/crash/%n.core
security.setid_core.owner = 0
security.setid_core.group = 0
security.setid_core.mode = 384
phyre:elad {48}

When dump is 1 set-id coredumps are enabled.
Path is where they will be saved. It works *exactly* like
kern.defcorename as Bill suggested, but affects only the set-id
dumps.
Owner and group are obvious, mode is *octal* (I'll add sysctl support
for an octal printing flag like CTLFLAG_HEX).

Defaults are dump=0, path=/var/crash/%n.core (we can add /var/core),
owner=0, group=0, and mode=600.

Comments?

-e.

-- 
Elad Efrat

--------------010205040606050002070706
Content-Type: text/plain;
 name="setid_core.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="setid_core.diff"

Index: kern/init_sysctl.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_sysctl.c,v
retrieving revision 1.59
diff -u -p -r1.59 init_sysctl.c
--- kern/init_sysctl.c	26 Dec 2005 18:45:27 -0000	1.59
+++ kern/init_sysctl.c	21 Jan 2006 19:43:55 -0000
@@ -92,6 +92,11 @@ __KERNEL_RCSID(0, "$NetBSD: init_sysctl.
 
 /* XXX this should not be here */
 int security_curtain = 0;
+int security_setidcore_dump;
+char security_setidcore_path[MAXPATHLEN] = "/var/crash/%n.core";
+uid_t security_setidcore_owner = 0;
+gid_t security_setidcore_group = 0;
+mode_t security_setidcore_mode = 0600;
 
 /*
  * try over estimating by 5 procs/lwps
@@ -1028,6 +1033,44 @@ SYSCTL_SETUP(sysctl_security_setup, "sys
 				    " to users not owning them."),
 		       NULL, 0, &security_curtain, 0,
 		       CTL_SECURITY, SECURITY_CURTAIN, CTL_EOL);
+
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, "setid_core",
+		       SYSCTL_DESCR("Set-id processes' coredump settings."),
+		       NULL, 0, NULL, 0,
+		       CTL_SECURITY, SECURITY_SETIDCORE, CTL_EOL);
+
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "dump",
+		       SYSCTL_DESCR("Allow set-id processes to dump core."),
+		       NULL, 0, &security_setidcore_dump, 0,
+		       CTL_SECURITY, SECURITY_SETIDCORE, CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_STRING, "path",
+		       SYSCTL_DESCR("Path pattern for set-id coredumps."),
+		       NULL, 0, &security_setidcore_path, MAXPATHLEN,
+		       CTL_SECURITY, SECURITY_SETIDCORE, CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "owner",
+		       SYSCTL_DESCR("Owner id for set-id processes' cores."),
+		       NULL, 0, &security_setidcore_owner, 0,
+		       CTL_SECURITY, SECURITY_SETIDCORE, CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "group",
+		       SYSCTL_DESCR("Group id for set-id processes' cores."),
+		       NULL, 0, &security_setidcore_group, 0,
+		       CTL_SECURITY, SECURITY_SETIDCORE, CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "mode",
+		       SYSCTL_DESCR("Mode for set-id processes' cores."),
+		       NULL, 0, &security_setidcore_mode, 0,
+		       CTL_SECURITY, SECURITY_SETIDCORE, CTL_CREATE, CTL_EOL);
 }
 
 /*
Index: kern/kern_sig.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_sig.c,v
retrieving revision 1.213
diff -u -p -r1.213 kern_sig.c
--- kern/kern_sig.c	24 Dec 2005 19:12:23 -0000	1.213
+++ kern/kern_sig.c	21 Jan 2006 19:44:03 -0000
@@ -70,6 +70,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v
 #include <sys/sa.h>
 #include <sys/savar.h>
 #include <sys/exec.h>
+#include <sys/sysctl.h>
 
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
@@ -2101,9 +2102,10 @@ coredump(struct lwp *l, const char *patt
 	cred = p->p_cred->pc_ucred;
 
 	/*
-	 * Make sure the process has not set-id, to prevent data leaks.
+	 * Make sure the process has not set-id, to prevent data leaks,
+	 * unless it was specifically requested to allow set-id coredumps.
 	 */
-	if (p->p_flag & P_SUGID)
+	if ((p->p_flag & P_SUGID) && !security_setidcore_dump)
 		return (EPERM);
 
 	/*
@@ -2126,6 +2128,9 @@ restart:
 	    (vp->v_mount->mnt_flag & MNT_NOCOREDUMP) != 0)
 		return (EPERM);
 
+	if (p->p_flag & P_SUGID && security_setidcore_dump)
+		pattern = security_setidcore_path;
+
 	if (pattern == NULL)
 		pattern = p->p_limit->pl_corename;
 	if ((error = build_corename(p, name, pattern, sizeof(name))) != 0)
@@ -2155,6 +2160,13 @@ restart:
 	}
 	VATTR_NULL(&vattr);
 	vattr.va_size = 0;
+
+	if (p->p_flag & P_SUGID && security_setidcore_dump) {
+		vattr.va_uid = security_setidcore_owner;
+		vattr.va_gid = security_setidcore_group;
+		vattr.va_mode = security_setidcore_mode;
+	}
+
 	VOP_LEASE(vp, l, cred, LEASE_WRITE);
 	VOP_SETATTR(vp, &vattr, cred, l);
 	p->p_acflag |= ACORE;
Index: sys/sysctl.h
===================================================================
RCS file: /cvsroot/src/sys/sys/sysctl.h,v
retrieving revision 1.145
diff -u -p -r1.145 sysctl.h
--- sys/sysctl.h	28 Dec 2005 19:09:30 -0000	1.145
+++ sys/sysctl.h	21 Jan 2006 19:44:13 -0000
@@ -902,7 +902,8 @@ struct kinfo_file {
  * CTL_SECURITY definitions.
  */
 #define	SECURITY_CURTAIN	1
-#define	SECURITY_MAXID		2
+#define	SECURITY_SETIDCORE	2
+#define	SECURITY_MAXID		3
 
 #define	CTL_SECURITY_NAMES { \
 	{ 0, 0 }, \
@@ -911,6 +912,11 @@ struct kinfo_file {
 
 /* XXX this should not be here */
 extern int security_curtain;
+extern int security_setidcore_dump;
+extern char security_setidcore_path[];
+extern uid_t security_setidcore_owner;
+extern gid_t security_setidcore_group;
+extern mode_t security_setidcore_mode;
 
 #ifdef _KERNEL
 

--------------010205040606050002070706--