- Fix rlimits to work when user space passes in fewer rlimits than the number

of rlimits supported by the kernel.
- remove hat rules
- add hat flag for each profile
- fix apparmorfs profile listing code.  Used to only return the first
  80 or so profiles, and then refuse to output more
This commit is contained in:
John Johansen 2008-06-09 10:12:23 +00:00
parent 8f13e0d60d
commit 303721fca2
3 changed files with 61 additions and 50 deletions

View file

@ -7,12 +7,12 @@ Signed-off-by: John Johansen <jjohansen@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
---
security/apparmor/main.c | 1479 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1479 insertions(+)
security/apparmor/main.c | 1471 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1471 insertions(+)
--- /dev/null
+++ b/security/apparmor/main.c
@@ -0,0 +1,1479 @@
@@ -0,0 +1,1471 @@
+/*
+ * Copyright (C) 2002-2007 Novell/SUSE
+ *
@ -1333,14 +1333,6 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
+
+ if (hat_name) {
+ char *name, *profile_name;
+ if (!PROFILE_COMPLAIN(profile) &&
+ !(aa_match(profile->file_rules, hat_name, NULL)
+ & AA_CHANGE_HAT)) {
+ /* missing permission to change_hat is treated the
+ * same as a failed hat search */
+ error = -ENOENT;
+ goto out;
+ }
+
+ if (previous_profile)
+ profile_name = previous_profile->name;

View file

@ -13,13 +13,13 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
---
security/apparmor/Kconfig | 42 ++++
security/apparmor/Makefile | 13 +
security/apparmor/apparmor.h | 367 +++++++++++++++++++++++++++++++++++++++++
security/apparmor/apparmor.h | 368 +++++++++++++++++++++++++++++++++++++++++
security/apparmor/apparmorfs.c | 280 +++++++++++++++++++++++++++++++
security/apparmor/inline.h | 250 +++++++++++++++++++++++++++
security/apparmor/list.c | 156 +++++++++++++++++
security/apparmor/list.c | 174 +++++++++++++++++++
security/apparmor/locking.txt | 68 +++++++
security/apparmor/procattr.c | 195 +++++++++++++++++++++
8 files changed, 1371 insertions(+)
8 files changed, 1390 insertions(+)
--- /dev/null
+++ b/security/apparmor/Kconfig
@ -84,7 +84,7 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
+ $(call cmd,make-caps)
--- /dev/null
+++ b/security/apparmor/apparmor.h
@@ -0,0 +1,367 @@
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 1998-2007 Novell/SUSE
+ *
@ -281,6 +281,7 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
+ char **exec_table;
+ struct aa_dfa *file_rules;
+ struct {
+ int hat;
+ int complain;
+ int audit;
+ } flags;
@ -990,7 +991,7 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
+#endif /* __INLINE_H__ */
--- /dev/null
+++ b/security/apparmor/list.c
@@ -0,0 +1,156 @@
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 1998-2007 Novell/SUSE
+ *
@ -1084,15 +1085,18 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
+ write_unlock(&profile_ns_list_lock);
+}
+
+static void *p_start(struct seq_file *f, loff_t *pos)
+
+static struct aa_profile *next_profile(struct aa_profile *profile)
+{
+ struct aa_profile *next = profile;
+ struct aa_namespace *ns;
+ struct aa_profile *profile;
+ loff_t l = *pos;
+ read_lock(&profile_ns_list_lock);
+ if (l--)
+ return NULL;
+ list_for_each_entry(ns, &profile_ns_list, list) {
+
+ list_for_each_entry_continue(next, &profile->ns->profiles, list)
+ return next;
+
+ ns = profile->ns;
+ read_unlock(&ns->lock);
+ list_for_each_entry_continue(ns, &profile_ns_list, list) {
+ read_lock(&ns->lock);
+ list_for_each_entry(profile, &ns->profiles, list)
+ return profile;
@ -1101,36 +1105,51 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
+ return NULL;
+}
+
+static void *p_start(struct seq_file *f, loff_t *pos)
+{
+ struct aa_namespace *ns;
+ loff_t l = *pos;
+
+ read_lock(&profile_ns_list_lock);
+ if (!list_empty(&profile_ns_list)) {
+ struct aa_profile *profile = NULL;
+ ns = list_first_entry(&profile_ns_list, typeof(*ns), list);
+ read_lock(&ns->lock);
+ if (!list_empty(&ns->profiles))
+ profile = list_first_entry(&ns->profiles,
+ typeof(*profile), list);
+ else
+ read_unlock(&ns->lock);
+ for ( ; profile && l > 0; l--)
+ profile = next_profile(profile);
+ return profile;
+ }
+ return NULL;
+}
+
+static void *p_next(struct seq_file *f, void *p, loff_t *pos)
+{
+ struct aa_profile *profile = (struct aa_profile *) p;
+ struct list_head *lh = profile->list.next;
+ struct aa_namespace *ns;
+ (*pos)++;
+ if (lh != &profile->ns->profiles)
+ return list_entry(lh, struct aa_profile, list);
+
+ lh = profile->ns->list.next;
+ read_unlock(&profile->ns->lock);
+ while (lh != &profile_ns_list) {
+ ns = list_entry(lh, struct aa_namespace, list);
+ read_lock(&ns->lock);
+ list_for_each_entry(profile, &ns->profiles, list)
+ (*pos)++;
+ profile = next_profile(profile);
+
+ return profile;
+ read_unlock(&ns->lock);
+ lh = ns->list.next;
+ }
+ return NULL;
+}
+
+static void p_stop(struct seq_file *f, void *v)
+static void p_stop(struct seq_file *f, void *p)
+{
+ struct aa_profile *profile = (struct aa_profile *) p;
+
+ if (profile)
+ read_unlock(&profile->ns->lock);
+ read_unlock(&profile_ns_list_lock);
+}
+
+static int seq_show_profile(struct seq_file *f, void *v)
+static int seq_show_profile(struct seq_file *f, void *p)
+{
+ struct aa_profile *profile = (struct aa_profile *)v;
+ struct aa_profile *profile = (struct aa_profile *)p;
+
+ if (profile->ns == default_namespace)
+ seq_printf(f, "%s (%s)\n", profile->name,
+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce");

View file

@ -64,7 +64,7 @@ linux limitations.
* @count: reference count of the profile
* @task_contexts: list of tasks confined by profile
* @lock: lock for the task_contexts list
@@ -206,6 +221,9 @@ struct aa_profile {
@@ -207,6 +222,9 @@ struct aa_profile {
kernel_cap_t audit_caps;
kernel_cap_t quiet_caps;
@ -74,7 +74,7 @@ linux limitations.
struct kref count;
struct list_head task_contexts;
spinlock_t lock;
@@ -257,6 +275,7 @@ struct aa_audit {
@@ -258,6 +276,7 @@ struct aa_audit {
const char *name2;
const char *name3;
int request_mask, denied_mask, audit_mask;
@ -82,7 +82,7 @@ linux limitations.
struct iattr *iattr;
pid_t task, parent;
int family, type, protocol;
@@ -324,6 +343,10 @@ extern int aa_may_ptrace(struct aa_task_
@@ -325,6 +344,10 @@ extern int aa_may_ptrace(struct aa_task_
extern int aa_net_perm(struct aa_profile *profile, char *operation,
int family, int type, int protocol);
extern int aa_revalidate_sk(struct sock *sk, char *operation);
@ -300,7 +300,7 @@ linux limitations.
if (new_profile == ns->null_complain_profile)
aa_audit_hint(cxt->profile, sa);
@@ -1482,17 +1578,18 @@ struct aa_profile *__aa_replace_profile(
@@ -1474,17 +1570,18 @@ struct aa_profile *__aa_replace_profile(
cxt = lock_task_and_profiles(task, profile);
if (unlikely(profile && profile->isstale)) {
@ -327,7 +327,7 @@ linux limitations.
}
if (cxt)
@@ -1500,8 +1597,15 @@ struct aa_profile *__aa_replace_profile(
@@ -1492,8 +1589,15 @@ struct aa_profile *__aa_replace_profile(
aa_change_task_context(task, new_cxt, profile, 0, NULL);
task_unlock(task);
@ -343,7 +343,7 @@ linux limitations.
}
/**
@@ -1566,6 +1670,7 @@ void aa_change_task_context(struct task_
@@ -1558,6 +1662,7 @@ void aa_change_task_context(struct task_
if (old_cxt) {
list_del_init(&old_cxt->list);
@ -351,7 +351,7 @@ linux limitations.
call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback);
}
if (new_cxt) {
@@ -1577,6 +1682,7 @@ void aa_change_task_context(struct task_
@@ -1569,6 +1674,7 @@ void aa_change_task_context(struct task_
new_cxt->cookie = cookie;
new_cxt->task = task;
new_cxt->profile = aa_dup_profile(profile);
@ -401,7 +401,7 @@ linux limitations.
+ profile->rlimits.mask = tmp;
+
+ size = aa_is_array(e, NULL);
+ if (size != RLIM_NLIMITS)
+ if (size <= RLIM_NLIMITS)
+ goto fail;
+ for (i = 0; i < size; i++) {
+ u64 tmp = 0;