Message ID | 20200910202107.3799376-4-keescook@chromium.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Fork brute force attack mitigation (fbfam) | expand |
On Thu, Sep 10, 2020 at 01:21:04PM -0700, Kees Cook wrote: > From: John Wood <john.wood@gmx.com> > > Use the previous defined api to manage statistics calling it accordingly > when a task forks, calls execve or exits. > > Signed-off-by: John Wood <john.wood@gmx.com> > --- > fs/exec.c | 2 ++ > kernel/exit.c | 2 ++ > kernel/fork.c | 4 ++++ > 3 files changed, 8 insertions(+) > > diff --git a/fs/exec.c b/fs/exec.c > index a91003e28eaa..b30118674d32 100644 > --- a/fs/exec.c > +++ b/fs/exec.c > @@ -71,6 +71,7 @@ > #include "internal.h" > > #include <trace/events/sched.h> > +#include <fbfam/fbfam.h> > > static int bprm_creds_from_file(struct linux_binprm *bprm); > > @@ -1940,6 +1941,7 @@ static int bprm_execve(struct linux_binprm *bprm, > task_numa_free(current, false); > if (displaced) > put_files_struct(displaced); > + fbfam_execve(); As mentioned in the other emails, I think this could trivially be converted into an LSM: all the hooks are available AFAICT. If you only want to introspect execve _happening_, you can use bprm_creds_for_exec which is called a few lines above. Otherwise, my prior suggestion ("the exec has happened" hook via brpm_cred_committing, etc). > return retval; > > out: > diff --git a/kernel/exit.c b/kernel/exit.c > index 733e80f334e7..39a6139dcf31 100644 > --- a/kernel/exit.c > +++ b/kernel/exit.c > @@ -67,6 +67,7 @@ > #include <linux/uaccess.h> > #include <asm/unistd.h> > #include <asm/mmu_context.h> > +#include <fbfam/fbfam.h> > > static void __unhash_process(struct task_struct *p, bool group_dead) > { > @@ -852,6 +853,7 @@ void __noreturn do_exit(long code) > __this_cpu_add(dirty_throttle_leaks, tsk->nr_dirtied); > exit_rcu(); > exit_tasks_rcu_finish(); > + fbfam_exit(); > > lockdep_free_task(tsk); > do_task_dead(); The place for this would be put_task_struct, and the LSM hook is task_free. :) (The only caveat with task_free hook is that it may be called in non-process context due to being freed during RCU, etc. In practice, this is unlikely to cause problems.) > diff --git a/kernel/fork.c b/kernel/fork.c > index 49677d668de4..c933838450a8 100644 > --- a/kernel/fork.c > +++ b/kernel/fork.c > @@ -107,6 +107,8 @@ > #define CREATE_TRACE_POINTS > #include <trace/events/task.h> > > +#include <fbfam/fbfam.h> > + > /* > * Minimum number of threads to boot the kernel > */ > @@ -941,6 +943,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node) > #ifdef CONFIG_MEMCG > tsk->active_memcg = NULL; > #endif > + > + fbfam_fork(tsk); > return tsk; Since you don't need "orig", this is also trivially an LSM hook. dup_task_struct() is called by copy_process(), which will also call the task_alloc LSM hook later on. > > free_stack: > -- > 2.25.1 >
On Thu, 10 Sep 2020 16:33:38 -0700 Kees Cook <keescook@chromium.org> wrote: > > @@ -1940,6 +1941,7 @@ static int bprm_execve(struct linux_binprm *bprm, > > task_numa_free(current, false); > > if (displaced) > > put_files_struct(displaced); > > + fbfam_execve(); > > As mentioned in the other emails, I think this could trivially be > converted into an LSM: all the hooks are available AFAICT. If you only > want to introspect execve _happening_, you can use bprm_creds_for_exec > which is called a few lines above. Otherwise, my prior suggestion ("the > exec has happened" hook via brpm_cred_committing, etc). And if its information only, you could just register a callback to the trace_sched_process_exec() tracepoint and do whatever you want then. The tracepoints are available for anyone to attach to. Not just tracing. -- Steve
On Tue, 29 Sep 2020 19:47:12 -0400 Steven Rostedt <rostedt@goodmis.org> wrote: > On Thu, 10 Sep 2020 16:33:38 -0700 > Kees Cook <keescook@chromium.org> wrote: > > > > @@ -1940,6 +1941,7 @@ static int bprm_execve(struct linux_binprm *bprm, > > > task_numa_free(current, false); > > > if (displaced) > > > put_files_struct(displaced); > > > + fbfam_execve(); > > > > As mentioned in the other emails, I think this could trivially be > > converted into an LSM: all the hooks are available AFAICT. If you only > > want to introspect execve _happening_, you can use bprm_creds_for_exec > > which is called a few lines above. Otherwise, my prior suggestion ("the > > exec has happened" hook via brpm_cred_committing, etc). > > And if its information only, you could just register a callback to the > trace_sched_process_exec() tracepoint and do whatever you want then. > > The tracepoints are available for anyone to attach to. Not just tracing. > And there's also trace_sched_process_fork() and trace_sched_process_exit(). -- Steve
Hi Steven, On Tue, Sep 29, 2020 at 07:49:24PM -0400, Steven Rostedt wrote: > On Tue, 29 Sep 2020 19:47:12 -0400 > Steven Rostedt <rostedt@goodmis.org> wrote: > > > On Thu, 10 Sep 2020 16:33:38 -0700 > > Kees Cook <keescook@chromium.org> wrote: > > > > > > @@ -1940,6 +1941,7 @@ static int bprm_execve(struct linux_binprm *bprm, > > > > task_numa_free(current, false); > > > > if (displaced) > > > > put_files_struct(displaced); > > > > + fbfam_execve(); > > > > > > As mentioned in the other emails, I think this could trivially be > > > converted into an LSM: all the hooks are available AFAICT. If you only > > > want to introspect execve _happening_, you can use bprm_creds_for_exec > > > which is called a few lines above. Otherwise, my prior suggestion ("the > > > exec has happened" hook via brpm_cred_committing, etc). > > > > And if its information only, you could just register a callback to the > > trace_sched_process_exec() tracepoint and do whatever you want then. > > > > The tracepoints are available for anyone to attach to. Not just tracing. > > > And there's also trace_sched_process_fork() and > trace_sched_process_exit(). Since this feature requires a pointer to the statistical data in the task_struct structure, and the LSM allows this using the security blobs, I think that the best for now is convert all the code to an LSM. Anyway, thanks for the suggestion. > -- Steve Thanks, John Wood
diff --git a/fs/exec.c b/fs/exec.c index a91003e28eaa..b30118674d32 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -71,6 +71,7 @@ #include "internal.h" #include <trace/events/sched.h> +#include <fbfam/fbfam.h> static int bprm_creds_from_file(struct linux_binprm *bprm); @@ -1940,6 +1941,7 @@ static int bprm_execve(struct linux_binprm *bprm, task_numa_free(current, false); if (displaced) put_files_struct(displaced); + fbfam_execve(); return retval; out: diff --git a/kernel/exit.c b/kernel/exit.c index 733e80f334e7..39a6139dcf31 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -67,6 +67,7 @@ #include <linux/uaccess.h> #include <asm/unistd.h> #include <asm/mmu_context.h> +#include <fbfam/fbfam.h> static void __unhash_process(struct task_struct *p, bool group_dead) { @@ -852,6 +853,7 @@ void __noreturn do_exit(long code) __this_cpu_add(dirty_throttle_leaks, tsk->nr_dirtied); exit_rcu(); exit_tasks_rcu_finish(); + fbfam_exit(); lockdep_free_task(tsk); do_task_dead(); diff --git a/kernel/fork.c b/kernel/fork.c index 49677d668de4..c933838450a8 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -107,6 +107,8 @@ #define CREATE_TRACE_POINTS #include <trace/events/task.h> +#include <fbfam/fbfam.h> + /* * Minimum number of threads to boot the kernel */ @@ -941,6 +943,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node) #ifdef CONFIG_MEMCG tsk->active_memcg = NULL; #endif + + fbfam_fork(tsk); return tsk; free_stack: