Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
L
Linux
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
jan.koester
Linux
Commits
86b92cb7
Commit
86b92cb7
authored
7 years ago
by
John Johansen
Browse files
Options
Downloads
Patches
Plain Diff
apparmor: move resource checks to using labels
Signed-off-by:
John Johansen
<
john.johansen@canonical.com
>
parent
c70c86c4
Loading
Loading
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
security/apparmor/include/resource.h
+2
-2
2 additions, 2 deletions
security/apparmor/include/resource.h
security/apparmor/lsm.c
+2
-4
2 additions, 4 deletions
security/apparmor/lsm.c
security/apparmor/resource.c
+76
-36
76 additions, 36 deletions
security/apparmor/resource.c
with
80 additions
and
42 deletions
security/apparmor/include/resource.h
+
2
−
2
View file @
86b92cb7
...
@@ -37,10 +37,10 @@ struct aa_rlimit {
...
@@ -37,10 +37,10 @@ struct aa_rlimit {
extern
struct
aa_sfs_entry
aa_sfs_entry_rlimit
[];
extern
struct
aa_sfs_entry
aa_sfs_entry_rlimit
[];
int
aa_map_resource
(
int
resource
);
int
aa_map_resource
(
int
resource
);
int
aa_task_setrlimit
(
struct
aa_
profile
*
profile
,
struct
task_struct
*
,
int
aa_task_setrlimit
(
struct
aa_
label
*
label
,
struct
task_struct
*
task
,
unsigned
int
resource
,
struct
rlimit
*
new_rlim
);
unsigned
int
resource
,
struct
rlimit
*
new_rlim
);
void
__aa_transition_rlimits
(
struct
aa_
profile
*
old
,
struct
aa_
profile
*
new
);
void
__aa_transition_rlimits
(
struct
aa_
label
*
old
,
struct
aa_
label
*
new
);
static
inline
void
aa_free_rlimit_rules
(
struct
aa_rlimit
*
rlims
)
static
inline
void
aa_free_rlimit_rules
(
struct
aa_rlimit
*
rlims
)
{
{
...
...
This diff is collapsed.
Click to expand it.
security/apparmor/lsm.c
+
2
−
4
View file @
86b92cb7
...
@@ -625,8 +625,7 @@ static void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
...
@@ -625,8 +625,7 @@ static void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
current
->
pdeath_signal
=
0
;
current
->
pdeath_signal
=
0
;
/* reset soft limits and set hard limits for the new label */
/* reset soft limits and set hard limits for the new label */
__aa_transition_rlimits
(
labels_profile
(
label
),
__aa_transition_rlimits
(
label
,
new_ctx
->
label
);
labels_profile
(
new_ctx
->
label
));
}
}
/**
/**
...
@@ -646,8 +645,7 @@ static int apparmor_task_setrlimit(struct task_struct *task,
...
@@ -646,8 +645,7 @@ static int apparmor_task_setrlimit(struct task_struct *task,
int
error
=
0
;
int
error
=
0
;
if
(
!
unconfined
(
label
))
if
(
!
unconfined
(
label
))
error
=
aa_task_setrlimit
(
labels_profile
(
label
),
task
,
error
=
aa_task_setrlimit
(
label
,
task
,
resource
,
new_rlim
);
resource
,
new_rlim
);
__end_current_label_crit_section
(
label
);
__end_current_label_crit_section
(
label
);
return
error
;
return
error
;
...
...
This diff is collapsed.
Click to expand it.
security/apparmor/resource.c
+
76
−
36
View file @
86b92cb7
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
*/
*/
#include
<linux/audit.h>
#include
<linux/audit.h>
#include
<linux/security.h>
#include
"include/audit.h"
#include
"include/audit.h"
#include
"include/context.h"
#include
"include/context.h"
...
@@ -36,6 +37,11 @@ static void audit_cb(struct audit_buffer *ab, void *va)
...
@@ -36,6 +37,11 @@ static void audit_cb(struct audit_buffer *ab, void *va)
audit_log_format
(
ab
,
" rlimit=%s value=%lu"
,
audit_log_format
(
ab
,
" rlimit=%s value=%lu"
,
rlim_names
[
aad
(
sa
)
->
rlim
.
rlim
],
aad
(
sa
)
->
rlim
.
max
);
rlim_names
[
aad
(
sa
)
->
rlim
.
rlim
],
aad
(
sa
)
->
rlim
.
max
);
if
(
aad
(
sa
)
->
peer
)
{
audit_log_format
(
ab
,
" peer="
);
aa_label_xaudit
(
ab
,
labels_ns
(
aad
(
sa
)
->
label
),
aad
(
sa
)
->
peer
,
FLAGS_NONE
,
GFP_ATOMIC
);
}
}
}
/**
/**
...
@@ -48,13 +54,17 @@ static void audit_cb(struct audit_buffer *ab, void *va)
...
@@ -48,13 +54,17 @@ static void audit_cb(struct audit_buffer *ab, void *va)
* Returns: 0 or sa->error else other error code on failure
* Returns: 0 or sa->error else other error code on failure
*/
*/
static
int
audit_resource
(
struct
aa_profile
*
profile
,
unsigned
int
resource
,
static
int
audit_resource
(
struct
aa_profile
*
profile
,
unsigned
int
resource
,
unsigned
long
value
,
int
error
)
unsigned
long
value
,
struct
aa_label
*
peer
,
const
char
*
info
,
int
error
)
{
{
DEFINE_AUDIT_DATA
(
sa
,
LSM_AUDIT_DATA_NONE
,
OP_SETRLIMIT
);
DEFINE_AUDIT_DATA
(
sa
,
LSM_AUDIT_DATA_NONE
,
OP_SETRLIMIT
);
aad
(
&
sa
)
->
rlim
.
rlim
=
resource
;
aad
(
&
sa
)
->
rlim
.
rlim
=
resource
;
aad
(
&
sa
)
->
rlim
.
max
=
value
;
aad
(
&
sa
)
->
rlim
.
max
=
value
;
aad
(
&
sa
)
->
peer
=
peer
;
aad
(
&
sa
)
->
info
=
info
;
aad
(
&
sa
)
->
error
=
error
;
aad
(
&
sa
)
->
error
=
error
;
return
aa_audit
(
AUDIT_APPARMOR_AUTO
,
profile
,
&
sa
,
audit_cb
);
return
aa_audit
(
AUDIT_APPARMOR_AUTO
,
profile
,
&
sa
,
audit_cb
);
}
}
...
@@ -72,9 +82,21 @@ int aa_map_resource(int resource)
...
@@ -72,9 +82,21 @@ int aa_map_resource(int resource)
return
rlim_map
[
resource
];
return
rlim_map
[
resource
];
}
}
static
int
profile_setrlimit
(
struct
aa_profile
*
profile
,
unsigned
int
resource
,
struct
rlimit
*
new_rlim
)
{
int
e
=
0
;
if
(
profile
->
rlimits
.
mask
&
(
1
<<
resource
)
&&
new_rlim
->
rlim_max
>
profile
->
rlimits
.
limits
[
resource
].
rlim_max
)
e
=
-
EACCES
;
return
audit_resource
(
profile
,
resource
,
new_rlim
->
rlim_max
,
NULL
,
NULL
,
e
);
}
/**
/**
* aa_task_setrlimit - test permission to set an rlimit
* aa_task_setrlimit - test permission to set an rlimit
* @
profile - profile
confining the task (NOT NULL)
* @
label - label
confining the task (NOT NULL)
* @task - task the resource is being set on
* @task - task the resource is being set on
* @resource - the resource being set
* @resource - the resource being set
* @new_rlim - the new resource limit (NOT NULL)
* @new_rlim - the new resource limit (NOT NULL)
...
@@ -83,14 +105,15 @@ int aa_map_resource(int resource)
...
@@ -83,14 +105,15 @@ int aa_map_resource(int resource)
*
*
* Returns: 0 or error code if setting resource failed
* Returns: 0 or error code if setting resource failed
*/
*/
int
aa_task_setrlimit
(
struct
aa_
profile
*
profile
,
struct
task_struct
*
task
,
int
aa_task_setrlimit
(
struct
aa_
label
*
label
,
struct
task_struct
*
task
,
unsigned
int
resource
,
struct
rlimit
*
new_rlim
)
unsigned
int
resource
,
struct
rlimit
*
new_rlim
)
{
{
struct
aa_label
*
task_label
;
struct
aa_profile
*
profile
;
struct
aa_label
*
peer
;
int
error
=
0
;
int
error
=
0
;
rcu_read_lock
();
rcu_read_lock
();
task_label
=
aa_get_newest_cred_label
(
(
__task_cred
(
task
))
)
;
peer
=
aa_get_newest_cred_label
(
__task_cred
(
task
));
rcu_read_unlock
();
rcu_read_unlock
();
/* TODO: extend resource control to handle other (non current)
/* TODO: extend resource control to handle other (non current)
...
@@ -99,53 +122,70 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
...
@@ -99,53 +122,70 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
* the same profile or that the task setting the resource of another
* the same profile or that the task setting the resource of another
* task has CAP_SYS_RESOURCE.
* task has CAP_SYS_RESOURCE.
*/
*/
if
((
profile
!=
labels_profile
(
task_label
)
&&
aa_capable
(
&
profile
->
label
,
CAP_SYS_RESOURCE
,
1
))
||
(
profile
->
rlimits
.
mask
&
(
1
<<
resource
)
&&
new_rlim
->
rlim_max
>
profile
->
rlimits
.
limits
[
resource
].
rlim_max
))
error
=
-
EACCES
;
aa_put_label
(
task_label
);
if
(
label
!=
peer
&&
!
aa_capable
(
label
,
CAP_SYS_RESOURCE
,
SECURITY_CAP_NOAUDIT
))
return
audit_resource
(
profile
,
resource
,
new_rlim
->
rlim_max
,
error
);
error
=
fn_for_each
(
label
,
profile
,
audit_resource
(
profile
,
resource
,
new_rlim
->
rlim_max
,
peer
,
"cap_sys_resoure"
,
-
EACCES
));
else
error
=
fn_for_each_confined
(
label
,
profile
,
profile_setrlimit
(
profile
,
resource
,
new_rlim
));
aa_put_label
(
peer
);
return
error
;
}
}
/**
/**
* __aa_transition_rlimits - apply new profile rlimits
* __aa_transition_rlimits - apply new profile rlimits
* @old: old
profile
on task (NOT NULL)
* @old
_l
: old
label
on task (NOT NULL)
* @new: new
profile
with rlimits to apply (NOT NULL)
* @new
_l
: new
label
with rlimits to apply (NOT NULL)
*/
*/
void
__aa_transition_rlimits
(
struct
aa_
profile
*
old
,
struct
aa_
profile
*
new
)
void
__aa_transition_rlimits
(
struct
aa_
label
*
old
_l
,
struct
aa_
label
*
new
_l
)
{
{
unsigned
int
mask
=
0
;
unsigned
int
mask
=
0
;
struct
rlimit
*
rlim
,
*
initrlim
;
struct
rlimit
*
rlim
,
*
initrlim
;
int
i
;
struct
aa_profile
*
old
,
*
new
;
struct
label_it
i
;
old
=
labels_profile
(
old_l
);
new
=
labels_profile
(
new_l
);
/* for any rlimits the profile controlled reset the soft limit
/* for any rlimits the profile controlled
,
reset the soft limit
* to the less of the tasks hard limit and the init tasks soft limit
* to the less
er
of the tasks hard limit and the init tasks soft limit
*/
*/
if
(
old
->
rlimits
.
mask
)
{
label_for_each_confined
(
i
,
old_l
,
old
)
{
for
(
i
=
0
,
mask
=
1
;
i
<
RLIM_NLIMITS
;
i
++
,
mask
<<=
1
)
{
if
(
old
->
rlimits
.
mask
)
{
if
(
old
->
rlimits
.
mask
&
mask
)
{
int
j
;
rlim
=
current
->
signal
->
rlim
+
i
;
initrlim
=
init_task
.
signal
->
rlim
+
i
;
for
(
j
=
0
,
mask
=
1
;
j
<
RLIM_NLIMITS
;
j
++
,
rlim
->
rlim_cur
=
min
(
rlim
->
rlim_max
,
mask
<<=
1
)
{
initrlim
->
rlim_cur
);
if
(
old
->
rlimits
.
mask
&
mask
)
{
rlim
=
current
->
signal
->
rlim
+
j
;
initrlim
=
init_task
.
signal
->
rlim
+
j
;
rlim
->
rlim_cur
=
min
(
rlim
->
rlim_max
,
initrlim
->
rlim_cur
);
}
}
}
}
}
}
}
/* set any new hard limits as dictated by the new profile */
/* set any new hard limits as dictated by the new profile */
if
(
!
new
->
rlimits
.
mask
)
label_for_each_confined
(
i
,
new_l
,
new
)
{
return
;
int
j
;
for
(
i
=
0
,
mask
=
1
;
i
<
RLIM_NLIMITS
;
i
++
,
mask
<<=
1
)
{
if
(
!
(
new
->
rlimits
.
mask
&
mask
))
continue
;
rlim
=
current
->
signal
->
rlim
+
i
;
if
(
!
new
->
rlimits
.
mask
)
rlim
->
rlim_max
=
min
(
rlim
->
rlim_max
,
continue
;
new
->
rlimits
.
limits
[
i
].
rlim_max
);
for
(
j
=
0
,
mask
=
1
;
j
<
RLIM_NLIMITS
;
j
++
,
mask
<<=
1
)
{
/* soft limit should not exceed hard limit */
if
(
!
(
new
->
rlimits
.
mask
&
mask
))
rlim
->
rlim_cur
=
min
(
rlim
->
rlim_cur
,
rlim
->
rlim_max
);
continue
;
rlim
=
current
->
signal
->
rlim
+
j
;
rlim
->
rlim_max
=
min
(
rlim
->
rlim_max
,
new
->
rlimits
.
limits
[
j
].
rlim_max
);
/* soft limit should not exceed hard limit */
rlim
->
rlim_cur
=
min
(
rlim
->
rlim_cur
,
rlim
->
rlim_max
);
}
}
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment