-.\" $OpenBSD: sysctl.3,v 1.232 2014/04/27 16:58:08 jmc Exp $
+.\" $OpenBSD: sysctl.3,v 1.233 2014/05/04 03:53:37 deraadt Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: April 27 2014 $
+.Dd $Mdocdate: May 4 2014 $
.Dt SYSCTL 3
.Os
.Sh NAME
.It 0 Ta "euid == 0" Ta "current directory"
.It 1 Ta "never" Ta ""
.It 2 Ta "always" Ta Pa "/var/crash"
+.It 2 Ta "depends" Ta Pa "/var/crash/$programname/"
.El
.It Dv KERN_NPROCS
The number of entries in the kernel process table.
-.\" $OpenBSD: sysctl.8,v 1.177 2014/04/27 16:56:51 jmc Exp $
+.\" $OpenBSD: sysctl.8,v 1.178 2014/05/04 03:53:37 deraadt Exp $
.\" $NetBSD: sysctl.8,v 1.4 1995/09/30 07:12:49 thorpej Exp $
.\"
.\" Copyright (c) 1993
.\"
.\" @(#)sysctl.8 8.2 (Berkeley) 5/9/95
.\"
-.Dd $Mdocdate: April 27 2014 $
+.Dd $Mdocdate: May 4 2014 $
.Dt SYSCTL 8
.Os
.Sh NAME
# sysctl kern.shminfo.shmmax=33554432
# sysctl kern.shminfo.shmseg=32
.Ed
+.Pp
+To place core dumps from
+.Xr issetugid 2
+programs (in this example
+.Xr bgpd 8 )
+into a safe place for debugging purposes
+.Bd -literal -offset indent
+# mkdir /var/crash/bgpd
+# chmod 700 /var/crash/bgpd
+# sysctl kern.nosuidcoredump=3
+.Ed
+.Pp
.Sh SEE ALSO
.Xr sysctl 3 ,
.Xr options 4 ,
-.\" $OpenBSD: core.5,v 1.16 2014/01/21 03:15:46 schwarze Exp $
+.\" $OpenBSD: core.5,v 1.17 2014/05/04 03:53:38 deraadt Exp $
.\" $NetBSD: core.5,v 1.4 1994/11/30 19:31:11 jtc Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993
.\"
.\" @(#)core.5 8.3 (Berkeley) 12/11/93
.\"
-.Dd $Mdocdate: January 21 2014 $
+.Dd $Mdocdate: May 4 2014 $
.Dt CORE 5
.Os
.Sh NAME
file format appeared in
.At v3 .
.Sh CAVEATS
-Programs with their set-user-ID bit set will not dump core,
-to prevent sensitive information from inadvertently ending up on disk.
-See
+Programs which are started with (either) the set-user-ID or
+set-group-ID bits set,
+or which change their uid or gid after starting, will normally not
+dump core.
+This is to prevent sensitive information from inadvertently ending
+up on disk.
+This behaviour can be changed (for debugging purposes) by changing
.Li kern.nosuidcoredump
-in
.Xr sysctl 3
-for more information.
+variable to the right settings.
-/* $OpenBSD: kern_sig.c,v 1.164 2014/04/18 11:51:17 guenther Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.165 2014/05/04 03:53:37 deraadt Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
#include <sys/buf.h>
#include <sys/acct.h>
#include <sys/file.h>
+#include <sys/filedesc.h>
#include <sys/kernel.h>
#include <sys/wait.h>
#include <sys/ktrace.h>
struct nameidata nd;
struct vattr vattr;
struct coredump_iostate io;
- int error, len;
- char name[sizeof("/var/crash/") + MAXCOMLEN + sizeof(".core")];
- char *dir = "";
+ int error, len, incrash = 0;
+ char name[MAXPATHLEN];
+ const char *dir = "/var/crash";
pr->ps_flags |= PS_COREDUMP;
/*
- * Don't dump if not root and the process has used set user or
- * group privileges, unless the nosuidcoredump sysctl is set to 2,
- * in which case dumps are put into /var/crash/.
+ * If the process has inconsistant uids, nosuidcoredump
+ * determines coredump placement policy.
*/
if (((pr->ps_flags & PS_SUGID) && (error = suser(p, 0))) ||
((pr->ps_flags & PS_SUGID) && nosuidcoredump)) {
- if (nosuidcoredump == 2)
- dir = "/var/crash/";
+ if (nosuidcoredump == 3 || nosuidcoredump == 2)
+ incrash = 1;
else
return (EPERM);
}
p->p_rlimit[RLIMIT_CORE].rlim_cur)
return (EFBIG);
- len = snprintf(name, sizeof(name), "%s%s.core", dir, p->p_comm);
+ if (nosuidcoredump == 3) {
+ /*
+ * If the program directory does not exist, dumps of
+ * that core will silently fail.
+ */
+ len = snprintf(name, sizeof(name), "%s/%s/%u.core",
+ dir, p->p_comm, p->p_pid);
+ } else if (nosuidcoredump == 2)
+ len = snprintf(name, sizeof(name), "%s/%s.core",
+ dir, p->p_comm);
+ else
+ len = snprintf(name, sizeof(name), "%s.core", p->p_comm);
if (len >= sizeof(name))
return (EACCES);
/*
- * ... but actually write it as UID
+ * Control the UID used to write out. The normal case uses
+ * the real UID. If the sugid case is going to write into the
+ * controlled directory, we do so as root.
*/
- cred = crdup(cred);
- cred->cr_uid = cred->cr_ruid;
- cred->cr_gid = cred->cr_rgid;
+ if (incrash == 0) {
+ cred = crdup(cred);
+ cred->cr_uid = cred->cr_ruid;
+ cred->cr_gid = cred->cr_rgid;
+ } else {
+ if (p->p_fd->fd_rdir) {
+ vrele(p->p_fd->fd_rdir);
+ p->p_fd->fd_rdir = NULL;
+ }
+ p->p_ucred = crdup(p->p_ucred);
+ crfree(cred);
+ cred = p->p_ucred;
+ crhold(cred);
+ cred->cr_uid = 0;
+ cred->cr_gid = 0;
+ }
NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);