diff options
-rw-r--r-- | Documentation/security/00-INDEX | 2 | ||||
-rw-r--r-- | Documentation/security/Yama.txt | 60 | ||||
-rw-r--r-- | include/linux/prctl.h | 6 | ||||
-rw-r--r-- | security/Kconfig | 6 | ||||
-rw-r--r-- | security/Makefile | 2 | ||||
-rw-r--r-- | security/yama/Kconfig | 13 | ||||
-rw-r--r-- | security/yama/Makefile | 3 | ||||
-rw-r--r-- | security/yama/yama_lsm.c | 319 |
8 files changed, 411 insertions, 0 deletions
diff --git a/Documentation/security/00-INDEX b/Documentation/security/00-INDEX index 99b85d39751..eeed1de546d 100644 --- a/Documentation/security/00-INDEX +++ b/Documentation/security/00-INDEX | |||
@@ -6,6 +6,8 @@ SELinux.txt | |||
6 | - how to get started with the SELinux security enhancement. | 6 | - how to get started with the SELinux security enhancement. |
7 | Smack.txt | 7 | Smack.txt |
8 | - documentation on the Smack Linux Security Module. | 8 | - documentation on the Smack Linux Security Module. |
9 | Yama.txt | ||
10 | - documentation on the Yama Linux Security Module. | ||
9 | apparmor.txt | 11 | apparmor.txt |
10 | - documentation on the AppArmor security extension. | 12 | - documentation on the AppArmor security extension. |
11 | credentials.txt | 13 | credentials.txt |
diff --git a/Documentation/security/Yama.txt b/Documentation/security/Yama.txt new file mode 100644 index 00000000000..4f0b7896a21 --- /dev/null +++ b/Documentation/security/Yama.txt | |||
@@ -0,0 +1,60 @@ | |||
1 | Yama is a Linux Security Module that collects a number of system-wide DAC | ||
2 | security protections that are not handled by the core kernel itself. To | ||
3 | select it at boot time, specify "security=yama" (though this will disable | ||
4 | any other LSM). | ||
5 | |||
6 | Yama is controlled through sysctl in /proc/sys/kernel/yama: | ||
7 | |||
8 | - ptrace_scope | ||
9 | |||
10 | ============================================================== | ||
11 | |||
12 | ptrace_scope: | ||
13 | |||
14 | As Linux grows in popularity, it will become a larger target for | ||
15 | malware. One particularly troubling weakness of the Linux process | ||
16 | interfaces is that a single user is able to examine the memory and | ||
17 | running state of any of their processes. For example, if one application | ||
18 | (e.g. Pidgin) was compromised, it would be possible for an attacker to | ||
19 | attach to other running processes (e.g. Firefox, SSH sessions, GPG agent, | ||
20 | etc) to extract additional credentials and continue to expand the scope | ||
21 | of their attack without resorting to user-assisted phishing. | ||
22 | |||
23 | This is not a theoretical problem. SSH session hijacking | ||
24 | (http://www.storm.net.nz/projects/7) and arbitrary code injection | ||
25 | (http://c-skills.blogspot.com/2007/05/injectso.html) attacks already | ||
26 | exist and remain possible if ptrace is allowed to operate as before. | ||
27 | Since ptrace is not commonly used by non-developers and non-admins, system | ||
28 | builders should be allowed the option to disable this debugging system. | ||
29 | |||
30 | For a solution, some applications use prctl(PR_SET_DUMPABLE, ...) to | ||
31 | specifically disallow such ptrace attachment (e.g. ssh-agent), but many | ||
32 | do not. A more general solution is to only allow ptrace directly from a | ||
33 | parent to a child process (i.e. direct "gdb EXE" and "strace EXE" still | ||
34 | work), or with CAP_SYS_PTRACE (i.e. "gdb --pid=PID", and "strace -p PID" | ||
35 | still work as root). | ||
36 | |||
37 | For software that has defined application-specific relationships | ||
38 | between a debugging process and its inferior (crash handlers, etc), | ||
39 | prctl(PR_SET_PTRACER, pid, ...) can be used. An inferior can declare which | ||
40 | other process (and its descendents) are allowed to call PTRACE_ATTACH | ||
41 | against it. Only one such declared debugging process can exists for | ||
42 | each inferior at a time. For example, this is used by KDE, Chromium, and | ||
43 | Firefox's crash handlers, and by Wine for allowing only Wine processes | ||
44 | to ptrace each other. | ||
45 | |||
46 | 0 - classic ptrace permissions: a process can PTRACE_ATTACH to any other | ||
47 | process running under the same uid, as long as it is dumpable (i.e. | ||
48 | did not transition uids, start privileged, or have called | ||
49 | prctl(PR_SET_DUMPABLE...) already). | ||
50 | |||
51 | 1 - restricted ptrace: a process must have a predefined relationship | ||
52 | with the inferior it wants to call PTRACE_ATTACH on. By default, | ||
53 | this relationship is that of only its descendants when the above | ||
54 | classic criteria is also met. To change the relationship, an | ||
55 | inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare | ||
56 | an allowed debugger PID to call PTRACE_ATTACH on the inferior. | ||
57 | |||
58 | The original children-only logic was based on the restrictions in grsecurity. | ||
59 | |||
60 | ============================================================== | ||
diff --git a/include/linux/prctl.h b/include/linux/prctl.h index 7ddc7f1b480..4d0e5bc5458 100644 --- a/include/linux/prctl.h +++ b/include/linux/prctl.h | |||
@@ -114,4 +114,10 @@ | |||
114 | # define PR_SET_MM_START_BRK 6 | 114 | # define PR_SET_MM_START_BRK 6 |
115 | # define PR_SET_MM_BRK 7 | 115 | # define PR_SET_MM_BRK 7 |
116 | 116 | ||
117 | /* | ||
118 | * Set specific pid that is allowed to ptrace the current task. | ||
119 | * A value of 0 mean "no process". | ||
120 | */ | ||
121 | #define PR_SET_PTRACER 0x59616d61 | ||
122 | |||
117 | #endif /* _LINUX_PRCTL_H */ | 123 | #endif /* _LINUX_PRCTL_H */ |
diff --git a/security/Kconfig b/security/Kconfig index 51bd5a0b69a..ccc61f8006b 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
@@ -187,6 +187,7 @@ source security/selinux/Kconfig | |||
187 | source security/smack/Kconfig | 187 | source security/smack/Kconfig |
188 | source security/tomoyo/Kconfig | 188 | source security/tomoyo/Kconfig |
189 | source security/apparmor/Kconfig | 189 | source security/apparmor/Kconfig |
190 | source security/yama/Kconfig | ||
190 | 191 | ||
191 | source security/integrity/Kconfig | 192 | source security/integrity/Kconfig |
192 | 193 | ||
@@ -196,6 +197,7 @@ choice | |||
196 | default DEFAULT_SECURITY_SMACK if SECURITY_SMACK | 197 | default DEFAULT_SECURITY_SMACK if SECURITY_SMACK |
197 | default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO | 198 | default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO |
198 | default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR | 199 | default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR |
200 | default DEFAULT_SECURITY_YAMA if SECURITY_YAMA | ||
199 | default DEFAULT_SECURITY_DAC | 201 | default DEFAULT_SECURITY_DAC |
200 | 202 | ||
201 | help | 203 | help |
@@ -214,6 +216,9 @@ choice | |||
214 | config DEFAULT_SECURITY_APPARMOR | 216 | config DEFAULT_SECURITY_APPARMOR |
215 | bool "AppArmor" if SECURITY_APPARMOR=y | 217 | bool "AppArmor" if SECURITY_APPARMOR=y |
216 | 218 | ||
219 | config DEFAULT_SECURITY_YAMA | ||
220 | bool "Yama" if SECURITY_YAMA=y | ||
221 | |||
217 | config DEFAULT_SECURITY_DAC | 222 | config DEFAULT_SECURITY_DAC |
218 | bool "Unix Discretionary Access Controls" | 223 | bool "Unix Discretionary Access Controls" |
219 | 224 | ||
@@ -225,6 +230,7 @@ config DEFAULT_SECURITY | |||
225 | default "smack" if DEFAULT_SECURITY_SMACK | 230 | default "smack" if DEFAULT_SECURITY_SMACK |
226 | default "tomoyo" if DEFAULT_SECURITY_TOMOYO | 231 | default "tomoyo" if DEFAULT_SECURITY_TOMOYO |
227 | default "apparmor" if DEFAULT_SECURITY_APPARMOR | 232 | default "apparmor" if DEFAULT_SECURITY_APPARMOR |
233 | default "yama" if DEFAULT_SECURITY_YAMA | ||
228 | default "" if DEFAULT_SECURITY_DAC | 234 | default "" if DEFAULT_SECURITY_DAC |
229 | 235 | ||
230 | endmenu | 236 | endmenu |
diff --git a/security/Makefile b/security/Makefile index a5e502f8a05..c26c81e9257 100644 --- a/security/Makefile +++ b/security/Makefile | |||
@@ -7,6 +7,7 @@ subdir-$(CONFIG_SECURITY_SELINUX) += selinux | |||
7 | subdir-$(CONFIG_SECURITY_SMACK) += smack | 7 | subdir-$(CONFIG_SECURITY_SMACK) += smack |
8 | subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo | 8 | subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo |
9 | subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor | 9 | subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor |
10 | subdir-$(CONFIG_SECURITY_YAMA) += yama | ||
10 | 11 | ||
11 | # always enable default capabilities | 12 | # always enable default capabilities |
12 | obj-y += commoncap.o | 13 | obj-y += commoncap.o |
@@ -21,6 +22,7 @@ obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o | |||
21 | obj-$(CONFIG_AUDIT) += lsm_audit.o | 22 | obj-$(CONFIG_AUDIT) += lsm_audit.o |
22 | obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o | 23 | obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o |
23 | obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o | 24 | obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o |
25 | obj-$(CONFIG_SECURITY_YAMA) += yama/built-in.o | ||
24 | obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o | 26 | obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o |
25 | 27 | ||
26 | # Object integrity file lists | 28 | # Object integrity file lists |
diff --git a/security/yama/Kconfig b/security/yama/Kconfig new file mode 100644 index 00000000000..51d6709d8bb --- /dev/null +++ b/security/yama/Kconfig | |||
@@ -0,0 +1,13 @@ | |||
1 | config SECURITY_YAMA | ||
2 | bool "Yama support" | ||
3 | depends on SECURITY | ||
4 | select SECURITYFS | ||
5 | select SECURITY_PATH | ||
6 | default n | ||
7 | help | ||
8 | This selects Yama, which extends DAC support with additional | ||
9 | system-wide security settings beyond regular Linux discretionary | ||
10 | access controls. Currently available is ptrace scope restriction. | ||
11 | Further information can be found in Documentation/security/Yama.txt. | ||
12 | |||
13 | If you are unsure how to answer this question, answer N. | ||
diff --git a/security/yama/Makefile b/security/yama/Makefile new file mode 100644 index 00000000000..8b5e0658845 --- /dev/null +++ b/security/yama/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | obj-$(CONFIG_SECURITY_YAMA) := yama.o | ||
2 | |||
3 | yama-y := yama_lsm.o | ||
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c new file mode 100644 index 00000000000..dd4d36067c5 --- /dev/null +++ b/security/yama/yama_lsm.c | |||
@@ -0,0 +1,319 @@ | |||
1 | /* | ||
2 | * Yama Linux Security Module | ||
3 | * | ||
4 | * Author: Kees Cook <keescook@chromium.org> | ||
5 | * | ||
6 | * Copyright (C) 2010 Canonical, Ltd. | ||
7 | * Copyright (C) 2011 The Chromium OS Authors. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2, as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/security.h> | ||
16 | #include <linux/sysctl.h> | ||
17 | #include <linux/ptrace.h> | ||
18 | #include <linux/prctl.h> | ||
19 | #include <linux/ratelimit.h> | ||
20 | |||
21 | static int ptrace_scope = 1; | ||
22 | |||
23 | /* describe a ptrace relationship for potential exception */ | ||
24 | struct ptrace_relation { | ||
25 | struct task_struct *tracer; | ||
26 | struct task_struct *tracee; | ||
27 | struct list_head node; | ||
28 | }; | ||
29 | |||
30 | static LIST_HEAD(ptracer_relations); | ||
31 | static DEFINE_SPINLOCK(ptracer_relations_lock); | ||
32 | |||
33 | /** | ||
34 | * yama_ptracer_add - add/replace an exception for this tracer/tracee pair | ||
35 | * @tracer: the task_struct of the process doing the ptrace | ||
36 | * @tracee: the task_struct of the process to be ptraced | ||
37 | * | ||
38 | * Each tracee can have, at most, one tracer registered. Each time this | ||
39 | * is called, the prior registered tracer will be replaced for the tracee. | ||
40 | * | ||
41 | * Returns 0 if relationship was added, -ve on error. | ||
42 | */ | ||
43 | static int yama_ptracer_add(struct task_struct *tracer, | ||
44 | struct task_struct *tracee) | ||
45 | { | ||
46 | int rc = 0; | ||
47 | struct ptrace_relation *added; | ||
48 | struct ptrace_relation *entry, *relation = NULL; | ||
49 | |||
50 | added = kmalloc(sizeof(*added), GFP_KERNEL); | ||
51 | if (!added) | ||
52 | return -ENOMEM; | ||
53 | |||
54 | spin_lock_bh(&ptracer_relations_lock); | ||
55 | list_for_each_entry(entry, &ptracer_relations, node) | ||
56 | if (entry->tracee == tracee) { | ||
57 | relation = entry; | ||
58 | break; | ||
59 | } | ||
60 | if (!relation) { | ||
61 | relation = added; | ||
62 | relation->tracee = tracee; | ||
63 | list_add(&relation->node, &ptracer_relations); | ||
64 | } | ||
65 | relation->tracer = tracer; | ||
66 | |||
67 | spin_unlock_bh(&ptracer_relations_lock); | ||
68 | if (added != relation) | ||
69 | kfree(added); | ||
70 | |||
71 | return rc; | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * yama_ptracer_del - remove exceptions related to the given tasks | ||
76 | * @tracer: remove any relation where tracer task matches | ||
77 | * @tracee: remove any relation where tracee task matches | ||
78 | */ | ||
79 | static void yama_ptracer_del(struct task_struct *tracer, | ||
80 | struct task_struct *tracee) | ||
81 | { | ||
82 | struct ptrace_relation *relation, *safe; | ||
83 | |||
84 | spin_lock_bh(&ptracer_relations_lock); | ||
85 | list_for_each_entry_safe(relation, safe, &ptracer_relations, node) | ||
86 | if (relation->tracee == tracee || | ||
87 | relation->tracer == tracer) { | ||
88 | list_del(&relation->node); | ||
89 | kfree(relation); | ||
90 | } | ||
91 | spin_unlock_bh(&ptracer_relations_lock); | ||
92 | } | ||
93 | |||
94 | /** | ||
95 | * yama_task_free - check for task_pid to remove from exception list | ||
96 | * @task: task being removed | ||
97 | */ | ||
98 | static void yama_task_free(struct task_struct *task) | ||
99 | { | ||
100 | yama_ptracer_del(task, task); | ||
101 | } | ||
102 | |||
103 | /** | ||
104 | * yama_task_prctl - check for Yama-specific prctl operations | ||
105 | * @option: operation | ||
106 | * @arg2: argument | ||
107 | * @arg3: argument | ||
108 | * @arg4: argument | ||
109 | * @arg5: argument | ||
110 | * | ||
111 | * Return 0 on success, -ve on error. -ENOSYS is returned when Yama | ||
112 | * does not handle the given option. | ||
113 | */ | ||
114 | static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, | ||
115 | unsigned long arg4, unsigned long arg5) | ||
116 | { | ||
117 | int rc; | ||
118 | struct task_struct *myself = current; | ||
119 | |||
120 | rc = cap_task_prctl(option, arg2, arg3, arg4, arg5); | ||
121 | if (rc != -ENOSYS) | ||
122 | return rc; | ||
123 | |||
124 | switch (option) { | ||
125 | case PR_SET_PTRACER: | ||
126 | /* Since a thread can call prctl(), find the group leader | ||
127 | * before calling _add() or _del() on it, since we want | ||
128 | * process-level granularity of control. The tracer group | ||
129 | * leader checking is handled later when walking the ancestry | ||
130 | * at the time of PTRACE_ATTACH check. | ||
131 | */ | ||
132 | rcu_read_lock(); | ||
133 | if (!thread_group_leader(myself)) | ||
134 | myself = rcu_dereference(myself->group_leader); | ||
135 | get_task_struct(myself); | ||
136 | rcu_read_unlock(); | ||
137 | |||
138 | if (arg2 == 0) { | ||
139 | yama_ptracer_del(NULL, myself); | ||
140 | rc = 0; | ||
141 | } else { | ||
142 | struct task_struct *tracer; | ||
143 | |||
144 | rcu_read_lock(); | ||
145 | tracer = find_task_by_vpid(arg2); | ||
146 | if (tracer) | ||
147 | get_task_struct(tracer); | ||
148 | else | ||
149 | rc = -EINVAL; | ||
150 | rcu_read_unlock(); | ||
151 | |||
152 | if (tracer) { | ||
153 | rc = yama_ptracer_add(tracer, myself); | ||
154 | put_task_struct(tracer); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | put_task_struct(myself); | ||
159 | break; | ||
160 | } | ||
161 | |||
162 | return rc; | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * task_is_descendant - walk up a process family tree looking for a match | ||
167 | * @parent: the process to compare against while walking up from child | ||
168 | * @child: the process to start from while looking upwards for parent | ||
169 | * | ||
170 | * Returns 1 if child is a descendant of parent, 0 if not. | ||
171 | */ | ||
172 | static int task_is_descendant(struct task_struct *parent, | ||
173 | struct task_struct *child) | ||
174 | { | ||
175 | int rc = 0; | ||
176 | struct task_struct *walker = child; | ||
177 | |||
178 | if (!parent || !child) | ||
179 | return 0; | ||
180 | |||
181 | rcu_read_lock(); | ||
182 | if (!thread_group_leader(parent)) | ||
183 | parent = rcu_dereference(parent->group_leader); | ||
184 | while (walker->pid > 0) { | ||
185 | if (!thread_group_leader(walker)) | ||
186 | walker = rcu_dereference(walker->group_leader); | ||
187 | if (walker == parent) { | ||
188 | rc = 1; | ||
189 | break; | ||
190 | } | ||
191 | walker = rcu_dereference(walker->real_parent); | ||
192 | } | ||
193 | rcu_read_unlock(); | ||
194 | |||
195 | return rc; | ||
196 | } | ||
197 | |||
198 | /** | ||
199 | * ptracer_exception_found - tracer registered as exception for this tracee | ||
200 | * @tracer: the task_struct of the process attempting ptrace | ||
201 | * @tracee: the task_struct of the process to be ptraced | ||
202 | * | ||
203 | * Returns 1 if tracer has is ptracer exception ancestor for tracee. | ||
204 | */ | ||
205 | static int ptracer_exception_found(struct task_struct *tracer, | ||
206 | struct task_struct *tracee) | ||
207 | { | ||
208 | int rc = 0; | ||
209 | struct ptrace_relation *relation; | ||
210 | struct task_struct *parent = NULL; | ||
211 | |||
212 | spin_lock_bh(&ptracer_relations_lock); | ||
213 | rcu_read_lock(); | ||
214 | if (!thread_group_leader(tracee)) | ||
215 | tracee = rcu_dereference(tracee->group_leader); | ||
216 | list_for_each_entry(relation, &ptracer_relations, node) | ||
217 | if (relation->tracee == tracee) { | ||
218 | parent = relation->tracer; | ||
219 | break; | ||
220 | } | ||
221 | |||
222 | if (task_is_descendant(parent, tracer)) | ||
223 | rc = 1; | ||
224 | rcu_read_unlock(); | ||
225 | spin_unlock_bh(&ptracer_relations_lock); | ||
226 | |||
227 | return rc; | ||
228 | } | ||
229 | |||
230 | /** | ||
231 | * yama_ptrace_access_check - validate PTRACE_ATTACH calls | ||
232 | * @child: task that current task is attempting to ptrace | ||
233 | * @mode: ptrace attach mode | ||
234 | * | ||
235 | * Returns 0 if following the ptrace is allowed, -ve on error. | ||
236 | */ | ||
237 | static int yama_ptrace_access_check(struct task_struct *child, | ||
238 | unsigned int mode) | ||
239 | { | ||
240 | int rc; | ||
241 | |||
242 | /* If standard caps disallows it, so does Yama. We should | ||
243 | * only tighten restrictions further. | ||
244 | */ | ||
245 | rc = cap_ptrace_access_check(child, mode); | ||
246 | if (rc) | ||
247 | return rc; | ||
248 | |||
249 | /* require ptrace target be a child of ptracer on attach */ | ||
250 | if (mode == PTRACE_MODE_ATTACH && | ||
251 | ptrace_scope && | ||
252 | !task_is_descendant(current, child) && | ||
253 | !ptracer_exception_found(current, child) && | ||
254 | !capable(CAP_SYS_PTRACE)) | ||
255 | rc = -EPERM; | ||
256 | |||
257 | if (rc) { | ||
258 | char name[sizeof(current->comm)]; | ||
259 | printk_ratelimited(KERN_NOTICE "ptrace of non-child" | ||
260 | " pid %d was attempted by: %s (pid %d)\n", | ||
261 | child->pid, | ||
262 | get_task_comm(name, current), | ||
263 | current->pid); | ||
264 | } | ||
265 | |||
266 | return rc; | ||
267 | } | ||
268 | |||
269 | static struct security_operations yama_ops = { | ||
270 | .name = "yama", | ||
271 | |||
272 | .ptrace_access_check = yama_ptrace_access_check, | ||
273 | .task_prctl = yama_task_prctl, | ||
274 | .task_free = yama_task_free, | ||
275 | }; | ||
276 | |||
277 | #ifdef CONFIG_SYSCTL | ||
278 | static int zero; | ||
279 | static int one = 1; | ||
280 | |||
281 | struct ctl_path yama_sysctl_path[] = { | ||
282 | { .procname = "kernel", }, | ||
283 | { .procname = "yama", }, | ||
284 | { } | ||
285 | }; | ||
286 | |||
287 | static struct ctl_table yama_sysctl_table[] = { | ||
288 | { | ||
289 | .procname = "ptrace_scope", | ||
290 | .data = &ptrace_scope, | ||
291 | .maxlen = sizeof(int), | ||
292 | .mode = 0644, | ||
293 | .proc_handler = proc_dointvec_minmax, | ||
294 | .extra1 = &zero, | ||
295 | .extra2 = &one, | ||
296 | }, | ||
297 | { } | ||
298 | }; | ||
299 | #endif /* CONFIG_SYSCTL */ | ||
300 | |||
301 | static __init int yama_init(void) | ||
302 | { | ||
303 | if (!security_module_enable(&yama_ops)) | ||
304 | return 0; | ||
305 | |||
306 | printk(KERN_INFO "Yama: becoming mindful.\n"); | ||
307 | |||
308 | if (register_security(&yama_ops)) | ||
309 | panic("Yama: kernel registration failed.\n"); | ||
310 | |||
311 | #ifdef CONFIG_SYSCTL | ||
312 | if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table)) | ||
313 | panic("Yama: sysctl registration failed.\n"); | ||
314 | #endif | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | security_initcall(yama_init); | ||