diff options
Diffstat (limited to 'security/security.c')
-rw-r--r-- | security/security.c | 54 |
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 @@ | |||
40 | struct security_hook_heads security_hook_heads __lsm_ro_after_init; | 40 | struct security_hook_heads security_hook_heads __lsm_ro_after_init; |
41 | static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); | 41 | static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); |
42 | 42 | ||
43 | static struct kmem_cache *lsm_file_cache; | ||
44 | |||
43 | char *lsm_names; | 45 | char *lsm_names; |
44 | static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init; | 46 | static 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 | */ | ||
471 | static 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 | ||
1145 | int security_file_alloc(struct file *file) | 1178 | int 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 | ||
1150 | void security_file_free(struct file *file) | 1190 | void 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 | ||
1155 | int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 1203 | int 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 | } |