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
Kirill Smelkov
linux
Commits
bd71164a
Commit
bd71164a
authored
May 12, 2013
by
James Morris
Browse files
Options
Browse Files
Download
Plain Diff
Merge tag 'aa-3.10' of
git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor
into ra-next
parents
f722406f
2654bfbc
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
286 additions
and
248 deletions
+286
-248
security/apparmor/audit.c
security/apparmor/audit.c
+1
-1
security/apparmor/context.c
security/apparmor/context.c
+28
-16
security/apparmor/domain.c
security/apparmor/domain.c
+9
-17
security/apparmor/include/apparmor.h
security/apparmor/include/apparmor.h
+11
-1
security/apparmor/include/context.h
security/apparmor/include/context.h
+43
-18
security/apparmor/include/file.h
security/apparmor/include/file.h
+7
-7
security/apparmor/include/match.h
security/apparmor/include/match.h
+13
-8
security/apparmor/include/policy.h
security/apparmor/include/policy.h
+8
-8
security/apparmor/include/procattr.h
security/apparmor/include/procattr.h
+0
-1
security/apparmor/include/sid.h
security/apparmor/include/sid.h
+3
-1
security/apparmor/ipc.c
security/apparmor/ipc.c
+4
-9
security/apparmor/lib.c
security/apparmor/lib.c
+13
-7
security/apparmor/lsm.c
security/apparmor/lsm.c
+34
-35
security/apparmor/match.c
security/apparmor/match.c
+12
-11
security/apparmor/path.c
security/apparmor/path.c
+1
-1
security/apparmor/policy.c
security/apparmor/policy.c
+84
-97
security/apparmor/policy_unpack.c
security/apparmor/policy_unpack.c
+3
-1
security/apparmor/procattr.c
security/apparmor/procattr.c
+0
-6
security/apparmor/resource.c
security/apparmor/resource.c
+12
-3
No files found.
security/apparmor/audit.c
View file @
bd71164a
...
...
@@ -88,7 +88,7 @@ static const char *const aa_audit_type[] = {
"HINT"
,
"STATUS"
,
"ERROR"
,
"KILLED"
"KILLED"
,
"AUTO"
};
...
...
security/apparmor/context.c
View file @
bd71164a
...
...
@@ -68,6 +68,23 @@ void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)
aa_get_profile
(
new
->
onexec
);
}
/**
* aa_get_task_profile - Get another task's profile
* @task: task to query (NOT NULL)
*
* Returns: counted reference to @task's profile
*/
struct
aa_profile
*
aa_get_task_profile
(
struct
task_struct
*
task
)
{
struct
aa_profile
*
p
;
rcu_read_lock
();
p
=
aa_get_profile
(
__aa_task_profile
(
task
));
rcu_read_unlock
();
return
p
;
}
/**
* aa_replace_current_profile - replace the current tasks profiles
* @profile: new profile (NOT NULL)
...
...
@@ -76,7 +93,7 @@ void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)
*/
int
aa_replace_current_profile
(
struct
aa_profile
*
profile
)
{
struct
aa_task_cxt
*
cxt
=
current_c
red
()
->
security
;
struct
aa_task_cxt
*
cxt
=
current_c
xt
()
;
struct
cred
*
new
;
BUG_ON
(
!
profile
);
...
...
@@ -87,17 +104,13 @@ int aa_replace_current_profile(struct aa_profile *profile)
if
(
!
new
)
return
-
ENOMEM
;
cxt
=
new
->
security
;
if
(
unconfined
(
profile
)
||
(
cxt
->
profile
->
ns
!=
profile
->
ns
))
{
cxt
=
cred_cxt
(
new
)
;
if
(
unconfined
(
profile
)
||
(
cxt
->
profile
->
ns
!=
profile
->
ns
))
/* if switching to unconfined or a different profile namespace
* clear out context state
*/
aa_put_profile
(
cxt
->
previous
);
aa_put_profile
(
cxt
->
onexec
);
cxt
->
previous
=
NULL
;
cxt
->
onexec
=
NULL
;
cxt
->
token
=
0
;
}
aa_clear_task_cxt_trans
(
cxt
);
/* be careful switching cxt->profile, when racing replacement it
* is possible that cxt->profile->replacedby is the reference keeping
* @profile valid, so make sure to get its reference before dropping
...
...
@@ -123,7 +136,7 @@ int aa_set_current_onexec(struct aa_profile *profile)
if
(
!
new
)
return
-
ENOMEM
;
cxt
=
new
->
security
;
cxt
=
cred_cxt
(
new
)
;
aa_get_profile
(
profile
);
aa_put_profile
(
cxt
->
onexec
);
cxt
->
onexec
=
profile
;
...
...
@@ -150,7 +163,7 @@ int aa_set_current_hat(struct aa_profile *profile, u64 token)
return
-
ENOMEM
;
BUG_ON
(
!
profile
);
cxt
=
new
->
security
;
cxt
=
cred_cxt
(
new
)
;
if
(
!
cxt
->
previous
)
{
/* transfer refcount */
cxt
->
previous
=
cxt
->
profile
;
...
...
@@ -187,7 +200,7 @@ int aa_restore_previous_profile(u64 token)
if
(
!
new
)
return
-
ENOMEM
;
cxt
=
new
->
security
;
cxt
=
cred_cxt
(
new
)
;
if
(
cxt
->
token
!=
token
)
{
abort_creds
(
new
);
return
-
EACCES
;
...
...
@@ -205,11 +218,10 @@ int aa_restore_previous_profile(u64 token)
aa_get_profile
(
cxt
->
profile
);
aa_put_profile
(
cxt
->
previous
);
}
/*
clear exec && prev information when restoring to previous conte
xt */
/*
ref has been transfered so avoid putting ref in clear_task_c
xt */
cxt
->
previous
=
NULL
;
cxt
->
token
=
0
;
aa_put_profile
(
cxt
->
onexec
);
cxt
->
onexec
=
NULL
;
/* clear exec && prev information when restoring to previous context */
aa_clear_task_cxt_trans
(
cxt
);
commit_creds
(
new
);
return
0
;
...
...
security/apparmor/domain.c
View file @
bd71164a
...
...
@@ -62,17 +62,14 @@ static int may_change_ptraced_domain(struct task_struct *task,
struct
aa_profile
*
to_profile
)
{
struct
task_struct
*
tracer
;
const
struct
cred
*
cred
=
NULL
;
struct
aa_profile
*
tracerp
=
NULL
;
int
error
=
0
;
rcu_read_lock
();
tracer
=
ptrace_parent
(
task
);
if
(
tracer
)
{
if
(
tracer
)
/* released below */
cred
=
get_task_cred
(
tracer
);
tracerp
=
aa_cred_profile
(
cred
);
}
tracerp
=
aa_get_task_profile
(
tracer
);
/* not ptraced */
if
(
!
tracer
||
unconfined
(
tracerp
))
...
...
@@ -82,8 +79,7 @@ static int may_change_ptraced_domain(struct task_struct *task,
out:
rcu_read_unlock
();
if
(
cred
)
put_cred
(
cred
);
aa_put_profile
(
tracerp
);
return
error
;
}
...
...
@@ -360,7 +356,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if
(
bprm
->
cred_prepared
)
return
0
;
cxt
=
bprm
->
cred
->
security
;
cxt
=
cred_cxt
(
bprm
->
cred
)
;
BUG_ON
(
!
cxt
);
profile
=
aa_get_profile
(
aa_newest_version
(
cxt
->
profile
));
...
...
@@ -443,6 +439,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
}
else
{
error
=
-
ENOENT
;
info
=
"profile not found"
;
/* remove MAY_EXEC to audit as failure */
perms
.
allow
&=
~
MAY_EXEC
;
}
}
}
else
if
(
COMPLAIN_MODE
(
profile
))
{
...
...
@@ -514,11 +512,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
cxt
->
profile
=
new_profile
;
/* clear out all temporary/transitional state from the context */
aa_put_profile
(
cxt
->
previous
);
aa_put_profile
(
cxt
->
onexec
);
cxt
->
previous
=
NULL
;
cxt
->
onexec
=
NULL
;
cxt
->
token
=
0
;
aa_clear_task_cxt_trans
(
cxt
);
audit:
error
=
aa_audit_file
(
profile
,
&
perms
,
GFP_KERNEL
,
OP_EXEC
,
MAY_EXEC
,
...
...
@@ -557,7 +551,7 @@ int apparmor_bprm_secureexec(struct linux_binprm *bprm)
void
apparmor_bprm_committing_creds
(
struct
linux_binprm
*
bprm
)
{
struct
aa_profile
*
profile
=
__aa_current_profile
();
struct
aa_task_cxt
*
new_cxt
=
bprm
->
cred
->
security
;
struct
aa_task_cxt
*
new_cxt
=
cred_cxt
(
bprm
->
cred
)
;
/* bail out if unconfined or not changing profile */
if
((
new_cxt
->
profile
==
profile
)
||
...
...
@@ -634,7 +628,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
/* released below */
cred
=
get_current_cred
();
cxt
=
cred
->
security
;
cxt
=
cred
_cxt
(
cred
)
;
profile
=
aa_cred_profile
(
cred
);
previous_profile
=
cxt
->
previous
;
...
...
@@ -750,7 +744,6 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
bool
permtest
)
{
const
struct
cred
*
cred
;
struct
aa_task_cxt
*
cxt
;
struct
aa_profile
*
profile
,
*
target
=
NULL
;
struct
aa_namespace
*
ns
=
NULL
;
struct
file_perms
perms
=
{};
...
...
@@ -770,7 +763,6 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
}
cred
=
get_current_cred
();
cxt
=
cred
->
security
;
profile
=
aa_cred_profile
(
cred
);
/*
...
...
security/apparmor/include/apparmor.h
View file @
bd71164a
...
...
@@ -15,6 +15,7 @@
#ifndef __APPARMOR_H
#define __APPARMOR_H
#include <linux/slab.h>
#include <linux/fs.h>
#include "match.h"
...
...
@@ -64,9 +65,18 @@ extern int apparmor_initialized __initdata;
/* fn's in lib */
char
*
aa_split_fqname
(
char
*
args
,
char
**
ns_name
);
void
aa_info_message
(
const
char
*
str
);
void
*
kvmalloc
(
size_t
size
);
void
*
__aa_kvmalloc
(
size_t
size
,
gfp_t
flags
);
void
kvfree
(
void
*
buffer
);
static
inline
void
*
kvmalloc
(
size_t
size
)
{
return
__aa_kvmalloc
(
size
,
0
);
}
static
inline
void
*
kvzalloc
(
size_t
size
)
{
return
__aa_kvmalloc
(
size
,
__GFP_ZERO
);
}
/**
* aa_strneq - compare null terminated @str to a non null terminated substring
...
...
security/apparmor/include/context.h
View file @
bd71164a
...
...
@@ -21,6 +21,9 @@
#include "policy.h"
#define cred_cxt(X) (X)->security
#define current_cxt() cred_cxt(current_cred())
/* struct aa_file_cxt - the AppArmor context the file was opened in
* @perms: the permission the file was opened with
*
...
...
@@ -80,23 +83,8 @@ int aa_replace_current_profile(struct aa_profile *profile);
int
aa_set_current_onexec
(
struct
aa_profile
*
profile
);
int
aa_set_current_hat
(
struct
aa_profile
*
profile
,
u64
token
);
int
aa_restore_previous_profile
(
u64
cookie
);
struct
aa_profile
*
aa_get_task_profile
(
struct
task_struct
*
task
);
/**
* __aa_task_is_confined - determine if @task has any confinement
* @task: task to check confinement of (NOT NULL)
*
* If @task != current needs to be called in RCU safe critical section
*/
static
inline
bool
__aa_task_is_confined
(
struct
task_struct
*
task
)
{
struct
aa_task_cxt
*
cxt
=
__task_cred
(
task
)
->
security
;
BUG_ON
(
!
cxt
||
!
cxt
->
profile
);
if
(
unconfined
(
aa_newest_version
(
cxt
->
profile
)))
return
0
;
return
1
;
}
/**
* aa_cred_profile - obtain cred's profiles
...
...
@@ -108,11 +96,35 @@ static inline bool __aa_task_is_confined(struct task_struct *task)
*/
static
inline
struct
aa_profile
*
aa_cred_profile
(
const
struct
cred
*
cred
)
{
struct
aa_task_cxt
*
cxt
=
cred
->
security
;
struct
aa_task_cxt
*
cxt
=
cred
_cxt
(
cred
)
;
BUG_ON
(
!
cxt
||
!
cxt
->
profile
);
return
aa_newest_version
(
cxt
->
profile
);
}
/**
* __aa_task_profile - retrieve another task's profile
* @task: task to query (NOT NULL)
*
* Returns: @task's profile without incrementing its ref count
*
* If @task != current needs to be called in RCU safe critical section
*/
static
inline
struct
aa_profile
*
__aa_task_profile
(
struct
task_struct
*
task
)
{
return
aa_cred_profile
(
__task_cred
(
task
));
}
/**
* __aa_task_is_confined - determine if @task has any confinement
* @task: task to check confinement of (NOT NULL)
*
* If @task != current needs to be called in RCU safe critical section
*/
static
inline
bool
__aa_task_is_confined
(
struct
task_struct
*
task
)
{
return
!
unconfined
(
__aa_task_profile
(
task
));
}
/**
* __aa_current_profile - find the current tasks confining profile
*
...
...
@@ -136,7 +148,7 @@ static inline struct aa_profile *__aa_current_profile(void)
*/
static
inline
struct
aa_profile
*
aa_current_profile
(
void
)
{
const
struct
aa_task_cxt
*
cxt
=
current_c
red
()
->
security
;
const
struct
aa_task_cxt
*
cxt
=
current_c
xt
()
;
struct
aa_profile
*
profile
;
BUG_ON
(
!
cxt
||
!
cxt
->
profile
);
...
...
@@ -151,4 +163,17 @@ static inline struct aa_profile *aa_current_profile(void)
return
profile
;
}
/**
* aa_clear_task_cxt_trans - clear transition tracking info from the cxt
* @cxt: task context to clear (NOT NULL)
*/
static
inline
void
aa_clear_task_cxt_trans
(
struct
aa_task_cxt
*
cxt
)
{
aa_put_profile
(
cxt
->
previous
);
aa_put_profile
(
cxt
->
onexec
);
cxt
->
previous
=
NULL
;
cxt
->
onexec
=
NULL
;
cxt
->
token
=
0
;
}
#endif
/* __AA_CONTEXT_H */
security/apparmor/include/file.h
View file @
bd71164a
...
...
@@ -186,11 +186,6 @@ static inline void aa_free_file_rules(struct aa_file_rules *rules)
aa_free_domain_entries
(
&
rules
->
trans
);
}
#define ACC_FMODE(x) (("\000\004\002\006"[(x)&O_ACCMODE]) | (((x) << 1) & 0x40))
/* from namei.c */
#define MAP_OPEN_FLAGS(x) ((((x) + 1) & O_ACCMODE) ? (x) + 1 : (x))
/**
* aa_map_file_perms - map file flags to AppArmor permissions
* @file: open file to map flags to AppArmor permissions
...
...
@@ -199,8 +194,13 @@ static inline void aa_free_file_rules(struct aa_file_rules *rules)
*/
static
inline
u32
aa_map_file_to_perms
(
struct
file
*
file
)
{
int
flags
=
MAP_OPEN_FLAGS
(
file
->
f_flags
);
u32
perms
=
ACC_FMODE
(
file
->
f_mode
);
int
flags
=
file
->
f_flags
;
u32
perms
=
0
;
if
(
file
->
f_mode
&
FMODE_WRITE
)
perms
|=
MAY_WRITE
;
if
(
file
->
f_mode
&
FMODE_READ
)
perms
|=
MAY_READ
;
if
((
flags
&
O_APPEND
)
&&
(
perms
&
MAY_WRITE
))
perms
=
(
perms
&
~
MAY_WRITE
)
|
MAY_APPEND
;
...
...
security/apparmor/include/match.h
View file @
bd71164a
...
...
@@ -4,7 +4,7 @@
* This file contains AppArmor policy dfa matching engine definitions.
*
* Copyright (C) 1998-2008 Novell/SUSE
* Copyright 2009-201
0
Canonical Ltd.
* Copyright 2009-201
2
Canonical Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
...
...
@@ -16,25 +16,30 @@
#define __AA_MATCH_H
#include <linux/kref.h>
#include <linux/workqueue.h>
#define DFA_NOMATCH 0
#define DFA_START 1
#define DFA_VALID_PERM_MASK 0xffffffff
#define DFA_VALID_PERM2_MASK 0xffffffff
/**
* The format used for transition tables is based on the GNU flex table
* file format (--tables-file option; see Table File Format in the flex
* info pages and the flex sources for documentation). The magic number
* used in the header is 0x1B5E783D instead of 0xF13C57B1 though, because
* the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used
* slightly differently (see the apparmor-parser package).
* new tables have been defined and others YY_ID_CHK (check) and YY_ID_DEF
* (default) tables are used slightly differently (see the apparmor-parser
* package).
*
*
* The data in the packed dfa is stored in network byte order, and the tables
* are arranged for flexibility. We convert the table data to host native
* byte order.
*
* The dfa begins with a table set header, and is followed by the actual
* tables.
*/
#define YYTH_MAGIC 0x1B5E783D
#define YYTH_DEF_RECURSE 0x1
/* DEF Table is recursive */
struct
table_set_header
{
u32
th_magic
;
/* YYTH_MAGIC */
...
...
@@ -63,7 +68,7 @@ struct table_set_header {
#define YYTD_DATA32 4
#define YYTD_DATA64 8
/*
Each ACCEPT2 table
gets 6 dedicated flags, YYTD_DATAX define the
/*
ACCEPT & ACCEPT2 tables
gets 6 dedicated flags, YYTD_DATAX define the
* first flags
*/
#define ACCEPT1_FLAGS(X) ((X) & 0x3f)
...
...
security/apparmor/include/policy.h
View file @
bd71164a
...
...
@@ -32,13 +32,13 @@
extern
const
char
*
const
profile_mode_names
[];
#define APPARMOR_NAMES_MAX_INDEX 3
#define
COMPLAIN_MODE(_profile)
\
((aa_g_profile_mode ==
APPARMOR_COMPLAIN) ||
\
((_profile)->mode ==
APPARMOR_COMPLAIN
))
#define
PROFILE_MODE(_profile, _mode)
\
((aa_g_profile_mode ==
(_mode)) ||
\
((_profile)->mode ==
(_mode)
))
#define
KILL_MODE(_profile) \
((aa_g_profile_mode == APPARMOR_KILL) || \
((_profile)->mode == APPARMOR_KILL)
)
#define
COMPLAIN_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_COMPLAIN)
#define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL
)
#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)
...
...
@@ -105,6 +105,7 @@ struct aa_ns_acct {
* @acct: accounting for the namespace
* @unconfined: special unconfined profile for the namespace
* @sub_ns: list of namespaces under the current namespace.
* @uniq_null: uniq value used for null learning profiles
*
* An aa_namespace defines the set profiles that are searched to determine
* which profile to attach to a task. Profiles can not be shared between
...
...
@@ -127,6 +128,7 @@ struct aa_namespace {
struct
aa_ns_acct
acct
;
struct
aa_profile
*
unconfined
;
struct
list_head
sub_ns
;
atomic_t
uniq_null
;
};
/* struct aa_policydb - match engine for a policy
...
...
@@ -148,7 +150,6 @@ struct aa_policydb {
* @rename: optional profile name that this profile renamed
* @xmatch: optional extended matching for unconfined executables names
* @xmatch_len: xmatch prefix len, used to determine xmatch priority
* @sid: the unique security id number of this profile
* @audit: the auditing mode of the profile
* @mode: the enforcement mode of the profile
* @flags: flags controlling profile behavior
...
...
@@ -184,7 +185,6 @@ struct aa_profile {
struct
aa_dfa
*
xmatch
;
int
xmatch_len
;
u32
sid
;
enum
audit_mode
audit
;
enum
profile_mode
mode
;
u32
flags
;
...
...
security/apparmor/include/procattr.h
View file @
bd71164a
...
...
@@ -21,6 +21,5 @@
int
aa_getprocattr
(
struct
aa_profile
*
profile
,
char
**
string
);
int
aa_setprocattr_changehat
(
char
*
args
,
size_t
size
,
int
test
);
int
aa_setprocattr_changeprofile
(
char
*
fqname
,
bool
onexec
,
int
test
);
int
aa_setprocattr_permipc
(
char
*
fqname
);
#endif
/* __AA_PROCATTR_H */
security/apparmor/include/sid.h
View file @
bd71164a
...
...
@@ -16,7 +16,9 @@
#include <linux/types.h>
struct
aa_profile
;
/* sid value that will not be allocated */
#define AA_SID_INVALID 0
#define AA_SID_ALLOC AA_SID_INVALID
u32
aa_alloc_sid
(
void
);
void
aa_free_sid
(
u32
sid
);
...
...
security/apparmor/ipc.c
View file @
bd71164a
...
...
@@ -95,23 +95,18 @@ int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
* - tracer profile has CAP_SYS_PTRACE
*/
struct
aa_profile
*
tracer_p
;
/* cred released below */
const
struct
cred
*
cred
=
get_task_cred
(
tracer
);
struct
aa_profile
*
tracer_p
=
aa_get_task_profile
(
tracer
);
int
error
=
0
;
tracer_p
=
aa_cred_profile
(
cred
);
if
(
!
unconfined
(
tracer_p
))
{
/* lcred released below */
const
struct
cred
*
lcred
=
get_task_cred
(
tracee
);
struct
aa_profile
*
tracee_p
=
aa_cred_profile
(
lcred
);
struct
aa_profile
*
tracee_p
=
aa_get_task_profile
(
tracee
);
error
=
aa_may_ptrace
(
tracer
,
tracer_p
,
tracee_p
,
mode
);
error
=
aa_audit_ptrace
(
tracer_p
,
tracee_p
,
error
);
put_cred
(
lcred
);
aa_put_profile
(
tracee_p
);
}
put_cred
(
cred
);
aa_put_profile
(
tracer_p
);
return
error
;
}
security/apparmor/lib.c
View file @
bd71164a
...
...
@@ -45,8 +45,10 @@ char *aa_split_fqname(char *fqname, char **ns_name)
*
ns_name
=
skip_spaces
(
&
name
[
1
]);
if
(
split
)
{
/* overwrite ':' with \0 */
*
split
=
0
;
name
=
skip_spaces
(
split
+
1
);
*
split
++
=
0
;
if
(
strncmp
(
split
,
"//"
,
2
)
==
0
)
split
+=
2
;
name
=
skip_spaces
(
split
);
}
else
/* a ns name without a following profile is allowed */
name
=
NULL
;
...
...
@@ -75,15 +77,16 @@ void aa_info_message(const char *str)
}
/**
* kvmalloc - do allocation preferring kmalloc but falling back to vmalloc
* @size: size of allocation
* __aa_kvmalloc - do allocation preferring kmalloc but falling back to vmalloc
* @size: how many bytes of memory are required
* @flags: the type of memory to allocate (see kmalloc).
*
* Return: allocated buffer or NULL if failed
*
* It is possible that policy being loaded from the user is larger than
* what can be allocated by kmalloc, in those cases fall back to vmalloc.
*/
void
*
kvmalloc
(
size_t
size
)
void
*
__aa_kvmalloc
(
size_t
size
,
gfp_t
flags
)
{
void
*
buffer
=
NULL
;
...
...
@@ -92,14 +95,17 @@ void *kvmalloc(size_t size)
/* do not attempt kmalloc if we need more than 16 pages at once */
if
(
size
<=
(
16
*
PAGE_SIZE
))
buffer
=
kmalloc
(
size
,
GFP_NOIO
|
__GFP_NOWARN
);
buffer
=
kmalloc
(
size
,
flags
|
GFP_NOIO
|
__GFP_NOWARN
);
if
(
!
buffer
)
{
/* see kvfree for why size must be at least work_struct size
* when allocated via vmalloc
*/
if
(
size
<
sizeof
(
struct
work_struct
))
size
=
sizeof
(
struct
work_struct
);
buffer
=
vmalloc
(
size
);
if
(
flags
&
__GFP_ZERO
)
buffer
=
vzalloc
(
size
);
else
buffer
=
vmalloc
(
size
);
}
return
buffer
;
}
...
...
security/apparmor/lsm.c
View file @
bd71164a
...
...
@@ -48,8 +48,8 @@ int apparmor_initialized __initdata;
*/
static
void
apparmor_cred_free
(
struct
cred
*
cred
)
{
aa_free_task_context
(
cred
->
security
);
cred
->
security
=
NULL
;
aa_free_task_context
(
cred
_cxt
(
cred
)
);
cred
_cxt
(
cred
)
=
NULL
;
}
/*
...
...
@@ -62,7 +62,7 @@ static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp)
if
(
!
cxt
)
return
-
ENOMEM
;
cred
->
security
=
cxt
;
cred
_cxt
(
cred
)
=
cxt
;
return
0
;
}
...
...
@@ -77,8 +77,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
if
(
!
cxt
)
return
-
ENOMEM
;
aa_dup_task_context
(
cxt
,
old
->
security
);
new
->
security
=
cxt
;
aa_dup_task_context
(
cxt
,
cred_cxt
(
old
)
);
cred_cxt
(
new
)
=
cxt
;
return
0
;
}
...
...
@@ -87,8 +87,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
*/
static
void
apparmor_cred_transfer
(
struct
cred
*
new
,
const
struct
cred
*
old
)
{
const
struct
aa_task_cxt
*
old_cxt
=
old
->
security
;
struct
aa_task_cxt
*
new_cxt
=
new
->
security
;
const
struct
aa_task_cxt
*
old_cxt
=
cred_cxt
(
old
)
;
struct
aa_task_cxt
*
new_cxt
=
cred_cxt
(
new
)
;
aa_dup_task_context
(
new_cxt
,
old_cxt
);
}
...
...
@@ -469,7 +469,6 @@ static int apparmor_file_lock(struct file *file, unsigned int cmd)
static
int
common_mmap
(
int
op
,
struct
file
*
file
,
unsigned
long
prot
,
unsigned
long
flags
)
{
struct
dentry
*
dentry
;
int
mask
=
0
;
if
(
!
file
||
!
file
->
f_security
)
...
...
@@ -486,7 +485,6 @@ static int common_mmap(int op, struct file *file, unsigned long prot,
if
(
prot
&
PROT_EXEC
)
mask
|=
AA_EXEC_MMAP
;
dentry
=
file
->
f_path
.
dentry
;
return
common_file_perm
(
op
,
file
,
mask
);
}
...
...
@@ -507,11 +505,9 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
char
**
value
)
{
int
error
=
-
ENOENT
;
struct
aa_profile
*
profile
;
/* released below */
const
struct
cred
*
cred
=
get_task_cred
(
task
);
struct
aa_task_cxt
*
cxt
=
cred
->
security
;
profile
=
aa_cred_profile
(
cred
);
struct
aa_task_cxt
*
cxt
=
cred_cxt
(
cred
);
if
(
strcmp
(
name
,
"current"
)
==
0
)
error
=
aa_getprocattr
(
aa_newest_version
(
cxt
->
profile
),
...
...
@@ -533,6 +529,8 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
static
int
apparmor_setprocattr
(
struct
task_struct
*
task
,
char
*
name
,
void
*
value
,
size_t
size
)
{
struct
common_audit_data
sa
;
struct
apparmor_audit_data
aad
=
{
0
,};
char
*
command
,
*
args
=
value
;
size_t
arg_size
;
int
error
;
...
...
@@ -576,30 +574,31 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
}
else
if
(
strcmp
(
command
,
"permprofile"
)
==
0
)
{
error
=
aa_setprocattr_changeprofile
(
args
,
!
AA_ONEXEC
,
AA_DO_TEST
);
}
else
if
(
strcmp
(
command
,
"permipc"
)
==
0
)
{
error
=
aa_setprocattr_permipc
(
args
);
}
else
{
struct
common_audit_data
sa
;
struct
apparmor_audit_data
aad
=
{
0
,};
sa
.
type
=
LSM_AUDIT_DATA_NONE
;
sa
.
aad
=
&
aad
;
aad
.
op
=
OP_SETPROCATTR
;
aad
.
info
=
name
;
aad
.
error
=
-
EINVAL
;
return
aa_audit
(
AUDIT_APPARMOR_DENIED
,
__aa_current_profile
(),
GFP_KERNEL
,
&
sa
,
NULL
);
}
}
else
goto
fail
;
}
else
if
(
strcmp
(
name
,
"exec"
)
==
0
)
{
error
=
aa_setprocattr_changeprofile
(
args
,
AA_ONEXEC
,
!
AA_DO_TEST
);
}
else
{
if
(
strcmp
(
command
,
"exec"
)
==
0
)
error
=
aa_setprocattr_changeprofile
(
args
,
AA_ONEXEC
,
!
AA_DO_TEST
);
else
goto
fail
;
}
else
/* only support the "current" and "exec" process attributes */
return
-
EINVAL
;
}
if
(
!
error
)
error
=
size
;
return
error
;
fail:
sa
.
type
=
LSM_AUDIT_DATA_NONE
;
sa
.
aad
=
&
aad
;
aad
.
profile
=
aa_current_profile
();
aad
.
op
=
OP_SETPROCATTR
;
aad
.
info
=
name
;
aad
.
error
=
-
EINVAL
;
aa_audit_msg
(
AUDIT_APPARMOR_DENIED
,
&
sa
,
NULL
);
return
-
EINVAL
;
}
static
int
apparmor_task_setrlimit
(
struct
task_struct
*
task
,
...
...
@@ -886,7 +885,7 @@ static int __init set_init_cxt(void)
return
-
ENOMEM
;
cxt
->
profile
=
aa_get_profile
(
root_ns
->
unconfined
);
cred
->
security
=
cxt
;
cred
_cxt
(
cred
)
=
cxt
;
return
0
;
}
...
...
@@ -915,8 +914,11 @@ static int __init apparmor_init(void)
error
=
register_security
(
&
apparmor_ops
);
if
(
error
)
{
struct
cred
*
cred
=
(
struct
cred
*
)
current
->
real_cred
;
aa_free_task_context
(
cred_cxt
(
cred
));
cred_cxt
(
cred
)
=
NULL
;
AA_ERROR
(
"Unable to register AppArmor
\n
"
);
goto
set_init_cxt
_out
;
goto
register_security
_out
;
}
/* Report that AppArmor successfully initialized */
...
...
@@ -930,9 +932,6 @@ static int __init apparmor_init(void)
return
error
;
set_init_cxt_out:
aa_free_task_context
(
current
->
real_cred
->
security
);
register_security_out:
aa_free_root_ns
();
...
...
security/apparmor/match.c
View file @
bd71164a
...
...
@@ -4,7 +4,7 @@
* This file contains AppArmor dfa based regular expression matching engine
*
* Copyright (C) 1998-2008 Novell/SUSE
* Copyright 2009-201
0
Canonical Ltd.
* Copyright 2009-201
2
Canonical Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
...
...
@@ -23,6 +23,8 @@
#include "include/apparmor.h"
#include "include/match.h"
#define base_idx(X) ((X) & 0xffffff)
/**
* unpack_table - unpack a dfa table (one of accept, default, base, next check)
* @blob: data to unpack (NOT NULL)
...
...
@@ -30,7 +32,7 @@
*
* Returns: pointer to table else NULL on failure
*
* NOTE: must be freed by kvfree (not k
malloc
)
* NOTE: must be freed by kvfree (not k
free
)
*/
static
struct
table_header
*
unpack_table
(
char
*
blob
,
size_t
bsize
)
{
...
...
@@ -57,7 +59,7 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
if
(
bsize
<
tsize
)
goto
out
;
table
=
kv
m
alloc
(
tsize
);
table
=
kv
z
alloc
(
tsize
);
if
(
table
)
{
*
table
=
th
;
if
(
th
.
td_flags
==
YYTD_DATA8
)
...
...
@@ -137,8 +139,7 @@ static int verify_dfa(struct aa_dfa *dfa, int flags)
for
(
i
=
0
;
i
<
state_count
;
i
++
)
{
if
(
DEFAULT_TABLE
(
dfa
)[
i
]
>=
state_count
)
goto
out
;
/* TODO: do check that DEF state recursion terminates */
if
(
BASE_TABLE
(
dfa
)[
i
]
+
255
>=
trans_count
)
{
if
(
base_idx
(
BASE_TABLE
(
dfa
)[
i
])
+
255
>=
trans_count
)
{
printk
(
KERN_ERR
"AppArmor DFA next/check upper "
"bounds error
\n
"
);
goto
out
;
...
...
@@ -314,7 +315,7 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
u8
*
equiv
=
EQUIV_TABLE
(
dfa
);
/* default is direct to next state */
for
(;
len
;
len
--
)
{
pos
=
base
[
state
]
+
equiv
[(
u8
)
*
str
++
];
pos
=
base
_idx
(
base
[
state
])
+
equiv
[(
u8
)
*
str
++
];
if
(
check
[
pos
]
==
state
)
state
=
next
[
pos
];
else
...
...
@@ -323,7 +324,7 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
}
else
{
/* default is direct to next state */
for
(;
len
;
len
--
)
{
pos
=
base
[
state
]
+
(
u8
)
*
str
++
;
pos
=
base
_idx
(
base
[
state
])
+
(
u8
)
*
str
++
;
if
(
check
[
pos
]
==
state
)
state
=
next
[
pos
];
else
...
...
@@ -364,7 +365,7 @@ unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
u8
*
equiv
=
EQUIV_TABLE
(
dfa
);
/* default is direct to next state */
while
(
*
str
)
{
pos
=
base
[
state
]
+
equiv
[(
u8
)
*
str
++
];
pos
=
base
_idx
(
base
[
state
])
+
equiv
[(
u8
)
*
str
++
];
if
(
check
[
pos
]
==
state
)
state
=
next
[
pos
];
else
...
...
@@ -373,7 +374,7 @@ unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
}
else
{
/* default is direct to next state */
while
(
*
str
)
{
pos
=
base
[
state
]
+
(
u8
)
*
str
++
;
pos
=
base
_idx
(
base
[
state
])
+
(
u8
)
*
str
++
;
if
(
check
[
pos
]
==
state
)
state
=
next
[
pos
];
else
...
...
@@ -409,14 +410,14 @@ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
u8
*
equiv
=
EQUIV_TABLE
(
dfa
);
/* default is direct to next state */
pos
=
base
[
state
]
+
equiv
[(
u8
)
c
];
pos
=
base
_idx
(
base
[
state
])
+
equiv
[(
u8
)
c
];
if
(
check
[
pos
]
==
state
)
state
=
next
[
pos
];
else
state
=
def
[
state
];
}
else
{
/* default is direct to next state */
pos
=
base
[
state
]
+
(
u8
)
c
;
pos
=
base
_idx
(
base
[
state
])
+
(
u8
)
c
;
if
(
check
[
pos
]
==
state
)
state
=
next
[
pos
];
else
...
...
security/apparmor/path.c
View file @
bd71164a
...
...
@@ -174,7 +174,7 @@ static int get_name_to_buffer(struct path *path, int flags, char *buffer,
if
(
info
&&
error
)
{
if
(
error
==
-
ENOENT
)
*
info
=
"Failed name lookup - deleted entry"
;
else
if
(
error
==
-
E
STALE
)
else
if
(
error
==
-
E
ACCES
)
*
info
=
"Failed name lookup - disconnected path"
;
else
if
(
error
==
-
ENAMETOOLONG
)
*
info
=
"Failed name lookup - name too long"
;
...
...
security/apparmor/policy.c
View file @
bd71164a
...
...
@@ -87,7 +87,6 @@
#include "include/policy.h"
#include "include/policy_unpack.h"
#include "include/resource.h"
#include "include/sid.h"
/* root profile namespace */
...
...
@@ -292,7 +291,6 @@ static struct aa_namespace *alloc_namespace(const char *prefix,
if
(
!
ns
->
unconfined
)
goto
fail_unconfined
;
ns
->
unconfined
->
sid
=
aa_alloc_sid
();
ns
->
unconfined
->
flags
=
PFLAG_UNCONFINED
|
PFLAG_IX_ON_NAME_ERROR
|
PFLAG_IMMUTABLE
;
...
...
@@ -303,6 +301,8 @@ static struct aa_namespace *alloc_namespace(const char *prefix,
*/
ns
->
unconfined
->
ns
=
aa_get_namespace
(
ns
);
atomic_set
(
&
ns
->
uniq_null
,
0
);
return
ns
;
fail_unconfined:
...
...
@@ -497,7 +497,6 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
/* released when @new is freed */
new
->
parent
=
aa_get_profile
(
old
->
parent
);
new
->
ns
=
aa_get_namespace
(
old
->
ns
);
new
->
sid
=
old
->
sid
;
__list_add_profile
(
&
policy
->
profiles
,
new
);
/* inherit children */
list_for_each_entry_safe
(
child
,
tmp
,
&
old
->
base
.
profiles
,
base
.
list
)
{
...
...
@@ -635,83 +634,6 @@ void __init aa_free_root_ns(void)
aa_put_namespace
(
ns
);
}
/**
* aa_alloc_profile - allocate, initialize and return a new profile
* @hname: name of the profile (NOT NULL)
*
* Returns: refcount profile or NULL on failure
*/
struct
aa_profile
*
aa_alloc_profile
(
const
char
*
hname
)
{
struct
aa_profile
*
profile
;
/* freed by free_profile - usually through aa_put_profile */
profile
=
kzalloc
(
sizeof
(
*
profile
),
GFP_KERNEL
);
if
(
!
profile
)
return
NULL
;
if
(
!
policy_init
(
&
profile
->
base
,
NULL
,
hname
))
{
kzfree
(
profile
);
return
NULL
;
}
/* refcount released by caller */
return
profile
;
}
/**
* aa_new_null_profile - create a new null-X learning profile
* @parent: profile that caused this profile to be created (NOT NULL)
* @hat: true if the null- learning profile is a hat
*
* Create a null- complain mode profile used in learning mode. The name of
* the profile is unique and follows the format of parent//null-sid.
*
* null profiles are added to the profile list but the list does not
* hold a count on them so that they are automatically released when
* not in use.
*
* Returns: new refcounted profile else NULL on failure
*/
struct
aa_profile
*
aa_new_null_profile
(
struct
aa_profile
*
parent
,
int
hat
)
{
struct
aa_profile
*
profile
=
NULL
;
char
*
name
;
u32
sid
=
aa_alloc_sid
();
/* freed below */
name
=
kmalloc
(
strlen
(
parent
->
base
.
hname
)
+
2
+
7
+
8
,
GFP_KERNEL
);
if
(
!
name
)
goto
fail
;
sprintf
(
name
,
"%s//null-%x"
,
parent
->
base
.
hname
,
sid
);
profile
=
aa_alloc_profile
(
name
);
kfree
(
name
);
if
(
!
profile
)
goto
fail
;
profile
->
sid
=
sid
;
profile
->
mode
=
APPARMOR_COMPLAIN
;
profile
->
flags
=
PFLAG_NULL
;
if
(
hat
)
profile
->
flags
|=
PFLAG_HAT
;
/* released on free_profile */
profile
->
parent
=
aa_get_profile
(
parent
);
profile
->
ns
=
aa_get_namespace
(
parent
->
ns
);
write_lock
(
&
profile
->
ns
->
lock
);
__list_add_profile
(
&
parent
->
base
.
profiles
,
profile
);
write_unlock
(
&
profile
->
ns
->
lock
);
/* refcount released by caller */
return
profile
;
fail:
aa_free_sid
(
sid
);
return
NULL
;
}
/**
* free_profile - free a profile
* @profile: the profile to free (MAYBE NULL)
...
...
@@ -749,7 +671,6 @@ static void free_profile(struct aa_profile *profile)
aa_free_cap_rules
(
&
profile
->
caps
);
aa_free_rlimit_rules
(
&
profile
->
rlimits
);
aa_free_sid
(
profile
->
sid
);
aa_put_dfa
(
profile
->
xmatch
);
aa_put_dfa
(
profile
->
policy
.
dfa
);
...
...
@@ -790,6 +711,81 @@ void aa_free_profile_kref(struct kref *kref)
free_profile
(
p
);
}
/**
* aa_alloc_profile - allocate, initialize and return a new profile
* @hname: name of the profile (NOT NULL)
*
* Returns: refcount profile or NULL on failure
*/
struct
aa_profile
*
aa_alloc_profile
(
const
char
*
hname
)
{
struct
aa_profile
*
profile
;
/* freed by free_profile - usually through aa_put_profile */
profile
=
kzalloc
(
sizeof
(
*
profile
),
GFP_KERNEL
);
if
(
!
profile
)
return
NULL
;
if
(
!
policy_init
(
&
profile
->
base
,
NULL
,
hname
))
{
kzfree
(
profile
);
return
NULL
;
}
/* refcount released by caller */
return
profile
;
}
/**
* aa_new_null_profile - create a new null-X learning profile
* @parent: profile that caused this profile to be created (NOT NULL)
* @hat: true if the null- learning profile is a hat
*
* Create a null- complain mode profile used in learning mode. The name of
* the profile is unique and follows the format of parent//null-<uniq>.
*
* null profiles are added to the profile list but the list does not
* hold a count on them so that they are automatically released when
* not in use.
*
* Returns: new refcounted profile else NULL on failure
*/
struct
aa_profile
*
aa_new_null_profile
(
struct
aa_profile
*
parent
,
int
hat
)
{
struct
aa_profile
*
profile
=
NULL
;
char
*
name
;
int
uniq
=
atomic_inc_return
(
&
parent
->
ns
->
uniq_null
);
/* freed below */
name
=
kmalloc
(
strlen
(
parent
->
base
.
hname
)
+
2
+
7
+
8
,
GFP_KERNEL
);
if
(
!
name
)
goto
fail
;
sprintf
(
name
,
"%s//null-%x"
,
parent
->
base
.
hname
,
uniq
);
profile
=
aa_alloc_profile
(
name
);
kfree
(
name
);
if
(
!
profile
)
goto
fail
;
profile
->
mode
=
APPARMOR_COMPLAIN
;
profile
->
flags
=
PFLAG_NULL
;
if
(
hat
)
profile
->
flags
|=
PFLAG_HAT
;
/* released on free_profile */
profile
->
parent
=
aa_get_profile
(
parent
);
profile
->
ns
=
aa_get_namespace
(
parent
->
ns
);
write_lock
(
&
profile
->
ns
->
lock
);
__list_add_profile
(
&
parent
->
base
.
profiles
,
profile
);
write_unlock
(
&
profile
->
ns
->
lock
);
/* refcount released by caller */
return
profile
;
fail:
return
NULL
;
}
/* TODO: profile accounting - setup in remove */
/**
...
...
@@ -972,7 +968,6 @@ static void __add_new_profile(struct aa_namespace *ns, struct aa_policy *policy,
profile
->
parent
=
aa_get_profile
((
struct
aa_profile
*
)
policy
);
__list_add_profile
(
&
policy
->
profiles
,
profile
);
/* released on free_profile */
profile
->
sid
=
aa_alloc_sid
();
profile
->
ns
=
aa_get_namespace
(
ns
);
}
...
...
@@ -1110,14 +1105,8 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
if
(
!
error
)
{
if
(
rename_profile
)
__replace_profile
(
rename_profile
,
new_profile
);
if
(
old_profile
)
{
/* when there are both rename and old profiles
* inherit old profiles sid
*/
if
(
rename_profile
)
aa_free_sid
(
new_profile
->
sid
);
if
(
old_profile
)
__replace_profile
(
old_profile
,
new_profile
);
}
if
(
!
(
old_profile
||
rename_profile
))
__add_new_profile
(
ns
,
policy
,
new_profile
);
}
...
...
@@ -1167,14 +1156,12 @@ ssize_t aa_remove_profiles(char *fqname, size_t size)
if
(
fqname
[
0
]
==
':'
)
{
char
*
ns_name
;
name
=
aa_split_fqname
(
fqname
,
&
ns_name
);
if
(
ns_name
)
{
/* released below */
ns
=
aa_find_namespace
(
root
,
ns_name
);
if
(
!
ns
)
{
info
=
"namespace does not exist"
;
error
=
-
ENOENT
;
goto
fail
;
}
/* released below */
ns
=
aa_find_namespace
(
root
,
ns_name
);
if
(
!
ns
)
{
info
=
"namespace does not exist"
;
error
=
-
ENOENT
;
goto
fail
;
}
}
else
/* released below */
...
...
security/apparmor/policy_unpack.c
View file @
bd71164a
...
...
@@ -27,7 +27,6 @@
#include "include/match.h"
#include "include/policy.h"
#include "include/policy_unpack.h"
#include "include/sid.h"
/*
* The AppArmor interface treats data as a type byte followed by the
...
...
@@ -290,6 +289,9 @@ static int unpack_strdup(struct aa_ext *e, char **string, const char *name)
return
res
;
}
#define DFA_VALID_PERM_MASK 0xffffffff
#define DFA_VALID_PERM2_MASK 0xffffffff
/**
* verify_accept - verify the accept tables of a dfa
* @dfa: dfa to verify accept tables of (NOT NULL)
...
...
security/apparmor/procattr.c
View file @
bd71164a
...
...
@@ -163,9 +163,3 @@ int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test)
name
=
aa_split_fqname
(
fqname
,
&
ns_name
);
return
aa_change_profile
(
ns_name
,
name
,
onexec
,
test
);
}
int
aa_setprocattr_permipc
(
char
*
fqname
)
{
/* TODO: add ipc permission querying */
return
-
ENOTSUPP
;
}
security/apparmor/resource.c
View file @
bd71164a
...
...
@@ -15,6 +15,7 @@
#include <linux/audit.h>
#include "include/audit.h"
#include "include/context.h"
#include "include/resource.h"
#include "include/policy.h"
...
...
@@ -90,17 +91,25 @@ int aa_map_resource(int resource)
int
aa_task_setrlimit
(
struct
aa_profile
*
profile
,
struct
task_struct
*
task
,
unsigned
int
resource
,
struct
rlimit
*
new_rlim
)
{
struct
aa_profile
*
task_profile
;
int
error
=
0
;
rcu_read_lock
();
task_profile
=
aa_get_profile
(
aa_cred_profile
(
__task_cred
(
task
)));
rcu_read_unlock
();
/* TODO: extend resource control to handle other (non current)
* processes. AppArmor rules currently have the implicit assumption
* that the task is setting the resource of the current process
* profiles. AppArmor rules currently have the implicit assumption
* that the task is setting the resource of a task confined with
* the same profile.
*/
if
(
(
task
!=
current
->
group_leader
)
||
if
(
profile
!=
task_profile
||
(
profile
->
rlimits
.
mask
&
(
1
<<
resource
)
&&
new_rlim
->
rlim_max
>
profile
->
rlimits
.
limits
[
resource
].
rlim_max
))
error
=
-
EACCES
;
aa_put_profile
(
task_profile
);
return
audit_resource
(
profile
,
resource
,
new_rlim
->
rlim_max
,
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