Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
e00b02bb
Commit
e00b02bb
authored
Jun 09, 2017
by
John Johansen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
apparmor: move change_profile mediation to using labels
Signed-off-by:
John Johansen
<
john.johansen@canonical.com
>
parent
89dbf196
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
123 additions
and
68 deletions
+123
-68
security/apparmor/domain.c
security/apparmor/domain.c
+123
-68
No files found.
security/apparmor/domain.c
View file @
e00b02bb
...
@@ -301,26 +301,6 @@ static int change_profile_perms(struct aa_profile *profile,
...
@@ -301,26 +301,6 @@ static int change_profile_perms(struct aa_profile *profile,
return
label_match
(
profile
,
target
,
stack
,
start
,
true
,
request
,
perms
);
return
label_match
(
profile
,
target
,
stack
,
start
,
true
,
request
,
perms
);
}
}
static
struct
aa_perms
change_profile_perms_wrapper
(
struct
aa_profile
*
profile
,
struct
aa_profile
*
target
,
u32
request
,
unsigned
int
start
)
{
struct
aa_perms
perms
;
if
(
profile_unconfined
(
profile
))
{
perms
.
allow
=
AA_MAY_CHANGE_PROFILE
|
AA_MAY_ONEXEC
;
perms
.
audit
=
perms
.
quiet
=
perms
.
kill
=
0
;
return
perms
;
}
if
(
change_profile_perms
(
profile
,
&
target
->
label
,
false
,
request
,
start
,
&
perms
))
return
nullperms
;
return
perms
;
}
/**
/**
* __attach_match_ - find an attachment match
* __attach_match_ - find an attachment match
* @name - to match against (NOT NULL)
* @name - to match against (NOT NULL)
...
@@ -1140,6 +1120,39 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
...
@@ -1140,6 +1120,39 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
}
}
static
int
change_profile_perms_wrapper
(
const
char
*
op
,
const
char
*
name
,
struct
aa_profile
*
profile
,
struct
aa_label
*
target
,
bool
stack
,
u32
request
,
struct
aa_perms
*
perms
)
{
const
char
*
info
=
NULL
;
int
error
=
0
;
/*
* Fail explicitly requested domain transitions when no_new_privs
* and not unconfined OR the transition results in a stack on
* the current label.
* Stacking domain transitions and transitions from unconfined are
* allowed even when no_new_privs is set because this aways results
* in a reduction of permissions.
*/
if
(
task_no_new_privs
(
current
)
&&
!
stack
&&
!
profile_unconfined
(
profile
)
&&
!
aa_label_is_subset
(
target
,
&
profile
->
label
))
{
info
=
"no new privs"
;
error
=
-
EPERM
;
}
if
(
!
error
)
error
=
change_profile_perms
(
profile
,
target
,
stack
,
request
,
profile
->
file
.
start
,
perms
);
if
(
error
)
error
=
aa_audit_file
(
profile
,
perms
,
op
,
request
,
name
,
NULL
,
target
,
GLOBAL_ROOT_UID
,
info
,
error
);
return
error
;
}
/**
/**
* aa_change_profile - perform a one-way profile transition
* aa_change_profile - perform a one-way profile transition
...
@@ -1157,12 +1170,14 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
...
@@ -1157,12 +1170,14 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
*/
*/
int
aa_change_profile
(
const
char
*
fqname
,
int
flags
)
int
aa_change_profile
(
const
char
*
fqname
,
int
flags
)
{
{
const
struct
cred
*
cred
;
struct
aa_label
*
label
,
*
new
=
NULL
,
*
target
=
NULL
;
struct
aa_label
*
label
;
struct
aa_profile
*
profile
;
struct
aa_profile
*
profile
,
*
target
=
NULL
;
struct
aa_perms
perms
=
{};
struct
aa_perms
perms
=
{};
const
char
*
info
=
NULL
,
*
op
;
const
char
*
info
=
NULL
;
const
char
*
auditname
=
fqname
;
/* retain leading & if stack */
bool
stack
=
flags
&
AA_CHANGE_STACK
;
int
error
=
0
;
int
error
=
0
;
char
*
op
;
u32
request
;
u32
request
;
if
(
!
fqname
||
!*
fqname
)
{
if
(
!
fqname
||
!*
fqname
)
{
...
@@ -1172,76 +1187,116 @@ int aa_change_profile(const char *fqname, int flags)
...
@@ -1172,76 +1187,116 @@ int aa_change_profile(const char *fqname, int flags)
if
(
flags
&
AA_CHANGE_ONEXEC
)
{
if
(
flags
&
AA_CHANGE_ONEXEC
)
{
request
=
AA_MAY_ONEXEC
;
request
=
AA_MAY_ONEXEC
;
if
(
stack
)
op
=
OP_STACK_ONEXEC
;
else
op
=
OP_CHANGE_ONEXEC
;
op
=
OP_CHANGE_ONEXEC
;
}
else
{
}
else
{
request
=
AA_MAY_CHANGE_PROFILE
;
request
=
AA_MAY_CHANGE_PROFILE
;
if
(
stack
)
op
=
OP_STACK
;
else
op
=
OP_CHANGE_PROFILE
;
op
=
OP_CHANGE_PROFILE
;
}
}
cred
=
get_current_cred
();
label
=
aa_get_current_label
();
label
=
aa_get_newest_cred_label
(
cred
);
profile
=
labels_profile
(
label
);
/*
if
(
*
fqname
==
'&'
)
{
* Fail explicitly requested domain transitions if no_new_privs
stack
=
true
;
* and not unconfined.
/* don't have label_parse() do stacking */
* Domain transitions from unconfined are allowed even when
fqname
++
;
* no_new_privs is set because this aways results in a reduction
* of permissions.
*/
if
(
task_no_new_privs
(
current
)
&&
!
profile_unconfined
(
profile
))
{
put_cred
(
cred
);
return
-
EPERM
;
}
}
target
=
aa_label_parse
(
label
,
fqname
,
GFP_KERNEL
,
true
,
false
);
if
(
IS_ERR
(
target
))
{
struct
aa_profile
*
tprofile
;
target
=
aa_fqlookupn_profile
(
label
,
fqname
,
strlen
(
fqname
));
info
=
"label not found"
;
if
(
!
target
)
{
error
=
PTR_ERR
(
target
);
info
=
"profile not found"
;
target
=
NULL
;
error
=
-
ENOENT
;
/*
* TODO: fixme using labels_profile is not right - do profile
* per complain profile
*/
if
((
flags
&
AA_CHANGE_TEST
)
||
if
((
flags
&
AA_CHANGE_TEST
)
||
!
COMPLAIN_MODE
(
profile
))
!
COMPLAIN_MODE
(
labels_profile
(
label
)
))
goto
audit
;
goto
audit
;
/* released below */
/* released below */
t
arget
=
aa_new_null_profile
(
profile
,
false
,
fqnam
e
,
t
profile
=
aa_new_null_profile
(
labels_profile
(
label
),
fals
e
,
GFP_KERNEL
);
fqname
,
GFP_KERNEL
);
if
(
!
t
arget
)
{
if
(
!
t
profile
)
{
info
=
"failed null profile create"
;
info
=
"failed null profile create"
;
error
=
-
ENOMEM
;
error
=
-
ENOMEM
;
goto
audit
;
goto
audit
;
}
}
target
=
&
tprofile
->
label
;
goto
check
;
}
}
perms
=
change_profile_perms_wrapper
(
profile
,
target
,
request
,
/*
profile
->
file
.
start
);
* self directed transitions only apply to current policy ns
if
(
!
(
perms
.
allow
&
request
))
{
* TODO: currently requiring perms for stacking and straight change
error
=
-
EACCES
;
* stacking doesn't strictly need this. Determine how much
goto
audit
;
* we want to loosen this restriction for stacking
}
*
* if (!stack) {
*/
error
=
fn_for_each_in_ns
(
label
,
profile
,
change_profile_perms_wrapper
(
op
,
auditname
,
profile
,
target
,
stack
,
request
,
&
perms
));
if
(
error
)
/* auditing done in change_profile_perms_wrapper */
goto
out
;
/* } */
check:
/* check if tracing task is allowed to trace target domain */
/* check if tracing task is allowed to trace target domain */
error
=
may_change_ptraced_domain
(
&
target
->
label
,
&
info
);
error
=
may_change_ptraced_domain
(
target
,
&
info
);
if
(
error
)
{
if
(
error
&&
!
fn_for_each_in_ns
(
label
,
profile
,
info
=
"ptrace prevents transition"
;
COMPLAIN_MODE
(
profile
)))
goto
audit
;
goto
audit
;
}
/* TODO: add permission check to allow this
* if ((flags & AA_CHANGE_ONEXEC) && !current_is_single_threaded()) {
* info = "not a single threaded task";
* error = -EACCES;
* goto audit;
* }
*/
if
(
flags
&
AA_CHANGE_TEST
)
if
(
flags
&
AA_CHANGE_TEST
)
goto
audi
t
;
goto
ou
t
;
if
(
flags
&
AA_CHANGE_ONEXEC
)
if
(
!
(
flags
&
AA_CHANGE_ONEXEC
))
{
error
=
aa_set_current_onexec
(
&
target
->
label
,
0
);
/* only transition profiles in the current ns */
if
(
stack
)
new
=
aa_label_merge
(
label
,
target
,
GFP_KERNEL
);
else
else
error
=
aa_replace_current_label
(
&
target
->
label
);
new
=
fn_label_build_in_ns
(
label
,
profile
,
GFP_KERNEL
,
aa_get_label
(
target
),
aa_get_label
(
&
profile
->
label
));
if
(
IS_ERR_OR_NULL
(
new
))
{
info
=
"failed to build target label"
;
error
=
PTR_ERR
(
new
);
new
=
NULL
;
perms
.
allow
=
0
;
goto
audit
;
}
error
=
aa_replace_current_label
(
new
);
}
else
/* full transition will be built in exec path */
error
=
aa_set_current_onexec
(
target
,
stack
);
audit:
audit:
if
(
!
(
flags
&
AA_CHANGE_TEST
))
error
=
fn_for_each_in_ns
(
label
,
profile
,
error
=
aa_audit_file
(
profile
,
&
perms
,
op
,
request
,
NULL
,
aa_audit_file
(
profile
,
&
perms
,
op
,
request
,
auditname
,
fqname
,
NULL
,
GLOBAL_ROOT_UID
,
info
,
NULL
,
new
?
new
:
target
,
error
);
GLOBAL_ROOT_UID
,
info
,
error
)
);
aa_put_profile
(
target
);
out:
aa_put_label
(
new
);
aa_put_label
(
target
);
aa_put_label
(
label
);
aa_put_label
(
label
);
put_cred
(
cred
);
return
error
;
return
error
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment