mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-31 14:25:52 +00:00
- 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:
@@ -7,12 +7,12 @@ Signed-off-by: John Johansen <jjohansen@suse.de>
|
|||||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||||
|
|
||||||
---
|
---
|
||||||
security/apparmor/main.c | 1479 +++++++++++++++++++++++++++++++++++++++++++++++
|
security/apparmor/main.c | 1471 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
1 file changed, 1479 insertions(+)
|
1 file changed, 1471 insertions(+)
|
||||||
|
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/security/apparmor/main.c
|
+++ b/security/apparmor/main.c
|
||||||
@@ -0,0 +1,1479 @@
|
@@ -0,0 +1,1471 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2002-2007 Novell/SUSE
|
+ * Copyright (C) 2002-2007 Novell/SUSE
|
||||||
+ *
|
+ *
|
||||||
@@ -1333,14 +1333,6 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
|||||||
+
|
+
|
||||||
+ if (hat_name) {
|
+ if (hat_name) {
|
||||||
+ char *name, *profile_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)
|
+ if (previous_profile)
|
||||||
+ profile_name = previous_profile->name;
|
+ profile_name = previous_profile->name;
|
||||||
|
@@ -13,13 +13,13 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
|||||||
---
|
---
|
||||||
security/apparmor/Kconfig | 42 ++++
|
security/apparmor/Kconfig | 42 ++++
|
||||||
security/apparmor/Makefile | 13 +
|
security/apparmor/Makefile | 13 +
|
||||||
security/apparmor/apparmor.h | 367 +++++++++++++++++++++++++++++++++++++++++
|
security/apparmor/apparmor.h | 368 +++++++++++++++++++++++++++++++++++++++++
|
||||||
security/apparmor/apparmorfs.c | 280 +++++++++++++++++++++++++++++++
|
security/apparmor/apparmorfs.c | 280 +++++++++++++++++++++++++++++++
|
||||||
security/apparmor/inline.h | 250 +++++++++++++++++++++++++++
|
security/apparmor/inline.h | 250 +++++++++++++++++++++++++++
|
||||||
security/apparmor/list.c | 156 +++++++++++++++++
|
security/apparmor/list.c | 174 +++++++++++++++++++
|
||||||
security/apparmor/locking.txt | 68 +++++++
|
security/apparmor/locking.txt | 68 +++++++
|
||||||
security/apparmor/procattr.c | 195 +++++++++++++++++++++
|
security/apparmor/procattr.c | 195 +++++++++++++++++++++
|
||||||
8 files changed, 1371 insertions(+)
|
8 files changed, 1390 insertions(+)
|
||||||
|
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/security/apparmor/Kconfig
|
+++ b/security/apparmor/Kconfig
|
||||||
@@ -84,7 +84,7 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
|||||||
+ $(call cmd,make-caps)
|
+ $(call cmd,make-caps)
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/security/apparmor/apparmor.h
|
+++ b/security/apparmor/apparmor.h
|
||||||
@@ -0,0 +1,367 @@
|
@@ -0,0 +1,368 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 1998-2007 Novell/SUSE
|
+ * Copyright (C) 1998-2007 Novell/SUSE
|
||||||
+ *
|
+ *
|
||||||
@@ -281,6 +281,7 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
|||||||
+ char **exec_table;
|
+ char **exec_table;
|
||||||
+ struct aa_dfa *file_rules;
|
+ struct aa_dfa *file_rules;
|
||||||
+ struct {
|
+ struct {
|
||||||
|
+ int hat;
|
||||||
+ int complain;
|
+ int complain;
|
||||||
+ int audit;
|
+ int audit;
|
||||||
+ } flags;
|
+ } flags;
|
||||||
@@ -990,7 +991,7 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
|||||||
+#endif /* __INLINE_H__ */
|
+#endif /* __INLINE_H__ */
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/security/apparmor/list.c
|
+++ b/security/apparmor/list.c
|
||||||
@@ -0,0 +1,156 @@
|
@@ -0,0 +1,174 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 1998-2007 Novell/SUSE
|
+ * Copyright (C) 1998-2007 Novell/SUSE
|
||||||
+ *
|
+ *
|
||||||
@@ -1084,15 +1085,18 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
|||||||
+ write_unlock(&profile_ns_list_lock);
|
+ 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_namespace *ns;
|
||||||
+ struct aa_profile *profile;
|
+
|
||||||
+ loff_t l = *pos;
|
+ list_for_each_entry_continue(next, &profile->ns->profiles, list)
|
||||||
+ read_lock(&profile_ns_list_lock);
|
+ return next;
|
||||||
+ if (l--)
|
+
|
||||||
+ return NULL;
|
+ ns = profile->ns;
|
||||||
+ list_for_each_entry(ns, &profile_ns_list, list) {
|
+ read_unlock(&ns->lock);
|
||||||
|
+ list_for_each_entry_continue(ns, &profile_ns_list, list) {
|
||||||
+ read_lock(&ns->lock);
|
+ read_lock(&ns->lock);
|
||||||
+ list_for_each_entry(profile, &ns->profiles, list)
|
+ list_for_each_entry(profile, &ns->profiles, list)
|
||||||
+ return profile;
|
+ return profile;
|
||||||
@@ -1101,36 +1105,51 @@ Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
|||||||
+ return NULL;
|
+ 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)
|
+static void *p_next(struct seq_file *f, void *p, loff_t *pos)
|
||||||
+{
|
+{
|
||||||
+ struct aa_profile *profile = (struct aa_profile *) p;
|
+ 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;
|
+ (*pos)++;
|
||||||
+ read_unlock(&profile->ns->lock);
|
+ profile = next_profile(profile);
|
||||||
+ while (lh != &profile_ns_list) {
|
+
|
||||||
+ ns = list_entry(lh, struct aa_namespace, list);
|
+ return profile;
|
||||||
+ read_lock(&ns->lock);
|
|
||||||
+ list_for_each_entry(profile, &ns->profiles, list)
|
|
||||||
+ 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);
|
+ 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)
|
+ if (profile->ns == default_namespace)
|
||||||
+ seq_printf(f, "%s (%s)\n", profile->name,
|
+ seq_printf(f, "%s (%s)\n", profile->name,
|
||||||
+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce");
|
+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce");
|
||||||
|
@@ -64,7 +64,7 @@ linux limitations.
|
|||||||
* @count: reference count of the profile
|
* @count: reference count of the profile
|
||||||
* @task_contexts: list of tasks confined by profile
|
* @task_contexts: list of tasks confined by profile
|
||||||
* @lock: lock for the task_contexts list
|
* @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 audit_caps;
|
||||||
kernel_cap_t quiet_caps;
|
kernel_cap_t quiet_caps;
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ linux limitations.
|
|||||||
struct kref count;
|
struct kref count;
|
||||||
struct list_head task_contexts;
|
struct list_head task_contexts;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
@@ -257,6 +275,7 @@ struct aa_audit {
|
@@ -258,6 +276,7 @@ struct aa_audit {
|
||||||
const char *name2;
|
const char *name2;
|
||||||
const char *name3;
|
const char *name3;
|
||||||
int request_mask, denied_mask, audit_mask;
|
int request_mask, denied_mask, audit_mask;
|
||||||
@@ -82,7 +82,7 @@ linux limitations.
|
|||||||
struct iattr *iattr;
|
struct iattr *iattr;
|
||||||
pid_t task, parent;
|
pid_t task, parent;
|
||||||
int family, type, protocol;
|
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,
|
extern int aa_net_perm(struct aa_profile *profile, char *operation,
|
||||||
int family, int type, int protocol);
|
int family, int type, int protocol);
|
||||||
extern int aa_revalidate_sk(struct sock *sk, char *operation);
|
extern int aa_revalidate_sk(struct sock *sk, char *operation);
|
||||||
@@ -300,7 +300,7 @@ linux limitations.
|
|||||||
if (new_profile == ns->null_complain_profile)
|
if (new_profile == ns->null_complain_profile)
|
||||||
aa_audit_hint(cxt->profile, sa);
|
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);
|
cxt = lock_task_and_profiles(task, profile);
|
||||||
if (unlikely(profile && profile->isstale)) {
|
if (unlikely(profile && profile->isstale)) {
|
||||||
@@ -327,7 +327,7 @@ linux limitations.
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cxt)
|
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);
|
aa_change_task_context(task, new_cxt, profile, 0, NULL);
|
||||||
|
|
||||||
task_unlock(task);
|
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) {
|
if (old_cxt) {
|
||||||
list_del_init(&old_cxt->list);
|
list_del_init(&old_cxt->list);
|
||||||
@@ -351,7 +351,7 @@ linux limitations.
|
|||||||
call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback);
|
call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback);
|
||||||
}
|
}
|
||||||
if (new_cxt) {
|
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->cookie = cookie;
|
||||||
new_cxt->task = task;
|
new_cxt->task = task;
|
||||||
new_cxt->profile = aa_dup_profile(profile);
|
new_cxt->profile = aa_dup_profile(profile);
|
||||||
@@ -401,7 +401,7 @@ linux limitations.
|
|||||||
+ profile->rlimits.mask = tmp;
|
+ profile->rlimits.mask = tmp;
|
||||||
+
|
+
|
||||||
+ size = aa_is_array(e, NULL);
|
+ size = aa_is_array(e, NULL);
|
||||||
+ if (size != RLIM_NLIMITS)
|
+ if (size <= RLIM_NLIMITS)
|
||||||
+ goto fail;
|
+ goto fail;
|
||||||
+ for (i = 0; i < size; i++) {
|
+ for (i = 0; i < size; i++) {
|
||||||
+ u64 tmp = 0;
|
+ u64 tmp = 0;
|
||||||
|
Reference in New Issue
Block a user