Blame view

security/yama/yama_lsm.c 12.2 KB
2d514487f   Kees Cook   security: Yama LSM
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   * Yama Linux Security Module
   *
   * Author: Kees Cook <keescook@chromium.org>
   *
   * Copyright (C) 2010 Canonical, Ltd.
   * Copyright (C) 2011 The Chromium OS Authors.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2, as
   * published by the Free Software Foundation.
   *
   */
3c4ed7bdf   Casey Schaufler   LSM: Split securi...
14
  #include <linux/lsm_hooks.h>
2d514487f   Kees Cook   security: Yama LSM
15
16
17
18
  #include <linux/sysctl.h>
  #include <linux/ptrace.h>
  #include <linux/prctl.h>
  #include <linux/ratelimit.h>
235e75278   Kees Cook   Yama: remove lock...
19
  #include <linux/workqueue.h>
8a56038c2   Kees Cook   Yama: consolidate...
20
  #include <linux/string_helpers.h>
dca6b4149   Jann Horn   Yama: fix double-...
21
22
23
  #include <linux/task_work.h>
  #include <linux/sched.h>
  #include <linux/spinlock.h>
2d514487f   Kees Cook   security: Yama LSM
24

389da25f9   Kees Cook   Yama: add additio...
25
26
27
28
29
30
  #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
31
32
33
34
35
  
  /* describe a ptrace relationship for potential exception */
  struct ptrace_relation {
  	struct task_struct *tracer;
  	struct task_struct *tracee;
235e75278   Kees Cook   Yama: remove lock...
36
  	bool invalid;
2d514487f   Kees Cook   security: Yama LSM
37
  	struct list_head node;
93b69d437   Kees Cook   Yama: add RCU to ...
38
  	struct rcu_head rcu;
2d514487f   Kees Cook   security: Yama LSM
39
40
41
42
  };
  
  static LIST_HEAD(ptracer_relations);
  static DEFINE_SPINLOCK(ptracer_relations_lock);
235e75278   Kees Cook   Yama: remove lock...
43
44
  static void yama_relation_cleanup(struct work_struct *work);
  static DECLARE_WORK(yama_relation_work, yama_relation_cleanup);
dca6b4149   Jann Horn   Yama: fix double-...
45
46
47
48
49
50
51
52
  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...
53
  {
dca6b4149   Jann Horn   Yama: fix double-...
54
55
  	struct access_report_info *info =
  		container_of(work, struct access_report_info, work);
8a56038c2   Kees Cook   Yama: consolidate...
56
  	char *target_cmd, *agent_cmd;
dca6b4149   Jann Horn   Yama: fix double-...
57
58
  	target_cmd = kstrdup_quotable_cmdline(info->target, GFP_KERNEL);
  	agent_cmd = kstrdup_quotable_cmdline(info->agent, GFP_KERNEL);
8a56038c2   Kees Cook   Yama: consolidate...
59
60
61
62
  
  	pr_notice_ratelimited(
  		"ptrace %s of \"%s\"[%d] was attempted by \"%s\"[%d]
  ",
dca6b4149   Jann Horn   Yama: fix double-...
63
64
  		info->access, target_cmd, info->target->pid, agent_cmd,
  		info->agent->pid);
8a56038c2   Kees Cook   Yama: consolidate...
65
66
67
  
  	kfree(agent_cmd);
  	kfree(target_cmd);
dca6b4149   Jann Horn   Yama: fix double-...
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
100
101
102
103
104
105
106
107
108
109
110
  
  	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;
  	if (task_work_add(current, &info->work, true) == 0)
  		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...
111
  }
235e75278   Kees Cook   Yama: remove lock...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  /**
   * 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
131
132
133
134
135
136
137
138
139
140
141
142
143
  /**
   * 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 ...
144
  	struct ptrace_relation *relation, *added;
2d514487f   Kees Cook   security: Yama LSM
145
146
147
148
  
  	added = kmalloc(sizeof(*added), GFP_KERNEL);
  	if (!added)
  		return -ENOMEM;
93b69d437   Kees Cook   Yama: add RCU to ...
149
150
  	added->tracee = tracee;
  	added->tracer = tracer;
235e75278   Kees Cook   Yama: remove lock...
151
  	added->invalid = false;
93b69d437   Kees Cook   Yama: add RCU to ...
152

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

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

93b69d437   Kees Cook   Yama: add RCU to ...
167
168
  out:
  	rcu_read_unlock();
235e75278   Kees Cook   Yama: remove lock...
169
  	spin_unlock(&ptracer_relations_lock);
93b69d437   Kees Cook   Yama: add RCU to ...
170
  	return 0;
2d514487f   Kees Cook   security: Yama LSM
171
172
173
174
175
176
177
178
179
180
  }
  
  /**
   * 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 ...
181
  	struct ptrace_relation *relation;
235e75278   Kees Cook   Yama: remove lock...
182
  	bool marked = false;
2d514487f   Kees Cook   security: Yama LSM
183

93b69d437   Kees Cook   Yama: add RCU to ...
184
185
  	rcu_read_lock();
  	list_for_each_entry_rcu(relation, &ptracer_relations, node) {
235e75278   Kees Cook   Yama: remove lock...
186
187
  		if (relation->invalid)
  			continue;
2d514487f   Kees Cook   security: Yama LSM
188
  		if (relation->tracee == tracee ||
bf06189e4   Kees Cook   Yama: add PR_SET_...
189
  		    (tracer && relation->tracer == tracer)) {
235e75278   Kees Cook   Yama: remove lock...
190
191
  			relation->invalid = true;
  			marked = true;
2d514487f   Kees Cook   security: Yama LSM
192
  		}
93b69d437   Kees Cook   Yama: add RCU to ...
193
194
  	}
  	rcu_read_unlock();
235e75278   Kees Cook   Yama: remove lock...
195
196
197
  
  	if (marked)
  		schedule_work(&yama_relation_work);
2d514487f   Kees Cook   security: Yama LSM
198
199
200
201
202
203
  }
  
  /**
   * yama_task_free - check for task_pid to remove from exception list
   * @task: task being removed
   */
c6993e4ac   Kees Cook   security: allow Y...
204
  void yama_task_free(struct task_struct *task)
2d514487f   Kees Cook   security: Yama LSM
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
  {
  	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.
   */
c6993e4ac   Kees Cook   security: allow Y...
220
  int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
2d514487f   Kees Cook   security: Yama LSM
221
222
  			   unsigned long arg4, unsigned long arg5)
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
223
  	int rc = -ENOSYS;
2d514487f   Kees Cook   security: Yama LSM
224
  	struct task_struct *myself = current;
2d514487f   Kees Cook   security: Yama LSM
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  	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...
242
  		} else if (arg2 == PR_SET_PTRACER_ANY || (int)arg2 == -1) {
bf06189e4   Kees Cook   Yama: add PR_SET_...
243
  			rc = yama_ptracer_add(NULL, myself);
2d514487f   Kees Cook   security: Yama LSM
244
245
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
296
297
298
299
300
301
302
303
304
305
  		} else {
  			struct task_struct *tracer;
  
  			rcu_read_lock();
  			tracer = find_task_by_vpid(arg2);
  			if (tracer)
  				get_task_struct(tracer);
  			else
  				rc = -EINVAL;
  			rcu_read_unlock();
  
  			if (tracer) {
  				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...
306
   * Returns 1 if tracer has a ptracer exception ancestor for tracee.
2d514487f   Kees Cook   security: Yama LSM
307
308
309
310
311
312
313
   */
  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_...
314
  	bool found = false;
2d514487f   Kees Cook   security: Yama LSM
315

2d514487f   Kees Cook   security: Yama LSM
316
  	rcu_read_lock();
50523a29d   Josh Stone   Yama: allow acces...
317
318
319
320
321
322
323
324
325
326
327
328
  
  	/*
  	 * 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
329
330
  	if (!thread_group_leader(tracee))
  		tracee = rcu_dereference(tracee->group_leader);
235e75278   Kees Cook   Yama: remove lock...
331
332
333
  	list_for_each_entry_rcu(relation, &ptracer_relations, node) {
  		if (relation->invalid)
  			continue;
2d514487f   Kees Cook   security: Yama LSM
334
335
  		if (relation->tracee == tracee) {
  			parent = relation->tracer;
bf06189e4   Kees Cook   Yama: add PR_SET_...
336
  			found = true;
2d514487f   Kees Cook   security: Yama LSM
337
338
  			break;
  		}
235e75278   Kees Cook   Yama: remove lock...
339
  	}
2d514487f   Kees Cook   security: Yama LSM
340

bf06189e4   Kees Cook   Yama: add PR_SET_...
341
  	if (found && (parent == NULL || task_is_descendant(parent, tracer)))
2d514487f   Kees Cook   security: Yama LSM
342
  		rc = 1;
50523a29d   Josh Stone   Yama: allow acces...
343
344
  
  unlock:
2d514487f   Kees Cook   security: Yama LSM
345
  	rcu_read_unlock();
2d514487f   Kees Cook   security: Yama LSM
346
347
348
349
350
351
352
353
354
355
356
  
  	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...
357
  static int yama_ptrace_access_check(struct task_struct *child,
2d514487f   Kees Cook   security: Yama LSM
358
359
  				    unsigned int mode)
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
360
  	int rc = 0;
2d514487f   Kees Cook   security: Yama LSM
361
362
  
  	/* require ptrace target be a child of ptracer on attach */
3dfb7d8cd   Jann Horn   security: let sec...
363
  	if (mode & PTRACE_MODE_ATTACH) {
389da25f9   Kees Cook   Yama: add additio...
364
365
366
367
368
  		switch (ptrace_scope) {
  		case YAMA_SCOPE_DISABLED:
  			/* No additional restrictions. */
  			break;
  		case YAMA_SCOPE_RELATIONAL:
4c44aaafa   Eric W. Biederman   userns: Kill task...
369
  			rcu_read_lock();
41c13bfcc   Kees Cook   Yama: Check for p...
370
371
372
  			if (!pid_alive(child))
  				rc = -EPERM;
  			if (!rc && !task_is_descendant(current, child) &&
389da25f9   Kees Cook   Yama: add additio...
373
  			    !ptracer_exception_found(current, child) &&
4c44aaafa   Eric W. Biederman   userns: Kill task...
374
  			    !ns_capable(__task_cred(child)->user_ns, CAP_SYS_PTRACE))
389da25f9   Kees Cook   Yama: add additio...
375
  				rc = -EPERM;
4c44aaafa   Eric W. Biederman   userns: Kill task...
376
  			rcu_read_unlock();
389da25f9   Kees Cook   Yama: add additio...
377
378
  			break;
  		case YAMA_SCOPE_CAPABILITY:
4c44aaafa   Eric W. Biederman   userns: Kill task...
379
380
  			rcu_read_lock();
  			if (!ns_capable(__task_cred(child)->user_ns, CAP_SYS_PTRACE))
389da25f9   Kees Cook   Yama: add additio...
381
  				rc = -EPERM;
4c44aaafa   Eric W. Biederman   userns: Kill task...
382
  			rcu_read_unlock();
389da25f9   Kees Cook   Yama: add additio...
383
384
385
386
387
388
389
  			break;
  		case YAMA_SCOPE_NO_ATTACH:
  		default:
  			rc = -EPERM;
  			break;
  		}
  	}
2d514487f   Kees Cook   security: Yama LSM
390

8a56038c2   Kees Cook   Yama: consolidate...
391
392
  	if (rc && (mode & PTRACE_MODE_NOAUDIT) == 0)
  		report_access("attach", child, current);
2d514487f   Kees Cook   security: Yama LSM
393
394
395
  
  	return rc;
  }
9d8dad742   Kees Cook   Yama: higher rest...
396
397
398
399
400
401
  /**
   * 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.
   */
c6993e4ac   Kees Cook   security: allow Y...
402
  int yama_ptrace_traceme(struct task_struct *parent)
9d8dad742   Kees Cook   Yama: higher rest...
403
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
404
  	int rc = 0;
9d8dad742   Kees Cook   Yama: higher rest...
405
406
407
408
  
  	/* Only disallow PTRACE_TRACEME on more aggressive settings. */
  	switch (ptrace_scope) {
  	case YAMA_SCOPE_CAPABILITY:
eddc0a3ab   Eric W. Biederman   yama: Better per...
409
  		if (!has_ns_capability(parent, current_user_ns(), CAP_SYS_PTRACE))
9d8dad742   Kees Cook   Yama: higher rest...
410
411
412
413
414
415
  			rc = -EPERM;
  		break;
  	case YAMA_SCOPE_NO_ATTACH:
  		rc = -EPERM;
  		break;
  	}
dca6b4149   Jann Horn   Yama: fix double-...
416
417
  	if (rc) {
  		task_lock(current);
8a56038c2   Kees Cook   Yama: consolidate...
418
  		report_access("traceme", current, parent);
dca6b4149   Jann Horn   Yama: fix double-...
419
420
  		task_unlock(current);
  	}
9d8dad742   Kees Cook   Yama: higher rest...
421
422
423
  
  	return rc;
  }
ca97d939d   James Morris   security: mark LS...
424
  static struct security_hook_list yama_hooks[] __lsm_ro_after_init = {
e20b043a6   Casey Schaufler   LSM: Add security...
425
426
427
428
  	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
429
  };
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
430

2d514487f   Kees Cook   security: Yama LSM
431
  #ifdef CONFIG_SYSCTL
389da25f9   Kees Cook   Yama: add additio...
432
433
434
  static int yama_dointvec_minmax(struct ctl_table *table, int write,
  				void __user *buffer, size_t *lenp, loff_t *ppos)
  {
41a4695ca   Kees Cook   Yama: do not modi...
435
  	struct ctl_table table_copy;
389da25f9   Kees Cook   Yama: add additio...
436
437
438
  
  	if (write && !capable(CAP_SYS_PTRACE))
  		return -EPERM;
389da25f9   Kees Cook   Yama: add additio...
439
  	/* Lock the max value if it ever gets set. */
41a4695ca   Kees Cook   Yama: do not modi...
440
441
442
  	table_copy = *table;
  	if (*(int *)table_copy.data == *(int *)table_copy.extra2)
  		table_copy.extra1 = table_copy.extra2;
389da25f9   Kees Cook   Yama: add additio...
443

41a4695ca   Kees Cook   Yama: do not modi...
444
  	return proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos);
389da25f9   Kees Cook   Yama: add additio...
445
  }
2d514487f   Kees Cook   security: Yama LSM
446
  static int zero;
389da25f9   Kees Cook   Yama: add additio...
447
  static int max_scope = YAMA_SCOPE_NO_ATTACH;
2d514487f   Kees Cook   security: Yama LSM
448
449
450
451
452
453
454
455
456
457
458
459
460
  
  struct ctl_path yama_sysctl_path[] = {
  	{ .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...
461
  		.proc_handler   = yama_dointvec_minmax,
2d514487f   Kees Cook   security: Yama LSM
462
  		.extra1         = &zero,
389da25f9   Kees Cook   Yama: add additio...
463
  		.extra2         = &max_scope,
2d514487f   Kees Cook   security: Yama LSM
464
465
466
  	},
  	{ }
  };
730daa164   Kees Cook   Yama: remove need...
467
  static void __init yama_init_sysctl(void)
2d514487f   Kees Cook   security: Yama LSM
468
  {
2d514487f   Kees Cook   security: Yama LSM
469
470
471
  	if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table))
  		panic("Yama: sysctl registration failed.
  ");
2d514487f   Kees Cook   security: Yama LSM
472
  }
730daa164   Kees Cook   Yama: remove need...
473
474
475
  #else
  static inline void yama_init_sysctl(void) { }
  #endif /* CONFIG_SYSCTL */
2d514487f   Kees Cook   security: Yama LSM
476

730daa164   Kees Cook   Yama: remove need...
477
478
479
480
  void __init yama_add_hooks(void)
  {
  	pr_info("Yama: becoming mindful.
  ");
d69dece5f   Casey Schaufler   LSM: Add /sys/ker...
481
  	security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama");
730daa164   Kees Cook   Yama: remove need...
482
483
  	yama_init_sysctl();
  }