Fix rlimits so that it doesn't try to do nproc checks when moving

to an unconfined state; which would result in dereferencing a null
profile pointer.
This commit is contained in:
John Johansen 2008-04-07 04:47:08 +00:00
parent aba82ff427
commit aef0eb93dd

View file

@ -1,9 +1,9 @@
---
security/apparmor/apparmor.h | 23 ++++++
security/apparmor/lsm.c | 16 ++++
security/apparmor/main.c | 132 +++++++++++++++++++++++++++++++----
security/apparmor/main.c | 133 +++++++++++++++++++++++++++++++----
security/apparmor/module_interface.c | 56 ++++++++++++++
4 files changed, 214 insertions(+), 13 deletions(-)
4 files changed, 215 insertions(+), 13 deletions(-)
--- a/security/apparmor/apparmor.h
+++ b/security/apparmor/apparmor.h
@ -116,7 +116,7 @@
if (sa->iattr) {
struct iattr *iattr = sa->iattr;
@@ -873,6 +876,78 @@ int aa_revalidate_sk(struct sock *sk, ch
@@ -873,6 +876,80 @@ int aa_revalidate_sk(struct sock *sk, ch
return error;
}
@ -140,16 +140,17 @@
+ sa.rlimit = resource + 1;
+
+ if (profile->rlimits.mask & (1 << resource) &&
+ new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max)
+ new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max) {
+ sa.error_code = -EACCES;
+
+ error = aa_audit(profile, &sa);
+ }
+
+ return error;
+}
+
+static int aa_rlimit_nproc(struct aa_profile *profile) {
+ if ((profile->rlimits.mask & (1 << RLIMIT_NPROC)) &&
+ if (profile && (profile->rlimits.mask & (1 << RLIMIT_NPROC)) &&
+ profile->task_count >= profile->rlimits.limits[RLIMIT_NPROC].rlim_max)
+ return -EAGAIN;
+ return 0;
@ -162,6 +163,7 @@
+ if (!profile)
+ return;
+
+ return;
+ if (!profile->rlimits.mask)
+ return;
+
@ -195,7 +197,7 @@
/*******************************
* Global task related functions
@@ -886,6 +961,7 @@ int aa_revalidate_sk(struct sock *sk, ch
@@ -886,6 +963,7 @@ int aa_revalidate_sk(struct sock *sk, ch
*/
int aa_clone(struct task_struct *child)
{
@ -203,7 +205,7 @@
struct aa_task_context *cxt, *child_cxt;
struct aa_profile *profile;
@@ -895,6 +971,11 @@ int aa_clone(struct task_struct *child)
@@ -895,6 +973,11 @@ int aa_clone(struct task_struct *child)
if (!child_cxt)
return -ENOMEM;
@ -215,17 +217,16 @@
repeat:
profile = aa_get_profile(current);
if (profile) {
@@ -911,18 +992,23 @@ repeat:
@@ -911,18 +994,22 @@ repeat:
goto repeat;
}
+ sa.error_code = aa_rlimit_nproc(profile);
+ if (sa.error_code) {
+ if (aa_rlimit_nproc(profile)) {
+ sa.info = "rlimit nproc limit exceeded";
+ unlock_profile(profile);
+ aa_audit_reject(profile, &sa);
+ aa_put_profile(profile);
+ return sa.error_code;
+ return -EAGAIN;
+ }
+
/* No need to grab the child's task lock here. */
@ -244,7 +245,7 @@
aa_audit_hint(profile, &sa);
}
aa_put_profile(profile);
@@ -1100,6 +1186,10 @@ repeat:
@@ -1100,6 +1187,10 @@ repeat:
sa.task = current->parent->pid;
aa_audit_reject(profile, &sa);
}
@ -255,7 +256,7 @@
new_profile = old_profile;
goto cleanup;
}
@@ -1239,6 +1329,12 @@ static int do_change_profile(struct aa_p
@@ -1239,6 +1330,12 @@ static int do_change_profile(struct aa_p
goto out;
}
@ -268,7 +269,7 @@
if (new_profile == ns->null_complain_profile)
aa_audit_hint(cxt->profile, sa);
@@ -1427,17 +1523,18 @@ struct aa_profile *__aa_replace_profile(
@@ -1427,17 +1524,18 @@ struct aa_profile *__aa_replace_profile(
cxt = lock_task_and_profiles(task, profile);
if (unlikely(profile && profile->isstale)) {
@ -295,7 +296,7 @@
}
if (cxt)
@@ -1445,8 +1542,15 @@ struct aa_profile *__aa_replace_profile(
@@ -1445,8 +1543,15 @@ struct aa_profile *__aa_replace_profile(
aa_change_task_context(task, new_cxt, profile, 0, NULL);
task_unlock(task);
@ -311,7 +312,7 @@
}
/**
@@ -1511,6 +1615,7 @@ void aa_change_task_context(struct task_
@@ -1511,6 +1616,7 @@ void aa_change_task_context(struct task_
if (old_cxt) {
list_del_init(&old_cxt->list);
@ -319,7 +320,7 @@
call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback);
}
if (new_cxt) {
@@ -1522,6 +1627,7 @@ void aa_change_task_context(struct task_
@@ -1522,6 +1628,7 @@ void aa_change_task_context(struct task_
new_cxt->cookie = cookie;
new_cxt->task = task;
new_cxt->profile = aa_dup_profile(profile);
@ -363,7 +364,7 @@
+ /* rlimits are optional */
+ if (aa_is_nameX(e, AA_STRUCT, "rlimits")) {
+ int i, size;
+ u32 tmp;
+ u32 tmp = 0;
+ if (!aa_is_u32(e, &tmp, NULL))
+ goto fail;
+ profile->rlimits.mask = tmp;
@ -372,7 +373,7 @@
+ if (size != RLIM_NLIMITS)
+ goto fail;
+ for (i = 0; i < size; i++) {
+ u64 tmp;
+ u64 tmp = 0;
+ if (!aa_is_u64(e, &tmp, NULL))
+ goto fail;
+ profile->rlimits.limits[i].rlim_max = tmp;