summaryrefslogtreecommitdiffstats
path: root/security/security.c
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2018-11-12 15:02:49 -0500
committerKees Cook <keescook@chromium.org>2019-01-08 16:18:44 -0500
commit33bf60cabcc7687b194a689b068b65e9ecd556be (patch)
treef8bbf4c27ce73e33ab5f1efa7e99448ab9755373 /security/security.c
parentf28952ac900822a189fc383a5b73631e72c69356 (diff)
LSM: Infrastructure management of the file security
Move management of the file->f_security blob out of the individual security modules and into the infrastructure. The modules no longer allocate or free the data, instead they tell the infrastructure how much space they require. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Reviewed-by: Kees Cook <keescook@chromium.org> [kees: adjusted for ordered init series] Signed-off-by: Kees Cook <keescook@chromium.org>
Diffstat (limited to 'security/security.c')
-rw-r--r--security/security.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/security/security.c b/security/security.c
index 09be8ce007a2..f32d7d2075c6 100644
--- a/security/security.c
+++ b/security/security.c
@@ -40,6 +40,8 @@
40struct security_hook_heads security_hook_heads __lsm_ro_after_init; 40struct 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
43static struct kmem_cache *lsm_file_cache;
44
43char *lsm_names; 45char *lsm_names;
44static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init; 46static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init;
45 47
@@ -158,6 +160,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
158 return; 160 return;
159 161
160 lsm_set_blob_size(&needed->lbs_cred, &blob_sizes.lbs_cred); 162 lsm_set_blob_size(&needed->lbs_cred, &blob_sizes.lbs_cred);
163 lsm_set_blob_size(&needed->lbs_file, &blob_sizes.lbs_file);
161} 164}
162 165
163/* Prepare LSM for initialization. */ 166/* Prepare LSM for initialization. */
@@ -279,6 +282,15 @@ static void __init ordered_lsm_init(void)
279 prepare_lsm(*lsm); 282 prepare_lsm(*lsm);
280 283
281 init_debug("cred blob size = %d\n", blob_sizes.lbs_cred); 284 init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
285 init_debug("file blob size = %d\n", blob_sizes.lbs_file);
286
287 /*
288 * Create any kmem_caches needed for blobs
289 */
290 if (blob_sizes.lbs_file)
291 lsm_file_cache = kmem_cache_create("lsm_file_cache",
292 blob_sizes.lbs_file, 0,
293 SLAB_PANIC, NULL);
282 294
283 for (lsm = ordered_lsms; *lsm; lsm++) 295 for (lsm = ordered_lsms; *lsm; lsm++)
284 initialize_lsm(*lsm); 296 initialize_lsm(*lsm);
@@ -448,6 +460,27 @@ void __init lsm_early_cred(struct cred *cred)
448 panic("%s: Early cred alloc failed.\n", __func__); 460 panic("%s: Early cred alloc failed.\n", __func__);
449} 461}
450 462
463/**
464 * lsm_file_alloc - allocate a composite file blob
465 * @file: the file that needs a blob
466 *
467 * Allocate the file blob for all the modules
468 *
469 * Returns 0, or -ENOMEM if memory can't be allocated.
470 */
471static int lsm_file_alloc(struct file *file)
472{
473 if (!lsm_file_cache) {
474 file->f_security = NULL;
475 return 0;
476 }
477
478 file->f_security = kmem_cache_zalloc(lsm_file_cache, GFP_KERNEL);
479 if (file->f_security == NULL)
480 return -ENOMEM;
481 return 0;
482}
483
451/* 484/*
452 * Hook list operation macros. 485 * Hook list operation macros.
453 * 486 *
@@ -1144,12 +1177,27 @@ int security_file_permission(struct file *file, int mask)
1144 1177
1145int security_file_alloc(struct file *file) 1178int security_file_alloc(struct file *file)
1146{ 1179{
1147 return call_int_hook(file_alloc_security, 0, file); 1180 int rc = lsm_file_alloc(file);
1181
1182 if (rc)
1183 return rc;
1184 rc = call_int_hook(file_alloc_security, 0, file);
1185 if (unlikely(rc))
1186 security_file_free(file);
1187 return rc;
1148} 1188}
1149 1189
1150void security_file_free(struct file *file) 1190void security_file_free(struct file *file)
1151{ 1191{
1192 void *blob;
1193
1152 call_void_hook(file_free_security, file); 1194 call_void_hook(file_free_security, file);
1195
1196 blob = file->f_security;
1197 if (blob) {
1198 file->f_security = NULL;
1199 kmem_cache_free(lsm_file_cache, blob);
1200 }
1153} 1201}
1154 1202
1155int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1203int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -1267,7 +1315,7 @@ int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
1267 return rc; 1315 return rc;
1268 1316
1269 rc = call_int_hook(cred_alloc_blank, 0, cred, gfp); 1317 rc = call_int_hook(cred_alloc_blank, 0, cred, gfp);
1270 if (rc) 1318 if (unlikely(rc))
1271 security_cred_free(cred); 1319 security_cred_free(cred);
1272 return rc; 1320 return rc;
1273} 1321}
@@ -1288,7 +1336,7 @@ int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp)
1288 return rc; 1336 return rc;
1289 1337
1290 rc = call_int_hook(cred_prepare, 0, new, old, gfp); 1338 rc = call_int_hook(cred_prepare, 0, new, old, gfp);
1291 if (rc) 1339 if (unlikely(rc))
1292 security_cred_free(new); 1340 security_cred_free(new);
1293 return rc; 1341 return rc;
1294} 1342}