summaryrefslogtreecommitdiffstats
path: root/security/security.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/security.c')
-rw-r--r--security/security.c89
1 files changed, 87 insertions, 2 deletions
diff --git a/security/security.c b/security/security.c
index 60b39db95c2f..09be8ce007a2 100644
--- a/security/security.c
+++ b/security/security.c
@@ -41,6 +41,8 @@ struct security_hook_heads security_hook_heads __lsm_ro_after_init;
41static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); 41static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
42 42
43char *lsm_names; 43char *lsm_names;
44static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init;
45
44/* Boot-time LSM user choice */ 46/* Boot-time LSM user choice */
45static __initdata const char *chosen_lsm_order; 47static __initdata const char *chosen_lsm_order;
46static __initdata const char *chosen_major_lsm; 48static __initdata const char *chosen_major_lsm;
@@ -139,6 +141,25 @@ static bool __init lsm_allowed(struct lsm_info *lsm)
139 return true; 141 return true;
140} 142}
141 143
144static void __init lsm_set_blob_size(int *need, int *lbs)
145{
146 int offset;
147
148 if (*need > 0) {
149 offset = *lbs;
150 *lbs += *need;
151 *need = offset;
152 }
153}
154
155static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
156{
157 if (!needed)
158 return;
159
160 lsm_set_blob_size(&needed->lbs_cred, &blob_sizes.lbs_cred);
161}
162
142/* Prepare LSM for initialization. */ 163/* Prepare LSM for initialization. */
143static void __init prepare_lsm(struct lsm_info *lsm) 164static void __init prepare_lsm(struct lsm_info *lsm)
144{ 165{
@@ -153,6 +174,8 @@ static void __init prepare_lsm(struct lsm_info *lsm)
153 exclusive = lsm; 174 exclusive = lsm;
154 init_debug("exclusive chosen: %s\n", lsm->name); 175 init_debug("exclusive chosen: %s\n", lsm->name);
155 } 176 }
177
178 lsm_set_blob_sizes(lsm->blobs);
156 } 179 }
157} 180}
158 181
@@ -255,6 +278,8 @@ static void __init ordered_lsm_init(void)
255 for (lsm = ordered_lsms; *lsm; lsm++) 278 for (lsm = ordered_lsms; *lsm; lsm++)
256 prepare_lsm(*lsm); 279 prepare_lsm(*lsm);
257 280
281 init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
282
258 for (lsm = ordered_lsms; *lsm; lsm++) 283 for (lsm = ordered_lsms; *lsm; lsm++)
259 initialize_lsm(*lsm); 284 initialize_lsm(*lsm);
260 285
@@ -382,6 +407,47 @@ int unregister_lsm_notifier(struct notifier_block *nb)
382} 407}
383EXPORT_SYMBOL(unregister_lsm_notifier); 408EXPORT_SYMBOL(unregister_lsm_notifier);
384 409
410/**
411 * lsm_cred_alloc - allocate a composite cred blob
412 * @cred: the cred that needs a blob
413 * @gfp: allocation type
414 *
415 * Allocate the cred blob for all the modules
416 *
417 * Returns 0, or -ENOMEM if memory can't be allocated.
418 */
419static int lsm_cred_alloc(struct cred *cred, gfp_t gfp)
420{
421 if (blob_sizes.lbs_cred == 0) {
422 cred->security = NULL;
423 return 0;
424 }
425
426 cred->security = kzalloc(blob_sizes.lbs_cred, gfp);
427 if (cred->security == NULL)
428 return -ENOMEM;
429 return 0;
430}
431
432/**
433 * lsm_early_cred - during initialization allocate a composite cred blob
434 * @cred: the cred that needs a blob
435 *
436 * Allocate the cred blob for all the modules if it's not already there
437 */
438void __init lsm_early_cred(struct cred *cred)
439{
440 int rc;
441
442 if (cred == NULL)
443 panic("%s: NULL cred.\n", __func__);
444 if (cred->security != NULL)
445 return;
446 rc = lsm_cred_alloc(cred, GFP_KERNEL);
447 if (rc)
448 panic("%s: Early cred alloc failed.\n", __func__);
449}
450
385/* 451/*
386 * Hook list operation macros. 452 * Hook list operation macros.
387 * 453 *
@@ -1195,17 +1261,36 @@ void security_task_free(struct task_struct *task)
1195 1261
1196int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) 1262int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
1197{ 1263{
1198 return call_int_hook(cred_alloc_blank, 0, cred, gfp); 1264 int rc = lsm_cred_alloc(cred, gfp);
1265
1266 if (rc)
1267 return rc;
1268
1269 rc = call_int_hook(cred_alloc_blank, 0, cred, gfp);
1270 if (rc)
1271 security_cred_free(cred);
1272 return rc;
1199} 1273}
1200 1274
1201void security_cred_free(struct cred *cred) 1275void security_cred_free(struct cred *cred)
1202{ 1276{
1203 call_void_hook(cred_free, cred); 1277 call_void_hook(cred_free, cred);
1278
1279 kfree(cred->security);
1280 cred->security = NULL;
1204} 1281}
1205 1282
1206int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp) 1283int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp)
1207{ 1284{
1208 return call_int_hook(cred_prepare, 0, new, old, gfp); 1285 int rc = lsm_cred_alloc(new, gfp);
1286
1287 if (rc)
1288 return rc;
1289
1290 rc = call_int_hook(cred_prepare, 0, new, old, gfp);
1291 if (rc)
1292 security_cred_free(new);
1293 return rc;
1209} 1294}
1210 1295
1211void security_transfer_creds(struct cred *new, const struct cred *old) 1296void security_transfer_creds(struct cred *new, const struct cred *old)