Commit a3c6147c authored by John Johansen's avatar John Johansen Committed by Tim Gardner

UBUNTU: SAUCE: (no-up) apparmor: sync of apparmor3.5-beta1 snapshot

BugLink: http://bugs.launchpad.net/bugs/1379535

This is a sync and squash of the apparmor 3.5-beta1 snapshot. The
set of patches in this squash are available in
  git://kernel.ubuntu.com/jj/ubuntu-xenial.git
using the the tag
  apparmor-3.5-beta1-presuash-snapshot

This fixes multiple bugs and adds the policy namespace stacking features.
BugLink: http://bugs.launchpad.net/bugs/1379535Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
Signed-off-by: default avatarTim Gardner <tim.gardner@canonical.com>
parent 3733c356
# #
# Generated include files # Generated include files
# #
net_names.h
capability_names.h capability_names.h
rlim_names.h rlim_names.h
...@@ -30,14 +30,62 @@ config SECURITY_APPARMOR_BOOTPARAM_VALUE ...@@ -30,14 +30,62 @@ config SECURITY_APPARMOR_BOOTPARAM_VALUE
If you are unsure how to answer this question, answer 1. If you are unsure how to answer this question, answer 1.
config SECURITY_APPARMOR_STATS
bool "enable debug statistics"
depends on SECURITY_APPARMOR
select APPARMOR_LABEL_STATS
default n
help
This enables keeping statistics on various internal structures
and functions in apparmor.
If you are unsure how to answer this question, answer N.
config SECURITY_APPARMOR_UNCONFINED_INIT
bool "Set init to unconfined on boot"
depends on SECURITY_APPARMOR
default y
help
This option determines policy behavior during early boot by
placing the init process in the unconfined state, or the
'default' profile.
This option determines policy behavior during early boot by
placing the init process in the unconfined state, or the
'default' profile.
'Y' means init and its children are not confined, unless the
init process is re-execed after a policy load; loaded policy
will only apply to processes started after the load.
'N' means init and its children are confined in a profile
named 'default', which can be replaced later and thus
provide for confinement for processes started early at boot,
though not confined during early boot.
If you are unsure how to answer this question, answer Y.
config SECURITY_APPARMOR_HASH config SECURITY_APPARMOR_HASH
bool "SHA1 hash of loaded profiles" bool "enable introspection of sha1 hashes for loaded profiles"
depends on SECURITY_APPARMOR depends on SECURITY_APPARMOR
select CRYPTO select CRYPTO
select CRYPTO_SHA1 select CRYPTO_SHA1
default y default y
help help
This option selects whether sha1 hashing is done against loaded This option selects whether introspection of loaded policy
profiles and exported for inspection to user space via the apparmor is available to userspace via the apparmor filesystem.
filesystem.
config SECURITY_APPARMOR_HASH_DEFAULT
bool "Enable policy hash introspection by default"
depends on SECURITY_APPARMOR_HASH
default y
help
This option selects whether sha1 hashing of loaded policy
is enabled by default. The generation of sha1 hashes for
loaded policy provide system administrators a quick way
to verify that policy in the kernel matches what is expected,
however it can slow down policy load on some devices. In
these cases policy hashing can be disabled by default and
enabled only if needed.
...@@ -4,11 +4,45 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o ...@@ -4,11 +4,45 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \ apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \ path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
resource.o sid.o file.o resource.o sid.o file.o label.o mount.o net.o af_unix.o \
policy_ns.o
apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
clean-files := capability_names.h rlim_names.h clean-files := capability_names.h rlim_names.h net_names.h
# Build a lower case string table of address family names
# Transform lines from
# define AF_LOCAL 1 /* POSIX name for AF_UNIX */
# #define AF_INET 2 /* Internet IP Protocol */
# to
# [1] = "local",
# [2] = "inet",
#
# and build the securityfs entries for the mapping.
# Transforms lines from
# #define AF_INET 2 /* Internet IP Protocol */
# to
# #define AA_FS_AF_MASK "local inet"
quiet_cmd_make-af = GEN $@
cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \
's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
echo "};" >> $@ ;\
echo -n '\#define AA_FS_AF_MASK "' >> $@ ;\
sed -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \
's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\
$< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
# Build a lower case string table of sock type names
# Transform lines from
# SOCK_STREAM = 1,
# to
# [1] = "stream",
quiet_cmd_make-sock = GEN $@
cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\
sed $^ >>$@ -r -n \
-e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
echo "};" >> $@
# Build a lower case string table of capability names # Build a lower case string table of capability names
# Transforms lines from # Transforms lines from
...@@ -61,6 +95,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \ ...@@ -61,6 +95,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
$(obj)/capability.o : $(obj)/capability_names.h $(obj)/capability.o : $(obj)/capability_names.h
$(obj)/net.o : $(obj)/net_names.h
$(obj)/resource.o : $(obj)/rlim_names.h $(obj)/resource.o : $(obj)/rlim_names.h
$(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
$(src)/Makefile $(src)/Makefile
...@@ -68,3 +103,8 @@ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \ ...@@ -68,3 +103,8 @@ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
$(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \ $(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
$(src)/Makefile $(src)/Makefile
$(call cmd,make-rlim) $(call cmd,make-rlim)
$(obj)/net_names.h : $(srctree)/include/linux/socket.h \
$(srctree)/include/linux/net.h \
$(src)/Makefile
$(call cmd,make-af)
$(call cmd,make-sock)
This diff is collapsed.
This diff is collapsed.
...@@ -18,60 +18,8 @@ ...@@ -18,60 +18,8 @@
#include "include/apparmor.h" #include "include/apparmor.h"
#include "include/audit.h" #include "include/audit.h"
#include "include/policy.h" #include "include/policy.h"
#include "include/policy_ns.h"
const char *const op_table[] = {
"null",
"sysctl",
"capable",
"unlink",
"mkdir",
"rmdir",
"mknod",
"truncate",
"link",
"symlink",
"rename_src",
"rename_dest",
"chmod",
"chown",
"getattr",
"open",
"file_perm",
"file_lock",
"file_mmap",
"file_mprotect",
"create",
"post_create",
"bind",
"connect",
"listen",
"accept",
"sendmsg",
"recvmsg",
"getsockname",
"getpeername",
"getsockopt",
"setsockopt",
"socket_shutdown",
"ptrace",
"exec",
"change_hat",
"change_profile",
"change_onexec",
"setprocattr",
"setrlimit",
"profile_replace",
"profile_load",
"profile_remove"
};
const char *const audit_mode_names[] = { const char *const audit_mode_names[] = {
"normal", "normal",
...@@ -114,34 +62,42 @@ static void audit_pre(struct audit_buffer *ab, void *ca) ...@@ -114,34 +62,42 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
if (aa_g_audit_header) { if (aa_g_audit_header) {
audit_log_format(ab, "apparmor="); audit_log_format(ab, "apparmor=");
audit_log_string(ab, aa_audit_type[sa->aad->type]); audit_log_string(ab, aa_audit_type[aad(sa)->type]);
} }
if (sa->aad->op) { if (aad(sa)->op) {
audit_log_format(ab, " operation="); audit_log_format(ab, " operation=");
audit_log_string(ab, op_table[sa->aad->op]); audit_log_string(ab, aad(sa)->op);
} }
if (sa->aad->info) { if (aad(sa)->info) {
audit_log_format(ab, " info="); audit_log_format(ab, " info=");
audit_log_string(ab, sa->aad->info); audit_log_string(ab, aad(sa)->info);
if (sa->aad->error) if (aad(sa)->error)
audit_log_format(ab, " error=%d", sa->aad->error); audit_log_format(ab, " error=%d", aad(sa)->error);
} }
if (sa->aad->profile) { if (aad(sa)->label) {
struct aa_profile *profile = sa->aad->profile; struct aa_label *label = aad(sa)->label;
if (label_isprofile(label)) {
struct aa_profile *profile = labels_profile(label);
if (profile->ns != root_ns) { if (profile->ns != root_ns) {
audit_log_format(ab, " namespace="); audit_log_format(ab, " namespace=");
audit_log_untrustedstring(ab, profile->ns->base.hname); audit_log_untrustedstring(ab,
profile->ns->base.hname);
} }
audit_log_format(ab, " profile="); audit_log_format(ab, " profile=");
audit_log_untrustedstring(ab, profile->base.hname); audit_log_untrustedstring(ab, profile->base.hname);
} else {
audit_log_format(ab, " label=");
aa_label_xaudit(ab, root_ns, label, FLAG_VIEW_SUBNS,
GFP_ATOMIC);
}
} }
if (sa->aad->name) { if (aad(sa)->name) {
audit_log_format(ab, " name="); audit_log_format(ab, " name=");
audit_log_untrustedstring(ab, sa->aad->name); audit_log_untrustedstring(ab, aad(sa)->name);
} }
} }
...@@ -153,7 +109,12 @@ static void audit_pre(struct audit_buffer *ab, void *ca) ...@@ -153,7 +109,12 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
void aa_audit_msg(int type, struct common_audit_data *sa, void aa_audit_msg(int type, struct common_audit_data *sa,
void (*cb) (struct audit_buffer *, void *)) void (*cb) (struct audit_buffer *, void *))
{ {
sa->aad->type = type; /* TODO: redirect messages for profile to the correct ns
* rejects from subns should goto the audit associated
* with it, and audits from parent ns should got ns
* associated with it
*/
aad(sa)->type = type;
common_lsm_audit(sa, audit_pre, cb); common_lsm_audit(sa, audit_pre, cb);
} }
...@@ -161,7 +122,6 @@ void aa_audit_msg(int type, struct common_audit_data *sa, ...@@ -161,7 +122,6 @@ void aa_audit_msg(int type, struct common_audit_data *sa,
* aa_audit - Log a profile based audit event to the audit subsystem * aa_audit - Log a profile based audit event to the audit subsystem
* @type: audit type for the message * @type: audit type for the message
* @profile: profile to check against (NOT NULL) * @profile: profile to check against (NOT NULL)
* @gfp: allocation flags to use
* @sa: audit event (NOT NULL) * @sa: audit event (NOT NULL)
* @cb: optional callback fn for type specific fields (MAYBE NULL) * @cb: optional callback fn for type specific fields (MAYBE NULL)
* *
...@@ -169,14 +129,13 @@ void aa_audit_msg(int type, struct common_audit_data *sa, ...@@ -169,14 +129,13 @@ void aa_audit_msg(int type, struct common_audit_data *sa,
* *
* Returns: error on failure * Returns: error on failure
*/ */
int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
struct common_audit_data *sa,
void (*cb) (struct audit_buffer *, void *)) void (*cb) (struct audit_buffer *, void *))
{ {
BUG_ON(!profile); BUG_ON(!profile);
if (type == AUDIT_APPARMOR_AUTO) { if (type == AUDIT_APPARMOR_AUTO) {
if (likely(!sa->aad->error)) { if (likely(!aad(sa)->error)) {
if (AUDIT_MODE(profile) != AUDIT_ALL) if (AUDIT_MODE(profile) != AUDIT_ALL)
return 0; return 0;
type = AUDIT_APPARMOR_AUDIT; type = AUDIT_APPARMOR_AUDIT;
...@@ -188,22 +147,22 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, ...@@ -188,22 +147,22 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
if (AUDIT_MODE(profile) == AUDIT_QUIET || if (AUDIT_MODE(profile) == AUDIT_QUIET ||
(type == AUDIT_APPARMOR_DENIED && (type == AUDIT_APPARMOR_DENIED &&
AUDIT_MODE(profile) == AUDIT_QUIET)) AUDIT_MODE(profile) == AUDIT_QUIET))
return sa->aad->error; return aad(sa)->error;
if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED) if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
type = AUDIT_APPARMOR_KILL; type = AUDIT_APPARMOR_KILL;
if (!unconfined(profile)) aad(sa)->label = &profile->label;
sa->aad->profile = profile;
aa_audit_msg(type, sa, cb); aa_audit_msg(type, sa, cb);
if (sa->aad->type == AUDIT_APPARMOR_KILL) if (aad(sa)->type == AUDIT_APPARMOR_KILL)
(void)send_sig_info(SIGKILL, NULL, (void)send_sig_info(SIGKILL, NULL,
sa->u.tsk ? sa->u.tsk : current); sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
sa->u.tsk : current);
if (sa->aad->type == AUDIT_APPARMOR_ALLOWED) if (aad(sa)->type == AUDIT_APPARMOR_ALLOWED)
return complain_error(sa->aad->error); return complain_error(aad(sa)->error);
return sa->aad->error; return aad(sa)->error;
} }
...@@ -53,6 +53,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) ...@@ -53,6 +53,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)
/** /**
* audit_caps - audit a capability * audit_caps - audit a capability
* @sa: audit data
* @profile: profile being tested for confinement (NOT NULL) * @profile: profile being tested for confinement (NOT NULL)
* @cap: capability tested * @cap: capability tested
* @error: error code returned by test * @error: error code returned by test
...@@ -62,17 +63,12 @@ static void audit_cb(struct audit_buffer *ab, void *va) ...@@ -62,17 +63,12 @@ static void audit_cb(struct audit_buffer *ab, void *va)
* *
* Returns: 0 or sa->error on success, error code on failure * Returns: 0 or sa->error on success, error code on failure
*/ */
static int audit_caps(struct aa_profile *profile, int cap, int error) static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
int cap, int error)
{ {
struct audit_cache *ent; struct audit_cache *ent;
int type = AUDIT_APPARMOR_AUTO; int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa; aad(sa)->error = error;
struct apparmor_audit_data aad = {0,};
sa.type = LSM_AUDIT_DATA_CAP;
sa.aad = &aad;
sa.u.cap = cap;
sa.aad->op = OP_CAPABLE;
sa.aad->error = error;
if (likely(!error)) { if (likely(!error)) {
/* test if auditing is being forced */ /* test if auditing is being forced */
...@@ -104,24 +100,44 @@ static int audit_caps(struct aa_profile *profile, int cap, int error) ...@@ -104,24 +100,44 @@ static int audit_caps(struct aa_profile *profile, int cap, int error)
} }
put_cpu_var(audit_cache); put_cpu_var(audit_cache);
return aa_audit(type, profile, GFP_ATOMIC, &sa, audit_cb); return aa_audit(type, profile, sa, audit_cb);
} }
/** /**
* profile_capable - test if profile allows use of capability @cap * profile_capable - test if profile allows use of capability @cap
* @profile: profile being enforced (NOT NULL, NOT unconfined) * @profile: profile being enforced (NOT NULL, NOT unconfined)
* @cap: capability to test if allowed * @cap: capability to test if allowed
* @audit: whether an audit record should be generated
* @sa: audit data (MAY BE NULL indicating no auditing)
* *
* Returns: 0 if allowed else -EPERM * Returns: 0 if allowed else -EPERM
*/ */
static int profile_capable(struct aa_profile *profile, int cap) static int profile_capable(struct aa_profile *profile, int cap, int audit,
struct common_audit_data *sa)
{ {
return cap_raised(profile->caps.allow, cap) ? 0 : -EPERM; int error;
if (cap_raised(profile->caps.allow, cap) &&
!cap_raised(profile->caps.denied, cap))
error = 0;
else
error = -EPERM;
if (audit == SECURITY_CAP_NOAUDIT) {
if (!COMPLAIN_MODE(profile))
return error;
/* audit the cap request in complain mode but note that it
* should be optional.
*/
aad(sa)->info = "optional: no audit";
}
return audit_caps(sa, profile, cap, error);
} }
/** /**
* aa_capable - test permission to use capability * aa_capable - test permission to use capability
* @profile: profile being tested against (NOT NULL) * @label: label being tested for capability (NOT NULL)
* @cap: capability to be tested * @cap: capability to be tested
* @audit: whether an audit record should be generated * @audit: whether an audit record should be generated
* *
...@@ -129,15 +145,15 @@ static int profile_capable(struct aa_profile *profile, int cap) ...@@ -129,15 +145,15 @@ static int profile_capable(struct aa_profile *profile, int cap)
* *
* Returns: 0 on success, or else an error code. * Returns: 0 on success, or else an error code.
*/ */
int aa_capable(struct aa_profile *profile, int cap, int audit) int aa_capable(struct aa_label *label, int cap, int audit)
{ {
int error = profile_capable(profile, cap); struct aa_profile *profile;
int error = 0;
DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
sa.u.cap = cap;
if (!audit) { error = fn_for_each_confined(label, profile,
if (COMPLAIN_MODE(profile)) profile_capable(profile, cap, audit, &sa));
return complain_error(error);
return error;
}
return audit_caps(profile, cap, error); return error;
} }
...@@ -13,11 +13,11 @@ ...@@ -13,11 +13,11 @@
* License. * License.
* *
* *
* AppArmor sets confinement on every task, via the the aa_task_cxt and * AppArmor sets confinement on every task, via the the aa_task_ctx and
* the aa_task_cxt.profile, both of which are required and are not allowed * the aa_task_ctx.label, both of which are required and are not allowed
* to be NULL. The aa_task_cxt is not reference counted and is unique * to be NULL. The aa_task_ctx is not reference counted and is unique
* to each cred (which is reference count). The profile pointed to by * to each cred (which is reference count). The label pointed to by
* the task_cxt is reference counted. * the task_ctx is reference counted.
* *
* TODO * TODO
* If a task uses change_hat it currently does not return to the old * If a task uses change_hat it currently does not return to the old
...@@ -30,28 +30,28 @@ ...@@ -30,28 +30,28 @@
#include "include/policy.h" #include "include/policy.h"
/** /**
* aa_alloc_task_context - allocate a new task_cxt * aa_alloc_task_context - allocate a new task_ctx
* @flags: gfp flags for allocation * @flags: gfp flags for allocation
* *
* Returns: allocated buffer or NULL on failure * Returns: allocated buffer or NULL on failure
*/ */
struct aa_task_cxt *aa_alloc_task_context(gfp_t flags) struct aa_task_ctx *aa_alloc_task_context(gfp_t flags)
{ {
return kzalloc(sizeof(struct aa_task_cxt), flags); return kzalloc(sizeof(struct aa_task_ctx), flags);
} }
/** /**
* aa_free_task_context - free a task_cxt * aa_free_task_context - free a task_ctx
* @cxt: task_cxt to free (MAYBE NULL) * @ctx: task_ctx to free (MAYBE NULL)
*/ */
void aa_free_task_context(struct aa_task_cxt *cxt) void aa_free_task_context(struct aa_task_ctx *ctx)
{ {
if (cxt) { if (ctx) {
aa_put_profile(cxt->profile); aa_put_label(ctx->label);
aa_put_profile(cxt->previous); aa_put_label(ctx->previous);
aa_put_profile(cxt->onexec); aa_put_label(ctx->onexec);
kzfree(cxt); kzfree(ctx);
} }
} }
...@@ -60,64 +60,63 @@ void aa_free_task_context(struct aa_task_cxt *cxt) ...@@ -60,64 +60,63 @@ void aa_free_task_context(struct aa_task_cxt *cxt)
* @new: a blank task context (NOT NULL) * @new: a blank task context (NOT NULL)
* @old: the task context to copy (NOT NULL) * @old: the task context to copy (NOT NULL)
*/ */
void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old) void aa_dup_task_context(struct aa_task_ctx *new, const struct aa_task_ctx *old)
{ {
*new = *old; *new = *old;
aa_get_profile(new->profile); aa_get_label(new->label);
aa_get_profile(new->previous); aa_get_label(new->previous);
aa_get_profile(new->onexec); aa_get_label(new->onexec);
} }
/** /**
* aa_get_task_profile - Get another task's profile * aa_get_task_label - Get another task's label
* @task: task to query (NOT NULL) * @task: task to query (NOT NULL)
* *
* Returns: counted reference to @task's profile * Returns: counted reference to @task's label
*/ */
struct aa_profile *aa_get_task_profile(struct task_struct *task) struct aa_label *aa_get_task_label(struct task_struct *task)
{ {
struct aa_profile *p; struct aa_label *p;
rcu_read_lock(); rcu_read_lock();
p = aa_get_profile(__aa_task_profile(task)); p = aa_get_newest_label(__aa_task_raw_label(task));
rcu_read_unlock(); rcu_read_unlock();
return p; return p;
} }
/** /**
* aa_replace_current_profile - replace the current tasks profiles * aa_replace_current_label - replace the current tasks label
* @profile: new profile (NOT NULL) * @label: new label (NOT NULL)
* *
* Returns: 0 or error on failure * Returns: 0 or error on failure
*/ */
int aa_replace_current_profile(struct aa_profile *profile) int aa_replace_current_label(struct aa_label *label)
{ {
struct aa_task_cxt *cxt = current_cxt(); struct aa_task_ctx *ctx = current_ctx();
struct cred *new; struct cred *new;
BUG_ON(!profile); BUG_ON(!label);
if (cxt->profile == profile) if (ctx->label == label)
return 0; return 0;
if (current_cred() != current_real_cred())
return -EBUSY;
new = prepare_creds(); new = prepare_creds();
if (!new) if (!new)
return -ENOMEM; return -ENOMEM;
cxt = cred_cxt(new); ctx = cred_ctx(new);
if (unconfined(profile) || (cxt->profile->ns != profile->ns)) if (unconfined(label) || (labels_ns(ctx->label) != labels_ns(label)))
/* if switching to unconfined or a different profile namespace /* if switching to unconfined or a different label namespace
* clear out context state * clear out context state
*/ */
aa_clear_task_cxt_trans(cxt); aa_clear_task_ctx_trans(ctx);
/* be careful switching cxt->profile, when racing replacement it aa_get_label(label);
* is possible that cxt->profile->replacedby->profile is the reference aa_put_label(ctx->label);
* keeping @profile valid, so make sure to get its reference before ctx->label = label;
* dropping the reference on cxt->profile */
aa_get_profile(profile);
aa_put_profile(cxt->profile);
cxt->profile = profile;
commit_creds(new); commit_creds(new);
return 0; return 0;
...@@ -125,21 +124,22 @@ int aa_replace_current_profile(struct aa_profile *profile) ...@@ -125,21 +124,22 @@ int aa_replace_current_profile(struct aa_profile *profile)
/** /**
* aa_set_current_onexec - set the tasks change_profile to happen onexec * aa_set_current_onexec - set the tasks change_profile to happen onexec
* @profile: system profile to set at exec (MAYBE NULL to clear value) * @label: system label to set at exec (MAYBE NULL to clear value)
* * @stack: whether stacking should be done
* Returns: 0 or error on failure * Returns: 0 or error on failure
*/ */
int aa_set_current_onexec(struct aa_profile *profile) int aa_set_current_onexec(struct aa_label *label, bool stack)
{ {
struct aa_task_cxt *cxt; struct aa_task_ctx *ctx;
struct cred *new = prepare_creds(); struct cred *new = prepare_creds();
if (!new) if (!new)
return -ENOMEM; return -ENOMEM;
cxt = cred_cxt(new); ctx = cred_ctx(new);
aa_get_profile(profile); aa_get_label(label);
aa_put_profile(cxt->onexec); aa_clear_task_ctx_trans(ctx);
cxt->onexec = profile; ctx->onexec = label;
ctx->token = stack;
commit_creds(new); commit_creds(new);
return 0; return 0;
...@@ -147,7 +147,7 @@ int aa_set_current_onexec(struct aa_profile *profile) ...@@ -147,7 +147,7 @@ int aa_set_current_onexec(struct aa_profile *profile)
/** /**
* aa_set_current_hat - set the current tasks hat * aa_set_current_hat - set the current tasks hat
* @profile: profile to set as the current hat (NOT NULL) * @label: label to set as the current hat (NOT NULL)
* @token: token value that must be specified to change from the hat * @token: token value that must be specified to change from the hat
* *
* Do switch of tasks hat. If the task is currently in a hat * Do switch of tasks hat. If the task is currently in a hat
...@@ -155,67 +155,67 @@ int aa_set_current_onexec(struct aa_profile *profile) ...@@ -155,67 +155,67 @@ int aa_set_current_onexec(struct aa_profile *profile)
* *
* Returns: 0 or error on failure * Returns: 0 or error on failure
*/ */
int aa_set_current_hat(struct aa_profile *profile, u64 token) int aa_set_current_hat(struct aa_label *label, u64 token)
{ {
struct aa_task_cxt *cxt; struct aa_task_ctx *ctx;
struct cred *new = prepare_creds(); struct cred *new = prepare_creds();
if (!new) if (!new)
return -ENOMEM; return -ENOMEM;
BUG_ON(!profile); BUG_ON(!label);
cxt = cred_cxt(new); ctx = cred_ctx(new);
if (!cxt->previous) { if (!ctx->previous) {
/* transfer refcount */ /* transfer refcount */
cxt->previous = cxt->profile; ctx->previous = ctx->label;
cxt->token = token; ctx->token = token;
} else if (cxt->token == token) { } else if (ctx->token == token) {
aa_put_profile(cxt->profile); aa_put_label(ctx->label);
} else { } else {
/* previous_profile && cxt->token != token */ /* previous_profile && ctx->token != token */
abort_creds(new); abort_creds(new);
return -EACCES; return -EACCES;
} }
cxt->profile = aa_get_newest_profile(profile); ctx->label = aa_get_newest_label(label);
/* clear exec on switching context */ /* clear exec on switching context */
aa_put_profile(cxt->onexec); aa_put_label(ctx->onexec);
cxt->onexec = NULL; ctx->onexec = NULL;
commit_creds(new); commit_creds(new);
return 0; return 0;
} }
/** /**
* aa_restore_previous_profile - exit from hat context restoring the profile * aa_restore_previous_label - exit from hat context restoring previous label
* @token: the token that must be matched to exit hat context * @token: the token that must be matched to exit hat context
* *
* Attempt to return out of a hat to the previous profile. The token * Attempt to return out of a hat to the previous label. The token
* must match the stored token value. * must match the stored token value.
* *
* Returns: 0 or error of failure * Returns: 0 or error of failure
*/ */
int aa_restore_previous_profile(u64 token) int aa_restore_previous_label(u64 token)
{ {
struct aa_task_cxt *cxt; struct aa_task_ctx *ctx;
struct cred *new = prepare_creds(); struct cred *new = prepare_creds();
if (!new) if (!new)
return -ENOMEM; return -ENOMEM;
cxt = cred_cxt(new); ctx = cred_ctx(new);
if (cxt->token != token) { if (ctx->token != token) {
abort_creds(new); abort_creds(new);
return -EACCES; return -EACCES;
} }
/* ignore restores when there is no saved profile */ /* ignore restores when there is no saved label */
if (!cxt->previous) { if (!ctx->previous) {
abort_creds(new); abort_creds(new);
return 0; return 0;
} }
aa_put_profile(cxt->profile); aa_put_label(ctx->label);
cxt->profile = aa_get_newest_profile(cxt->previous); ctx->label = aa_get_newest_label(ctx->previous);
BUG_ON(!cxt->profile); BUG_ON(!ctx->label);
/* clear exec && prev information when restoring to previous context */ /* clear exec && prev information when restoring to previous context */
aa_clear_task_cxt_trans(cxt); aa_clear_task_ctx_trans(ctx);
commit_creds(new); commit_creds(new);
return 0; return 0;
......
This diff is collapsed.
This diff is collapsed.
/*
* AppArmor security module
*
* This file contains AppArmor af_unix fine grained mediation
*
* Copyright 2014 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#ifndef __AA_AF_UNIX_H
#include <net/af_unix.h>
#include "label.h"
//#include "include/net.h"
#define unix_addr_len(L) ((L) - sizeof(sa_family_t))
#define unix_abstract_name_len(L) (unix_addr_len(L) - 1)
#define unix_abstract_len(U) (unix_abstract_name_len((U)->addr->len))
#define addr_unix_abstract_name(B) ((B)[0] == 0)
#define addr_unix_anonymous(U) (addr_unix_len(U) <= 0)
#define addr_unix_abstract(U) (!addr_unix_anonymous(U) && addr_unix_abstract_name((U)->addr))
//#define unix_addr_fs(U) (!unix_addr_anonymous(U) && !unix_addr_abstract_name((U)->addr))
#define unix_addr(A) ((struct sockaddr_un *)(A))
#define unix_addr_anon(A, L) ((A) && unix_addr_len(L) <= 0)
#define unix_addr_fs(A, L) (!unix_addr_anon(A, L) && !addr_unix_abstract_name(unix_addr(A)->sun_path))
#define UNIX_ANONYMOUS(U) (!unix_sk(U)->addr)
/* from net/unix/af_unix.c */
#define UNIX_ABSTRACT(U) (!UNIX_ANONYMOUS(U) && \
unix_sk(U)->addr->hash < UNIX_HASH_SIZE)
#define UNIX_FS(U) (!UNIX_ANONYMOUS(U) && unix_sk(U)->addr->name->sun_path[0])
#define unix_peer(sk) (unix_sk(sk)->peer)
#define unix_connected(S) ((S)->state == SS_CONNECTED)
static inline void print_unix_addr(struct sockaddr_un *A, int L)
{
char *buf = (A) ? (char *) &(A)->sun_path : NULL;
int len = unix_addr_len(L);
if (!buf || len <= 0)
printk(" <anonymous>");
else if (buf[0])
printk(" %s", buf);
else
/* abstract name len includes leading \0 */
printk(" %d @%.*s", len - 1, len - 1, buf+1);
};
/*
printk("%s: %s: f %d, t %d, p %d", __FUNCTION__, \
#SK , \
*/
#define print_unix_sk(SK) \
do { \
struct unix_sock *u = unix_sk(SK); \
printk("%s: f %d, t %d, p %d", #SK , \
(SK)->sk_family, (SK)->sk_type, (SK)->sk_protocol); \
if (u->addr) \
print_unix_addr(u->addr->name, u->addr->len); \
else \
print_unix_addr(NULL, sizeof(sa_family_t)); \
/* printk("\n");*/ \
} while (0)
#define print_sk(SK) \
do { \
if (!(SK)) { \
printk("%s: %s is null\n", __FUNCTION__, #SK); \
} else if ((SK)->sk_family == PF_UNIX) { \
print_unix_sk(SK); \
printk("\n"); \
} else { \
printk("%s: %s: family %d\n", __FUNCTION__, #SK , \
(SK)->sk_family); \
} \
} while (0)
#define print_sock_addr(U) \
do { \
printk("%s:\n", __FUNCTION__); \
printk(" sock %s:", sock_ctx && sock_ctx->label ? aa_label_printk(sock_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(sock); \
printk(" other %s:", other_ctx && other_ctx->label ? aa_label_printk(other_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(other); \
printk(" new %s", new_ctx && new_ctx->label ? aa_label_printk(new_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(newsk); \
} while (0)
int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request,
struct sock *sk, struct sock *peer_sk,
struct aa_label *peer_label);
int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
struct sock *sk);
int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock);
int aa_unix_create_perm(struct aa_label *label, int family, int type,
int protocol);
int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
int addrlen);
int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
int addrlen);
int aa_unix_listen_perm(struct socket *sock, int backlog);
int aa_unix_accept_perm(struct socket *sock, struct socket *newsock);
int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
struct msghdr *msg, int size);
int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
int optname);
int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
struct socket *sock);
#endif /* __AA_AF_UNIX_H */
/* /*
* AppArmor security module * AppArmor security module
* *
* This file contains AppArmor basic global and lib definitions * This file contains AppArmor basic global
* *
* Copyright (C) 1998-2008 Novell/SUSE * Copyright (C) 1998-2008 Novell/SUSE
* Copyright 2009-2010 Canonical Ltd. * Copyright 2009-2016 Canonical Ltd.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -15,10 +15,7 @@ ...@@ -15,10 +15,7 @@
#ifndef __APPARMOR_H #ifndef __APPARMOR_H
#define __APPARMOR_H #define __APPARMOR_H
#include <linux/slab.h> #include <linux/types.h>
#include <linux/fs.h>
#include "match.h"
/* /*
* Class of mediation types in the AppArmor policy db * Class of mediation types in the AppArmor policy db
...@@ -30,91 +27,22 @@ ...@@ -30,91 +27,22 @@
#define AA_CLASS_NET 4 #define AA_CLASS_NET 4
#define AA_CLASS_RLIMITS 5 #define AA_CLASS_RLIMITS 5
#define AA_CLASS_DOMAIN 6 #define AA_CLASS_DOMAIN 6
#define AA_CLASS_MOUNT 7
#define AA_CLASS_PTRACE 9
#define AA_CLASS_SIGNAL 10
#define AA_CLASS_LABEL 16
#define AA_CLASS_LAST AA_CLASS_DOMAIN #define AA_CLASS_LAST AA_CLASS_LABEL
/* Control parameters settable through module/boot flags */ /* Control parameters settable through module/boot flags */
extern enum audit_mode aa_g_audit; extern enum audit_mode aa_g_audit;
extern bool aa_g_audit_header; extern bool aa_g_audit_header;
extern bool aa_g_debug; extern bool aa_g_debug;
extern bool aa_g_hash_policy;
extern bool aa_g_lock_policy; extern bool aa_g_lock_policy;
extern bool aa_g_logsyscall; extern bool aa_g_logsyscall;
extern bool aa_g_paranoid_load; extern bool aa_g_paranoid_load;
extern unsigned int aa_g_path_max; extern unsigned int aa_g_path_max;
extern bool aa_g_unconfined_init;
/*
* DEBUG remains global (no per profile flag) since it is mostly used in sysctl
* which is not related to profile accesses.
*/
#define AA_DEBUG(fmt, args...) \
do { \
if (aa_g_debug && printk_ratelimit()) \
printk(KERN_DEBUG "AppArmor: " fmt, ##args); \
} while (0)
#define AA_ERROR(fmt, args...) \
do { \
if (printk_ratelimit()) \
printk(KERN_ERR "AppArmor: " fmt, ##args); \
} while (0)
/* Flag indicating whether initialization completed */
extern int apparmor_initialized __initdata;
/* fn's in lib */
char *aa_split_fqname(char *args, char **ns_name);
void aa_info_message(const char *str);
void *__aa_kvmalloc(size_t size, gfp_t flags);
static inline void *kvmalloc(size_t size)
{
return __aa_kvmalloc(size, 0);
}
static inline void *kvzalloc(size_t size)
{
return __aa_kvmalloc(size, __GFP_ZERO);
}
/* returns 0 if kref not incremented */
static inline int kref_get_not0(struct kref *kref)
{
return atomic_inc_not_zero(&kref->refcount);
}
/**
* aa_strneq - compare null terminated @str to a non null terminated substring
* @str: a null terminated string
* @sub: a substring, not necessarily null terminated
* @len: length of @sub to compare
*
* The @str string must be full consumed for this to be considered a match
*/
static inline bool aa_strneq(const char *str, const char *sub, int len)
{
return !strncmp(str, sub, len) && !str[len];
}
/**
* aa_dfa_null_transition - step to next state after null character
* @dfa: the dfa to match against
* @start: the state of the dfa to start matching in
*
* aa_dfa_null_transition transitions to the next state after a null
* character which is not used in standard matching and is only
* used to separate pairs.
*/
static inline unsigned int aa_dfa_null_transition(struct aa_dfa *dfa,
unsigned int start)
{
/* the null transition only needs the string's null terminator byte */
return aa_dfa_next(dfa, start, 0);
}
static inline bool mediated_filesystem(struct dentry *dentry)
{
return !(dentry->d_sb->s_flags & MS_NOUSER);
}
#endif /* __APPARMOR_H */ #endif /* __APPARMOR_H */
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#ifndef __AA_APPARMORFS_H #ifndef __AA_APPARMORFS_H
#define __AA_APPARMORFS_H #define __AA_APPARMORFS_H
extern struct path aa_null;
enum aa_fs_type { enum aa_fs_type {
AA_FS_TYPE_BOOLEAN, AA_FS_TYPE_BOOLEAN,
AA_FS_TYPE_STRING, AA_FS_TYPE_STRING,
...@@ -62,7 +64,7 @@ extern const struct file_operations aa_fs_seq_file_ops; ...@@ -62,7 +64,7 @@ extern const struct file_operations aa_fs_seq_file_ops;
extern void __init aa_destroy_aafs(void); extern void __init aa_destroy_aafs(void);
struct aa_profile; struct aa_profile;
struct aa_namespace; struct aa_ns;
enum aafs_ns_type { enum aafs_ns_type {
AAFS_NS_DIR, AAFS_NS_DIR,
...@@ -97,8 +99,7 @@ void __aa_fs_profile_rmdir(struct aa_profile *profile); ...@@ -97,8 +99,7 @@ void __aa_fs_profile_rmdir(struct aa_profile *profile);
void __aa_fs_profile_migrate_dents(struct aa_profile *old, void __aa_fs_profile_migrate_dents(struct aa_profile *old,
struct aa_profile *new); struct aa_profile *new);
int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent); int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent);
void __aa_fs_namespace_rmdir(struct aa_namespace *ns); void __aa_fs_ns_rmdir(struct aa_ns *ns);
int __aa_fs_namespace_mkdir(struct aa_namespace *ns, struct dentry *parent, int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name);
const char *name);
#endif /* __AA_APPARMORFS_H */ #endif /* __AA_APPARMORFS_H */
This diff is collapsed.
...@@ -19,11 +19,12 @@ ...@@ -19,11 +19,12 @@
#include "apparmorfs.h" #include "apparmorfs.h"
struct aa_profile; struct aa_label;
/* aa_caps - confinement data for capabilities /* aa_caps - confinement data for capabilities
* @allowed: capabilities mask * @allowed: capabilities mask
* @audit: caps that are to be audited * @audit: caps that are to be audited
* @denied: caps that are explicitly denied
* @quiet: caps that should not be audited * @quiet: caps that should not be audited
* @kill: caps that when requested will result in the task being killed * @kill: caps that when requested will result in the task being killed
* @extended: caps that are subject finer grained mediation * @extended: caps that are subject finer grained mediation
...@@ -31,6 +32,7 @@ struct aa_profile; ...@@ -31,6 +32,7 @@ struct aa_profile;
struct aa_caps { struct aa_caps {
kernel_cap_t allow; kernel_cap_t allow;
kernel_cap_t audit; kernel_cap_t audit;
kernel_cap_t denied;
kernel_cap_t quiet; kernel_cap_t quiet;
kernel_cap_t kill; kernel_cap_t kill;
kernel_cap_t extended; kernel_cap_t extended;
...@@ -38,7 +40,7 @@ struct aa_caps { ...@@ -38,7 +40,7 @@ struct aa_caps {
extern struct aa_fs_entry aa_fs_entry_caps[]; extern struct aa_fs_entry aa_fs_entry_caps[];
int aa_capable(struct aa_profile *profile, int cap, int audit); int aa_capable(struct aa_label *label, int cap, int audit);
static inline void aa_free_cap_rules(struct aa_caps *caps) static inline void aa_free_cap_rules(struct aa_caps *caps)
{ {
......
This diff is collapsed.
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/types.h> #include <linux/types.h>
#include "include/label.h"
#ifndef __AA_DOMAIN_H #ifndef __AA_DOMAIN_H
#define __AA_DOMAIN_H #define __AA_DOMAIN_H
...@@ -23,6 +25,9 @@ struct aa_domain { ...@@ -23,6 +25,9 @@ struct aa_domain {
char **table; char **table;
}; };
struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
const char **name);
int apparmor_bprm_set_creds(struct linux_binprm *bprm); int apparmor_bprm_set_creds(struct linux_binprm *bprm);
int apparmor_bprm_secureexec(struct linux_binprm *bprm); int apparmor_bprm_secureexec(struct linux_binprm *bprm);
void apparmor_bprm_committing_creds(struct linux_binprm *bprm); void apparmor_bprm_committing_creds(struct linux_binprm *bprm);
...@@ -30,7 +35,7 @@ void apparmor_bprm_committed_creds(struct linux_binprm *bprm); ...@@ -30,7 +35,7 @@ void apparmor_bprm_committed_creds(struct linux_binprm *bprm);
void aa_free_domain_entries(struct aa_domain *domain); void aa_free_domain_entries(struct aa_domain *domain);
int aa_change_hat(const char *hats[], int count, u64 token, bool permtest); int aa_change_hat(const char *hats[], int count, u64 token, bool permtest);
int aa_change_profile(const char *ns_name, const char *name, bool onexec, int aa_change_profile(const char *fqname, bool onexec, bool permtest,
bool permtest); bool stack);
#endif /* __AA_DOMAIN_H */ #endif /* __AA_DOMAIN_H */
This diff is collapsed.
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This file contains AppArmor ipc mediation function definitions. * This file contains AppArmor ipc mediation function definitions.
* *
* Copyright (C) 1998-2008 Novell/SUSE * Copyright (C) 1998-2008 Novell/SUSE
* Copyright 2009-2010 Canonical Ltd. * Copyright 2009-2013 Canonical Ltd.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -19,10 +19,22 @@ ...@@ -19,10 +19,22 @@
struct aa_profile; struct aa_profile;
int aa_may_ptrace(struct aa_profile *tracer, struct aa_profile *tracee, #define AA_PTRACE_TRACE MAY_WRITE
unsigned int mode); #define AA_PTRACE_READ MAY_READ
#define AA_MAY_BE_TRACED AA_MAY_APPEND
#define AA_MAY_BE_READ AA_MAY_CREATE
#define PTRACE_PERM_SHIFT 2
int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee, #define AA_PTRACE_PERM_MASK (AA_PTRACE_READ | AA_PTRACE_TRACE | \
unsigned int mode); AA_MAY_BE_READ | AA_MAY_BE_TRACED)
#define AA_SIGNAL_PERM_MASK (MAY_READ | MAY_WRITE)
#define AA_FS_SIG_MASK "hup int quit ill trap abrt bus fpe kill usr1 " \
"segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg " \
"xcpu xfsz vtalrm prof winch io pwr sys emt lost"
int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
u32 request);
int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig);
#endif /* __AA_IPC_H */ #endif /* __AA_IPC_H */
This diff is collapsed.
This diff is collapsed.
...@@ -99,6 +99,8 @@ struct aa_dfa { ...@@ -99,6 +99,8 @@ struct aa_dfa {
struct table_header *tables[YYTD_ID_TSIZE]; struct table_header *tables[YYTD_ID_TSIZE];
}; };
extern struct aa_dfa *nulldfa;
#define byte_to_byte(X) (X) #define byte_to_byte(X) (X)
#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \ #define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \
...@@ -116,6 +118,9 @@ static inline size_t table_size(size_t len, size_t el_size) ...@@ -116,6 +118,9 @@ static inline size_t table_size(size_t len, size_t el_size)
return ALIGN(sizeof(struct table_header) + len * el_size, 8); return ALIGN(sizeof(struct table_header) + len * el_size, 8);
} }
int aa_setup_dfa_engine(void);
void aa_teardown_dfa_engine(void);
struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags); struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags);
unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start, unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
const char *str, int len); const char *str, int len);
...@@ -126,6 +131,21 @@ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, ...@@ -126,6 +131,21 @@ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
void aa_dfa_free_kref(struct kref *kref); void aa_dfa_free_kref(struct kref *kref);
/**
* aa_get_dfa - increment refcount on dfa @p
* @dfa: dfa (MAYBE NULL)
*
* Returns: pointer to @dfa if @dfa is NULL will return NULL
* Requires: @dfa must be held with valid refcount when called
*/
static inline struct aa_dfa *aa_get_dfa(struct aa_dfa *dfa)
{
if (dfa)
kref_get(&(dfa->count));
return dfa;
}
/** /**
* aa_put_dfa - put a dfa refcount * aa_put_dfa - put a dfa refcount
* @dfa: dfa to put refcount (MAYBE NULL) * @dfa: dfa to put refcount (MAYBE NULL)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -22,6 +22,7 @@ struct aa_load_ent { ...@@ -22,6 +22,7 @@ struct aa_load_ent {
struct aa_profile *new; struct aa_profile *new;
struct aa_profile *old; struct aa_profile *old;
struct aa_profile *rename; struct aa_profile *rename;
const char *ns_name;
}; };
void aa_load_ent_free(struct aa_load_ent *ent); void aa_load_ent_free(struct aa_load_ent *ent);
......
...@@ -18,8 +18,7 @@ ...@@ -18,8 +18,7 @@
#define AA_DO_TEST 1 #define AA_DO_TEST 1
#define AA_ONEXEC 1 #define AA_ONEXEC 1
int aa_getprocattr(struct aa_profile *profile, char **string); int aa_getprocattr(struct aa_label *label, char **string);
int aa_setprocattr_changehat(char *args, size_t size, int test); int aa_setprocattr_changehat(char *args, size_t size, int test);
int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test);
#endif /* __AA_PROCATTR_H */ #endif /* __AA_PROCATTR_H */
...@@ -37,10 +37,10 @@ struct aa_rlimit { ...@@ -37,10 +37,10 @@ struct aa_rlimit {
extern struct aa_fs_entry aa_fs_entry_rlimit[]; extern struct aa_fs_entry aa_fs_entry_rlimit[];
int aa_map_resource(int resource); int aa_map_resource(int resource);
int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *, int aa_task_setrlimit(struct aa_label *label, struct task_struct *,
unsigned int resource, struct rlimit *new_rlim); unsigned int resource, struct rlimit *new_rlim);
void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new); void __aa_transition_rlimits(struct aa_label *old, struct aa_label *new);
static inline void aa_free_rlimit_rules(struct aa_rlimit *rlims) static inline void aa_free_rlimit_rules(struct aa_rlimit *rlims)
{ {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
0x1B, 0x5E, 0x78, 0x3D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x04, 0x90, 0x00, 0x00, 0x6E, 0x6F, 0x74, 0x66, 0x6C, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment