Blame view

security/yama/yama_lsm.c 12 KB
d2912cb15   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
2d514487f   Kees Cook   security: Yama LSM
2
3
4
5
6
7
8
  /*
   * Yama Linux Security Module
   *
   * Author: Kees Cook <keescook@chromium.org>
   *
   * Copyright (C) 2010 Canonical, Ltd.
   * Copyright (C) 2011 The Chromium OS Authors.
2d514487f   Kees Cook   security: Yama LSM
9
   */
3c4ed7bdf   Casey Schaufler   LSM: Split securi...
10
  #include <linux/lsm_hooks.h>
2d514487f   Kees Cook   security: Yama LSM
11
12
13
14
  #include <linux/sysctl.h>
  #include <linux/ptrace.h>
  #include <linux/prctl.h>
  #include <linux/ratelimit.h>
235e75278   Kees Cook   Yama: remove lock...
15
  #include <linux/workqueue.h>
8a56038c2   Kees Cook   Yama: consolidate...
16
  #include <linux/string_helpers.h>
dca6b4149   Jann Horn   Yama: fix double-...
17
18
19
  #include <linux/task_work.h>
  #include <linux/sched.h>
  #include <linux/spinlock.h>
2d514487f   Kees Cook   security: Yama LSM
20

389da25f9   Kees Cook   Yama: add additio...
21
22
23
24
25
26
  #define YAMA_SCOPE_DISABLED	0
  #define YAMA_SCOPE_RELATIONAL	1
  #define YAMA_SCOPE_CAPABILITY	2
  #define YAMA_SCOPE_NO_ATTACH	3
  
  static int ptrace_scope = YAMA_SCOPE_RELATIONAL;
2d514487f   Kees Cook   security: Yama LSM
27
28
29
30
31
  
  /* describe a ptrace relationship for potential exception */
  struct ptrace_relation {
  	struct task_struct *tracer;
  	struct task_struct *tracee;
235e75278   Kees Cook   Yama: remove lock...
32
  	bool invalid;
2d514487f   Kees Cook   security: Yama LSM
33
  	struct list_head node;
93b69d437   Kees Cook   Yama: add RCU to ...
34
  	struct rcu_head rcu;
2d514487f   Kees Cook   security: Yama LSM
35
36
37
38
  };
  
  static LIST_HEAD(ptracer_relations);
  static DEFINE_SPINLOCK(ptracer_relations_lock);
235e75278   Kees Cook   Yama: remove lock...
39
40
  static void yama_relation_cleanup(struct work_struct *work);
  static DECLARE_WORK(yama_relation_work, yama_relation_cleanup);
dca6b4149   Jann Horn   Yama: fix double-...
41
42
43
44
45
46
47
48
  struct access_report_info {
  	struct callback_head work;
  	const char *access;
  	struct task_struct *target;
  	struct task_struct *agent;
  };
  
  static void __report_access(struct callback_head *work)
8a56038c2   Kees Cook   Yama: consolidate...
49
  {
dca6b4149   Jann Horn   Yama: fix double-...
50
51
  	struct access_report_info *info =
  		container_of(work, struct access_report_info, work);
8a56038c2   Kees Cook   Yama: consolidate...
52
  	char *target_cmd, *agent_cmd;
dca6b4149   Jann Horn   Yama: fix double-...
53
54
  	target_cmd = kstrdup_quotable_cmdline(info->target, GFP_KERNEL);
  	agent_cmd = kstrdup_quotable_cmdline(info->agent, GFP_KERNEL);
8a56038c2   Kees Cook   Yama: consolidate...
55
56
57
58
  
  	pr_notice_ratelimited(
  		"ptrace %s of \"%s\"[%d] was attempted by \"%s\"[%d]
  ",
dca6b4149   Jann Horn   Yama: fix double-...
59
60
  		info->access, target_cmd, info->target->pid, agent_cmd,
  		info->agent->pid);
8a56038c2   Kees Cook   Yama: consolidate...
61
62
63
  
  	kfree(agent_cmd);
  	kfree(target_cmd);
dca6b4149   Jann Horn   Yama: fix double-...
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  
  	put_task_struct(info->agent);
  	put_task_struct(info->target);
  	kfree(info);
  }
  
  /* defers execution because cmdline access can sleep */
  static void report_access(const char *access, struct task_struct *target,
  				struct task_struct *agent)
  {
  	struct access_report_info *info;
  	char agent_comm[sizeof(agent->comm)];
  
  	assert_spin_locked(&target->alloc_lock); /* for target->comm */
  
  	if (current->flags & PF_KTHREAD) {
  		/* I don't think kthreads call task_work_run() before exiting.
  		 * Imagine angry ranting about procfs here.
  		 */
  		pr_notice_ratelimited(
  		    "ptrace %s of \"%s\"[%d] was attempted by \"%s\"[%d]
  ",
  		    access, target->comm, target->pid,
  		    get_task_comm(agent_comm, agent), agent->pid);
  		return;
  	}
  
  	info = kmalloc(sizeof(*info), GFP_ATOMIC);
  	if (!info)
  		return;
  	init_task_work(&info->work, __report_access);
  	get_task_struct(target);
  	get_task_struct(agent);
  	info->access = access;
  	info->target = target;
  	info->agent = agent;
91989c707   Jens Axboe   task_work: cleanu...
100
  	if (task_work_add(current, &info->work, TWA_RESUME) == 0)
dca6b4149   Jann Horn   Yama: fix double-...
101
102
103
104
105
106
  		return; /* success */
  
  	WARN(1, "report_access called from exiting task");
  	put_task_struct(target);
  	put_task_struct(agent);
  	kfree(info);
8a56038c2   Kees Cook   Yama: consolidate...
107
  }
235e75278   Kees Cook   Yama: remove lock...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  /**
   * yama_relation_cleanup - remove invalid entries from the relation list
   *
   */
  static void yama_relation_cleanup(struct work_struct *work)
  {
  	struct ptrace_relation *relation;
  
  	spin_lock(&ptracer_relations_lock);
  	rcu_read_lock();
  	list_for_each_entry_rcu(relation, &ptracer_relations, node) {
  		if (relation->invalid) {
  			list_del_rcu(&relation->node);
  			kfree_rcu(relation, rcu);
  		}
  	}
  	rcu_read_unlock();
  	spin_unlock(&ptracer_relations_lock);
  }
2d514487f   Kees Cook   security: Yama LSM
127
128
129
130
131
132
133
134
135
136
137
138
139
  /**
   * yama_ptracer_add - add/replace an exception for this tracer/tracee pair
   * @tracer: the task_struct of the process doing the ptrace
   * @tracee: the task_struct of the process to be ptraced
   *
   * Each tracee can have, at most, one tracer registered. Each time this
   * is called, the prior registered tracer will be replaced for the tracee.
   *
   * Returns 0 if relationship was added, -ve on error.
   */
  static int yama_ptracer_add(struct task_struct *tracer,
  			    struct task_struct *tracee)
  {
93b69d437   Kees Cook   Yama: add RCU to ...
140
  	struct ptrace_relation *relation, *added;
2d514487f   Kees Cook   security: Yama LSM
141
142
143
144
  
  	added = kmalloc(sizeof(*added), GFP_KERNEL);
  	if (!added)
  		return -ENOMEM;
93b69d437   Kees Cook   Yama: add RCU to ...
145
146
  	added->tracee = tracee;
  	added->tracer = tracer;
235e75278   Kees Cook   Yama: remove lock...
147
  	added->invalid = false;
93b69d437   Kees Cook   Yama: add RCU to ...
148

235e75278   Kees Cook   Yama: remove lock...
149
  	spin_lock(&ptracer_relations_lock);
93b69d437   Kees Cook   Yama: add RCU to ...
150
151
  	rcu_read_lock();
  	list_for_each_entry_rcu(relation, &ptracer_relations, node) {
235e75278   Kees Cook   Yama: remove lock...
152
153
  		if (relation->invalid)
  			continue;
93b69d437   Kees Cook   Yama: add RCU to ...
154
155
156
157
  		if (relation->tracee == tracee) {
  			list_replace_rcu(&relation->node, &added->node);
  			kfree_rcu(relation, rcu);
  			goto out;
2d514487f   Kees Cook   security: Yama LSM
158
  		}
2d514487f   Kees Cook   security: Yama LSM
159
  	}
2d514487f   Kees Cook   security: Yama LSM
160

93b69d437   Kees Cook   Yama: add RCU to ...
161
  	list_add_rcu(&added->node, &ptracer_relations);
2d514487f   Kees Cook   security: Yama LSM
162

93b69d437   Kees Cook   Yama: add RCU to ...
163
164
  out:
  	rcu_read_unlock();
235e75278   Kees Cook   Yama: remove lock...
165
  	spin_unlock(&ptracer_relations_lock);
93b69d437   Kees Cook   Yama: add RCU to ...
166
  	return 0;
2d514487f   Kees Cook   security: Yama LSM
167
168
169
170
171
172
173
174
175
176
  }
  
  /**
   * yama_ptracer_del - remove exceptions related to the given tasks
   * @tracer: remove any relation where tracer task matches
   * @tracee: remove any relation where tracee task matches
   */
  static void yama_ptracer_del(struct task_struct *tracer,
  			     struct task_struct *tracee)
  {
93b69d437   Kees Cook   Yama: add RCU to ...
177
  	struct ptrace_relation *relation;
235e75278   Kees Cook   Yama: remove lock...
178
  	bool marked = false;
2d514487f   Kees Cook   security: Yama LSM
179

93b69d437   Kees Cook   Yama: add RCU to ...
180
181
  	rcu_read_lock();
  	list_for_each_entry_rcu(relation, &ptracer_relations, node) {
235e75278   Kees Cook   Yama: remove lock...
182
183
  		if (relation->invalid)
  			continue;
2d514487f   Kees Cook   security: Yama LSM
184
  		if (relation->tracee == tracee ||
bf06189e4   Kees Cook   Yama: add PR_SET_...
185
  		    (tracer && relation->tracer == tracer)) {
235e75278   Kees Cook   Yama: remove lock...
186
187
  			relation->invalid = true;
  			marked = true;
2d514487f   Kees Cook   security: Yama LSM
188
  		}
93b69d437   Kees Cook   Yama: add RCU to ...
189
190
  	}
  	rcu_read_unlock();
235e75278   Kees Cook   Yama: remove lock...
191
192
193
  
  	if (marked)
  		schedule_work(&yama_relation_work);
2d514487f   Kees Cook   security: Yama LSM
194
195
196
197
198
199
  }
  
  /**
   * yama_task_free - check for task_pid to remove from exception list
   * @task: task being removed
   */
1aa176ef5   Jann Horn   Yama: mark local ...
200
  static void yama_task_free(struct task_struct *task)
2d514487f   Kees Cook   security: Yama LSM
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
  {
  	yama_ptracer_del(task, task);
  }
  
  /**
   * yama_task_prctl - check for Yama-specific prctl operations
   * @option: operation
   * @arg2: argument
   * @arg3: argument
   * @arg4: argument
   * @arg5: argument
   *
   * Return 0 on success, -ve on error.  -ENOSYS is returned when Yama
   * does not handle the given option.
   */
1aa176ef5   Jann Horn   Yama: mark local ...
216
  static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
2d514487f   Kees Cook   security: Yama LSM
217
218
  			   unsigned long arg4, unsigned long arg5)
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
219
  	int rc = -ENOSYS;
2d514487f   Kees Cook   security: Yama LSM
220
  	struct task_struct *myself = current;
2d514487f   Kees Cook   security: Yama LSM
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
  	switch (option) {
  	case PR_SET_PTRACER:
  		/* Since a thread can call prctl(), find the group leader
  		 * before calling _add() or _del() on it, since we want
  		 * process-level granularity of control. The tracer group
  		 * leader checking is handled later when walking the ancestry
  		 * at the time of PTRACE_ATTACH check.
  		 */
  		rcu_read_lock();
  		if (!thread_group_leader(myself))
  			myself = rcu_dereference(myself->group_leader);
  		get_task_struct(myself);
  		rcu_read_unlock();
  
  		if (arg2 == 0) {
  			yama_ptracer_del(NULL, myself);
  			rc = 0;
2e4930eb7   Kees Cook   Yama: handle 32-b...
238
  		} else if (arg2 == PR_SET_PTRACER_ANY || (int)arg2 == -1) {
bf06189e4   Kees Cook   Yama: add PR_SET_...
239
  			rc = yama_ptracer_add(NULL, myself);
2d514487f   Kees Cook   security: Yama LSM
240
241
  		} else {
  			struct task_struct *tracer;
2ee082608   Mike Rapoport   pids: introduce f...
242
243
  			tracer = find_get_task_by_vpid(arg2);
  			if (!tracer) {
2d514487f   Kees Cook   security: Yama LSM
244
  				rc = -EINVAL;
2ee082608   Mike Rapoport   pids: introduce f...
245
  			} else {
2d514487f   Kees Cook   security: Yama LSM
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
  				rc = yama_ptracer_add(tracer, myself);
  				put_task_struct(tracer);
  			}
  		}
  
  		put_task_struct(myself);
  		break;
  	}
  
  	return rc;
  }
  
  /**
   * task_is_descendant - walk up a process family tree looking for a match
   * @parent: the process to compare against while walking up from child
   * @child: the process to start from while looking upwards for parent
   *
   * Returns 1 if child is a descendant of parent, 0 if not.
   */
  static int task_is_descendant(struct task_struct *parent,
  			      struct task_struct *child)
  {
  	int rc = 0;
  	struct task_struct *walker = child;
  
  	if (!parent || !child)
  		return 0;
  
  	rcu_read_lock();
  	if (!thread_group_leader(parent))
  		parent = rcu_dereference(parent->group_leader);
  	while (walker->pid > 0) {
  		if (!thread_group_leader(walker))
  			walker = rcu_dereference(walker->group_leader);
  		if (walker == parent) {
  			rc = 1;
  			break;
  		}
  		walker = rcu_dereference(walker->real_parent);
  	}
  	rcu_read_unlock();
  
  	return rc;
  }
  
  /**
   * ptracer_exception_found - tracer registered as exception for this tracee
   * @tracer: the task_struct of the process attempting ptrace
   * @tracee: the task_struct of the process to be ptraced
   *
50523a29d   Josh Stone   Yama: allow acces...
296
   * Returns 1 if tracer has a ptracer exception ancestor for tracee.
2d514487f   Kees Cook   security: Yama LSM
297
298
299
300
301
302
303
   */
  static int ptracer_exception_found(struct task_struct *tracer,
  				   struct task_struct *tracee)
  {
  	int rc = 0;
  	struct ptrace_relation *relation;
  	struct task_struct *parent = NULL;
bf06189e4   Kees Cook   Yama: add PR_SET_...
304
  	bool found = false;
2d514487f   Kees Cook   security: Yama LSM
305

2d514487f   Kees Cook   security: Yama LSM
306
  	rcu_read_lock();
50523a29d   Josh Stone   Yama: allow acces...
307
308
309
310
311
312
313
314
315
316
317
318
  
  	/*
  	 * If there's already an active tracing relationship, then make an
  	 * exception for the sake of other accesses, like process_vm_rw().
  	 */
  	parent = ptrace_parent(tracee);
  	if (parent != NULL && same_thread_group(parent, tracer)) {
  		rc = 1;
  		goto unlock;
  	}
  
  	/* Look for a PR_SET_PTRACER relationship. */
2d514487f   Kees Cook   security: Yama LSM
319
320
  	if (!thread_group_leader(tracee))
  		tracee = rcu_dereference(tracee->group_leader);
235e75278   Kees Cook   Yama: remove lock...
321
322
323
  	list_for_each_entry_rcu(relation, &ptracer_relations, node) {
  		if (relation->invalid)
  			continue;
2d514487f   Kees Cook   security: Yama LSM
324
325
  		if (relation->tracee == tracee) {
  			parent = relation->tracer;
bf06189e4   Kees Cook   Yama: add PR_SET_...
326
  			found = true;
2d514487f   Kees Cook   security: Yama LSM
327
328
  			break;
  		}
235e75278   Kees Cook   Yama: remove lock...
329
  	}
2d514487f   Kees Cook   security: Yama LSM
330

bf06189e4   Kees Cook   Yama: add PR_SET_...
331
  	if (found && (parent == NULL || task_is_descendant(parent, tracer)))
2d514487f   Kees Cook   security: Yama LSM
332
  		rc = 1;
50523a29d   Josh Stone   Yama: allow acces...
333
334
  
  unlock:
2d514487f   Kees Cook   security: Yama LSM
335
  	rcu_read_unlock();
2d514487f   Kees Cook   security: Yama LSM
336
337
338
339
340
341
342
343
344
345
346
  
  	return rc;
  }
  
  /**
   * yama_ptrace_access_check - validate PTRACE_ATTACH calls
   * @child: task that current task is attempting to ptrace
   * @mode: ptrace attach mode
   *
   * Returns 0 if following the ptrace is allowed, -ve on error.
   */
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
347
  static int yama_ptrace_access_check(struct task_struct *child,
2d514487f   Kees Cook   security: Yama LSM
348
349
  				    unsigned int mode)
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
350
  	int rc = 0;
2d514487f   Kees Cook   security: Yama LSM
351
352
  
  	/* require ptrace target be a child of ptracer on attach */
3dfb7d8cd   Jann Horn   security: let sec...
353
  	if (mode & PTRACE_MODE_ATTACH) {
389da25f9   Kees Cook   Yama: add additio...
354
355
356
357
358
  		switch (ptrace_scope) {
  		case YAMA_SCOPE_DISABLED:
  			/* No additional restrictions. */
  			break;
  		case YAMA_SCOPE_RELATIONAL:
4c44aaafa   Eric W. Biederman   userns: Kill task...
359
  			rcu_read_lock();
9474f4e7c   Kees Cook   Yama: Check for p...
360
361
362
  			if (!pid_alive(child))
  				rc = -EPERM;
  			if (!rc && !task_is_descendant(current, child) &&
389da25f9   Kees Cook   Yama: add additio...
363
  			    !ptracer_exception_found(current, child) &&
4c44aaafa   Eric W. Biederman   userns: Kill task...
364
  			    !ns_capable(__task_cred(child)->user_ns, CAP_SYS_PTRACE))
389da25f9   Kees Cook   Yama: add additio...
365
  				rc = -EPERM;
4c44aaafa   Eric W. Biederman   userns: Kill task...
366
  			rcu_read_unlock();
389da25f9   Kees Cook   Yama: add additio...
367
368
  			break;
  		case YAMA_SCOPE_CAPABILITY:
4c44aaafa   Eric W. Biederman   userns: Kill task...
369
370
  			rcu_read_lock();
  			if (!ns_capable(__task_cred(child)->user_ns, CAP_SYS_PTRACE))
389da25f9   Kees Cook   Yama: add additio...
371
  				rc = -EPERM;
4c44aaafa   Eric W. Biederman   userns: Kill task...
372
  			rcu_read_unlock();
389da25f9   Kees Cook   Yama: add additio...
373
374
375
376
377
378
379
  			break;
  		case YAMA_SCOPE_NO_ATTACH:
  		default:
  			rc = -EPERM;
  			break;
  		}
  	}
2d514487f   Kees Cook   security: Yama LSM
380

8a56038c2   Kees Cook   Yama: consolidate...
381
382
  	if (rc && (mode & PTRACE_MODE_NOAUDIT) == 0)
  		report_access("attach", child, current);
2d514487f   Kees Cook   security: Yama LSM
383
384
385
  
  	return rc;
  }
9d8dad742   Kees Cook   Yama: higher rest...
386
387
388
389
390
391
  /**
   * yama_ptrace_traceme - validate PTRACE_TRACEME calls
   * @parent: task that will become the ptracer of the current task
   *
   * Returns 0 if following the ptrace is allowed, -ve on error.
   */
1aa176ef5   Jann Horn   Yama: mark local ...
392
  static int yama_ptrace_traceme(struct task_struct *parent)
9d8dad742   Kees Cook   Yama: higher rest...
393
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
394
  	int rc = 0;
9d8dad742   Kees Cook   Yama: higher rest...
395
396
397
398
  
  	/* Only disallow PTRACE_TRACEME on more aggressive settings. */
  	switch (ptrace_scope) {
  	case YAMA_SCOPE_CAPABILITY:
eddc0a3ab   Eric W. Biederman   yama: Better per...
399
  		if (!has_ns_capability(parent, current_user_ns(), CAP_SYS_PTRACE))
9d8dad742   Kees Cook   Yama: higher rest...
400
401
402
403
404
405
  			rc = -EPERM;
  		break;
  	case YAMA_SCOPE_NO_ATTACH:
  		rc = -EPERM;
  		break;
  	}
dca6b4149   Jann Horn   Yama: fix double-...
406
407
  	if (rc) {
  		task_lock(current);
8a56038c2   Kees Cook   Yama: consolidate...
408
  		report_access("traceme", current, parent);
dca6b4149   Jann Horn   Yama: fix double-...
409
410
  		task_unlock(current);
  	}
9d8dad742   Kees Cook   Yama: higher rest...
411
412
413
  
  	return rc;
  }
ca97d939d   James Morris   security: mark LS...
414
  static struct security_hook_list yama_hooks[] __lsm_ro_after_init = {
e20b043a6   Casey Schaufler   LSM: Add security...
415
416
417
418
  	LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check),
  	LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme),
  	LSM_HOOK_INIT(task_prctl, yama_task_prctl),
  	LSM_HOOK_INIT(task_free, yama_task_free),
2d514487f   Kees Cook   security: Yama LSM
419
  };
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
420

2d514487f   Kees Cook   security: Yama LSM
421
  #ifdef CONFIG_SYSCTL
389da25f9   Kees Cook   Yama: add additio...
422
  static int yama_dointvec_minmax(struct ctl_table *table, int write,
32927393d   Christoph Hellwig   sysctl: pass kern...
423
  				void *buffer, size_t *lenp, loff_t *ppos)
389da25f9   Kees Cook   Yama: add additio...
424
  {
41a4695ca   Kees Cook   Yama: do not modi...
425
  	struct ctl_table table_copy;
389da25f9   Kees Cook   Yama: add additio...
426
427
428
  
  	if (write && !capable(CAP_SYS_PTRACE))
  		return -EPERM;
389da25f9   Kees Cook   Yama: add additio...
429
  	/* Lock the max value if it ever gets set. */
41a4695ca   Kees Cook   Yama: do not modi...
430
431
432
  	table_copy = *table;
  	if (*(int *)table_copy.data == *(int *)table_copy.extra2)
  		table_copy.extra1 = table_copy.extra2;
389da25f9   Kees Cook   Yama: add additio...
433

41a4695ca   Kees Cook   Yama: do not modi...
434
  	return proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos);
389da25f9   Kees Cook   Yama: add additio...
435
  }
389da25f9   Kees Cook   Yama: add additio...
436
  static int max_scope = YAMA_SCOPE_NO_ATTACH;
2d514487f   Kees Cook   security: Yama LSM
437

1aa176ef5   Jann Horn   Yama: mark local ...
438
  static struct ctl_path yama_sysctl_path[] = {
2d514487f   Kees Cook   security: Yama LSM
439
440
441
442
443
444
445
446
447
448
449
  	{ .procname = "kernel", },
  	{ .procname = "yama", },
  	{ }
  };
  
  static struct ctl_table yama_sysctl_table[] = {
  	{
  		.procname       = "ptrace_scope",
  		.data           = &ptrace_scope,
  		.maxlen         = sizeof(int),
  		.mode           = 0644,
389da25f9   Kees Cook   Yama: add additio...
450
  		.proc_handler   = yama_dointvec_minmax,
eec4844fa   Matteo Croce   proc/sysctl: add ...
451
  		.extra1         = SYSCTL_ZERO,
389da25f9   Kees Cook   Yama: add additio...
452
  		.extra2         = &max_scope,
2d514487f   Kees Cook   security: Yama LSM
453
454
455
  	},
  	{ }
  };
730daa164   Kees Cook   Yama: remove need...
456
  static void __init yama_init_sysctl(void)
2d514487f   Kees Cook   security: Yama LSM
457
  {
2d514487f   Kees Cook   security: Yama LSM
458
459
460
  	if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table))
  		panic("Yama: sysctl registration failed.
  ");
2d514487f   Kees Cook   security: Yama LSM
461
  }
730daa164   Kees Cook   Yama: remove need...
462
463
464
  #else
  static inline void yama_init_sysctl(void) { }
  #endif /* CONFIG_SYSCTL */
2d514487f   Kees Cook   security: Yama LSM
465

d6aed64b7   Kees Cook   Yama: Initialize ...
466
  static int __init yama_init(void)
730daa164   Kees Cook   Yama: remove need...
467
468
469
  {
  	pr_info("Yama: becoming mindful.
  ");
d69dece5f   Casey Schaufler   LSM: Add /sys/ker...
470
  	security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama");
730daa164   Kees Cook   Yama: remove need...
471
  	yama_init_sysctl();
d6aed64b7   Kees Cook   Yama: Initialize ...
472
  	return 0;
730daa164   Kees Cook   Yama: remove need...
473
  }
d6aed64b7   Kees Cook   Yama: Initialize ...
474
475
476
477
478
  
  DEFINE_LSM(yama) = {
  	.name = "yama",
  	.init = yama_init,
  };