LSM: Infrastructure management of the file security
[linux-2.6-block.git] / security / apparmor / lsm.c
index 2c010874329f997559d5c2e786b2bc5031d85a41..6821187b06adfb02e0462dd7a9020c3c3cf46bf4 100644 (file)
@@ -60,7 +60,7 @@ DEFINE_PER_CPU(struct aa_buffers, aa_buffers);
 static void apparmor_cred_free(struct cred *cred)
 {
        aa_put_label(cred_label(cred));
-       cred_label(cred) = NULL;
+       set_cred_label(cred, NULL);
 }
 
 /*
@@ -68,7 +68,7 @@ static void apparmor_cred_free(struct cred *cred)
  */
 static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp)
 {
-       cred_label(cred) = NULL;
+       set_cred_label(cred, NULL);
        return 0;
 }
 
@@ -78,7 +78,7 @@ static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp)
 static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
                                 gfp_t gfp)
 {
-       cred_label(new) = aa_get_newest_label(cred_label(old));
+       set_cred_label(new, aa_get_newest_label(cred_label(old)));
        return 0;
 }
 
@@ -87,7 +87,7 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
  */
 static void apparmor_cred_transfer(struct cred *new, const struct cred *old)
 {
-       cred_label(new) = aa_get_newest_label(cred_label(old));
+       set_cred_label(new, aa_get_newest_label(cred_label(old)));
 }
 
 static void apparmor_task_free(struct task_struct *task)
@@ -434,21 +434,21 @@ static int apparmor_file_open(struct file *file)
 
 static int apparmor_file_alloc_security(struct file *file)
 {
-       int error = 0;
-
-       /* freed by apparmor_file_free_security */
+       struct aa_file_ctx *ctx = file_ctx(file);
        struct aa_label *label = begin_current_label_crit_section();
-       file->f_security = aa_alloc_file_ctx(label, GFP_KERNEL);
-       if (!file_ctx(file))
-               error = -ENOMEM;
-       end_current_label_crit_section(label);
 
-       return error;
+       spin_lock_init(&ctx->lock);
+       rcu_assign_pointer(ctx->label, aa_get_label(label));
+       end_current_label_crit_section(label);
+       return 0;
 }
 
 static void apparmor_file_free_security(struct file *file)
 {
-       aa_free_file_ctx(file_ctx(file));
+       struct aa_file_ctx *ctx = file_ctx(file);
+
+       if (ctx)
+               aa_put_label(rcu_access_pointer(ctx->label));
 }
 
 static int common_file_perm(const char *op, struct file *file, u32 mask)
@@ -1151,6 +1151,14 @@ static int apparmor_inet_conn_request(struct sock *sk, struct sk_buff *skb,
 }
 #endif
 
+/*
+ * The cred blob is a pointer to, not an instance of, an aa_task_ctx.
+ */
+struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = {
+       .lbs_cred = sizeof(struct aa_task_ctx *),
+       .lbs_file = sizeof(struct aa_file_ctx),
+};
+
 static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
        LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
        LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
@@ -1333,8 +1341,8 @@ bool aa_g_paranoid_load = true;
 module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO);
 
 /* Boot time disable flag */
-static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
-module_param_named(enabled, apparmor_enabled, bool, S_IRUGO);
+static int apparmor_enabled __lsm_ro_after_init = 1;
+module_param_named(enabled, apparmor_enabled, int, 0444);
 
 static int __init apparmor_enabled_setup(char *str)
 {
@@ -1485,7 +1493,8 @@ static int __init set_init_ctx(void)
        if (!ctx)
                return -ENOMEM;
 
-       cred_label(cred) = aa_get_label(ns_unconfined(root_ns));
+       lsm_early_cred(cred);
+       set_cred_label(cred, aa_get_label(ns_unconfined(root_ns)));
        task_ctx(current) = ctx;
 
        return 0;
@@ -1663,12 +1672,6 @@ static int __init apparmor_init(void)
 {
        int error;
 
-       if (!apparmor_enabled || !security_module_enable("apparmor")) {
-               aa_info_message("AppArmor disabled by boot time parameter");
-               apparmor_enabled = false;
-               return 0;
-       }
-
        aa_secids_init();
 
        error = aa_setup_dfa_engine();
@@ -1729,5 +1732,8 @@ alloc_out:
 
 DEFINE_LSM(apparmor) = {
        .name = "apparmor",
+       .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
+       .enabled = &apparmor_enabled,
+       .blobs = &apparmor_blob_sizes,
        .init = apparmor_init,
 };