#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/grinternal.h>

void
gr_log_signal(const int sig, const struct task_struct *t)
{
#ifdef CONFIG_GRKERNSEC_SIGNAL
	if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
				    (sig == SIGABRT) || (sig == SIGBUS))) {
		if (t->pid == current->pid) {
			security_alert_good(GR_UNISIGLOG_MSG, sig,
					    DEFAULTSECARGS);
		} else {
			security_alert_good(GR_DUALSIGLOG_MSG, sig,
					    gr_task_fullpath0(t), t->comm,
					    t->pid, t->uid, t->euid, t->gid,
					    t->egid, gr_parent_task_fullpath0(t),
					    t->p_pptr->comm,
					    t->p_pptr->pid, t->p_pptr->uid,
					    t->p_pptr->euid, t->p_pptr->gid,
					    t->p_pptr->egid, DEFAULTSECARGS);
		}
	}
#endif
	return;
}

int
gr_handle_signal(const struct task_struct *p, const int sig)
{
#ifdef CONFIG_GRKERNSEC
	if (current->pid > 1 && sig != SIGCHLD && gr_check_protected_task(p)) {
		security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath0(p),
			       p->comm, p->pid, p->uid,
			       p->euid, p->gid, p->egid,
			       gr_parent_task_fullpath0(p), p->p_pptr->comm,
			       p->p_pptr->pid, p->p_pptr->uid,
			       p->p_pptr->euid, p->p_pptr->gid,
			       p->p_pptr->egid, DEFAULTSECARGS);
		return -EPERM;
	} else if (gr_pid_is_chrooted((struct task_struct *)p)) {
		return -EPERM;
	}
#endif
	return 0;
}

void gr_handle_brute_attach(struct task_struct *p)
{
#ifdef CONFIG_GRKERNSEC_BRUTE
	read_lock(&tasklist_lock);
	read_lock(&grsec_exec_file_lock);
	if (p->p_pptr && p->p_pptr->exec_file == p->exec_file)
		p->p_pptr->brute = 1;
	read_unlock(&grsec_exec_file_lock);
	read_unlock(&tasklist_lock);
#endif
	return;
}

void gr_handle_brute_check(void)
{
#ifdef CONFIG_GRKERNSEC_BRUTE
	if (current->brute) {
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(30 * HZ);
	}	
#endif
	return;
}

