Example #1
0
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 */
}
Example #2
0
/*
 * 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;
}
Example #3
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
}