procfs panic

Christer Öberg christer.oberg at ornsat.com
Tue Oct 19 15:41:46 PDT 2004


Hi,

Playing around adding functionality to note/notepg (I attached a diff in 
case you want it)  I came across a bug (not caused by my modifications 
btw :))

Doing for example echo kill > /proc/somepid/[ctl/note/notepg] will cause 
a panic with the panic string "lockmgr: locking against myself", however 
opening the file and write()'ing to it works as expected. I don't know 
what bash is doing to cause this and for some reason I didn't get a 
crash dump but reproducing the bug should be a simple matter of doing 
echo kill > /proc/curproc/ctl


Common subdirectories: vfs/procfs/CVS and vfs/procfs.new/CVS
diff -uN vfs/procfs/README vfs/procfs.new/README
--- vfs/procfs/README	2003-06-17 04:28:42.000000000 +0000
+++ vfs/procfs.new/README	2004-10-19 23:33:18.000000000 +0000
@@ -32,11 +32,11 @@
 
 	note	- w/o.  writing a string here sends the
 			equivalent note to the process.
-			[ not implemented. ]
+			
 
 	notepg	- w/o.  the same as note, but sends to all
 			members of the process group.
-			[ not implemented. ]
+			
 
 	regs	- r/w.	process register set.  this can be read
 			or written any time even if the process
diff -uN vfs/procfs/procfs.h vfs/procfs.new/procfs.h
--- vfs/procfs/procfs.h	2004-08-17 18:57:35.000000000 +0000
+++ vfs/procfs.new/procfs.h	2004-10-19 23:11:24.000000000 +0000
@@ -136,6 +136,7 @@
 int procfs_read_dbregs (struct proc *, struct dbreg *);
 int procfs_write_dbregs (struct proc *, struct dbreg *);
 int procfs_donote (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
+int procfs_donotepg (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
 int procfs_doregs (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
 int procfs_dofpregs (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
 int procfs_dodbregs (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
diff -uN vfs/procfs/procfs_note.c vfs/procfs.new/procfs_note.c
--- vfs/procfs/procfs_note.c	2004-05-02 03:05:11.000000000 +0000
+++ vfs/procfs.new/procfs_note.c	2004-10-19 23:11:24.000000000 +0000
@@ -42,8 +42,36 @@
 
 #include <sys/param.h>
 #include <sys/vnode.h>
+#include <sys/signalvar.h>
 #include <vfs/procfs/procfs.h>
 
+
+#define TRACE_WAIT_P(curp, p) \
+	((p)->p_stat == SSTOP && \
+	 (p)->p_pptr == (curp) && \
+	 ((p)->p_flag & P_TRACED))
+
+static vfs_namemap_t signames[] = {
+	/* regular signal names */
+	{ "hup",	SIGHUP },	{ "int",	SIGINT },
+	{ "quit",	SIGQUIT },	{ "ill",	SIGILL },
+	{ "trap",	SIGTRAP },	{ "abrt",	SIGABRT },
+	{ "iot",	SIGIOT },	{ "emt",	SIGEMT },
+	{ "fpe",	SIGFPE },	{ "kill",	SIGKILL },
+	{ "bus",	SIGBUS },	{ "segv",	SIGSEGV },
+	{ "sys",	SIGSYS },	{ "pipe",	SIGPIPE },
+	{ "alrm",	SIGALRM },	{ "term",	SIGTERM },
+	{ "urg",	SIGURG },	{ "stop",	SIGSTOP },
+	{ "tstp",	SIGTSTP },	{ "cont",	SIGCONT },
+	{ "chld",	SIGCHLD },	{ "ttin",	SIGTTIN },
+	{ "ttou",	SIGTTOU },	{ "io",		SIGIO },
+	{ "xcpu",	SIGXCPU },	{ "xfsz",	SIGXFSZ },
+	{ "vtalrm",	SIGVTALRM },	{ "prof",	SIGPROF },
+	{ "winch",	SIGWINCH },	{ "info",	SIGINFO },
+	{ "usr1",	SIGUSR1 },	{ "usr2",	SIGUSR2 },
+	{ 0 },
+};
+
 int
 procfs_donote(struct proc *curp, struct proc *p, struct pfsnode *pfs,
 	      struct uio *uio)
@@ -51,7 +79,41 @@
 	int xlen;
 	int error;
 	char note[PROCFS_NOTELEN+1];
+	vfs_namemap_t *nm;
+	
+	if (uio->uio_rw != UIO_WRITE)
+		return (EINVAL);
+
+	xlen = PROCFS_NOTELEN;
+	error = vfs_getuserstr(uio, note, &xlen);
+	if (error)
+		return (error);
+
+	nm = vfs_findname(signames, note, xlen);
+	if (nm) {
+		if (TRACE_WAIT_P(curp, p)) {
+			p->p_xstat = nm->nm_val;
+#ifdef FIX_SSTEP
+			FIX_SSTEP(p);
+#endif
+			setrunnable(p);
+		} else {
+			psignal(p, nm->nm_val);
+		}
+	}
+	return (error);
+}
 
+int
+procfs_donotepg(struct proc *curp, struct proc *p, struct pfsnode *pfs,
+	      struct uio *uio)
+{
+	int xlen;
+	int error;
+	char note[PROCFS_NOTELEN+1];
+	vfs_namemap_t *nm;
+	struct pgrp *pgrp;
+	
 	if (uio->uio_rw != UIO_WRITE)
 		return (EINVAL);
 
@@ -60,6 +122,21 @@
 	if (error)
 		return (error);
 
-	/* send to process's notify function */
-	return (EOPNOTSUPP);
+	nm = vfs_findname(signames, note, xlen);
+	if (nm) {
+		pgrp=p->p_pgrp;
+		LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
+			if (TRACE_WAIT_P(curp, p)) {
+				p->p_xstat = nm->nm_val;
+#ifdef FIX_SSTEP
+				FIX_SSTEP(p);
+#endif
+				setrunnable(p);
+			} else {
+				psignal(p,nm->nm_val);
+			}
+		}
+	}
+	error = 0;
+	return (error);
 }
diff -uN vfs/procfs/procfs_subr.c vfs/procfs.new/procfs_subr.c
--- vfs/procfs/procfs_subr.c	2004-10-12 19:21:07.000000000 +0000
+++ vfs/procfs.new/procfs_subr.c	2004-10-19 23:11:24.000000000 +0000
@@ -285,9 +285,11 @@
 
 	switch (pfs->pfs_type) {
 	case Pnote:
-	case Pnotepg:
 		rtval = procfs_donote(curp, p, pfs, uio);
 		break;
+	case Pnotepg:
+		rtval = procfs_donotepg(curp, p, pfs, uio);
+		break;
 
 	case Pregs:
 		rtval = procfs_doregs(curp, p, pfs, uio);




More information about the Bugs mailing list