0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <asm/current.h>
0010 #include <linux/cred.h>
0011 #include <linux/errno.h>
0012 #include <linux/kernel.h>
0013 #include <linux/lsm_hooks.h>
0014 #include <linux/rcupdate.h>
0015 #include <linux/sched.h>
0016
0017 #include "common.h"
0018 #include "cred.h"
0019 #include "ptrace.h"
0020 #include "ruleset.h"
0021 #include "setup.h"
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 static bool domain_scope_le(const struct landlock_ruleset *const parent,
0033 const struct landlock_ruleset *const child)
0034 {
0035 const struct landlock_hierarchy *walker;
0036
0037 if (!parent)
0038 return true;
0039 if (!child)
0040 return false;
0041 for (walker = child->hierarchy; walker; walker = walker->parent) {
0042 if (walker == parent->hierarchy)
0043
0044 return true;
0045 }
0046
0047 return false;
0048 }
0049
0050 static bool task_is_scoped(const struct task_struct *const parent,
0051 const struct task_struct *const child)
0052 {
0053 bool is_scoped;
0054 const struct landlock_ruleset *dom_parent, *dom_child;
0055
0056 rcu_read_lock();
0057 dom_parent = landlock_get_task_domain(parent);
0058 dom_child = landlock_get_task_domain(child);
0059 is_scoped = domain_scope_le(dom_parent, dom_child);
0060 rcu_read_unlock();
0061 return is_scoped;
0062 }
0063
0064 static int task_ptrace(const struct task_struct *const parent,
0065 const struct task_struct *const child)
0066 {
0067
0068 if (!landlocked(parent))
0069 return 0;
0070 if (task_is_scoped(parent, child))
0071 return 0;
0072 return -EPERM;
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 static int hook_ptrace_access_check(struct task_struct *const child,
0089 const unsigned int mode)
0090 {
0091 return task_ptrace(current, child);
0092 }
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 static int hook_ptrace_traceme(struct task_struct *const parent)
0107 {
0108 return task_ptrace(parent, current);
0109 }
0110
0111 static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = {
0112 LSM_HOOK_INIT(ptrace_access_check, hook_ptrace_access_check),
0113 LSM_HOOK_INIT(ptrace_traceme, hook_ptrace_traceme),
0114 };
0115
0116 __init void landlock_add_ptrace_hooks(void)
0117 {
0118 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
0119 LANDLOCK_NAME);
0120 }