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