Subject: kern/6224: patch to add syslog'ing of core dumps and core dump failures
To: None <gnats-bugs@gnats.netbsd.org>
From: None <woods@mail.weird.com>
List: netbsd-bugs
Date: 10/01/1998 16:08:39
>Number:         6224
>Category:       kern
>Synopsis:       patch to add syslog'ing of core dumps and core dump failures
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Oct  1 13:20:01 1998
>Last-Modified:
>Originator:     Greg A. Woods
>Organization:
Planix, Inc.; Toronto, Ontario; Canada
>Release:        any NetBSD-current
>Environment:

System: NetBSD most 1.3.2 NetBSD 1.3.2 (MOST) #0: Sun Sep 20 01:28:07 EDT 1998 woods@most:/usr/src-1.3.2/sys/arch/sparc/compile/MOST sparc

>Description:

	NetBSD (and other similarly security conscious operating
	systems) have introduced several new limits on where, when, and
	how processes are permitted to dump core, such as preventing
	processes that are exec'ed set-id or that ever do any set-id
	operations, from dumping core (which in theory protects ordinary
	users from tricking such processes into revealing data they may
	have read from files the user would not otherwise be able to
	read).

	This makes it damn near impossible to find out about certain
	classes of bugs, such as those in a daemon process which runs
	from a setuid binary, especially if that daemon forks when
	handling remote connections (i.e. the parent never dies) and no
	remote users ever complain about premature disconnects.
	
>How-To-Repeat:

	Try to notice a periodic daemon failure.

	Of course with gdb's inability to follow a process that forks
	(i.e. to debug a child process), actually finding the bug after
	you've noticed a problem is even more difficult, though that's a
	whole other issue!  ;-)

>Fix:

	Apply some variant of the following patch so that failing core
	dumps get noticed by at least the person reading system logs.

	I suppose it might also be appropriate to wrap the new code in
	this patch with something like a sysctl(2) "kern.log_cores"
	flag, though I don't feel that's strictly necessary.

	The idea for the uprintf()s comes from killproc().  They may be
	considered annoying by some, and they may not even show up
	sometimes, but I think they're a good idea.

	Note also the "blue sky" comments in the new code....

	WARNING:  this patch compiles, but hasn't been tested extensively!

Index: sys/kern/kern_sig.c
===================================================================
RCS file: /cvs/NetBSD/src/sys/kern/kern_sig.c,v
retrieving revision 1.1.1.3
diff -c -r1.1.1.3 sys/kern/kern_sig.c
*** sys/kern/kern_sig.c	1998/07/26 20:01:50	1.1.1.3
--- sys/kern/kern_sig.c	1998/10/01 19:12:56
***************
*** 1018,1029 ****
  	register struct proc *p;
  	int signum;
  {
  
  	p->p_acflag |= AXSIG;
  	if (sigprop[signum] & SA_CORE) {
  		p->p_sigacts->ps_sig = signum;
! 		if (coredump(p) == 0)
  			signum |= WCOREFLAG;
  	}
  	exit1(p, W_EXITCODE(0, signum));
  	/* NOTREACHED */
--- 1018,1060 ----
  	register struct proc *p;
  	int signum;
  {
+ 	int error;
  
  	p->p_acflag |= AXSIG;
  	if (sigprop[signum] & SA_CORE) {
  		p->p_sigacts->ps_sig = signum;
! 		if ((error = coredump(p)) == 0)
  			signum |= WCOREFLAG;
+ 		/* XXX it would be really really cool if we logged the cwd too! */
+ 		switch (error) {	/* too bad strerror() isn't in the kernel.... */
+ 		case 0:
+ 			log(LOG_DEBUG, "%s: pid %d dumped core\n", p->p_comm, p->p_pid);
+ 			break;
+ 		case EAUTH:
+ 			log(LOG_ERR, "%s: pid %d was set-id, core dump not permitted\n", p->p_comm, p->p_pid);
+ 			uprintf("%s: pid %d was set-id, core dump not permitted\n", p->p_comm, p->p_pid);
+ 			break;
+ 		case EFBIG:
+ 			log(LOG_NOTICE, "%s: pid %d core dump would exceed rlimit\n", p->p_comm, p->p_pid);
+ 			uprintf("%s: pid %d core dump would exceed rlimit\n", p->p_comm, p->p_pid);
+ 			break;
+ 		case EINVAL:
+ 			log(LOG_WARNING, "%s: pid %d core dump not permitted over non-regular file\n", p->p_comm, p->p_pid);
+ 			uprintf("%s: pid %d core dump not permitted over non-regular file\n", p->p_comm, p->p_pid);
+ 			break;
+ 		case ENXIO:
+ 			log(LOG_NOTICE, "%s: pid %d filesystem mount flag prevented core dump\n", p->p_comm, p->p_pid);
+ 			uprintf("%s: pid %d filesystem mount flag prevented core dump\n", p->p_comm, p->p_pid);
+ 			break;
+ 		case EPERM:
+ 			log(LOG_WARNING, "%s: pid %d core dump not permitted\n", p->p_comm, p->p_pid);
+ 			uprintf("%s: pid %d core dump not permitted\n", p->p_comm, p->p_pid);
+ 			break;
+ 		default:
+ 			log(LOG_NOTICE, "%s: pid %d core dump failed [%d]\n", p->p_comm, p->p_pid, error);
+ 			uprintf("%s: pid %d core dump failed [%d]\n", p->p_comm, p->p_pid, error);
+ 			break;
+ 		}
  	}
  	exit1(p, W_EXITCODE(0, signum));
  	/* NOTREACHED */
***************
*** 1051,1057 ****
  	 * Make sure the process has not set-id, to prevent data leaks.
  	 */
  	if (p->p_flag & P_SUGID)
! 		return (EPERM);
  
  	/*
  	 * Refuse to core if the data + stack + user size is larger than
--- 1082,1088 ----
  	 * Make sure the process has not set-id, to prevent data leaks.
  	 */
  	if (p->p_flag & P_SUGID)
! 		return (EAUTH);		/* XXX better error code? */
  
  	/*
  	 * Refuse to core if the data + stack + user size is larger than
***************
*** 1067,1073 ****
  	 * sure that mount flags allow us to write core dumps there.
  	 */
  	if (p->p_fd->fd_cdir->v_mount->mnt_flag & MNT_NOCOREDUMP)
! 		return (EPERM);
  
  	if (shortcorename) 
  		sprintf(name, "core");
--- 1098,1104 ----
  	 * sure that mount flags allow us to write core dumps there.
  	 */
  	if (p->p_fd->fd_cdir->v_mount->mnt_flag & MNT_NOCOREDUMP)
! 		return (ENXIO);
  
  	if (shortcorename) 
  		sprintf(name, "core");
>Audit-Trail:
>Unformatted: