void gr_handle_crash(struct task_struct *task, const int sig) { struct acl_subject_label *curr; struct acl_subject_label *curr2; struct task_struct *tsk, *tsk2; const struct cred *cred; const struct cred *cred2; if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL) return; if (unlikely(!gr_acl_is_enabled())) return; curr = task->acl; if (!(curr->resmask & (1 << GR_CRASH_RES))) return; if (time_before_eq(curr->expires, get_seconds())) { curr->expires = 0; curr->crashes = 0; } curr->crashes++; if (!curr->expires) curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max; if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) && time_after(curr->expires, get_seconds())) { rcu_read_lock(); cred = __task_cred(task); if (cred->uid && proc_is_setxid(cred)) { gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max); spin_lock(&gr_uid_lock); gr_insert_uid(cred->uid, curr->expires); spin_unlock(&gr_uid_lock); curr->expires = 0; curr->crashes = 0; read_lock(&tasklist_lock); do_each_thread(tsk2, tsk) { cred2 = __task_cred(tsk); if (tsk != task && cred2->uid == cred->uid) gr_fake_force_sig(SIGKILL, tsk); } while_each_thread(tsk2, tsk);
void gr_handle_brute_attach(struct task_struct *p, unsigned long mm_flags) { #ifdef CONFIG_GRKERNSEC_BRUTE uid_t uid = 0; if (!grsec_enable_brute) return; rcu_read_lock(); read_lock(&tasklist_lock); read_lock(&grsec_exec_file_lock); if (p->real_parent && p->real_parent->exec_file == p->exec_file) p->real_parent->brute = 1; else { const struct cred *cred = __task_cred(p), *cred2; struct task_struct *tsk, *tsk2; if (!__get_dumpable(mm_flags) && cred->uid) { struct user_struct *user; uid = cred->uid; /* this is put upon execution past expiration */ user = find_user(uid); if (user == NULL) goto unlock; user->banned = 1; user->ban_expires = get_seconds() + GR_USER_BAN_TIME; if (user->ban_expires == ~0UL) user->ban_expires--; do_each_thread(tsk2, tsk) { cred2 = __task_cred(tsk); if (tsk != p && cred2->uid == uid) gr_fake_force_sig(SIGKILL, tsk); } while_each_thread(tsk2, tsk); } }
void gr_handle_kernel_exploit(void) { #ifdef CONFIG_GRKERNSEC_KERN_LOCKOUT const struct cred *cred; struct task_struct *tsk, *tsk2; struct user_struct *user; uid_t uid; if (in_irq() || in_serving_softirq() || in_nmi()) panic("grsec: halting the system due to suspicious kernel crash caused in interrupt context"); uid = current_uid(); if (uid == 0) panic("grsec: halting the system due to suspicious kernel crash caused by root"); else { /* kill all the processes of this user, hold a reference to their creds struct, and prevent them from creating another process until system reset */ printk(KERN_ALERT "grsec: banning user with uid %u until system restart for suspicious kernel crash\n", uid); /* we intentionally leak this ref */ user = get_uid(current->cred->user); if (user) { user->banned = 1; user->ban_expires = ~0UL; } read_lock(&tasklist_lock); do_each_thread(tsk2, tsk) { cred = __task_cred(tsk); if (cred->uid == uid) gr_fake_force_sig(SIGKILL, tsk); } while_each_thread(tsk2, tsk); read_unlock(&tasklist_lock); }