mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
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:
parent
aba82ff427
commit
aef0eb93dd
1 changed files with 21 additions and 20 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue