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--