diff options
Diffstat (limited to 'security/security.c')
-rw-r--r-- | security/security.c | 102 |
1 files changed, 71 insertions, 31 deletions
diff --git a/security/security.c b/security/security.c index 6bc591f77b1a..c900d7a1441a 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -52,33 +52,96 @@ static __initdata bool debug; | |||
52 | pr_info(__VA_ARGS__); \ | 52 | pr_info(__VA_ARGS__); \ |
53 | } while (0) | 53 | } while (0) |
54 | 54 | ||
55 | static bool __init is_enabled(struct lsm_info *lsm) | ||
56 | { | ||
57 | if (!lsm->enabled || *lsm->enabled) | ||
58 | return true; | ||
59 | |||
60 | return false; | ||
61 | } | ||
62 | |||
63 | /* Mark an LSM's enabled flag. */ | ||
64 | static int lsm_enabled_true __initdata = 1; | ||
65 | static int lsm_enabled_false __initdata = 0; | ||
66 | static void __init set_enabled(struct lsm_info *lsm, bool enabled) | ||
67 | { | ||
68 | /* | ||
69 | * When an LSM hasn't configured an enable variable, we can use | ||
70 | * a hard-coded location for storing the default enabled state. | ||
71 | */ | ||
72 | if (!lsm->enabled) { | ||
73 | if (enabled) | ||
74 | lsm->enabled = &lsm_enabled_true; | ||
75 | else | ||
76 | lsm->enabled = &lsm_enabled_false; | ||
77 | } else if (lsm->enabled == &lsm_enabled_true) { | ||
78 | if (!enabled) | ||
79 | lsm->enabled = &lsm_enabled_false; | ||
80 | } else if (lsm->enabled == &lsm_enabled_false) { | ||
81 | if (enabled) | ||
82 | lsm->enabled = &lsm_enabled_true; | ||
83 | } else { | ||
84 | *lsm->enabled = enabled; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | /* Is an LSM allowed to be initialized? */ | ||
89 | static bool __init lsm_allowed(struct lsm_info *lsm) | ||
90 | { | ||
91 | /* Skip if the LSM is disabled. */ | ||
92 | if (!is_enabled(lsm)) | ||
93 | return false; | ||
94 | |||
95 | /* Skip major-specific checks if not a major LSM. */ | ||
96 | if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0) | ||
97 | return true; | ||
98 | |||
99 | /* Disabled if this LSM isn't the chosen one. */ | ||
100 | if (strcmp(lsm->name, chosen_lsm) != 0) | ||
101 | return false; | ||
102 | |||
103 | return true; | ||
104 | } | ||
105 | |||
106 | /* Check if LSM should be initialized. */ | ||
107 | static void __init maybe_initialize_lsm(struct lsm_info *lsm) | ||
108 | { | ||
109 | int enabled = lsm_allowed(lsm); | ||
110 | |||
111 | /* Record enablement (to handle any following exclusive LSMs). */ | ||
112 | set_enabled(lsm, enabled); | ||
113 | |||
114 | /* If selected, initialize the LSM. */ | ||
115 | if (enabled) { | ||
116 | int ret; | ||
117 | |||
118 | init_debug("initializing %s\n", lsm->name); | ||
119 | ret = lsm->init(); | ||
120 | WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret); | ||
121 | } | ||
122 | } | ||
123 | |||
55 | static void __init ordered_lsm_init(void) | 124 | static void __init ordered_lsm_init(void) |
56 | { | 125 | { |
57 | struct lsm_info *lsm; | 126 | struct lsm_info *lsm; |
58 | int ret; | ||
59 | 127 | ||
60 | for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { | 128 | for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { |
61 | if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) != 0) | 129 | if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) != 0) |
62 | continue; | 130 | continue; |
63 | 131 | ||
64 | init_debug("initializing %s\n", lsm->name); | 132 | maybe_initialize_lsm(lsm); |
65 | ret = lsm->init(); | ||
66 | WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret); | ||
67 | } | 133 | } |
68 | } | 134 | } |
69 | 135 | ||
70 | static void __init major_lsm_init(void) | 136 | static void __init major_lsm_init(void) |
71 | { | 137 | { |
72 | struct lsm_info *lsm; | 138 | struct lsm_info *lsm; |
73 | int ret; | ||
74 | 139 | ||
75 | for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { | 140 | for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { |
76 | if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0) | 141 | if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0) |
77 | continue; | 142 | continue; |
78 | 143 | ||
79 | init_debug("initializing %s\n", lsm->name); | 144 | maybe_initialize_lsm(lsm); |
80 | ret = lsm->init(); | ||
81 | WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret); | ||
82 | } | 145 | } |
83 | } | 146 | } |
84 | 147 | ||
@@ -169,29 +232,6 @@ static int lsm_append(char *new, char **result) | |||
169 | } | 232 | } |
170 | 233 | ||
171 | /** | 234 | /** |
172 | * security_module_enable - Load given security module on boot ? | ||
173 | * @module: the name of the module | ||
174 | * | ||
175 | * Each LSM must pass this method before registering its own operations | ||
176 | * to avoid security registration races. This method may also be used | ||
177 | * to check if your LSM is currently loaded during kernel initialization. | ||
178 | * | ||
179 | * Returns: | ||
180 | * | ||
181 | * true if: | ||
182 | * | ||
183 | * - The passed LSM is the one chosen by user at boot time, | ||
184 | * - or the passed LSM is configured as the default and the user did not | ||
185 | * choose an alternate LSM at boot time. | ||
186 | * | ||
187 | * Otherwise, return false. | ||
188 | */ | ||
189 | int __init security_module_enable(const char *module) | ||
190 | { | ||
191 | return !strcmp(module, chosen_lsm); | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * security_add_hooks - Add a modules hooks to the hook lists. | 235 | * security_add_hooks - Add a modules hooks to the hook lists. |
196 | * @hooks: the hooks to add | 236 | * @hooks: the hooks to add |
197 | * @count: the number of hooks to add | 237 | * @count: the number of hooks to add |