Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Yama Linux Security Module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Author: Kees Cook <keescook@chromium.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (C) 2010 Canonical, Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Copyright (C) 2011 The Chromium OS Authors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/lsm_hooks.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/sysctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/prctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/string_helpers.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/task_work.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define YAMA_SCOPE_DISABLED	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define YAMA_SCOPE_RELATIONAL	1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define YAMA_SCOPE_CAPABILITY	2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define YAMA_SCOPE_NO_ATTACH	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static int ptrace_scope = YAMA_SCOPE_RELATIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /* describe a ptrace relationship for potential exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) struct ptrace_relation {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct task_struct *tracer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct task_struct *tracee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	bool invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	struct rcu_head rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static LIST_HEAD(ptracer_relations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static DEFINE_SPINLOCK(ptracer_relations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static void yama_relation_cleanup(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static DECLARE_WORK(yama_relation_work, yama_relation_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) struct access_report_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct callback_head work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	const char *access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	struct task_struct *target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	struct task_struct *agent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static void __report_access(struct callback_head *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	struct access_report_info *info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		container_of(work, struct access_report_info, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	char *target_cmd, *agent_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	target_cmd = kstrdup_quotable_cmdline(info->target, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	agent_cmd = kstrdup_quotable_cmdline(info->agent, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	pr_notice_ratelimited(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		"ptrace %s of \"%s\"[%d] was attempted by \"%s\"[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		info->access, target_cmd, info->target->pid, agent_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		info->agent->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	kfree(agent_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	kfree(target_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	put_task_struct(info->agent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	put_task_struct(info->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	kfree(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) /* defers execution because cmdline access can sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) static void report_access(const char *access, struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 				struct task_struct *agent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	struct access_report_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	char agent_comm[sizeof(agent->comm)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	assert_spin_locked(&target->alloc_lock); /* for target->comm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	if (current->flags & PF_KTHREAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		/* I don't think kthreads call task_work_run() before exiting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		 * Imagine angry ranting about procfs here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		pr_notice_ratelimited(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		    "ptrace %s of \"%s\"[%d] was attempted by \"%s\"[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		    access, target->comm, target->pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		    get_task_comm(agent_comm, agent), agent->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	info = kmalloc(sizeof(*info), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	init_task_work(&info->work, __report_access);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	get_task_struct(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	get_task_struct(agent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	info->access = access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	info->target = target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	info->agent = agent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	if (task_work_add(current, &info->work, TWA_RESUME) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		return; /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	WARN(1, "report_access called from exiting task");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	put_task_struct(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	put_task_struct(agent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	kfree(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * yama_relation_cleanup - remove invalid entries from the relation list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void yama_relation_cleanup(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	struct ptrace_relation *relation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	spin_lock(&ptracer_relations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	list_for_each_entry_rcu(relation, &ptracer_relations, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		if (relation->invalid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			list_del_rcu(&relation->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 			kfree_rcu(relation, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	spin_unlock(&ptracer_relations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * yama_ptracer_add - add/replace an exception for this tracer/tracee pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * @tracer: the task_struct of the process doing the ptrace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * @tracee: the task_struct of the process to be ptraced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * Each tracee can have, at most, one tracer registered. Each time this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * is called, the prior registered tracer will be replaced for the tracee.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * Returns 0 if relationship was added, -ve on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int yama_ptracer_add(struct task_struct *tracer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			    struct task_struct *tracee)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	struct ptrace_relation *relation, *added;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	added = kmalloc(sizeof(*added), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (!added)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	added->tracee = tracee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	added->tracer = tracer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	added->invalid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	spin_lock(&ptracer_relations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	list_for_each_entry_rcu(relation, &ptracer_relations, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		if (relation->invalid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		if (relation->tracee == tracee) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			list_replace_rcu(&relation->node, &added->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			kfree_rcu(relation, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	list_add_rcu(&added->node, &ptracer_relations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	spin_unlock(&ptracer_relations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * yama_ptracer_del - remove exceptions related to the given tasks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * @tracer: remove any relation where tracer task matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * @tracee: remove any relation where tracee task matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static void yama_ptracer_del(struct task_struct *tracer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			     struct task_struct *tracee)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	struct ptrace_relation *relation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	bool marked = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	list_for_each_entry_rcu(relation, &ptracer_relations, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		if (relation->invalid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		if (relation->tracee == tracee ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		    (tracer && relation->tracer == tracer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 			relation->invalid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			marked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	if (marked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		schedule_work(&yama_relation_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  * yama_task_free - check for task_pid to remove from exception list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  * @task: task being removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static void yama_task_free(struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	yama_ptracer_del(task, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * yama_task_prctl - check for Yama-specific prctl operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * @option: operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  * @arg2: argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * @arg3: argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * @arg4: argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * @arg5: argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  * Return 0 on success, -ve on error.  -ENOSYS is returned when Yama
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  * does not handle the given option.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			   unsigned long arg4, unsigned long arg5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	int rc = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	struct task_struct *myself = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	switch (option) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	case PR_SET_PTRACER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		/* Since a thread can call prctl(), find the group leader
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		 * before calling _add() or _del() on it, since we want
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		 * process-level granularity of control. The tracer group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		 * leader checking is handled later when walking the ancestry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		 * at the time of PTRACE_ATTACH check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		if (!thread_group_leader(myself))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			myself = rcu_dereference(myself->group_leader);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		get_task_struct(myself);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		if (arg2 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			yama_ptracer_del(NULL, myself);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		} else if (arg2 == PR_SET_PTRACER_ANY || (int)arg2 == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			rc = yama_ptracer_add(NULL, myself);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			struct task_struct *tracer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			tracer = find_get_task_by_vpid(arg2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			if (!tracer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 				rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 				rc = yama_ptracer_add(tracer, myself);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 				put_task_struct(tracer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		put_task_struct(myself);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)  * task_is_descendant - walk up a process family tree looking for a match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)  * @parent: the process to compare against while walking up from child
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)  * @child: the process to start from while looking upwards for parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  * Returns 1 if child is a descendant of parent, 0 if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int task_is_descendant(struct task_struct *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			      struct task_struct *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	struct task_struct *walker = child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	if (!parent || !child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	if (!thread_group_leader(parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		parent = rcu_dereference(parent->group_leader);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	while (walker->pid > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		if (!thread_group_leader(walker))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			walker = rcu_dereference(walker->group_leader);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		if (walker == parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		walker = rcu_dereference(walker->real_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)  * ptracer_exception_found - tracer registered as exception for this tracee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)  * @tracer: the task_struct of the process attempting ptrace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  * @tracee: the task_struct of the process to be ptraced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)  * Returns 1 if tracer has a ptracer exception ancestor for tracee.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static int ptracer_exception_found(struct task_struct *tracer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 				   struct task_struct *tracee)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	struct ptrace_relation *relation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	struct task_struct *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	 * If there's already an active tracing relationship, then make an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	 * exception for the sake of other accesses, like process_vm_rw().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	parent = ptrace_parent(tracee);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (parent != NULL && same_thread_group(parent, tracer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	/* Look for a PR_SET_PTRACER relationship. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	if (!thread_group_leader(tracee))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		tracee = rcu_dereference(tracee->group_leader);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	list_for_each_entry_rcu(relation, &ptracer_relations, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		if (relation->invalid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		if (relation->tracee == tracee) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 			parent = relation->tracer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 			found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	if (found && (parent == NULL || task_is_descendant(parent, tracer)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)  * yama_ptrace_access_check - validate PTRACE_ATTACH calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)  * @child: task that current task is attempting to ptrace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)  * @mode: ptrace attach mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)  * Returns 0 if following the ptrace is allowed, -ve on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int yama_ptrace_access_check(struct task_struct *child,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 				    unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	/* require ptrace target be a child of ptracer on attach */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (mode & PTRACE_MODE_ATTACH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		switch (ptrace_scope) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		case YAMA_SCOPE_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			/* No additional restrictions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		case YAMA_SCOPE_RELATIONAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 			rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			if (!pid_alive(child))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 				rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 			if (!rc && !task_is_descendant(current, child) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 			    !ptracer_exception_found(current, child) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			    !ns_capable(__task_cred(child)->user_ns, CAP_SYS_PTRACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 				rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		case YAMA_SCOPE_CAPABILITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			if (!ns_capable(__task_cred(child)->user_ns, CAP_SYS_PTRACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 				rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		case YAMA_SCOPE_NO_ATTACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	if (rc && (mode & PTRACE_MODE_NOAUDIT) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		report_access("attach", child, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  * yama_ptrace_traceme - validate PTRACE_TRACEME calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  * @parent: task that will become the ptracer of the current task
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  * Returns 0 if following the ptrace is allowed, -ve on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int yama_ptrace_traceme(struct task_struct *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	/* Only disallow PTRACE_TRACEME on more aggressive settings. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	switch (ptrace_scope) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	case YAMA_SCOPE_CAPABILITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		if (!has_ns_capability(parent, current_user_ns(), CAP_SYS_PTRACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	case YAMA_SCOPE_NO_ATTACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		task_lock(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		report_access("traceme", current, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		task_unlock(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static struct security_hook_list yama_hooks[] __lsm_ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	LSM_HOOK_INIT(task_prctl, yama_task_prctl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	LSM_HOOK_INIT(task_free, yama_task_free),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) #ifdef CONFIG_SYSCTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int yama_dointvec_minmax(struct ctl_table *table, int write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 				void *buffer, size_t *lenp, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	struct ctl_table table_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	if (write && !capable(CAP_SYS_PTRACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	/* Lock the max value if it ever gets set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	table_copy = *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (*(int *)table_copy.data == *(int *)table_copy.extra2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		table_copy.extra1 = table_copy.extra2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	return proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int max_scope = YAMA_SCOPE_NO_ATTACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static struct ctl_path yama_sysctl_path[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	{ .procname = "kernel", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	{ .procname = "yama", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static struct ctl_table yama_sysctl_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		.procname       = "ptrace_scope",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		.data           = &ptrace_scope,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		.maxlen         = sizeof(int),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		.mode           = 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		.proc_handler   = yama_dointvec_minmax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		.extra1         = SYSCTL_ZERO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		.extra2         = &max_scope,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static void __init yama_init_sysctl(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		panic("Yama: sysctl registration failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static inline void yama_init_sysctl(void) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) #endif /* CONFIG_SYSCTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static int __init yama_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	pr_info("Yama: becoming mindful.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	yama_init_sysctl();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) DEFINE_LSM(yama) = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	.name = "yama",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	.init = yama_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) };