From 303721fca252c6be49d3084fead764bced2dcf47 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Mon, 9 Jun 2008 10:12:23 +0000 Subject: [PATCH] - 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 --- kernel-patches/2.6.25/apparmor-main.diff | 14 +--- kernel-patches/2.6.25/apparmor-misc.diff | 81 +++++++++++++-------- kernel-patches/2.6.25/apparmor-rlimits.diff | 16 ++-- 3 files changed, 61 insertions(+), 50 deletions(-) diff --git a/kernel-patches/2.6.25/apparmor-main.diff b/kernel-patches/2.6.25/apparmor-main.diff index 3c5f17d0d..34eb8ca2e 100644 --- a/kernel-patches/2.6.25/apparmor-main.diff +++ b/kernel-patches/2.6.25/apparmor-main.diff @@ -7,12 +7,12 @@ Signed-off-by: John Johansen Signed-off-by: Andreas Gruenbacher --- - 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 + + 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; diff --git a/kernel-patches/2.6.25/apparmor-misc.diff b/kernel-patches/2.6.25/apparmor-misc.diff index 34c963b08..55156a418 100644 --- a/kernel-patches/2.6.25/apparmor-misc.diff +++ b/kernel-patches/2.6.25/apparmor-misc.diff @@ -13,13 +13,13 @@ Signed-off-by: Andreas Gruenbacher --- 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 + $(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 + 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 +#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 + 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 + 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) -+ return profile; -+ read_unlock(&ns->lock); -+ lh = ns->list.next; -+ } -+ return NULL; ++ (*pos)++; ++ profile = next_profile(profile); ++ ++ return profile; +} + -+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"); diff --git a/kernel-patches/2.6.25/apparmor-rlimits.diff b/kernel-patches/2.6.25/apparmor-rlimits.diff index 5895479c4..959100fea 100644 --- a/kernel-patches/2.6.25/apparmor-rlimits.diff +++ b/kernel-patches/2.6.25/apparmor-rlimits.diff @@ -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;