diff options
| -rw-r--r-- | security/apparmor/crypto.c | 34 | ||||
| -rw-r--r-- | security/apparmor/include/policy.h | 4 | ||||
| -rw-r--r-- | security/apparmor/policy.c | 3 |
3 files changed, 21 insertions, 20 deletions
diff --git a/security/apparmor/crypto.c b/security/apparmor/crypto.c index d6222ba4e919..532471d0b3a0 100644 --- a/security/apparmor/crypto.c +++ b/security/apparmor/crypto.c | |||
| @@ -15,14 +15,14 @@ | |||
| 15 | * it should be. | 15 | * it should be. |
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <linux/crypto.h> | 18 | #include <crypto/hash.h> |
| 19 | 19 | ||
| 20 | #include "include/apparmor.h" | 20 | #include "include/apparmor.h" |
| 21 | #include "include/crypto.h" | 21 | #include "include/crypto.h" |
| 22 | 22 | ||
| 23 | static unsigned int apparmor_hash_size; | 23 | static unsigned int apparmor_hash_size; |
| 24 | 24 | ||
| 25 | static struct crypto_hash *apparmor_tfm; | 25 | static struct crypto_shash *apparmor_tfm; |
| 26 | 26 | ||
| 27 | unsigned int aa_hash_size(void) | 27 | unsigned int aa_hash_size(void) |
| 28 | { | 28 | { |
| @@ -32,35 +32,33 @@ unsigned int aa_hash_size(void) | |||
| 32 | int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start, | 32 | int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start, |
| 33 | size_t len) | 33 | size_t len) |
| 34 | { | 34 | { |
| 35 | struct scatterlist sg[2]; | 35 | struct { |
| 36 | struct hash_desc desc = { | 36 | struct shash_desc shash; |
| 37 | .tfm = apparmor_tfm, | 37 | char ctx[crypto_shash_descsize(apparmor_tfm)]; |
| 38 | .flags = 0 | 38 | } desc; |
| 39 | }; | ||
| 40 | int error = -ENOMEM; | 39 | int error = -ENOMEM; |
| 41 | u32 le32_version = cpu_to_le32(version); | 40 | u32 le32_version = cpu_to_le32(version); |
| 42 | 41 | ||
| 43 | if (!apparmor_tfm) | 42 | if (!apparmor_tfm) |
| 44 | return 0; | 43 | return 0; |
| 45 | 44 | ||
| 46 | sg_init_table(sg, 2); | ||
| 47 | sg_set_buf(&sg[0], &le32_version, 4); | ||
| 48 | sg_set_buf(&sg[1], (u8 *) start, len); | ||
| 49 | |||
| 50 | profile->hash = kzalloc(apparmor_hash_size, GFP_KERNEL); | 45 | profile->hash = kzalloc(apparmor_hash_size, GFP_KERNEL); |
| 51 | if (!profile->hash) | 46 | if (!profile->hash) |
| 52 | goto fail; | 47 | goto fail; |
| 53 | 48 | ||
| 54 | error = crypto_hash_init(&desc); | 49 | desc.shash.tfm = apparmor_tfm; |
| 50 | desc.shash.flags = 0; | ||
| 51 | |||
| 52 | error = crypto_shash_init(&desc.shash); | ||
| 55 | if (error) | 53 | if (error) |
| 56 | goto fail; | 54 | goto fail; |
| 57 | error = crypto_hash_update(&desc, &sg[0], 4); | 55 | error = crypto_shash_update(&desc.shash, (u8 *) &le32_version, 4); |
| 58 | if (error) | 56 | if (error) |
| 59 | goto fail; | 57 | goto fail; |
| 60 | error = crypto_hash_update(&desc, &sg[1], len); | 58 | error = crypto_shash_update(&desc.shash, (u8 *) start, len); |
| 61 | if (error) | 59 | if (error) |
| 62 | goto fail; | 60 | goto fail; |
| 63 | error = crypto_hash_final(&desc, profile->hash); | 61 | error = crypto_shash_final(&desc.shash, profile->hash); |
| 64 | if (error) | 62 | if (error) |
| 65 | goto fail; | 63 | goto fail; |
| 66 | 64 | ||
| @@ -75,19 +73,19 @@ fail: | |||
| 75 | 73 | ||
| 76 | static int __init init_profile_hash(void) | 74 | static int __init init_profile_hash(void) |
| 77 | { | 75 | { |
| 78 | struct crypto_hash *tfm; | 76 | struct crypto_shash *tfm; |
| 79 | 77 | ||
| 80 | if (!apparmor_initialized) | 78 | if (!apparmor_initialized) |
| 81 | return 0; | 79 | return 0; |
| 82 | 80 | ||
| 83 | tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC); | 81 | tfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_ASYNC); |
| 84 | if (IS_ERR(tfm)) { | 82 | if (IS_ERR(tfm)) { |
| 85 | int error = PTR_ERR(tfm); | 83 | int error = PTR_ERR(tfm); |
| 86 | AA_ERROR("failed to setup profile sha1 hashing: %d\n", error); | 84 | AA_ERROR("failed to setup profile sha1 hashing: %d\n", error); |
| 87 | return error; | 85 | return error; |
| 88 | } | 86 | } |
| 89 | apparmor_tfm = tfm; | 87 | apparmor_tfm = tfm; |
| 90 | apparmor_hash_size = crypto_hash_digestsize(apparmor_tfm); | 88 | apparmor_hash_size = crypto_shash_digestsize(apparmor_tfm); |
| 91 | 89 | ||
| 92 | aa_info_message("AppArmor sha1 policy hashing enabled"); | 90 | aa_info_message("AppArmor sha1 policy hashing enabled"); |
| 93 | 91 | ||
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index f2d4b6348cbc..c28b0f20ab53 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h | |||
| @@ -360,7 +360,9 @@ static inline void aa_put_replacedby(struct aa_replacedby *p) | |||
| 360 | static inline void __aa_update_replacedby(struct aa_profile *orig, | 360 | static inline void __aa_update_replacedby(struct aa_profile *orig, |
| 361 | struct aa_profile *new) | 361 | struct aa_profile *new) |
| 362 | { | 362 | { |
| 363 | struct aa_profile *tmp = rcu_dereference(orig->replacedby->profile); | 363 | struct aa_profile *tmp; |
| 364 | tmp = rcu_dereference_protected(orig->replacedby->profile, | ||
| 365 | mutex_is_locked(&orig->ns->lock)); | ||
| 364 | rcu_assign_pointer(orig->replacedby->profile, aa_get_profile(new)); | 366 | rcu_assign_pointer(orig->replacedby->profile, aa_get_profile(new)); |
| 365 | orig->flags |= PFLAG_INVALID; | 367 | orig->flags |= PFLAG_INVALID; |
| 366 | aa_put_profile(tmp); | 368 | aa_put_profile(tmp); |
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 6172509fa2b7..345bec07a27d 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c | |||
| @@ -563,7 +563,8 @@ void __init aa_free_root_ns(void) | |||
| 563 | static void free_replacedby(struct aa_replacedby *r) | 563 | static void free_replacedby(struct aa_replacedby *r) |
| 564 | { | 564 | { |
| 565 | if (r) { | 565 | if (r) { |
| 566 | aa_put_profile(rcu_dereference(r->profile)); | 566 | /* r->profile will not be updated any more as r is dead */ |
| 567 | aa_put_profile(rcu_dereference_protected(r->profile, true)); | ||
| 567 | kzfree(r); | 568 | kzfree(r); |
| 568 | } | 569 | } |
| 569 | } | 570 | } |
