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
190a9518
Commit
190a9518
authored
Jun 09, 2017
by
John Johansen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
apparmor: move aa_file_perm() to use labels
Signed-off-by:
John Johansen
<
john.johansen@canonical.com
>
parent
290f458a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
64 additions
and
37 deletions
+64
-37
security/apparmor/file.c
security/apparmor/file.c
+40
-8
security/apparmor/include/file.h
security/apparmor/include/file.h
+21
-8
security/apparmor/lsm.c
security/apparmor/lsm.c
+3
-21
No files found.
security/apparmor/file.c
View file @
190a9518
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
#include "include/match.h"
#include "include/match.h"
#include "include/path.h"
#include "include/path.h"
#include "include/policy.h"
#include "include/policy.h"
#include "include/label.h"
static
u32
map_mask_to_chr_mask
(
u32
mask
)
static
u32
map_mask_to_chr_mask
(
u32
mask
)
{
{
...
@@ -433,22 +434,55 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
...
@@ -433,22 +434,55 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
/**
/**
* aa_file_perm - do permission revalidation check & audit for @file
* aa_file_perm - do permission revalidation check & audit for @file
* @op: operation being checked
* @op: operation being checked
* @
profile: profile
being enforced (NOT NULL)
* @
label: label
being enforced (NOT NULL)
* @file: file to revalidate access permissions on (NOT NULL)
* @file: file to revalidate access permissions on (NOT NULL)
* @request: requested permissions
* @request: requested permissions
*
*
* Returns: %0 if access allowed else error
* Returns: %0 if access allowed else error
*/
*/
int
aa_file_perm
(
const
char
*
op
,
struct
aa_
profile
*
profile
,
struct
file
*
file
,
int
aa_file_perm
(
const
char
*
op
,
struct
aa_
label
*
label
,
struct
file
*
file
,
u32
request
)
u32
request
)
{
{
struct
path_cond
cond
=
{
struct
path_cond
cond
=
{
.
uid
=
file_inode
(
file
)
->
i_uid
,
.
uid
=
file_inode
(
file
)
->
i_uid
,
.
mode
=
file_inode
(
file
)
->
i_mode
.
mode
=
file_inode
(
file
)
->
i_mode
};
};
struct
aa_file_ctx
*
fctx
;
struct
aa_label
*
flabel
;
u32
denied
;
int
error
=
0
;
AA_BUG
(
!
label
);
AA_BUG
(
!
file
);
fctx
=
file_ctx
(
file
);
rcu_read_lock
();
flabel
=
rcu_dereference
(
fctx
->
label
);
AA_BUG
(
!
flabel
);
/* revalidate access, if task is unconfined, or the cached cred
* doesn't match or if the request is for more permissions than
* was granted.
*
* Note: the test for !unconfined(flabel) is to handle file
* delegation from unconfined tasks
*/
denied
=
request
&
~
fctx
->
allow
;
if
(
unconfined
(
label
)
||
unconfined
(
flabel
)
||
(
!
denied
&&
aa_label_is_subset
(
flabel
,
label
)))
goto
done
;
/* TODO: label cross check */
if
(
file
->
f_path
.
mnt
&&
path_mediated_fs
(
file
->
f_path
.
dentry
))
error
=
aa_path_perm
(
op
,
labels_profile
(
label
),
&
file
->
f_path
,
PATH_DELEGATE_DELETED
,
request
,
&
cond
);
return
aa_path_perm
(
op
,
profile
,
&
file
->
f_path
,
PATH_DELEGATE_DELETED
,
done:
request
,
&
cond
);
rcu_read_unlock
();
return
error
;
}
}
static
void
revalidate_tty
(
struct
aa_label
*
label
)
static
void
revalidate_tty
(
struct
aa_label
*
label
)
...
@@ -469,8 +503,7 @@ static void revalidate_tty(struct aa_label *label)
...
@@ -469,8 +503,7 @@ static void revalidate_tty(struct aa_label *label)
struct
tty_file_private
,
list
);
struct
tty_file_private
,
list
);
file
=
file_priv
->
file
;
file
=
file_priv
->
file
;
if
(
aa_file_perm
(
OP_INHERIT
,
labels_profile
(
label
),
file
,
if
(
aa_file_perm
(
OP_INHERIT
,
label
,
file
,
MAY_READ
|
MAY_WRITE
))
MAY_READ
|
MAY_WRITE
))
drop_tty
=
1
;
drop_tty
=
1
;
}
}
spin_unlock
(
&
tty
->
files_lock
);
spin_unlock
(
&
tty
->
files_lock
);
...
@@ -484,8 +517,7 @@ static int match_file(const void *p, struct file *file, unsigned int fd)
...
@@ -484,8 +517,7 @@ static int match_file(const void *p, struct file *file, unsigned int fd)
{
{
struct
aa_label
*
label
=
(
struct
aa_label
*
)
p
;
struct
aa_label
*
label
=
(
struct
aa_label
*
)
p
;
if
(
aa_file_perm
(
OP_INHERIT
,
labels_profile
(
label
),
file
,
if
(
aa_file_perm
(
OP_INHERIT
,
label
,
file
,
aa_map_file_to_perms
(
file
)))
aa_map_file_to_perms
(
file
)))
return
fd
+
1
;
return
fd
+
1
;
return
0
;
return
0
;
}
}
...
...
security/apparmor/include/file.h
View file @
190a9518
...
@@ -15,6 +15,8 @@
...
@@ -15,6 +15,8 @@
#ifndef __AA_FILE_H
#ifndef __AA_FILE_H
#define __AA_FILE_H
#define __AA_FILE_H
#include <linux/spinlock.h>
#include "domain.h"
#include "domain.h"
#include "match.h"
#include "match.h"
#include "perms.h"
#include "perms.h"
...
@@ -33,13 +35,13 @@ struct path;
...
@@ -33,13 +35,13 @@ struct path;
#define file_ctx(X) ((struct aa_file_ctx *)(X)->f_security)
#define file_ctx(X) ((struct aa_file_ctx *)(X)->f_security)
/* struct aa_file_ctx - the AppArmor context the file was opened in
/* struct aa_file_ctx - the AppArmor context the file was opened in
* @lock: lock to update the ctx
* @label: label currently cached on the ctx
* @perms: the permission the file was opened with
* @perms: the permission the file was opened with
*
* The file_ctx could currently be directly stored in file->f_security
* as the profile reference is now stored in the f_cred. However the
* ctx struct will expand in the future so we keep the struct.
*/
*/
struct
aa_file_ctx
{
struct
aa_file_ctx
{
spinlock_t
lock
;
struct
aa_label
__rcu
*
label
;
u32
allow
;
u32
allow
;
};
};
...
@@ -50,12 +52,16 @@ struct aa_file_ctx {
...
@@ -50,12 +52,16 @@ struct aa_file_ctx {
*
*
* Returns: file_ctx or NULL on failure
* Returns: file_ctx or NULL on failure
*/
*/
static
inline
struct
aa_file_ctx
*
aa_alloc_file_ctx
(
gfp_t
gfp
)
static
inline
struct
aa_file_ctx
*
aa_alloc_file_ctx
(
struct
aa_label
*
label
,
gfp_t
gfp
)
{
{
struct
aa_file_ctx
*
ctx
;
struct
aa_file_ctx
*
ctx
;
ctx
=
kzalloc
(
sizeof
(
struct
aa_file_ctx
),
gfp
);
ctx
=
kzalloc
(
sizeof
(
struct
aa_file_ctx
),
gfp
);
if
(
ctx
)
{
spin_lock_init
(
&
ctx
->
lock
);
rcu_assign_pointer
(
ctx
->
label
,
aa_get_label
(
label
));
}
return
ctx
;
return
ctx
;
}
}
...
@@ -65,8 +71,15 @@ static inline struct aa_file_ctx *aa_alloc_file_ctx(gfp_t gfp)
...
@@ -65,8 +71,15 @@ static inline struct aa_file_ctx *aa_alloc_file_ctx(gfp_t gfp)
*/
*/
static
inline
void
aa_free_file_ctx
(
struct
aa_file_ctx
*
ctx
)
static
inline
void
aa_free_file_ctx
(
struct
aa_file_ctx
*
ctx
)
{
{
if
(
ctx
)
if
(
ctx
)
{
aa_put_label
(
rcu_access_pointer
(
ctx
->
label
));
kzfree
(
ctx
);
kzfree
(
ctx
);
}
}
static
inline
struct
aa_label
*
aa_get_file_label
(
struct
aa_file_ctx
*
ctx
)
{
return
aa_get_label_rcu
(
&
ctx
->
label
);
}
}
/*
/*
...
@@ -183,7 +196,7 @@ int aa_path_perm(const char *op, struct aa_profile *profile,
...
@@ -183,7 +196,7 @@ int aa_path_perm(const char *op, struct aa_profile *profile,
int
aa_path_link
(
struct
aa_profile
*
profile
,
struct
dentry
*
old_dentry
,
int
aa_path_link
(
struct
aa_profile
*
profile
,
struct
dentry
*
old_dentry
,
const
struct
path
*
new_dir
,
struct
dentry
*
new_dentry
);
const
struct
path
*
new_dir
,
struct
dentry
*
new_dentry
);
int
aa_file_perm
(
const
char
*
op
,
struct
aa_
profile
*
profile
,
struct
file
*
file
,
int
aa_file_perm
(
const
char
*
op
,
struct
aa_
label
*
label
,
struct
file
*
file
,
u32
request
);
u32
request
);
void
aa_inherit_files
(
const
struct
cred
*
cred
,
struct
files_struct
*
files
);
void
aa_inherit_files
(
const
struct
cred
*
cred
,
struct
files_struct
*
files
);
...
...
security/apparmor/lsm.c
View file @
190a9518
...
@@ -433,7 +433,7 @@ static int apparmor_file_alloc_security(struct file *file)
...
@@ -433,7 +433,7 @@ static int apparmor_file_alloc_security(struct file *file)
/* freed by apparmor_file_free_security */
/* freed by apparmor_file_free_security */
struct
aa_label
*
label
=
begin_current_label_crit_section
();
struct
aa_label
*
label
=
begin_current_label_crit_section
();
file
->
f_security
=
aa_alloc_file_ctx
(
GFP_KERNEL
);
file
->
f_security
=
aa_alloc_file_ctx
(
label
,
GFP_KERNEL
);
if
(
!
file_ctx
(
file
))
if
(
!
file_ctx
(
file
))
error
=
-
ENOMEM
;
error
=
-
ENOMEM
;
end_current_label_crit_section
(
label
);
end_current_label_crit_section
(
label
);
...
@@ -448,33 +448,15 @@ static void apparmor_file_free_security(struct file *file)
...
@@ -448,33 +448,15 @@ static void apparmor_file_free_security(struct file *file)
static
int
common_file_perm
(
const
char
*
op
,
struct
file
*
file
,
u32
mask
)
static
int
common_file_perm
(
const
char
*
op
,
struct
file
*
file
,
u32
mask
)
{
{
struct
aa_file_ctx
*
fctx
=
file
->
f_security
;
struct
aa_label
*
label
;
struct
aa_label
*
label
,
*
flabel
;
int
error
=
0
;
int
error
=
0
;
/* don't reaudit files closed during inheritance */
/* don't reaudit files closed during inheritance */
if
(
file
->
f_path
.
dentry
==
aa_null
.
dentry
)
if
(
file
->
f_path
.
dentry
==
aa_null
.
dentry
)
return
-
EACCES
;
return
-
EACCES
;
flabel
=
aa_cred_raw_label
(
file
->
f_cred
);
AA_BUG
(
!
flabel
);
if
(
!
file
->
f_path
.
mnt
||
!
path_mediated_fs
(
file
->
f_path
.
dentry
))
return
0
;
label
=
__begin_current_label_crit_section
();
label
=
__begin_current_label_crit_section
();
error
=
aa_file_perm
(
op
,
label
,
file
,
mask
);
/* revalidate access, if task is unconfined, or the cached cred
* doesn't match or if the request is for more permissions than
* was granted.
*
* Note: the test for !unconfined(fprofile) is to handle file
* delegation from unconfined tasks
*/
if
(
!
unconfined
(
label
)
&&
!
unconfined
(
flabel
)
&&
((
flabel
!=
label
)
||
(
mask
&
~
fctx
->
allow
)))
error
=
aa_file_perm
(
op
,
labels_profile
(
label
),
file
,
mask
);
__end_current_label_crit_section
(
label
);
__end_current_label_crit_section
(
label
);
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