Subject: coredump filename format (2)
To: None <tech-kern@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-kern
Date: 09/09/1999 18:12:13
--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii

[ please keep this on tech-kern, this deals with implementation, so I think
  it's better here.]

Hi,
I've hacked a few things about this. I killed kern.shortcorename and
added kern.defcorename which is a read/write string. Default value
can be set from the kernel option DEFCORENAME, and otherwise if 
%n.core.
The corename value is keep in a char array of MAXPATHLEN, stored in
struct plimit (it's ideally suited for this because it's already
designed for inheritance, maybe it should just be renamed ?).
For limit0 it's initialised with kern.shortcorename.
When S_UDID is set it's reset to kern.shortcorename (on exec, and a few other
place where I found S_UDID was set).
For now only %n, %u, %p are implemented, but some others will come (times,
signals, ...).

These changes are in the diff attached. Please check, especially the
S_UGID stuff.

In order to set corename in struct plimit, I'm planning to use sysctl and
change KERN_PROC to a node. We would then have
kern.proc.<procselect>.eproc for what KERN_PROC gives us now (and which appears
unused), kern.proc.<procselect>.corename for the corename, and
kern.proc.<procselect>.{h,s}limit.<limitname> to get/set limits in place of
the current getrlimit/setrlimit syscalls (getrlimit/setrlimit would then
be a wrapper around sysctl(3), and the syscall moved under COMPAT_XXX in the
kernel).
<procselect> can, as in the current KERN_PROC, have the following values:
allproc: match all processes.
pid.<pid_t>: match pid <pid_t>
pgrp.<pid_t>: match process group <pid_t>
tty.<dev_t>: match tty <dev_t>
uid.<uid_t>: match processes owned by <uid_t>
ruid.<ruid_t>: match processes with real uid <uid_t>

The advantage of this interface is that it allows to change limits
of already-running processes (with permission checks), which can eventually
be usefull (I've started too much processes. I can raise limits in my shells,
but my window manager can't start new processes any more ...). Also,
per-process attributes can ealisy be added now, a minor change to sysctl make
them user-modifiable.

Comments ?

--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
--

--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

Index: sys/conf/files
===================================================================
RCS file: /cvsroot/syssrc/sys/conf/files,v
retrieving revision 1.314
diff -u -r1.314 files
--- files	1999/09/01 00:32:42	1.314
+++ files	1999/09/09 15:58:39
@@ -9,7 +9,7 @@
 defopt	KTRACE
 defopt	LOCKDEBUG
 defopt	RTC_OFFSET
-defopt	SHORTCORENAME
+defopt	DEFCORENAME
 defopt	UCONSOLE
 
 defopt	MULTIPROCESSOR
Index: sys/kern/init_main.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/init_main.c,v
retrieving revision 1.154
diff -u -r1.154 init_main.c
--- init_main.c	1999/07/22 21:08:31	1.154
+++ init_main.c	1999/09/09 15:58:40
@@ -181,6 +181,7 @@
 #if defined(NFSSERVER) || defined(NFS)
 	extern void nfs_init __P((void));
 #endif
+	extern char defcorename[];
 
 	/*
 	 * Initialize the current process pointer (curproc) before
@@ -284,6 +285,7 @@
 	limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
+	strcpy(limit0.pl_corename, defcorename);
 	limit0.p_refcnt = 1;
 
 	/*
Index: sys/kern/kern_exec.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_exec.c,v
retrieving revision 1.102
diff -u -r1.102 kern_exec.c
--- kern_exec.c	1999/08/09 02:42:20	1.102
+++ kern_exec.c	1999/09/09 15:58:40
@@ -457,7 +457,7 @@
 			p->p_ucred->cr_uid = attr.va_uid;
 		if (attr.va_mode & S_ISGID)
 			p->p_ucred->cr_gid = attr.va_gid;
-		p->p_flag |= P_SUGID;
+		p_sugid(p);
 	} else
 		p->p_flag &= ~P_SUGID;
 	p->p_cred->p_svuid = p->p_ucred->cr_uid;
Index: sys/kern/kern_proc.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_proc.c,v
retrieving revision 1.34
diff -u -r1.34 kern_proc.c
--- kern_proc.c	1999/07/25 06:30:34	1.34
+++ kern_proc.c	1999/09/09 15:58:40
@@ -519,6 +519,23 @@
 	}
 }
 
+/* mark process as suid/sgid, reset some values do defaults */
+void
+p_sugid(p)
+	struct proc *p;
+{
+	extern char defcorename[];
+
+	p->p_flag |= P_SUGID;
+	/* reset what needs to be reset in plimit */
+	if (p->p_limit->p_refcnt > 1) {
+		p->p_limit->p_refcnt--;
+		p->p_limit = limcopy(p->p_limit);
+	}
+	strcpy(p->p_limit->pl_corename, defcorename);
+}
+
+
 #ifdef DEBUG
 void
 pgrpdump()
Index: sys/kern/kern_prot.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_prot.c,v
retrieving revision 1.54
diff -u -r1.54 kern_prot.c
--- kern_prot.c	1999/04/30 05:30:32	1.54
+++ kern_prot.c	1999/09/09 15:58:43
@@ -335,7 +335,7 @@
 	pc->pc_ucred->cr_uid = uid;
 	pc->p_ruid = uid;
 	pc->p_svuid = uid;
-	p->p_flag |= P_SUGID;
+	p_sugid(p);
 	return (0);
 }
 
@@ -363,7 +363,7 @@
 	 */
 	pc->pc_ucred = crcopy(pc->pc_ucred);
 	pc->pc_ucred->cr_uid = euid;
-	p->p_flag |= P_SUGID;
+	p_sugid(p);
 	return (0);
 }
 
@@ -408,7 +408,7 @@
 	}
 
 	if (euid != (uid_t)-1 && ruid != (uid_t)-1)
-		p->p_flag |= P_SUGID;
+		p_sugid(p);
 	return (0);
 }
 
@@ -434,7 +434,7 @@
 	pc->pc_ucred->cr_gid = gid;
 	pc->p_rgid = gid;
 	pc->p_svgid = gid;
-	p->p_flag |= P_SUGID;
+	p_sugid(p);
 	return (0);
 }
 
@@ -458,7 +458,7 @@
 		return (error);
 	pc->pc_ucred = crcopy(pc->pc_ucred);
 	pc->pc_ucred->cr_gid = egid;
-	p->p_flag |= P_SUGID;
+	p_sugid(p);
 	return (0);
 }
 
@@ -501,7 +501,7 @@
 	}
 
 	if (egid != (gid_t)-1 && rgid != (gid_t)-1)
-		p->p_flag |= P_SUGID;
+		p_sugid(p);
 	return (0);
 }
 
@@ -531,7 +531,7 @@
 	if (error)
 		return (error);
 	pc->pc_ucred->cr_ngroups = ngrp;
-	p->p_flag |= P_SUGID;
+	p_sugid(p);
 	return (0);
 }
 
Index: sys/kern/kern_resource.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_resource.c,v
retrieving revision 1.52
diff -u -r1.52 kern_resource.c
--- kern_resource.c	1999/07/25 06:30:34	1.52
+++ kern_resource.c	1999/09/09 15:58:43
@@ -458,6 +458,7 @@
 	newlim = pool_get(&plimit_pool, PR_WAITOK);
 	memcpy(newlim->pl_rlimit, lim->pl_rlimit,
 	    sizeof(struct rlimit) * RLIM_NLIMITS);
+	strcpy(newlim->pl_corename, lim->pl_corename);
 	newlim->p_lflags = 0;
 	newlim->p_refcnt = 1;
 	return (newlim);
Index: sys/kern/kern_sig.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_sig.c,v
retrieving revision 1.93
diff -u -r1.93 kern_sig.c
--- kern_sig.c	1999/08/31 12:30:35	1.93
+++ kern_sig.c	1999/09/09 15:58:44
@@ -79,6 +79,7 @@
 
 void stop __P((struct proc *p));
 void killproc __P((struct proc *, char *));
+static int build_corename __P((char *));
 
 sigset_t contsigmask, stopsigmask, sigcantmask;
 
@@ -1264,9 +1265,8 @@
 	struct nameidata nd;
 	struct vattr vattr;
 	int error, error1;
-	char name[MAXCOMLEN+6];		/* progname.core */
+	char name[MAXPATHLEN];
 	struct core core;
-	extern int shortcorename;
 
 	/*
 	 * Make sure the process has not set-id, to prevent data leaks.
@@ -1293,11 +1293,10 @@
 	    (vp->v_mount->mnt_flag & MNT_NOCOREDUMP) != 0)
 		return (EPERM);
 
-	if (shortcorename) 
-		sprintf(name, "core");
-	else
-		sprintf(name, "%s.core", p->p_comm);
-	
+	error = build_corename(name);
+	if (error)
+		return error;
+
 	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
 	error = vn_open(&nd, O_CREAT | FWRITE | FNOSYMLINK, S_IRUSR | S_IWUSR);
 	if (error)
@@ -1393,4 +1392,57 @@
 
 	psignal(p, SIGSYS);
 	return (ENOSYS);
+}
+
+static int
+build_corename(dst)
+	char *dst;
+{
+	const char *s;
+	char *d;
+	int len, i;
+
+	for (s = curproc->p_limit->pl_corename, len = 0, d = dst; *s != '\0'; s++) {
+		if (*s != '%') {
+			*d = *s;
+			d++;
+			len++;
+			if (len >= MAXPATHLEN - 1)
+				return ENAMETOOLONG;
+			continue;
+		}
+		if (*(s+1) == 'n') { /* %n */
+			i = snprintf(d,MAXPATHLEN - 1 - len, "%s",
+			    curproc->p_comm);
+			if (i >= MAXPATHLEN - 1 - len)
+				return ENAMETOOLONG;
+			len += i;
+			d += i;
+			s++;
+			continue;
+		}
+		if (*(s+1) == 'p') { /* %p */
+			i = snprintf(d, MAXPATHLEN - 1 - len, "%d",
+			    curproc->p_pid);
+			if (i >= MAXPATHLEN - 1 - len)
+				return ENAMETOOLONG;
+			len += i;
+			d += i;
+			s++;
+			continue;
+		}
+		if (*(s+1) == 'u') { /* %u */
+			i = snprintf(d, MAXPATHLEN - 1 - len, "%s",
+			    curproc->p_pgrp->pg_session->s_login);
+			if (i >= MAXPATHLEN - 1 - len)
+				return ENAMETOOLONG;
+			len += i;
+			d += i;
+			s++;
+			continue;
+		}
+		*d = *s;
+	}
+	*d = '\0';
+	return 0;
 }
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_sysctl.c,v
retrieving revision 1.50
diff -u -r1.50 kern_sysctl.c
--- kern_sysctl.c	1999/07/25 06:30:35	1.50
+++ kern_sysctl.c	1999/09/09 15:58:45
@@ -44,7 +44,7 @@
 
 #include "opt_ddb.h"
 #include "opt_insecure.h"
-#include "opt_shortcorename.h"
+#include "opt_defcorename.h"
 #include "opt_sysv.h"
 
 #include <sys/param.h>
@@ -210,10 +210,12 @@
 #else
 int securelevel = 0;
 #endif
-#ifdef SHORTCORENAME
-int shortcorename = 1;
+#ifdef DEFCORENAME
+char defcorename[MAXPATHLEN] = DEFCORENAME;
+int defcorenamelen = sizeof(DEFCORENAME);
 #else
-int shortcorename = 0;
+char defcorename[MAXPATHLEN] = "%n.core";
+int defcorenamelen = sizeof("%n.core");
 #endif
 
 /*
@@ -232,7 +234,6 @@
 	int error, level, inthostid;
 	int old_autonicetime;
 	int old_vnodes;
-	int old_shortcorename;
 	extern char ostype[], osrelease[], version[];
 
 	/* All sysctl names at this level, except for a few, are terminal. */
@@ -380,16 +381,14 @@
 #else
 		return (sysctl_rdint(oldp, oldlenp, newp, 0));
 #endif
- 	case KERN_SHORTCORENAME:
- 		/* Only allow values of zero or one. */
- 		old_shortcorename = shortcorename;
- 		error = sysctl_int(oldp, oldlenp, newp, newlen, 
- 		    &shortcorename);
- 		if (shortcorename != 0 && shortcorename != 1) {
- 			shortcorename = old_shortcorename;
- 			return (EINVAL);
- 		}
- 		return (error);
+ 	case KERN_DEFCORENAME:
+		if (newp && newlen < 1)
+			return (EINVAL);
+		error = sysctl_string(oldp, oldlenp, newp, newlen,
+		    defcorename, sizeof(defcorename));
+		if (newp && !error)
+			defcorenamelen = newlen;
+		return (error);
 	case KERN_SYNCHRONIZED_IO:
 		return (sysctl_rdint(oldp, oldlenp, newp, 1));
 	case KERN_IOV_MAX:
Index: sys/sys/proc.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/proc.h,v
retrieving revision 1.83
diff -u -r1.83 proc.h
--- proc.h	1999/08/10 23:33:27	1.83
+++ proc.h	1999/09/09 15:58:45
@@ -392,5 +392,6 @@
 void	proclist_unlock_read __P((void));
 int	proclist_lock_write __P((void));
 void	proclist_unlock_write __P((int));
+void	p_sugid __P((struct proc*));
 #endif	/* _KERNEL */
 #endif	/* !_SYS_PROC_H_ */
Index: sys/sys/resourcevar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/resourcevar.h,v
retrieving revision 1.13
diff -u -r1.13 resourcevar.h
--- resourcevar.h	1998/03/01 02:24:14	1.13
+++ resourcevar.h	1999/09/09 15:58:45
@@ -73,6 +73,7 @@
  */
 struct plimit {
 	struct	rlimit pl_rlimit[RLIM_NLIMITS];
+	char	 pl_corename[MAXPATHLEN];
 #define	PL_SHAREMOD	0x01		/* modifications are shared */
 	int	p_lflags;
 	int	p_refcnt;		/* number of references */
@@ -88,8 +89,7 @@
 void	 addupc_task __P((struct proc *p, u_long pc, u_int ticks));
 void	 calcru __P((struct proc *p, struct timeval *up, struct timeval *sp,
 	    struct timeval *ip));
-struct plimit
-	*limcopy __P((struct plimit *lim));
+struct plimit *limcopy __P((struct plimit *lim));
 void	 ruadd __P((struct rusage *ru, struct rusage *ru2));
 #endif
 #endif	/* !_SYS_RESOURCEVAR_H_ */
Index: sys/sys/sysctl.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/sysctl.h,v
retrieving revision 1.35
diff -u -r1.35 sysctl.h
--- sysctl.h	1999/06/24 14:18:12	1.35
+++ sysctl.h	1999/09/09 15:58:45
@@ -145,7 +145,7 @@
 #define	KERN_SYSVMSG		33	/* int: SysV message queue suppoprt */
 #define	KERN_SYSVSEM		34	/* int: SysV semaphore support */
 #define	KERN_SYSVSHM		35	/* int: SysV shared memory support */
-#define	KERN_SHORTCORENAME	36	/* int: programs dump core as "core" */
+#define	KERN_DEFCORENAME	36	/* string: default corename format */
 #define	KERN_SYNCHRONIZED_IO	37	/* int: POSIX synchronized I/O */
 #define	KERN_IOV_MAX		38	/* int: max iovec's for readv(2) etc. */
 #define	KERN_MBUF		39	/* node: mbuf parameters */
@@ -192,7 +192,7 @@
 	{ "sysvmsg", CTLTYPE_INT }, \
 	{ "sysvsem", CTLTYPE_INT }, \
 	{ "sysvshm", CTLTYPE_INT }, \
-	{ "shortcorename", CTLTYPE_INT }, \
+	{ "defcorename", CTLTYPE_STRING }, \
 	{ "synchronized_io", CTLTYPE_INT }, \
 	{ "iov_max", CTLTYPE_INT }, \
 	{ "mbuf", CTLTYPE_NODE }, \

--uAKRQypu60I7Lcqm--