static int kill1(struct lwp *l, pid_t pid, ksiginfo_t *ksi, register_t *retval) { int error; struct proc *p; if ((u_int)ksi->ksi_signo >= NSIG) return EINVAL; if (pid != l->l_proc->p_pid) { if (ksi->ksi_pid != l->l_proc->p_pid) return EPERM; if (ksi->ksi_uid != kauth_cred_geteuid(l->l_cred)) return EPERM; switch (ksi->ksi_code) { case SI_USER: case SI_QUEUE: break; default: return EPERM; } } if (pid > 0) { /* kill single process */ mutex_enter(proc_lock); p = proc_find_raw(pid); if (p == NULL || (p->p_stat != SACTIVE && p->p_stat != SSTOP)) { mutex_exit(proc_lock); /* IEEE Std 1003.1-2001: return success for zombies */ return p ? 0 : ESRCH; } mutex_enter(p->p_lock); error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_SIGNAL, p, KAUTH_ARG(ksi->ksi_signo), NULL, NULL); if (!error && ksi->ksi_signo) { kpsignal2(p, ksi); } mutex_exit(p->p_lock); mutex_exit(proc_lock); return error; } switch (pid) { case -1: /* broadcast signal */ return killpg1(l, ksi, 0, 1); case 0: /* signal own process group */ return killpg1(l, ksi, 0, 0); default: /* negative explicit process group */ return killpg1(l, ksi, -pid, 0); } /* NOTREACHED */ }
/* * Filter attach method for EVFILT_PROC. */ static int filt_procattach(struct knote *kn) { struct proc *p; struct lwp *curl; curl = curlwp; mutex_enter(proc_lock); if (kn->kn_flags & EV_FLAG1) { /* * NOTE_TRACK attaches to the child process too early * for proc_find, so do a raw look up and check the state * explicitly. */ p = proc_find_raw(kn->kn_id); if (p != NULL && p->p_stat != SIDL) p = NULL; } else { p = proc_find(kn->kn_id); } if (p == NULL) { mutex_exit(proc_lock); return ESRCH; } /* * Fail if it's not owned by you, or the last exec gave us * setuid/setgid privs (unless you're root). */ mutex_enter(p->p_lock); mutex_exit(proc_lock); if (kauth_authorize_process(curl->l_cred, KAUTH_PROCESS_KEVENT_FILTER, p, NULL, NULL, NULL) != 0) { mutex_exit(p->p_lock); return EACCES; } kn->kn_obj = p; kn->kn_flags |= EV_CLEAR; /* automatically set */ /* * internal flag indicating registration done by kernel */ if (kn->kn_flags & EV_FLAG1) { kn->kn_data = kn->kn_sdata; /* ppid */ kn->kn_fflags = NOTE_CHILD; kn->kn_flags &= ~EV_FLAG1; } SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext); mutex_exit(p->p_lock); return 0; }
void db_stack_trace_print(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif, void (*pr)(const char *, ...)) { #ifndef DDB_TRACE struct pcb *pcb; struct proc *p; struct lwp *l; const char *cp = modif; char c; bool lwpaddr = false; if (!have_addr) { struct reg * regs = &ddb_regs; stacktrace_subr(regs->r_regs[_R_A0], regs->r_regs[_R_A1], regs->r_regs[_R_A2], regs->r_regs[_R_A3], regs->r_regs[_R_PC], regs->r_regs[_R_SP], /* non-virtual frame pointer */ regs->r_regs[_R_S8], regs->r_regs[_R_RA], pr); return; } while ((c = *cp++) != 0) { if (c == 'a') { lwpaddr = true; } } if (lwpaddr) { l = (struct lwp *)(intptr_t)addr; (*pr)("pid %d.%d ", l->l_proc->p_pid, l->l_lid); } else { /* "trace/t" */ (*pr)("pid %d ", (int)addr); p = proc_find_raw(addr); if (p == NULL) { (*pr)("not found\n"); return; } l = LIST_FIRST(&p->p_lwps); /* XXX NJWLWP */ } pcb = lwp_getpcb(l); (*pr)("at %p\n", pcb); stacktrace_subr(0,0,0,0, /* no args known */ (vaddr_t)cpu_switchto, pcb->pcb_context.val[_L_SP], pcb->pcb_context.val[_L_S8], pcb->pcb_context.val[_L_RA], pr); #else /* * Incomplete but practically useful stack backtrace. */ #define MIPS_JR_RA 0x03e00008 /* instruction code for jr ra */ #define MIPS_JR_K0 0x03400008 /* instruction code for jr k0 */ #define MIPS_ERET 0x42000018 /* instruction code for eret */ register_t va, pc, ra, sp, func; int insn; InstFmt i; int stacksize; db_addr_t offset; const char *name; extern char verylocore[]; pc = ddb_regs.r_regs[_R_PC]; sp = ddb_regs.r_regs[_R_SP]; ra = ddb_regs.r_regs[_R_RA]; do { va = pc; do { va -= sizeof(int); insn = *(int *)(intptr_t)va; if (insn == MIPS_ERET) goto mips3_eret; } while (insn != MIPS_JR_RA && insn != MIPS_JR_K0); va += sizeof(int); mips3_eret: va += sizeof(int); while (*(int *)(intptr_t)va == 0x00000000) va += sizeof(int); func = va; stacksize = 0; do { i.word = *(int *)(intptr_t)va; if (((i.IType.op == OP_SW) || (i.IType.op == OP_SD)) && i.IType.rs == _R_SP && i.IType.rt == _R_RA) ra = *(int *)(intptr_t)(sp + (short)i.IType.imm); if (((i.IType.op == OP_ADDIU) || (i.IType.op == OP_DADDIU)) && i.IType.rs == _R_SP && i.IType.rt == _R_SP) stacksize = -(short)i.IType.imm; va += sizeof(int); } while (va < pc); db_find_sym_and_offset(func, &name, &offset); if (name == 0) name = "?"; (*pr)("%s()+0x%x, called by %p, stack size %d\n", name, pc - func, (void *)(intptr_t)ra, stacksize); if (ra == pc) { (*pr)("-- loop? --\n"); return; } sp += stacksize; pc = ra; } while (pc > (intptr_t)verylocore); if (pc < 0x80000000) (*pr)("-- user process --\n"); else (*pr)("-- kernel entry --\n"); #endif }