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); } }
/* format_corename will inspect the pattern parameter, and output a * name into corename, which must have space for at least * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. */ static int format_corename(struct core_name *cn, struct coredump_params *cprm) { const struct cred *cred = current_cred(); const char *pat_ptr = core_pattern; int ispipe = (*pat_ptr == '|'); int pid_in_pattern = 0; int err = 0; cn->size = CORENAME_MAX_SIZE * atomic_read(&call_count); cn->corename = kmalloc(cn->size, GFP_KERNEL); cn->used = 0; if (!cn->corename) return -ENOMEM; /* Repeat as long as we have more pattern to process and more output space */ while (*pat_ptr) { if (*pat_ptr != '%') { if (*pat_ptr == 0) goto out; err = cn_printf(cn, "%c", *pat_ptr++); } else { switch (*++pat_ptr) { /* single % at the end, drop that */ case 0: goto out; /* Double percent, output one percent */ case '%': err = cn_printf(cn, "%c", '%'); break; /* pid */ case 'p': pid_in_pattern = 1; err = cn_printf(cn, "%d", task_tgid_vnr(current)); break; /* uid */ case 'u': err = cn_printf(cn, "%d", cred->uid); break; /* gid */ case 'g': err = cn_printf(cn, "%d", cred->gid); break; case 'd': err = cn_printf(cn, "%d", __get_dumpable(cprm->mm_flags)); break; /* signal that caused the coredump */ case 's': err = cn_printf(cn, "%ld", cprm->siginfo->si_signo); break; /* UNIX time of coredump */ case 't': { struct timeval tv; do_gettimeofday(&tv); err = cn_printf(cn, "%lu", tv.tv_sec); break; } /* hostname */ case 'h': { char *namestart = cn->corename + cn->used; down_read(&uts_sem); err = cn_printf(cn, "%s", utsname()->nodename); up_read(&uts_sem); cn_escape(namestart); break; } /* executable */ case 'e': { char *commstart = cn->corename + cn->used; err = cn_printf(cn, "%s", current->comm); cn_escape(commstart); break; } case 'E': err = cn_print_exe_file(cn); break; /* core limit size */ case 'c': err = cn_printf(cn, "%lu", rlimit(RLIMIT_CORE)); break; default: break; } ++pat_ptr; } if (err) return err; } /* Backward compatibility with core_uses_pid: * * If core_pattern does not include a %p (as is the default) * and core_uses_pid is set, then .%pid will be appended to * the filename. Do not do this for piped commands. */ if (!ispipe && !pid_in_pattern && core_uses_pid) { err = cn_printf(cn, ".%d", task_tgid_vnr(current)); if (err) return err; } out: return ispipe; }