apparmor: add a kernel label to use on kernel objects
Separate kernel objects from unconfined. This is done so we can distinguish between the two in debugging, auditing and in preparation for being able to replace unconfined, which is not appropriate for the kernel. The kernel label will continue to behave similar to unconfined. Acked-by: Jon Tourville <jon.tourville@canonical.com> Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
e2f76ad7d2
commit
95c0581f9b
|
@ -74,6 +74,7 @@ struct aa_ns {
|
||||||
struct dentry *dents[AAFS_NS_SIZEOF];
|
struct dentry *dents[AAFS_NS_SIZEOF];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern struct aa_label *kernel_t;
|
||||||
extern struct aa_ns *root_ns;
|
extern struct aa_ns *root_ns;
|
||||||
|
|
||||||
extern const char *aa_hidden_ns_name;
|
extern const char *aa_hidden_ns_name;
|
||||||
|
|
|
@ -886,10 +886,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family,
|
||||||
struct aa_label *label;
|
struct aa_label *label;
|
||||||
|
|
||||||
if (kern) {
|
if (kern) {
|
||||||
struct aa_ns *ns = aa_get_current_ns();
|
label = aa_get_label(kernel_t);
|
||||||
|
|
||||||
label = aa_get_label(ns_unconfined(ns));
|
|
||||||
aa_put_ns(ns);
|
|
||||||
} else
|
} else
|
||||||
label = aa_get_current_label();
|
label = aa_get_current_label();
|
||||||
|
|
||||||
|
|
|
@ -145,12 +145,13 @@ int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
|
||||||
static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
|
static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
|
||||||
struct sock *sk)
|
struct sock *sk)
|
||||||
{
|
{
|
||||||
|
struct aa_sk_ctx *ctx = SK_CTX(sk);
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
AA_BUG(!label);
|
AA_BUG(!label);
|
||||||
AA_BUG(!sk);
|
AA_BUG(!sk);
|
||||||
|
|
||||||
if (!unconfined(label)) {
|
if (ctx->label != kernel_t && !unconfined(label)) {
|
||||||
struct aa_profile *profile;
|
struct aa_profile *profile;
|
||||||
DEFINE_AUDIT_SK(sa, op, sk);
|
DEFINE_AUDIT_SK(sa, op, sk);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
#include "include/label.h"
|
#include "include/label.h"
|
||||||
#include "include/policy.h"
|
#include "include/policy.h"
|
||||||
|
|
||||||
|
/* kernel label */
|
||||||
|
struct aa_label *kernel_t;
|
||||||
|
|
||||||
/* root profile namespace */
|
/* root profile namespace */
|
||||||
struct aa_ns *root_ns;
|
struct aa_ns *root_ns;
|
||||||
const char *aa_hidden_ns_name = "---";
|
const char *aa_hidden_ns_name = "---";
|
||||||
|
@ -77,6 +80,23 @@ const char *aa_ns_name(struct aa_ns *curr, struct aa_ns *view, bool subns)
|
||||||
return aa_hidden_ns_name;
|
return aa_hidden_ns_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct aa_profile *alloc_unconfined(const char *name)
|
||||||
|
{
|
||||||
|
struct aa_profile *profile;
|
||||||
|
|
||||||
|
profile = aa_alloc_profile(name, NULL, GFP_KERNEL);
|
||||||
|
if (!profile)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
profile->label.flags |= FLAG_IX_ON_NAME_ERROR |
|
||||||
|
FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
|
||||||
|
profile->mode = APPARMOR_UNCONFINED;
|
||||||
|
profile->file.dfa = aa_get_dfa(nulldfa);
|
||||||
|
profile->policy.dfa = aa_get_dfa(nulldfa);
|
||||||
|
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* alloc_ns - allocate, initialize and return a new namespace
|
* alloc_ns - allocate, initialize and return a new namespace
|
||||||
* @prefix: parent namespace name (MAYBE NULL)
|
* @prefix: parent namespace name (MAYBE NULL)
|
||||||
|
@ -101,16 +121,9 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
|
||||||
init_waitqueue_head(&ns->wait);
|
init_waitqueue_head(&ns->wait);
|
||||||
|
|
||||||
/* released by aa_free_ns() */
|
/* released by aa_free_ns() */
|
||||||
ns->unconfined = aa_alloc_profile("unconfined", NULL, GFP_KERNEL);
|
ns->unconfined = alloc_unconfined("unconfined");
|
||||||
if (!ns->unconfined)
|
if (!ns->unconfined)
|
||||||
goto fail_unconfined;
|
goto fail_unconfined;
|
||||||
|
|
||||||
ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR |
|
|
||||||
FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
|
|
||||||
ns->unconfined->mode = APPARMOR_UNCONFINED;
|
|
||||||
ns->unconfined->file.dfa = aa_get_dfa(nulldfa);
|
|
||||||
ns->unconfined->policy.dfa = aa_get_dfa(nulldfa);
|
|
||||||
|
|
||||||
/* ns and ns->unconfined share ns->unconfined refcount */
|
/* ns and ns->unconfined share ns->unconfined refcount */
|
||||||
ns->unconfined->ns = ns;
|
ns->unconfined->ns = ns;
|
||||||
|
|
||||||
|
@ -388,11 +401,22 @@ static void __ns_list_release(struct list_head *head)
|
||||||
*/
|
*/
|
||||||
int __init aa_alloc_root_ns(void)
|
int __init aa_alloc_root_ns(void)
|
||||||
{
|
{
|
||||||
|
struct aa_profile *kernel_p;
|
||||||
|
|
||||||
/* released by aa_free_root_ns - used as list ref*/
|
/* released by aa_free_root_ns - used as list ref*/
|
||||||
root_ns = alloc_ns(NULL, "root");
|
root_ns = alloc_ns(NULL, "root");
|
||||||
if (!root_ns)
|
if (!root_ns)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
kernel_p = alloc_unconfined("kernel_t");
|
||||||
|
if (!kernel_p) {
|
||||||
|
destroy_ns(root_ns);
|
||||||
|
aa_free_ns(root_ns);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
kernel_t = &kernel_p->label;
|
||||||
|
root_ns->unconfined->ns = aa_get_ns(root_ns);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,6 +429,7 @@ void __init aa_free_root_ns(void)
|
||||||
|
|
||||||
root_ns = NULL;
|
root_ns = NULL;
|
||||||
|
|
||||||
|
aa_label_free(kernel_t);
|
||||||
destroy_ns(ns);
|
destroy_ns(ns);
|
||||||
aa_put_ns(ns);
|
aa_put_ns(ns);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue