Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b822cb18 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull apparmor fixes from James Morris:
 "Bugfixes for the Apparmor code for regressions introduced in the 3.12
  pull request"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
  apparmor: fix suspicious RCU usage warning in policy.c/policy.h
  apparmor: Use shash crypto API interface for profile hashes
parents cbb16bec 4cd4fc77
Loading
Loading
Loading
Loading
+16 −18
Original line number Diff line number Diff line
@@ -15,14 +15,14 @@
 * it should be.
 */

#include <linux/crypto.h>
#include <crypto/hash.h>

#include "include/apparmor.h"
#include "include/crypto.h"

static unsigned int apparmor_hash_size;

static struct crypto_hash *apparmor_tfm;
static struct crypto_shash *apparmor_tfm;

unsigned int aa_hash_size(void)
{
@@ -32,35 +32,33 @@ unsigned int aa_hash_size(void)
int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
			 size_t len)
{
	struct scatterlist sg[2];
	struct hash_desc desc = {
		.tfm = apparmor_tfm,
		.flags = 0
	};
	struct {
		struct shash_desc shash;
		char ctx[crypto_shash_descsize(apparmor_tfm)];
	} desc;
	int error = -ENOMEM;
	u32 le32_version = cpu_to_le32(version);

	if (!apparmor_tfm)
		return 0;

	sg_init_table(sg, 2);
	sg_set_buf(&sg[0], &le32_version, 4);
	sg_set_buf(&sg[1], (u8 *) start, len);

	profile->hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
	if (!profile->hash)
		goto fail;

	error = crypto_hash_init(&desc);
	desc.shash.tfm = apparmor_tfm;
	desc.shash.flags = 0;

	error = crypto_shash_init(&desc.shash);
	if (error)
		goto fail;
	error = crypto_hash_update(&desc, &sg[0], 4);
	error = crypto_shash_update(&desc.shash, (u8 *) &le32_version, 4);
	if (error)
		goto fail;
	error = crypto_hash_update(&desc, &sg[1], len);
	error = crypto_shash_update(&desc.shash, (u8 *) start, len);
	if (error)
		goto fail;
	error = crypto_hash_final(&desc, profile->hash);
	error = crypto_shash_final(&desc.shash, profile->hash);
	if (error)
		goto fail;

@@ -75,19 +73,19 @@ int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,

static int __init init_profile_hash(void)
{
	struct crypto_hash *tfm;
	struct crypto_shash *tfm;

	if (!apparmor_initialized)
		return 0;

	tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
	tfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(tfm)) {
		int error = PTR_ERR(tfm);
		AA_ERROR("failed to setup profile sha1 hashing: %d\n", error);
		return error;
	}
	apparmor_tfm = tfm;
	apparmor_hash_size = crypto_hash_digestsize(apparmor_tfm);
	apparmor_hash_size = crypto_shash_digestsize(apparmor_tfm);

	aa_info_message("AppArmor sha1 policy hashing enabled");

+3 −1
Original line number Diff line number Diff line
@@ -360,7 +360,9 @@ static inline void aa_put_replacedby(struct aa_replacedby *p)
static inline void __aa_update_replacedby(struct aa_profile *orig,
					  struct aa_profile *new)
{
	struct aa_profile *tmp = rcu_dereference(orig->replacedby->profile);
	struct aa_profile *tmp;
	tmp = rcu_dereference_protected(orig->replacedby->profile,
					mutex_is_locked(&orig->ns->lock));
	rcu_assign_pointer(orig->replacedby->profile, aa_get_profile(new));
	orig->flags |= PFLAG_INVALID;
	aa_put_profile(tmp);
+2 −1
Original line number Diff line number Diff line
@@ -563,7 +563,8 @@ void __init aa_free_root_ns(void)
static void free_replacedby(struct aa_replacedby *r)
{
	if (r) {
		aa_put_profile(rcu_dereference(r->profile));
		/* r->profile will not be updated any more as r is dead */
		aa_put_profile(rcu_dereference_protected(r->profile, true));
		kzfree(r);
	}
}