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
6f98e892
Commit
6f98e892
authored
Sep 18, 2014
by
James Morris
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'smack-for-3.18' of
git://git.gitorious.org/smack-next/kernel
into next
parents
ac60ab4b
21c7eae2
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
520 additions
and
274 deletions
+520
-274
security/smack/Kconfig
security/smack/Kconfig
+16
-0
security/smack/smack.h
security/smack/smack.h
+20
-19
security/smack/smack_access.c
security/smack/smack_access.c
+51
-67
security/smack/smack_lsm.c
security/smack/smack_lsm.c
+388
-157
security/smack/smackfs.c
security/smack/smackfs.c
+45
-31
No files found.
security/smack/Kconfig
View file @
6f98e892
...
...
@@ -12,3 +12,19 @@ config SECURITY_SMACK
of other mandatory security schemes.
If you are unsure how to answer this question, answer N.
config SECURITY_SMACK_BRINGUP
bool "Reporting on access granted by Smack rules"
depends on SECURITY_SMACK
default n
help
Enable the bring-up ("b") access mode in Smack rules.
When access is granted by a rule with the "b" mode a
message about the access requested is generated. The
intention is that a process can be granted a wide set
of access initially with the bringup mode set on the
rules. The developer can use the information to
identify which rules are necessary and what accesses
may be inappropriate. The developer can reduce the
access rule set once the behavior is well understood.
This is a superior mechanism to the oft abused
"permissive" mode of other systems.
security/smack/smack.h
View file @
6f98e892
...
...
@@ -71,10 +71,10 @@ struct smack_known {
#define SMK_CIPSOLEN 24
struct
superblock_smack
{
char
*
smk_root
;
char
*
smk_floor
;
char
*
smk_hat
;
char
*
smk_default
;
struct
smack_known
*
smk_root
;
struct
smack_known
*
smk_floor
;
struct
smack_known
*
smk_hat
;
struct
smack_known
*
smk_default
;
int
smk_initialized
;
};
...
...
@@ -88,7 +88,7 @@ struct socket_smack {
* Inode smack data
*/
struct
inode_smack
{
char
*
smk_inode
;
/* label of the fso */
struct
smack_known
*
smk_inode
;
/* label of the fso */
struct
smack_known
*
smk_task
;
/* label of the task */
struct
smack_known
*
smk_mmap
;
/* label of the mmap domain */
struct
mutex
smk_lock
;
/* initialization lock */
...
...
@@ -112,7 +112,7 @@ struct task_smack {
struct
smack_rule
{
struct
list_head
list
;
struct
smack_known
*
smk_subject
;
char
*
smk_object
;
struct
smack_known
*
smk_object
;
int
smk_access
;
};
...
...
@@ -123,7 +123,7 @@ struct smk_netlbladdr {
struct
list_head
list
;
struct
sockaddr_in
smk_host
;
/* network address */
struct
in_addr
smk_mask
;
/* network mask */
char
*
smk_label
;
/* label */
struct
smack_known
*
smk_label
;
/* label */
};
/*
...
...
@@ -191,6 +191,7 @@ struct smk_port_label {
*/
#define MAY_TRANSMUTE 0x00001000
/* Controls directory labeling */
#define MAY_LOCK 0x00002000
/* Locks should be writes, but ... */
#define MAY_BRINGUP 0x00004000
/* Report use of this rule */
/*
* Just to make the common cases easier to deal with
...
...
@@ -200,9 +201,9 @@ struct smk_port_label {
#define MAY_NOT 0
/*
* Number of access types used by Smack (rwxatl)
* Number of access types used by Smack (rwxatl
b
)
*/
#define SMK_NUM_ACCESS_TYPE
6
#define SMK_NUM_ACCESS_TYPE
7
/* SMACK data */
struct
smack_audit_data
{
...
...
@@ -226,23 +227,23 @@ struct smk_audit_info {
/*
* These functions are in smack_lsm.c
*/
struct
inode_smack
*
new_inode_smack
(
char
*
);
struct
inode_smack
*
new_inode_smack
(
struct
smack_known
*
);
/*
* These functions are in smack_access.c
*/
int
smk_access_entry
(
char
*
,
char
*
,
struct
list_head
*
);
int
smk_access
(
struct
smack_known
*
,
char
*
,
int
,
struct
smk_audit_info
*
);
int
smk_tskacc
(
struct
task_smack
*
,
char
*
,
u32
,
struct
smk_audit_info
*
);
int
smk_curacc
(
char
*
,
u32
,
struct
smk_audit_info
*
);
int
smk_access
(
struct
smack_known
*
,
struct
smack_known
*
,
int
,
struct
smk_audit_info
*
);
int
smk_tskacc
(
struct
task_smack
*
,
struct
smack_known
*
,
u32
,
struct
smk_audit_info
*
);
int
smk_curacc
(
struct
smack_known
*
,
u32
,
struct
smk_audit_info
*
);
struct
smack_known
*
smack_from_secid
(
const
u32
);
char
*
smk_parse_smack
(
const
char
*
string
,
int
len
);
int
smk_netlbl_mls
(
int
,
char
*
,
struct
netlbl_lsm_secattr
*
,
int
);
char
*
smk_import
(
const
char
*
,
int
);
struct
smack_known
*
smk_import_entry
(
const
char
*
,
int
);
void
smk_insert_entry
(
struct
smack_known
*
skp
);
struct
smack_known
*
smk_find_entry
(
const
char
*
);
u32
smack_to_secid
(
const
char
*
);
/*
* Shared data.
...
...
@@ -252,7 +253,7 @@ extern int smack_cipso_mapped;
extern
struct
smack_known
*
smack_net_ambient
;
extern
struct
smack_known
*
smack_onlycap
;
extern
struct
smack_known
*
smack_syslog_label
;
extern
const
char
*
smack_cipso_option
;
extern
struct
smack_known
smack_cipso_option
;
extern
int
smack_ptrace_rule
;
extern
struct
smack_known
smack_known_floor
;
...
...
@@ -281,9 +282,9 @@ static inline int smk_inode_transmutable(const struct inode *isp)
}
/*
* Present a pointer to the smack label in an inode blob.
* Present a pointer to the smack label
entry
in an inode blob.
*/
static
inline
char
*
smk_of_inode
(
const
struct
inode
*
isp
)
static
inline
struct
smack_known
*
smk_of_inode
(
const
struct
inode
*
isp
)
{
struct
inode_smack
*
sip
=
isp
->
i_security
;
return
sip
->
smk_inode
;
...
...
security/smack/smack_access.c
View file @
6f98e892
...
...
@@ -94,7 +94,7 @@ int smk_access_entry(char *subject_label, char *object_label,
struct
smack_rule
*
srp
;
list_for_each_entry_rcu
(
srp
,
rule_list
,
list
)
{
if
(
srp
->
smk_object
==
object_label
&&
if
(
srp
->
smk_object
->
smk_known
==
object_label
&&
srp
->
smk_subject
->
smk_known
==
subject_label
)
{
may
=
srp
->
smk_access
;
break
;
...
...
@@ -111,8 +111,8 @@ int smk_access_entry(char *subject_label, char *object_label,
/**
* smk_access - determine if a subject has a specific access to an object
* @subject
_known
: a pointer to the subject's Smack label entry
* @object
_label: a pointer to the object's Smack label
* @subject: a pointer to the subject's Smack label entry
* @object
: a pointer to the object's Smack label entry
* @request: the access requested, in "MAY" format
* @a : a pointer to the audit data
*
...
...
@@ -122,7 +122,7 @@ int smk_access_entry(char *subject_label, char *object_label,
*
* Smack labels are shared on smack_list
*/
int
smk_access
(
struct
smack_known
*
subject
_known
,
char
*
object_label
,
int
smk_access
(
struct
smack_known
*
subject
,
struct
smack_known
*
object
,
int
request
,
struct
smk_audit_info
*
a
)
{
int
may
=
MAY_NOT
;
...
...
@@ -133,7 +133,7 @@ int smk_access(struct smack_known *subject_known, char *object_label,
*
* A star subject can't access any object.
*/
if
(
subject
_known
==
&
smack_known_star
)
{
if
(
subject
==
&
smack_known_star
)
{
rc
=
-
EACCES
;
goto
out_audit
;
}
...
...
@@ -142,28 +142,28 @@ int smk_access(struct smack_known *subject_known, char *object_label,
* Tasks cannot be assigned the internet label.
* An internet subject can access any object.
*/
if
(
object
_label
==
smack_known_web
.
smk_known
||
subject
_known
==
&
smack_known_web
)
if
(
object
==
&
smack_known_web
||
subject
==
&
smack_known_web
)
goto
out_audit
;
/*
* A star object can be accessed by any subject.
*/
if
(
object
_label
==
smack_known_star
.
smk_known
)
if
(
object
==
&
smack_known_star
)
goto
out_audit
;
/*
* An object can be accessed in any way by a subject
* with the same label.
*/
if
(
subject
_known
->
smk_known
==
object_label
)
if
(
subject
->
smk_known
==
object
->
smk_known
)
goto
out_audit
;
/*
* A hat subject can read any object.
* A floor object can be read by any subject.
*/
if
((
request
&
MAY_ANYREAD
)
==
request
)
{
if
(
object
_label
==
smack_known_floor
.
smk_known
)
if
(
object
==
&
smack_known_floor
)
goto
out_audit
;
if
(
subject
_known
==
&
smack_known_hat
)
if
(
subject
==
&
smack_known_hat
)
goto
out_audit
;
}
/*
...
...
@@ -174,27 +174,38 @@ int smk_access(struct smack_known *subject_known, char *object_label,
* indicates there is no entry for this pair.
*/
rcu_read_lock
();
may
=
smk_access_entry
(
subject
_known
->
smk_known
,
object_label
,
&
subject_known
->
smk_rules
);
may
=
smk_access_entry
(
subject
->
smk_known
,
object
->
smk_known
,
&
subject
->
smk_rules
);
rcu_read_unlock
();
if
(
may
>
0
&&
(
request
&
may
)
==
request
)
if
(
may
<=
0
||
(
request
&
may
)
!=
request
)
{
rc
=
-
EACCES
;
goto
out_audit
;
}
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
/*
* Return a positive value if using bringup mode.
* This allows the hooks to identify checks that
* succeed because of "b" rules.
*/
if
(
may
&
MAY_BRINGUP
)
rc
=
MAY_BRINGUP
;
#endif
rc
=
-
EACCES
;
out_audit:
#ifdef CONFIG_AUDIT
if
(
a
)
smack_log
(
subject
_known
->
smk_known
,
object_label
,
request
,
rc
,
a
);
smack_log
(
subject
->
smk_known
,
object
->
smk_known
,
request
,
rc
,
a
);
#endif
return
rc
;
}
/**
* smk_tskacc - determine if a task has a specific access to an object
* @tsp: a pointer to the subject task
* @obj_
label: a pointer to the object's Smack label
* @tsp: a pointer to the subject
's
task
* @obj_
known: a pointer to the object's label entry
* @mode: the access requested, in "MAY" format
* @a : common audit data
*
...
...
@@ -203,24 +214,25 @@ int smk_access(struct smack_known *subject_known, char *object_label,
* non zero otherwise. It allows that the task may have the capability
* to override the rules.
*/
int
smk_tskacc
(
struct
task_smack
*
subject
,
char
*
obj_label
,
int
smk_tskacc
(
struct
task_smack
*
tsp
,
struct
smack_known
*
obj_known
,
u32
mode
,
struct
smk_audit_info
*
a
)
{
struct
smack_known
*
s
kp
=
smk_of_task
(
subject
);
struct
smack_known
*
s
bj_known
=
smk_of_task
(
tsp
);
int
may
;
int
rc
;
/*
* Check the global rule list
*/
rc
=
smk_access
(
s
kp
,
obj_label
,
mode
,
NULL
);
if
(
rc
=
=
0
)
{
rc
=
smk_access
(
s
bj_known
,
obj_known
,
mode
,
NULL
);
if
(
rc
>
=
0
)
{
/*
* If there is an entry in the task's rule list
* it can further restrict access.
*/
may
=
smk_access_entry
(
skp
->
smk_known
,
obj_label
,
&
subject
->
smk_rules
);
may
=
smk_access_entry
(
sbj_known
->
smk_known
,
obj_known
->
smk_known
,
&
tsp
->
smk_rules
);
if
(
may
<
0
)
goto
out_audit
;
if
((
mode
&
may
)
==
mode
)
...
...
@@ -237,14 +249,15 @@ int smk_tskacc(struct task_smack *subject, char *obj_label,
out_audit:
#ifdef CONFIG_AUDIT
if
(
a
)
smack_log
(
skp
->
smk_known
,
obj_label
,
mode
,
rc
,
a
);
smack_log
(
sbj_known
->
smk_known
,
obj_known
->
smk_known
,
mode
,
rc
,
a
);
#endif
return
rc
;
}
/**
* smk_curacc - determine if current has a specific access to an object
* @obj_
label: a pointer to the object's Smack label
* @obj_
known: a pointer to the object's Smack label entry
* @mode: the access requested, in "MAY" format
* @a : common audit data
*
...
...
@@ -253,11 +266,12 @@ int smk_tskacc(struct task_smack *subject, char *obj_label,
* non zero otherwise. It allows that current may have the capability
* to override the rules.
*/
int
smk_curacc
(
char
*
obj_label
,
u32
mode
,
struct
smk_audit_info
*
a
)
int
smk_curacc
(
struct
smack_known
*
obj_known
,
u32
mode
,
struct
smk_audit_info
*
a
)
{
struct
task_smack
*
tsp
=
current_security
();
return
smk_tskacc
(
tsp
,
obj_
label
,
mode
,
a
);
return
smk_tskacc
(
tsp
,
obj_
known
,
mode
,
a
);
}
#ifdef CONFIG_AUDIT
...
...
@@ -328,6 +342,13 @@ void smack_log(char *subject_label, char *object_label, int request,
struct
smack_audit_data
*
sad
;
struct
common_audit_data
*
a
=
&
ad
->
a
;
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
/*
* The result may be positive in bringup mode.
*/
if
(
result
>
0
)
result
=
0
;
#endif
/* check if we have to log the current event */
if
(
result
!=
0
&&
(
log_policy
&
SMACK_AUDIT_DENIED
)
==
0
)
return
;
...
...
@@ -543,27 +564,6 @@ struct smack_known *smk_import_entry(const char *string, int len)
return
skp
;
}
/**
* smk_import - import a smack label
* @string: a text string that might be a Smack label
* @len: the maximum size, or zero if it is NULL terminated.
*
* Returns a pointer to the label in the label list that
* matches the passed string, adding it if necessary.
*/
char
*
smk_import
(
const
char
*
string
,
int
len
)
{
struct
smack_known
*
skp
;
/* labels cannot begin with a '-' */
if
(
string
[
0
]
==
'-'
)
return
NULL
;
skp
=
smk_import_entry
(
string
,
len
);
if
(
skp
==
NULL
)
return
NULL
;
return
skp
->
smk_known
;
}
/**
* smack_from_secid - find the Smack label associated with a secid
* @secid: an integer that might be associated with a Smack label
...
...
@@ -590,19 +590,3 @@ struct smack_known *smack_from_secid(const u32 secid)
rcu_read_unlock
();
return
&
smack_known_invalid
;
}
/**
* smack_to_secid - find the secid associated with a Smack label
* @smack: the Smack label
*
* Returns the appropriate secid if there is one,
* otherwise 0
*/
u32
smack_to_secid
(
const
char
*
smack
)
{
struct
smack_known
*
skp
=
smk_find_entry
(
smack
);
if
(
skp
==
NULL
)
return
0
;
return
skp
->
smk_secid
;
}
security/smack/smack_lsm.c
View file @
6f98e892
...
...
@@ -54,6 +54,151 @@
LIST_HEAD
(
smk_ipv6_port_list
);
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static
void
smk_bu_mode
(
int
mode
,
char
*
s
)
{
int
i
=
0
;
if
(
mode
&
MAY_READ
)
s
[
i
++
]
=
'r'
;
if
(
mode
&
MAY_WRITE
)
s
[
i
++
]
=
'w'
;
if
(
mode
&
MAY_EXEC
)
s
[
i
++
]
=
'x'
;
if
(
mode
&
MAY_APPEND
)
s
[
i
++
]
=
'a'
;
if
(
mode
&
MAY_TRANSMUTE
)
s
[
i
++
]
=
't'
;
if
(
mode
&
MAY_LOCK
)
s
[
i
++
]
=
'l'
;
if
(
i
==
0
)
s
[
i
++
]
=
'-'
;
s
[
i
]
=
'\0'
;
}
#endif
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static
int
smk_bu_note
(
char
*
note
,
struct
smack_known
*
sskp
,
struct
smack_known
*
oskp
,
int
mode
,
int
rc
)
{
char
acc
[
SMK_NUM_ACCESS_TYPE
+
1
];
if
(
rc
<=
0
)
return
rc
;
smk_bu_mode
(
mode
,
acc
);
pr_info
(
"Smack Bringup: (%s %s %s) %s
\n
"
,
sskp
->
smk_known
,
oskp
->
smk_known
,
acc
,
note
);
return
0
;
}
#else
#define smk_bu_note(note, sskp, oskp, mode, RC) (RC)
#endif
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static
int
smk_bu_current
(
char
*
note
,
struct
smack_known
*
oskp
,
int
mode
,
int
rc
)
{
struct
task_smack
*
tsp
=
current_security
();
char
acc
[
SMK_NUM_ACCESS_TYPE
+
1
];
if
(
rc
<=
0
)
return
rc
;
smk_bu_mode
(
mode
,
acc
);
pr_info
(
"Smack Bringup: (%s %s %s) %s %s
\n
"
,
tsp
->
smk_task
->
smk_known
,
oskp
->
smk_known
,
acc
,
current
->
comm
,
note
);
return
0
;
}
#else
#define smk_bu_current(note, oskp, mode, RC) (RC)
#endif
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static
int
smk_bu_task
(
struct
task_struct
*
otp
,
int
mode
,
int
rc
)
{
struct
task_smack
*
tsp
=
current_security
();
struct
task_smack
*
otsp
=
task_security
(
otp
);
char
acc
[
SMK_NUM_ACCESS_TYPE
+
1
];
if
(
rc
<=
0
)
return
rc
;
smk_bu_mode
(
mode
,
acc
);
pr_info
(
"Smack Bringup: (%s %s %s) %s to %s
\n
"
,
tsp
->
smk_task
->
smk_known
,
otsp
->
smk_task
->
smk_known
,
acc
,
current
->
comm
,
otp
->
comm
);
return
0
;
}
#else
#define smk_bu_task(otp, mode, RC) (RC)
#endif
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static
int
smk_bu_inode
(
struct
inode
*
inode
,
int
mode
,
int
rc
)
{
struct
task_smack
*
tsp
=
current_security
();
char
acc
[
SMK_NUM_ACCESS_TYPE
+
1
];
if
(
rc
<=
0
)
return
rc
;
smk_bu_mode
(
mode
,
acc
);
pr_info
(
"Smack Bringup: (%s %s %s) inode=(%s %ld) %s
\n
"
,
tsp
->
smk_task
->
smk_known
,
smk_of_inode
(
inode
)
->
smk_known
,
acc
,
inode
->
i_sb
->
s_id
,
inode
->
i_ino
,
current
->
comm
);
return
0
;
}
#else
#define smk_bu_inode(inode, mode, RC) (RC)
#endif
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static
int
smk_bu_file
(
struct
file
*
file
,
int
mode
,
int
rc
)
{
struct
task_smack
*
tsp
=
current_security
();
struct
smack_known
*
sskp
=
tsp
->
smk_task
;
struct
inode
*
inode
=
file
->
f_inode
;
char
acc
[
SMK_NUM_ACCESS_TYPE
+
1
];
if
(
rc
<=
0
)
return
rc
;
smk_bu_mode
(
mode
,
acc
);
pr_info
(
"Smack Bringup: (%s %s %s) file=(%s %ld %s) %s
\n
"
,
sskp
->
smk_known
,
(
char
*
)
file
->
f_security
,
acc
,
inode
->
i_sb
->
s_id
,
inode
->
i_ino
,
file
->
f_dentry
->
d_name
.
name
,
current
->
comm
);
return
0
;
}
#else
#define smk_bu_file(file, mode, RC) (RC)
#endif
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static
int
smk_bu_credfile
(
const
struct
cred
*
cred
,
struct
file
*
file
,
int
mode
,
int
rc
)
{
struct
task_smack
*
tsp
=
cred
->
security
;
struct
smack_known
*
sskp
=
tsp
->
smk_task
;
struct
inode
*
inode
=
file
->
f_inode
;
char
acc
[
SMK_NUM_ACCESS_TYPE
+
1
];
if
(
rc
<=
0
)
return
rc
;
smk_bu_mode
(
mode
,
acc
);
pr_info
(
"Smack Bringup: (%s %s %s) file=(%s %ld %s) %s
\n
"
,
sskp
->
smk_known
,
smk_of_inode
(
inode
)
->
smk_known
,
acc
,
inode
->
i_sb
->
s_id
,
inode
->
i_ino
,
file
->
f_dentry
->
d_name
.
name
,
current
->
comm
);
return
0
;
}
#else
#define smk_bu_credfile(cred, file, mode, RC) (RC)
#endif
/**
* smk_fetch - Fetch the smack label from a file.
* @ip: a pointer to the inode
...
...
@@ -87,11 +232,11 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip,
/**
* new_inode_smack - allocate an inode security blob
* @s
mack: a pointer to the Smack label
to use in the blob
* @s
kp: a pointer to the Smack label entry
to use in the blob
*
* Returns the new blob or NULL if there's no memory available
*/
struct
inode_smack
*
new_inode_smack
(
char
*
smack
)
struct
inode_smack
*
new_inode_smack
(
struct
smack_known
*
skp
)
{
struct
inode_smack
*
isp
;
...
...
@@ -99,7 +244,7 @@ struct inode_smack *new_inode_smack(char *smack)
if
(
isp
==
NULL
)
return
NULL
;
isp
->
smk_inode
=
s
mack
;
isp
->
smk_inode
=
s
kp
;
isp
->
smk_flags
=
0
;
mutex_init
(
&
isp
->
smk_lock
);
...
...
@@ -178,20 +323,20 @@ static inline unsigned int smk_ptrace_mode(unsigned int mode)
/**
* smk_ptrace_rule_check - helper for ptrace access
* @tracer: tracer process
* @tracee_label: label of the process that's about to be traced,
* the pointer must originate from smack structures
* @tracee_known: label entry of the process that's about to be traced
* @mode: ptrace attachment mode (PTRACE_MODE_*)
* @func: name of the function that called us, used for audit
*
* Returns 0 on access granted, -error on error
*/
static
int
smk_ptrace_rule_check
(
struct
task_struct
*
tracer
,
char
*
tracee_label
,
static
int
smk_ptrace_rule_check
(
struct
task_struct
*
tracer
,
struct
smack_known
*
tracee_known
,
unsigned
int
mode
,
const
char
*
func
)
{
int
rc
;
struct
smk_audit_info
ad
,
*
saip
=
NULL
;
struct
task_smack
*
tsp
;
struct
smack_known
*
skp
;
struct
smack_known
*
tracer_known
;
if
((
mode
&
PTRACE_MODE_NOAUDIT
)
==
0
)
{
smk_ad_init
(
&
ad
,
func
,
LSM_AUDIT_DATA_TASK
);
...
...
@@ -200,12 +345,12 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label,
}
tsp
=
task_security
(
tracer
);
skp
=
smk_of_task
(
tsp
);
tracer_known
=
smk_of_task
(
tsp
);
if
((
mode
&
PTRACE_MODE_ATTACH
)
&&
(
smack_ptrace_rule
==
SMACK_PTRACE_EXACT
||
smack_ptrace_rule
==
SMACK_PTRACE_DRACONIAN
))
{
if
(
skp
->
smk_known
==
tracee_label
)
if
(
tracer_known
->
smk_known
==
tracee_known
->
smk_known
)
rc
=
0
;
else
if
(
smack_ptrace_rule
==
SMACK_PTRACE_DRACONIAN
)
rc
=
-
EACCES
;
...
...
@@ -215,13 +360,15 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label,
rc
=
-
EACCES
;
if
(
saip
)
smack_log
(
skp
->
smk_known
,
tracee_label
,
0
,
rc
,
saip
);
smack_log
(
tracer_known
->
smk_known
,
tracee_known
->
smk_known
,
0
,
rc
,
saip
);
return
rc
;
}
/* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */
rc
=
smk_tskacc
(
tsp
,
tracee_
label
,
smk_ptrace_mode
(
mode
),
saip
);
rc
=
smk_tskacc
(
tsp
,
tracee_
known
,
smk_ptrace_mode
(
mode
),
saip
);
return
rc
;
}
...
...
@@ -250,7 +397,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
skp
=
smk_of_task
(
task_security
(
ctp
));
rc
=
smk_ptrace_rule_check
(
current
,
skp
->
smk_known
,
mode
,
__func__
);
rc
=
smk_ptrace_rule_check
(
current
,
skp
,
mode
,
__func__
);
return
rc
;
}
...
...
@@ -273,8 +420,7 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
skp
=
smk_of_task
(
current_security
());
rc
=
smk_ptrace_rule_check
(
ptp
,
skp
->
smk_known
,
PTRACE_MODE_ATTACH
,
__func__
);
rc
=
smk_ptrace_rule_check
(
ptp
,
skp
,
PTRACE_MODE_ATTACH
,
__func__
);
return
rc
;
}
...
...
@@ -318,10 +464,10 @@ static int smack_sb_alloc_security(struct super_block *sb)
if
(
sbsp
==
NULL
)
return
-
ENOMEM
;
sbsp
->
smk_root
=
smack_known_floor
.
smk_known
;
sbsp
->
smk_default
=
smack_known_floor
.
smk_known
;
sbsp
->
smk_floor
=
smack_known_floor
.
smk_known
;
sbsp
->
smk_hat
=
smack_known_hat
.
smk_known
;
sbsp
->
smk_root
=
&
smack_known_floor
;
sbsp
->
smk_default
=
&
smack_known_floor
;
sbsp
->
smk_floor
=
&
smack_known_floor
;
sbsp
->
smk_hat
=
&
smack_known_hat
;
/*
* smk_initialized will be zero from kzalloc.
*/
...
...
@@ -405,7 +551,6 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
struct
smack_known
*
skp
;
char
*
op
;
char
*
commap
;
char
*
nsp
;
int
transmute
=
0
;
int
specified
=
0
;
...
...
@@ -421,38 +566,38 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
if
(
strncmp
(
op
,
SMK_FSHAT
,
strlen
(
SMK_FSHAT
))
==
0
)
{
op
+=
strlen
(
SMK_FSHAT
);
nsp
=
smk_import
(
op
,
0
);
if
(
ns
p
!=
NULL
)
{
sp
->
smk_hat
=
ns
p
;
skp
=
smk_import_entry
(
op
,
0
);
if
(
sk
p
!=
NULL
)
{
sp
->
smk_hat
=
sk
p
;
specified
=
1
;
}
}
else
if
(
strncmp
(
op
,
SMK_FSFLOOR
,
strlen
(
SMK_FSFLOOR
))
==
0
)
{
op
+=
strlen
(
SMK_FSFLOOR
);
nsp
=
smk_import
(
op
,
0
);
if
(
ns
p
!=
NULL
)
{
sp
->
smk_floor
=
ns
p
;
skp
=
smk_import_entry
(
op
,
0
);
if
(
sk
p
!=
NULL
)
{
sp
->
smk_floor
=
sk
p
;
specified
=
1
;
}
}
else
if
(
strncmp
(
op
,
SMK_FSDEFAULT
,
strlen
(
SMK_FSDEFAULT
))
==
0
)
{
op
+=
strlen
(
SMK_FSDEFAULT
);
nsp
=
smk_import
(
op
,
0
);
if
(
ns
p
!=
NULL
)
{
sp
->
smk_default
=
ns
p
;
skp
=
smk_import_entry
(
op
,
0
);
if
(
sk
p
!=
NULL
)
{
sp
->
smk_default
=
sk
p
;
specified
=
1
;
}
}
else
if
(
strncmp
(
op
,
SMK_FSROOT
,
strlen
(
SMK_FSROOT
))
==
0
)
{
op
+=
strlen
(
SMK_FSROOT
);
nsp
=
smk_import
(
op
,
0
);
if
(
ns
p
!=
NULL
)
{
sp
->
smk_root
=
ns
p
;
skp
=
smk_import_entry
(
op
,
0
);
if
(
sk
p
!=
NULL
)
{
sp
->
smk_root
=
sk
p
;
specified
=
1
;
}
}
else
if
(
strncmp
(
op
,
SMK_FSTRANS
,
strlen
(
SMK_FSTRANS
))
==
0
)
{
op
+=
strlen
(
SMK_FSTRANS
);
nsp
=
smk_import
(
op
,
0
);
if
(
ns
p
!=
NULL
)
{
sp
->
smk_root
=
ns
p
;
skp
=
smk_import_entry
(
op
,
0
);
if
(
sk
p
!=
NULL
)
{
sp
->
smk_root
=
sk
p
;
transmute
=
1
;
specified
=
1
;
}
...
...
@@ -469,8 +614,8 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
* Unprivileged mounts get root and default from the caller.
*/
skp
=
smk_of_current
();
sp
->
smk_root
=
skp
->
smk_known
;
sp
->
smk_default
=
skp
->
smk_known
;
sp
->
smk_root
=
skp
;
sp
->
smk_default
=
skp
;
}
/*
* Initialize the root inode.
...
...
@@ -507,6 +652,7 @@ static int smack_sb_statfs(struct dentry *dentry)
smk_ad_setfield_u_fs_path_dentry
(
&
ad
,
dentry
);
rc
=
smk_curacc
(
sbp
->
smk_floor
,
MAY_READ
,
&
ad
);
rc
=
smk_bu_current
(
"statfs"
,
sbp
->
smk_floor
,
MAY_READ
,
rc
);
return
rc
;
}
...
...
@@ -546,7 +692,7 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm)
tracer
=
ptrace_parent
(
current
);
if
(
likely
(
tracer
!=
NULL
))
rc
=
smk_ptrace_rule_check
(
tracer
,
isp
->
smk_task
->
smk_known
,
isp
->
smk_task
,
PTRACE_MODE_ATTACH
,
__func__
);
rcu_read_unlock
();
...
...
@@ -607,7 +753,7 @@ static int smack_inode_alloc_security(struct inode *inode)
{
struct
smack_known
*
skp
=
smk_of_current
();
inode
->
i_security
=
new_inode_smack
(
skp
->
smk_known
);
inode
->
i_security
=
new_inode_smack
(
skp
);
if
(
inode
->
i_security
==
NULL
)
return
-
ENOMEM
;
return
0
;
...
...
@@ -627,8 +773,8 @@ static void smack_inode_free_security(struct inode *inode)
/**
* smack_inode_init_security - copy out the smack from an inode
* @inode: the inode
* @dir:
unused
* @inode: the
newly created
inode
* @dir:
containing directory object
* @qstr: unused
* @name: where to put the attribute name
* @value: where to put the attribute value
...
...
@@ -642,8 +788,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
{
struct
inode_smack
*
issp
=
inode
->
i_security
;
struct
smack_known
*
skp
=
smk_of_current
();
char
*
isp
=
smk_of_inode
(
inode
);
char
*
dsp
=
smk_of_inode
(
dir
);
struct
smack_known
*
isp
=
smk_of_inode
(
inode
);
struct
smack_known
*
dsp
=
smk_of_inode
(
dir
);
int
may
;
if
(
name
)
...
...
@@ -651,7 +797,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
if
(
value
)
{
rcu_read_lock
();
may
=
smk_access_entry
(
skp
->
smk_known
,
dsp
,
&
skp
->
smk_rules
);
may
=
smk_access_entry
(
skp
->
smk_known
,
dsp
->
smk_known
,
&
skp
->
smk_rules
);
rcu_read_unlock
();
/*
...
...
@@ -666,13 +813,13 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
issp
->
smk_flags
|=
SMK_INODE_CHANGED
;
}
*
value
=
kstrdup
(
isp
,
GFP_NOFS
);
*
value
=
kstrdup
(
isp
->
smk_known
,
GFP_NOFS
);
if
(
*
value
==
NULL
)
return
-
ENOMEM
;
}
if
(
len
)
*
len
=
strlen
(
isp
)
+
1
;
*
len
=
strlen
(
isp
->
smk_known
)
;
return
0
;
}
...
...
@@ -688,7 +835,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
static
int
smack_inode_link
(
struct
dentry
*
old_dentry
,
struct
inode
*
dir
,
struct
dentry
*
new_dentry
)
{
char
*
isp
;
struct
smack_known
*
isp
;
struct
smk_audit_info
ad
;
int
rc
;
...
...
@@ -697,11 +844,13 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
isp
=
smk_of_inode
(
old_dentry
->
d_inode
);
rc
=
smk_curacc
(
isp
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_inode
(
old_dentry
->
d_inode
,
MAY_WRITE
,
rc
);
if
(
rc
==
0
&&
new_dentry
->
d_inode
!=
NULL
)
{
isp
=
smk_of_inode
(
new_dentry
->
d_inode
);
smk_ad_setfield_u_fs_path_dentry
(
&
ad
,
new_dentry
);
rc
=
smk_curacc
(
isp
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_inode
(
new_dentry
->
d_inode
,
MAY_WRITE
,
rc
);
}
return
rc
;
...
...
@@ -728,6 +877,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
* You need write access to the thing you're unlinking
*/
rc
=
smk_curacc
(
smk_of_inode
(
ip
),
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_inode
(
ip
,
MAY_WRITE
,
rc
);
if
(
rc
==
0
)
{
/*
* You also need write access to the containing directory
...
...
@@ -735,6 +885,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_INODE
);
smk_ad_setfield_u_fs_inode
(
&
ad
,
dir
);
rc
=
smk_curacc
(
smk_of_inode
(
dir
),
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_inode
(
dir
,
MAY_WRITE
,
rc
);
}
return
rc
;
}
...
...
@@ -759,6 +910,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
* You need write access to the thing you're removing
*/
rc
=
smk_curacc
(
smk_of_inode
(
dentry
->
d_inode
),
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_inode
(
dentry
->
d_inode
,
MAY_WRITE
,
rc
);
if
(
rc
==
0
)
{
/*
* You also need write access to the containing directory
...
...
@@ -766,6 +918,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_INODE
);
smk_ad_setfield_u_fs_inode
(
&
ad
,
dir
);
rc
=
smk_curacc
(
smk_of_inode
(
dir
),
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_inode
(
dir
,
MAY_WRITE
,
rc
);
}
return
rc
;
...
...
@@ -773,10 +926,10 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
/**
* smack_inode_rename - Smack check on rename
* @old_inode:
the old directory
* @old_dentry:
unused
* @new_inode:
the new directory
* @new_dentry:
unused
* @old_inode:
unused
* @old_dentry:
the old object
* @new_inode:
unused
* @new_dentry:
the new object
*
* Read and write access is required on both the old and
* new directories.
...
...
@@ -789,7 +942,7 @@ static int smack_inode_rename(struct inode *old_inode,
struct
dentry
*
new_dentry
)
{
int
rc
;
char
*
isp
;
struct
smack_known
*
isp
;
struct
smk_audit_info
ad
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_DENTRY
);
...
...
@@ -797,11 +950,13 @@ static int smack_inode_rename(struct inode *old_inode,
isp
=
smk_of_inode
(
old_dentry
->
d_inode
);
rc
=
smk_curacc
(
isp
,
MAY_READWRITE
,
&
ad
);
rc
=
smk_bu_inode
(
old_dentry
->
d_inode
,
MAY_READWRITE
,
rc
);
if
(
rc
==
0
&&
new_dentry
->
d_inode
!=
NULL
)
{
isp
=
smk_of_inode
(
new_dentry
->
d_inode
);
smk_ad_setfield_u_fs_path_dentry
(
&
ad
,
new_dentry
);
rc
=
smk_curacc
(
isp
,
MAY_READWRITE
,
&
ad
);
rc
=
smk_bu_inode
(
new_dentry
->
d_inode
,
MAY_READWRITE
,
rc
);
}
return
rc
;
}
...
...
@@ -819,6 +974,7 @@ static int smack_inode_permission(struct inode *inode, int mask)
{
struct
smk_audit_info
ad
;
int
no_block
=
mask
&
MAY_NOT_BLOCK
;
int
rc
;
mask
&=
(
MAY_READ
|
MAY_WRITE
|
MAY_EXEC
|
MAY_APPEND
);
/*
...
...
@@ -832,7 +988,9 @@ static int smack_inode_permission(struct inode *inode, int mask)
return
-
ECHILD
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_INODE
);
smk_ad_setfield_u_fs_inode
(
&
ad
,
inode
);
return
smk_curacc
(
smk_of_inode
(
inode
),
mask
,
&
ad
);
rc
=
smk_curacc
(
smk_of_inode
(
inode
),
mask
,
&
ad
);
rc
=
smk_bu_inode
(
inode
,
mask
,
rc
);
return
rc
;
}
/**
...
...
@@ -845,6 +1003,8 @@ static int smack_inode_permission(struct inode *inode, int mask)
static
int
smack_inode_setattr
(
struct
dentry
*
dentry
,
struct
iattr
*
iattr
)
{
struct
smk_audit_info
ad
;
int
rc
;
/*
* Need to allow for clearing the setuid bit.
*/
...
...
@@ -853,12 +1013,14 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_DENTRY
);
smk_ad_setfield_u_fs_path_dentry
(
&
ad
,
dentry
);
return
smk_curacc
(
smk_of_inode
(
dentry
->
d_inode
),
MAY_WRITE
,
&
ad
);
rc
=
smk_curacc
(
smk_of_inode
(
dentry
->
d_inode
),
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_inode
(
dentry
->
d_inode
,
MAY_WRITE
,
rc
);
return
rc
;
}
/**
* smack_inode_getattr - Smack check for getting attributes
* @mnt:
unused
* @mnt:
vfsmount of the object
* @dentry: the object
*
* Returns 0 if access is permitted, an error code otherwise
...
...
@@ -867,21 +1029,24 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
{
struct
smk_audit_info
ad
;
struct
path
path
;
int
rc
;
path
.
dentry
=
dentry
;
path
.
mnt
=
mnt
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
path
);
return
smk_curacc
(
smk_of_inode
(
dentry
->
d_inode
),
MAY_READ
,
&
ad
);
rc
=
smk_curacc
(
smk_of_inode
(
dentry
->
d_inode
),
MAY_READ
,
&
ad
);
rc
=
smk_bu_inode
(
dentry
->
d_inode
,
MAY_READ
,
rc
);
return
rc
;
}
/**
* smack_inode_setxattr - Smack check for setting xattrs
* @dentry: the object
* @name: name of the attribute
* @value:
unused
* @size:
unused
* @value:
value of the attribute
* @size:
size of the value
* @flags: unused
*
* This protects the Smack attribute explicitly.
...
...
@@ -923,7 +1088,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
rc
=
-
EPERM
;
if
(
rc
==
0
&&
check_import
)
{
skp
=
s
mk_import_entry
(
value
,
size
)
;
skp
=
s
ize
?
smk_import_entry
(
value
,
size
)
:
NULL
;
if
(
skp
==
NULL
||
(
check_star
&&
(
skp
==
&
smack_known_star
||
skp
==
&
smack_known_web
)))
rc
=
-
EINVAL
;
...
...
@@ -932,8 +1097,10 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_DENTRY
);
smk_ad_setfield_u_fs_path_dentry
(
&
ad
,
dentry
);
if
(
rc
==
0
)
if
(
rc
==
0
)
{
rc
=
smk_curacc
(
smk_of_inode
(
dentry
->
d_inode
),
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_inode
(
dentry
->
d_inode
,
MAY_WRITE
,
rc
);
}
return
rc
;
}
...
...
@@ -963,9 +1130,9 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
if
(
strcmp
(
name
,
XATTR_NAME_SMACK
)
==
0
)
{
skp
=
smk_import_entry
(
value
,
size
);
if
(
skp
!=
NULL
)
isp
->
smk_inode
=
skp
->
smk_known
;
isp
->
smk_inode
=
skp
;
else
isp
->
smk_inode
=
smack_known_invalid
.
smk_known
;
isp
->
smk_inode
=
&
smack_known_invalid
;
}
else
if
(
strcmp
(
name
,
XATTR_NAME_SMACKEXEC
)
==
0
)
{
skp
=
smk_import_entry
(
value
,
size
);
if
(
skp
!=
NULL
)
...
...
@@ -993,11 +1160,14 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
static
int
smack_inode_getxattr
(
struct
dentry
*
dentry
,
const
char
*
name
)
{
struct
smk_audit_info
ad
;
int
rc
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_DENTRY
);
smk_ad_setfield_u_fs_path_dentry
(
&
ad
,
dentry
);
return
smk_curacc
(
smk_of_inode
(
dentry
->
d_inode
),
MAY_READ
,
&
ad
);
rc
=
smk_curacc
(
smk_of_inode
(
dentry
->
d_inode
),
MAY_READ
,
&
ad
);
rc
=
smk_bu_inode
(
dentry
->
d_inode
,
MAY_READ
,
rc
);
return
rc
;
}
/**
...
...
@@ -1033,6 +1203,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
smk_ad_setfield_u_fs_path_dentry
(
&
ad
,
dentry
);
rc
=
smk_curacc
(
smk_of_inode
(
dentry
->
d_inode
),
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_inode
(
dentry
->
d_inode
,
MAY_WRITE
,
rc
);
if
(
rc
!=
0
)
return
rc
;
...
...
@@ -1070,14 +1241,14 @@ static int smack_inode_getsecurity(const struct inode *inode,
struct
socket
*
sock
;
struct
super_block
*
sbp
;
struct
inode
*
ip
=
(
struct
inode
*
)
inode
;
char
*
isp
;
struct
smack_known
*
isp
;
int
ilen
;
int
rc
=
0
;
if
(
strcmp
(
name
,
XATTR_SMACK_SUFFIX
)
==
0
)
{
isp
=
smk_of_inode
(
inode
);
ilen
=
strlen
(
isp
)
+
1
;
*
buffer
=
isp
;
ilen
=
strlen
(
isp
->
smk_known
)
;
*
buffer
=
isp
->
smk_known
;
return
ilen
;
}
...
...
@@ -1095,15 +1266,15 @@ static int smack_inode_getsecurity(const struct inode *inode,
ssp
=
sock
->
sk
->
sk_security
;
if
(
strcmp
(
name
,
XATTR_SMACK_IPIN
)
==
0
)
isp
=
ssp
->
smk_in
->
smk_known
;
isp
=
ssp
->
smk_in
;
else
if
(
strcmp
(
name
,
XATTR_SMACK_IPOUT
)
==
0
)
isp
=
ssp
->
smk_out
->
smk_known
;
isp
=
ssp
->
smk_out
;
else
return
-
EOPNOTSUPP
;
ilen
=
strlen
(
isp
)
+
1
;
ilen
=
strlen
(
isp
->
smk_known
)
;
if
(
rc
==
0
)
{
*
buffer
=
isp
;
*
buffer
=
isp
->
smk_known
;
rc
=
ilen
;
}
...
...
@@ -1122,13 +1293,12 @@ static int smack_inode_getsecurity(const struct inode *inode,
static
int
smack_inode_listsecurity
(
struct
inode
*
inode
,
char
*
buffer
,
size_t
buffer_size
)
{
int
len
=
s
trlen
(
XATTR_NAME_SMACK
);
int
len
=
s
izeof
(
XATTR_NAME_SMACK
);
if
(
buffer
!=
NULL
&&
len
<=
buffer_size
)
{
if
(
buffer
!=
NULL
&&
len
<=
buffer_size
)
memcpy
(
buffer
,
XATTR_NAME_SMACK
,
len
);
return
len
;
}
return
-
EINVAL
;
}
/**
...
...
@@ -1140,7 +1310,7 @@ static void smack_inode_getsecid(const struct inode *inode, u32 *secid)
{
struct
inode_smack
*
isp
=
inode
->
i_security
;
*
secid
=
smack_to_secid
(
isp
->
smk_inode
)
;
*
secid
=
isp
->
smk_inode
->
smk_secid
;
}
/*
...
...
@@ -1179,7 +1349,7 @@ static int smack_file_alloc_security(struct file *file)
{
struct
smack_known
*
skp
=
smk_of_current
();
file
->
f_security
=
skp
->
smk_known
;
file
->
f_security
=
skp
;
return
0
;
}
...
...
@@ -1214,11 +1384,15 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
if
(
_IOC_DIR
(
cmd
)
&
_IOC_WRITE
)
if
(
_IOC_DIR
(
cmd
)
&
_IOC_WRITE
)
{
rc
=
smk_curacc
(
file
->
f_security
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_file
(
file
,
MAY_WRITE
,
rc
);
}
if
(
rc
==
0
&&
(
_IOC_DIR
(
cmd
)
&
_IOC_READ
))
if
(
rc
==
0
&&
(
_IOC_DIR
(
cmd
)
&
_IOC_READ
))
{
rc
=
smk_curacc
(
file
->
f_security
,
MAY_READ
,
&
ad
);
rc
=
smk_bu_file
(
file
,
MAY_READ
,
rc
);
}
return
rc
;
}
...
...
@@ -1233,10 +1407,13 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
static
int
smack_file_lock
(
struct
file
*
file
,
unsigned
int
cmd
)
{
struct
smk_audit_info
ad
;
int
rc
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
return
smk_curacc
(
file
->
f_security
,
MAY_LOCK
,
&
ad
);
rc
=
smk_curacc
(
file
->
f_security
,
MAY_LOCK
,
&
ad
);
rc
=
smk_bu_file
(
file
,
MAY_LOCK
,
rc
);
return
rc
;
}
/**
...
...
@@ -1266,12 +1443,14 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
rc
=
smk_curacc
(
file
->
f_security
,
MAY_LOCK
,
&
ad
);
rc
=
smk_bu_file
(
file
,
MAY_LOCK
,
rc
);
break
;
case
F_SETOWN
:
case
F_SETSIG
:
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
rc
=
smk_curacc
(
file
->
f_security
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_file
(
file
,
MAY_WRITE
,
rc
);
break
;
default:
break
;
...
...
@@ -1298,7 +1477,7 @@ static int smack_mmap_file(struct file *file,
struct
smack_known
*
mkp
;
struct
smack_rule
*
srp
;
struct
task_smack
*
tsp
;
char
*
osmack
;
struct
smack_known
*
okp
;
struct
inode_smack
*
isp
;
int
may
;
int
mmay
;
...
...
@@ -1324,17 +1503,18 @@ static int smack_mmap_file(struct file *file,
* to that rule's object label.
*/
list_for_each_entry_rcu
(
srp
,
&
skp
->
smk_rules
,
list
)
{
o
smack
=
srp
->
smk_object
;
o
kp
=
srp
->
smk_object
;
/*
* Matching labels always allows access.
*/
if
(
mkp
->
smk_known
==
o
smack
)
if
(
mkp
->
smk_known
==
o
kp
->
smk_known
)
continue
;
/*
* If there is a matching local rule take
* that into account as well.
*/
may
=
smk_access_entry
(
srp
->
smk_subject
->
smk_known
,
osmack
,
may
=
smk_access_entry
(
srp
->
smk_subject
->
smk_known
,
okp
->
smk_known
,
&
tsp
->
smk_rules
);
if
(
may
==
-
ENOENT
)
may
=
srp
->
smk_access
;
...
...
@@ -1352,7 +1532,7 @@ static int smack_mmap_file(struct file *file,
* If there isn't one a SMACK64MMAP subject
* can't have as much access as current.
*/
mmay
=
smk_access_entry
(
mkp
->
smk_known
,
o
smack
,
mmay
=
smk_access_entry
(
mkp
->
smk_known
,
o
kp
->
smk_known
,
&
mkp
->
smk_rules
);
if
(
mmay
==
-
ENOENT
)
{
rc
=
-
EACCES
;
...
...
@@ -1362,7 +1542,7 @@ static int smack_mmap_file(struct file *file,
* If there is a local entry it modifies the
* potential access, too.
*/
tmay
=
smk_access_entry
(
mkp
->
smk_known
,
o
smack
,
tmay
=
smk_access_entry
(
mkp
->
smk_known
,
o
kp
->
smk_known
,
&
tsp
->
smk_rules
);
if
(
tmay
!=
-
ENOENT
)
mmay
&=
tmay
;
...
...
@@ -1394,7 +1574,7 @@ static int smack_file_set_fowner(struct file *file)
{
struct
smack_known
*
skp
=
smk_of_current
();
file
->
f_security
=
skp
->
smk_known
;
file
->
f_security
=
skp
;
return
0
;
}
...
...
@@ -1424,14 +1604,15 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
file
=
container_of
(
fown
,
struct
file
,
f_owner
);
/* we don't log here as rc can be overriden */
skp
=
smk_find_entry
(
file
->
f_security
);
rc
=
smk_access
(
skp
,
tkp
->
smk_known
,
MAY_WRITE
,
NULL
);
skp
=
file
->
f_security
;
rc
=
smk_access
(
skp
,
tkp
,
MAY_WRITE
,
NULL
);
rc
=
smk_bu_note
(
"sigiotask"
,
skp
,
tkp
,
MAY_WRITE
,
rc
);
if
(
rc
!=
0
&&
has_capability
(
tsk
,
CAP_MAC_OVERRIDE
))
rc
=
0
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_TASK
);
smk_ad_setfield_u_tsk
(
&
ad
,
tsk
);
smack_log
(
file
->
f_security
,
tkp
->
smk_known
,
MAY_WRITE
,
rc
,
&
ad
);
smack_log
(
skp
->
smk_known
,
tkp
->
smk_known
,
MAY_WRITE
,
rc
,
&
ad
);
return
rc
;
}
...
...
@@ -1443,6 +1624,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
*/
static
int
smack_file_receive
(
struct
file
*
file
)
{
int
rc
;
int
may
=
0
;
struct
smk_audit_info
ad
;
...
...
@@ -1456,7 +1638,9 @@ static int smack_file_receive(struct file *file)
if
(
file
->
f_mode
&
FMODE_WRITE
)
may
|=
MAY_WRITE
;
return
smk_curacc
(
file
->
f_security
,
may
,
&
ad
);
rc
=
smk_curacc
(
file
->
f_security
,
may
,
&
ad
);
rc
=
smk_bu_file
(
file
,
may
,
rc
);
return
rc
;
}
/**
...
...
@@ -1478,12 +1662,15 @@ static int smack_file_open(struct file *file, const struct cred *cred)
struct
smk_audit_info
ad
;
int
rc
;
if
(
smack_privileged
(
CAP_MAC_OVERRIDE
))
if
(
smack_privileged
(
CAP_MAC_OVERRIDE
))
{
file
->
f_security
=
isp
->
smk_inode
;
return
0
;
}
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
rc
=
smk_access
(
tsp
->
smk_task
,
isp
->
smk_inode
,
MAY_READ
,
&
ad
);
rc
=
smk_bu_credfile
(
cred
,
file
,
MAY_READ
,
rc
);
if
(
rc
==
0
)
file
->
f_security
=
isp
->
smk_inode
;
...
...
@@ -1622,7 +1809,7 @@ static int smack_kernel_create_files_as(struct cred *new,
struct
inode_smack
*
isp
=
inode
->
i_security
;
struct
task_smack
*
tsp
=
new
->
security
;
tsp
->
smk_forked
=
smk_find_entry
(
isp
->
smk_inode
)
;
tsp
->
smk_forked
=
isp
->
smk_inode
;
tsp
->
smk_task
=
tsp
->
smk_forked
;
return
0
;
}
...
...
@@ -1640,10 +1827,13 @@ static int smk_curacc_on_task(struct task_struct *p, int access,
{
struct
smk_audit_info
ad
;
struct
smack_known
*
skp
=
smk_of_task
(
task_security
(
p
));
int
rc
;
smk_ad_init
(
&
ad
,
caller
,
LSM_AUDIT_DATA_TASK
);
smk_ad_setfield_u_tsk
(
&
ad
,
p
);
return
smk_curacc
(
skp
->
smk_known
,
access
,
&
ad
);
rc
=
smk_curacc
(
skp
,
access
,
&
ad
);
rc
=
smk_bu_task
(
p
,
access
,
rc
);
return
rc
;
}
/**
...
...
@@ -1797,6 +1987,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
struct
smk_audit_info
ad
;
struct
smack_known
*
skp
;
struct
smack_known
*
tkp
=
smk_of_task
(
task_security
(
p
));
int
rc
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_TASK
);
smk_ad_setfield_u_tsk
(
&
ad
,
p
);
...
...
@@ -1804,15 +1995,20 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
* Sending a signal requires that the sender
* can write the receiver.
*/
if
(
secid
==
0
)
return
smk_curacc
(
tkp
->
smk_known
,
MAY_WRITE
,
&
ad
);
if
(
secid
==
0
)
{
rc
=
smk_curacc
(
tkp
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_task
(
p
,
MAY_WRITE
,
rc
);
return
rc
;
}
/*
* If the secid isn't 0 we're dealing with some USB IO
* specific behavior. This is not clean. For one thing
* we can't take privilege into account.
*/
skp
=
smack_from_secid
(
secid
);
return
smk_access
(
skp
,
tkp
->
smk_known
,
MAY_WRITE
,
&
ad
);
rc
=
smk_access
(
skp
,
tkp
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_note
(
"USB signal"
,
skp
,
tkp
,
MAY_WRITE
,
rc
);
return
rc
;
}
/**
...
...
@@ -1846,7 +2042,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
struct
inode_smack
*
isp
=
inode
->
i_security
;
struct
smack_known
*
skp
=
smk_of_task
(
task_security
(
p
));
isp
->
smk_inode
=
skp
->
smk_known
;
isp
->
smk_inode
=
skp
;
}
/*
...
...
@@ -1904,7 +2100,7 @@ static void smack_sk_free_security(struct sock *sk)
*
* Returns the label of the far end or NULL if it's not special.
*/
static
char
*
smack_host_label
(
struct
sockaddr_in
*
sip
)
static
struct
smack_known
*
smack_host_label
(
struct
sockaddr_in
*
sip
)
{
struct
smk_netlbladdr
*
snp
;
struct
in_addr
*
siap
=
&
sip
->
sin_addr
;
...
...
@@ -1921,7 +2117,7 @@ static char *smack_host_label(struct sockaddr_in *sip)
if
((
&
snp
->
smk_host
.
sin_addr
)
->
s_addr
==
(
siap
->
s_addr
&
(
&
snp
->
smk_mask
)
->
s_addr
))
{
/* we have found the special CIPSO option */
if
(
snp
->
smk_label
==
smack_cipso_option
)
if
(
snp
->
smk_label
==
&
smack_cipso_option
)
return
NULL
;
return
snp
->
smk_label
;
}
...
...
@@ -1986,13 +2182,13 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
struct
smack_known
*
skp
;
int
rc
;
int
sk_lbl
;
char
*
hosts
p
;
struct
smack_known
*
hk
p
;
struct
socket_smack
*
ssp
=
sk
->
sk_security
;
struct
smk_audit_info
ad
;
rcu_read_lock
();
h
osts
p
=
smack_host_label
(
sap
);
if
(
h
osts
p
!=
NULL
)
{
h
k
p
=
smack_host_label
(
sap
);
if
(
h
k
p
!=
NULL
)
{
#ifdef CONFIG_AUDIT
struct
lsm_network_audit
net
;
...
...
@@ -2003,7 +2199,8 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
#endif
sk_lbl
=
SMACK_UNLABELED_SOCKET
;
skp
=
ssp
->
smk_out
;
rc
=
smk_access
(
skp
,
hostsp
,
MAY_WRITE
,
&
ad
);
rc
=
smk_access
(
skp
,
hkp
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_note
(
"IPv4 host check"
,
skp
,
hkp
,
MAY_WRITE
,
rc
);
}
else
{
sk_lbl
=
SMACK_CIPSO_SOCKET
;
rc
=
0
;
...
...
@@ -2104,18 +2301,19 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
struct
socket_smack
*
ssp
=
sk
->
sk_security
;
struct
smack_known
*
skp
;
unsigned
short
port
=
0
;
char
*
object
;
struct
smack_known
*
object
;
struct
smk_audit_info
ad
;
int
rc
;
#ifdef CONFIG_AUDIT
struct
lsm_network_audit
net
;
#endif
if
(
act
==
SMK_RECEIVING
)
{
skp
=
smack_net_ambient
;
object
=
ssp
->
smk_in
->
smk_known
;
object
=
ssp
->
smk_in
;
}
else
{
skp
=
ssp
->
smk_out
;
object
=
smack_net_ambient
->
smk_known
;
object
=
smack_net_ambient
;
}
/*
...
...
@@ -2142,7 +2340,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
list_for_each_entry
(
spp
,
&
smk_ipv6_port_list
,
list
)
{
if
(
spp
->
smk_port
!=
port
)
continue
;
object
=
spp
->
smk_in
->
smk_known
;
object
=
spp
->
smk_in
;
if
(
act
==
SMK_CONNECTING
)
ssp
->
smk_packet
=
spp
->
smk_out
;
break
;
...
...
@@ -2159,7 +2357,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
else
ad
.
a
.
u
.
net
->
v6info
.
daddr
=
address
->
sin6_addr
;
#endif
return
smk_access
(
skp
,
object
,
MAY_WRITE
,
&
ad
);
rc
=
smk_access
(
skp
,
object
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_note
(
"IPv6 port check"
,
skp
,
object
,
MAY_WRITE
,
rc
);
return
rc
;
}
/**
...
...
@@ -2191,7 +2391,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
return
-
EINVAL
;
if
(
strcmp
(
name
,
XATTR_SMACK_SUFFIX
)
==
0
)
{
nsp
->
smk_inode
=
skp
->
smk_known
;
nsp
->
smk_inode
=
skp
;
nsp
->
smk_flags
|=
SMK_INODE_INSTANT
;
return
0
;
}
...
...
@@ -2333,7 +2533,7 @@ static int smack_msg_msg_alloc_security(struct msg_msg *msg)
{
struct
smack_known
*
skp
=
smk_of_current
();
msg
->
security
=
skp
->
smk_known
;
msg
->
security
=
skp
;
return
0
;
}
...
...
@@ -2354,9 +2554,9 @@ static void smack_msg_msg_free_security(struct msg_msg *msg)
*
* Returns a pointer to the smack value
*/
static
char
*
smack_of_shm
(
struct
shmid_kernel
*
shp
)
static
struct
smack_known
*
smack_of_shm
(
struct
shmid_kernel
*
shp
)
{
return
(
char
*
)
shp
->
shm_perm
.
security
;
return
(
struct
smack_known
*
)
shp
->
shm_perm
.
security
;
}
/**
...
...
@@ -2370,7 +2570,7 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp)
struct
kern_ipc_perm
*
isp
=
&
shp
->
shm_perm
;
struct
smack_known
*
skp
=
smk_of_current
();
isp
->
security
=
skp
->
smk_known
;
isp
->
security
=
skp
;
return
0
;
}
...
...
@@ -2396,14 +2596,17 @@ static void smack_shm_free_security(struct shmid_kernel *shp)
*/
static
int
smk_curacc_shm
(
struct
shmid_kernel
*
shp
,
int
access
)
{
char
*
ssp
=
smack_of_shm
(
shp
);
struct
smack_known
*
ssp
=
smack_of_shm
(
shp
);
struct
smk_audit_info
ad
;
int
rc
;
#ifdef CONFIG_AUDIT
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_IPC
);
ad
.
a
.
u
.
ipc_id
=
shp
->
shm_perm
.
id
;
#endif
return
smk_curacc
(
ssp
,
access
,
&
ad
);
rc
=
smk_curacc
(
ssp
,
access
,
&
ad
);
rc
=
smk_bu_current
(
"shm"
,
ssp
,
access
,
rc
);
return
rc
;
}
/**
...
...
@@ -2478,9 +2681,9 @@ static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
*
* Returns a pointer to the smack value
*/
static
char
*
smack_of_sem
(
struct
sem_array
*
sma
)
static
struct
smack_known
*
smack_of_sem
(
struct
sem_array
*
sma
)
{
return
(
char
*
)
sma
->
sem_perm
.
security
;
return
(
struct
smack_known
*
)
sma
->
sem_perm
.
security
;
}
/**
...
...
@@ -2494,7 +2697,7 @@ static int smack_sem_alloc_security(struct sem_array *sma)
struct
kern_ipc_perm
*
isp
=
&
sma
->
sem_perm
;
struct
smack_known
*
skp
=
smk_of_current
();
isp
->
security
=
skp
->
smk_known
;
isp
->
security
=
skp
;
return
0
;
}
...
...
@@ -2520,14 +2723,17 @@ static void smack_sem_free_security(struct sem_array *sma)
*/
static
int
smk_curacc_sem
(
struct
sem_array
*
sma
,
int
access
)
{
char
*
ssp
=
smack_of_sem
(
sma
);
struct
smack_known
*
ssp
=
smack_of_sem
(
sma
);
struct
smk_audit_info
ad
;
int
rc
;
#ifdef CONFIG_AUDIT
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_IPC
);
ad
.
a
.
u
.
ipc_id
=
sma
->
sem_perm
.
id
;
#endif
return
smk_curacc
(
ssp
,
access
,
&
ad
);
rc
=
smk_curacc
(
ssp
,
access
,
&
ad
);
rc
=
smk_bu_current
(
"sem"
,
ssp
,
access
,
rc
);
return
rc
;
}
/**
...
...
@@ -2613,7 +2819,7 @@ static int smack_msg_queue_alloc_security(struct msg_queue *msq)
struct
kern_ipc_perm
*
kisp
=
&
msq
->
q_perm
;
struct
smack_known
*
skp
=
smk_of_current
();
kisp
->
security
=
skp
->
smk_known
;
kisp
->
security
=
skp
;
return
0
;
}
...
...
@@ -2634,11 +2840,11 @@ static void smack_msg_queue_free_security(struct msg_queue *msq)
* smack_of_msq - the smack pointer for the msq
* @msq: the object
*
* Returns a pointer to the smack
value
* Returns a pointer to the smack
label entry
*/
static
char
*
smack_of_msq
(
struct
msg_queue
*
msq
)
static
struct
smack_known
*
smack_of_msq
(
struct
msg_queue
*
msq
)
{
return
(
char
*
)
msq
->
q_perm
.
security
;
return
(
struct
smack_known
*
)
msq
->
q_perm
.
security
;
}
/**
...
...
@@ -2650,14 +2856,17 @@ static char *smack_of_msq(struct msg_queue *msq)
*/
static
int
smk_curacc_msq
(
struct
msg_queue
*
msq
,
int
access
)
{
char
*
msp
=
smack_of_msq
(
msq
);
struct
smack_known
*
msp
=
smack_of_msq
(
msq
);
struct
smk_audit_info
ad
;
int
rc
;
#ifdef CONFIG_AUDIT
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_IPC
);
ad
.
a
.
u
.
ipc_id
=
msq
->
q_perm
.
id
;
#endif
return
smk_curacc
(
msp
,
access
,
&
ad
);
rc
=
smk_curacc
(
msp
,
access
,
&
ad
);
rc
=
smk_bu_current
(
"msq"
,
msp
,
access
,
rc
);
return
rc
;
}
/**
...
...
@@ -2750,15 +2959,18 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
*/
static
int
smack_ipc_permission
(
struct
kern_ipc_perm
*
ipp
,
short
flag
)
{
char
*
is
p
=
ipp
->
security
;
struct
smack_known
*
isk
p
=
ipp
->
security
;
int
may
=
smack_flags_to_may
(
flag
);
struct
smk_audit_info
ad
;
int
rc
;
#ifdef CONFIG_AUDIT
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_IPC
);
ad
.
a
.
u
.
ipc_id
=
ipp
->
id
;
#endif
return
smk_curacc
(
isp
,
may
,
&
ad
);
rc
=
smk_curacc
(
iskp
,
may
,
&
ad
);
rc
=
smk_bu_current
(
"svipc"
,
iskp
,
may
,
rc
);
return
rc
;
}
/**
...
...
@@ -2768,9 +2980,9 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
*/
static
void
smack_ipc_getsecid
(
struct
kern_ipc_perm
*
ipp
,
u32
*
secid
)
{
char
*
smack
=
ipp
->
security
;
struct
smack_known
*
iskp
=
ipp
->
security
;
*
secid
=
smack_to_secid
(
smack
)
;
*
secid
=
iskp
->
smk_secid
;
}
/**
...
...
@@ -2787,7 +2999,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
struct
inode_smack
*
isp
;
struct
smack_known
*
skp
;
struct
smack_known
*
ckp
=
smk_of_current
();
char
*
final
;
struct
smack_known
*
final
;
char
trattr
[
TRANS_TRUE_SIZE
];
int
transflag
=
0
;
int
rc
;
...
...
@@ -2827,8 +3039,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
* so there's no opportunity to set the mount
* options.
*/
sbsp
->
smk_root
=
smack_known_star
.
smk_known
;
sbsp
->
smk_default
=
smack_known_star
.
smk_known
;
sbsp
->
smk_root
=
&
smack_known_star
;
sbsp
->
smk_default
=
&
smack_known_star
;
}
isp
->
smk_inode
=
sbsp
->
smk_root
;
isp
->
smk_flags
|=
SMK_INODE_INSTANT
;
...
...
@@ -2858,7 +3070,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
*
* Cgroupfs is special
*/
final
=
smack_known_star
.
smk_known
;
final
=
&
smack_known_star
;
break
;
case
DEVPTS_SUPER_MAGIC
:
/*
...
...
@@ -2866,7 +3078,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
* Programs that change smack have to treat the
* pty with respect.
*/
final
=
ckp
->
smk_known
;
final
=
ckp
;
break
;
case
PROC_SUPER_MAGIC
:
/*
...
...
@@ -2880,7 +3092,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
* but watch out, because they're volitile,
* getting recreated on every reboot.
*/
final
=
smack_known_star
.
smk_known
;
final
=
&
smack_known_star
;
/*
* No break.
*
...
...
@@ -2899,7 +3111,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
* UNIX domain sockets use lower level socket data.
*/
if
(
S_ISSOCK
(
inode
->
i_mode
))
{
final
=
smack_known_star
.
smk_known
;
final
=
&
smack_known_star
;
break
;
}
/*
...
...
@@ -2916,7 +3128,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
dp
=
dget
(
opt_dentry
);
skp
=
smk_fetch
(
XATTR_NAME_SMACK
,
inode
,
dp
);
if
(
skp
!=
NULL
)
final
=
skp
->
smk_known
;
final
=
skp
;
/*
* Transmuting directory
...
...
@@ -2965,7 +3177,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
}
if
(
final
==
NULL
)
isp
->
smk_inode
=
ckp
->
smk_known
;
isp
->
smk_inode
=
ckp
;
else
isp
->
smk_inode
=
final
;
...
...
@@ -3090,9 +3302,13 @@ static int smack_unix_stream_connect(struct sock *sock,
smk_ad_init_net
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_NET
,
&
net
);
smk_ad_setfield_u_net_sk
(
&
ad
,
other
);
#endif
rc
=
smk_access
(
skp
,
okp
->
smk_known
,
MAY_WRITE
,
&
ad
);
if
(
rc
==
0
)
rc
=
smk_access
(
okp
,
okp
->
smk_known
,
MAY_WRITE
,
NULL
);
rc
=
smk_access
(
skp
,
okp
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_note
(
"UDS connect"
,
skp
,
okp
,
MAY_WRITE
,
rc
);
if
(
rc
==
0
)
{
rc
=
smk_access
(
okp
,
skp
,
MAY_WRITE
,
NULL
);
rc
=
smk_bu_note
(
"UDS connect"
,
okp
,
skp
,
MAY_WRITE
,
rc
);
}
}
/*
...
...
@@ -3118,8 +3334,8 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
{
struct
socket_smack
*
ssp
=
sock
->
sk
->
sk_security
;
struct
socket_smack
*
osp
=
other
->
sk
->
sk_security
;
struct
smack_known
*
skp
;
struct
smk_audit_info
ad
;
int
rc
;
#ifdef CONFIG_AUDIT
struct
lsm_network_audit
net
;
...
...
@@ -3131,8 +3347,9 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
if
(
smack_privileged
(
CAP_MAC_OVERRIDE
))
return
0
;
skp
=
ssp
->
smk_out
;
return
smk_access
(
skp
,
osp
->
smk_in
->
smk_known
,
MAY_WRITE
,
&
ad
);
rc
=
smk_access
(
ssp
->
smk_out
,
osp
->
smk_in
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_note
(
"UDS send"
,
ssp
->
smk_out
,
osp
->
smk_in
,
MAY_WRITE
,
rc
);
return
rc
;
}
/**
...
...
@@ -3346,7 +3563,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
* This is the simplist possible security model
* for networking.
*/
rc
=
smk_access
(
skp
,
ssp
->
smk_in
->
smk_known
,
MAY_WRITE
,
&
ad
);
rc
=
smk_access
(
skp
,
ssp
->
smk_in
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_note
(
"IPv4 delivery"
,
skp
,
ssp
->
smk_in
,
MAY_WRITE
,
rc
);
if
(
rc
!=
0
)
netlbl_skbuff_err
(
skb
,
rc
,
0
);
break
;
...
...
@@ -3489,7 +3708,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
struct
netlbl_lsm_secattr
secattr
;
struct
sockaddr_in
addr
;
struct
iphdr
*
hdr
;
char
*
hs
p
;
struct
smack_known
*
hsk
p
;
int
rc
;
struct
smk_audit_info
ad
;
#ifdef CONFIG_AUDIT
...
...
@@ -3526,7 +3745,8 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
* Receiving a packet requires that the other end be able to write
* here. Read access is not required.
*/
rc
=
smk_access
(
skp
,
ssp
->
smk_in
->
smk_known
,
MAY_WRITE
,
&
ad
);
rc
=
smk_access
(
skp
,
ssp
->
smk_in
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_note
(
"IPv4 connect"
,
skp
,
ssp
->
smk_in
,
MAY_WRITE
,
rc
);
if
(
rc
!=
0
)
return
rc
;
...
...
@@ -3544,10 +3764,10 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
hdr
=
ip_hdr
(
skb
);
addr
.
sin_addr
.
s_addr
=
hdr
->
saddr
;
rcu_read_lock
();
hsp
=
smack_host_label
(
&
addr
);
hs
k
p
=
smack_host_label
(
&
addr
);
rcu_read_unlock
();
if
(
hsp
==
NULL
)
if
(
hs
k
p
==
NULL
)
rc
=
netlbl_req_setattr
(
req
,
&
skp
->
smk_netlabel
);
else
netlbl_req_delattr
(
req
);
...
...
@@ -3599,7 +3819,7 @@ static int smack_key_alloc(struct key *key, const struct cred *cred,
{
struct
smack_known
*
skp
=
smk_of_task
(
cred
->
security
);
key
->
security
=
skp
->
smk_known
;
key
->
security
=
skp
;
return
0
;
}
...
...
@@ -3630,6 +3850,7 @@ static int smack_key_permission(key_ref_t key_ref,
struct
smk_audit_info
ad
;
struct
smack_known
*
tkp
=
smk_of_task
(
cred
->
security
);
int
request
=
0
;
int
rc
;
keyp
=
key_ref_to_ptr
(
key_ref
);
if
(
keyp
==
NULL
)
...
...
@@ -3654,7 +3875,9 @@ static int smack_key_permission(key_ref_t key_ref,
request
=
MAY_READ
;
if
(
perm
&
(
KEY_NEED_WRITE
|
KEY_NEED_LINK
|
KEY_NEED_SETATTR
))
request
=
MAY_WRITE
;
return
smk_access
(
tkp
,
keyp
->
security
,
request
,
&
ad
);
rc
=
smk_access
(
tkp
,
keyp
->
security
,
request
,
&
ad
);
rc
=
smk_bu_note
(
"key access"
,
tkp
,
keyp
->
security
,
request
,
rc
);
return
rc
;
}
#endif
/* CONFIG_KEYS */
...
...
@@ -3685,6 +3908,7 @@ static int smack_key_permission(key_ref_t key_ref,
*/
static
int
smack_audit_rule_init
(
u32
field
,
u32
op
,
char
*
rulestr
,
void
**
vrule
)
{
struct
smack_known
*
skp
;
char
**
rule
=
(
char
**
)
vrule
;
*
rule
=
NULL
;
...
...
@@ -3694,7 +3918,9 @@ static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
if
(
op
!=
Audit_equal
&&
op
!=
Audit_not_equal
)
return
-
EINVAL
;
*
rule
=
smk_import
(
rulestr
,
0
);
skp
=
smk_import_entry
(
rulestr
,
0
);
if
(
skp
)
*
rule
=
skp
->
smk_known
;
return
0
;
}
...
...
@@ -3813,7 +4039,12 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
*/
static
int
smack_secctx_to_secid
(
const
char
*
secdata
,
u32
seclen
,
u32
*
secid
)
{
*
secid
=
smack_to_secid
(
secdata
);
struct
smack_known
*
skp
=
smk_find_entry
(
secdata
);
if
(
skp
)
*
secid
=
skp
->
smk_secid
;
else
*
secid
=
0
;
return
0
;
}
...
...
security/smack/smackfs.c
View file @
6f98e892
...
...
@@ -131,14 +131,17 @@ LIST_HEAD(smack_rule_list);
struct
smack_parsed_rule
{
struct
smack_known
*
smk_subject
;
char
*
smk_object
;
struct
smack_known
*
smk_object
;
int
smk_access1
;
int
smk_access2
;
};
static
int
smk_cipso_doi_value
=
SMACK_CIPSO_DOI_DEFAULT
;
const
char
*
smack_cipso_option
=
SMACK_CIPSO_OPTION
;
struct
smack_known
smack_cipso_option
=
{
.
smk_known
=
SMACK_CIPSO_OPTION
,
.
smk_secid
=
0
,
};
/*
* Values for parsing cipso rules
...
...
@@ -304,6 +307,10 @@ static int smk_perm_from_str(const char *string)
case
'L'
:
perm
|=
MAY_LOCK
;
break
;
case
'b'
:
case
'B'
:
perm
|=
MAY_BRINGUP
;
break
;
default:
return
perm
;
}
...
...
@@ -335,7 +342,7 @@ static int smk_fill_rule(const char *subject, const char *object,
if
(
rule
->
smk_subject
==
NULL
)
return
-
EINVAL
;
rule
->
smk_object
=
smk_import
(
object
,
len
);
rule
->
smk_object
=
smk_import
_entry
(
object
,
len
);
if
(
rule
->
smk_object
==
NULL
)
return
-
EINVAL
;
}
else
{
...
...
@@ -355,7 +362,7 @@ static int smk_fill_rule(const char *subject, const char *object,
kfree
(
cp
);
if
(
skp
==
NULL
)
return
-
ENOENT
;
rule
->
smk_object
=
skp
->
smk_known
;
rule
->
smk_object
=
skp
;
}
rule
->
smk_access1
=
smk_perm_from_str
(
access1
);
...
...
@@ -594,13 +601,15 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
* anything you read back.
*/
if
(
strlen
(
srp
->
smk_subject
->
smk_known
)
>=
max
||
strlen
(
srp
->
smk_object
)
>=
max
)
strlen
(
srp
->
smk_object
->
smk_known
)
>=
max
)
return
;
if
(
srp
->
smk_access
==
0
)
return
;
seq_printf
(
s
,
"%s %s"
,
srp
->
smk_subject
->
smk_known
,
srp
->
smk_object
);
seq_printf
(
s
,
"%s %s"
,
srp
->
smk_subject
->
smk_known
,
srp
->
smk_object
->
smk_known
);
seq_putc
(
s
,
' '
);
...
...
@@ -616,6 +625,8 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
seq_putc
(
s
,
't'
);
if
(
srp
->
smk_access
&
MAY_LOCK
)
seq_putc
(
s
,
'l'
);
if
(
srp
->
smk_access
&
MAY_BRINGUP
)
seq_putc
(
s
,
'b'
);
seq_putc
(
s
,
'\n'
);
}
...
...
@@ -1067,7 +1078,7 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v)
for
(
maskn
=
0
;
temp_mask
;
temp_mask
<<=
1
,
maskn
++
);
seq_printf
(
s
,
"%u.%u.%u.%u/%d %s
\n
"
,
hp
[
0
],
hp
[
1
],
hp
[
2
],
hp
[
3
],
maskn
,
skp
->
smk_label
);
hp
[
0
],
hp
[
1
],
hp
[
2
],
hp
[
3
],
maskn
,
skp
->
smk_label
->
smk_known
);
return
0
;
}
...
...
@@ -1147,10 +1158,10 @@ static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
static
ssize_t
smk_write_netlbladdr
(
struct
file
*
file
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
smk_netlbladdr
*
s
k
p
;
struct
smk_netlbladdr
*
s
n
p
;
struct
sockaddr_in
newname
;
char
*
smack
;
char
*
s
p
;
struct
smack_known
*
sk
p
;
char
*
data
;
char
*
host
=
(
char
*
)
&
newname
.
sin_addr
.
s_addr
;
int
rc
;
...
...
@@ -1213,15 +1224,15 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
* If smack begins with '-', it is an option, don't import it
*/
if
(
smack
[
0
]
!=
'-'
)
{
s
p
=
smk_import
(
smack
,
0
);
if
(
sp
==
NULL
)
{
s
kp
=
smk_import_entry
(
smack
,
0
);
if
(
s
k
p
==
NULL
)
{
rc
=
-
EINVAL
;
goto
free_out
;
}
}
else
{
/* check known options */
if
(
strcmp
(
smack
,
smack_cipso_option
)
==
0
)
s
p
=
(
char
*
)
smack_cipso_option
;
if
(
strcmp
(
smack
,
smack_cipso_option
.
smk_known
)
==
0
)
s
kp
=
&
smack_cipso_option
;
else
{
rc
=
-
EINVAL
;
goto
free_out
;
...
...
@@ -1244,9 +1255,9 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
nsa
=
newname
.
sin_addr
.
s_addr
;
/* try to find if the prefix is already in the list */
found
=
0
;
list_for_each_entry_rcu
(
s
k
p
,
&
smk_netlbladdr_list
,
list
)
{
if
(
s
k
p
->
smk_host
.
sin_addr
.
s_addr
==
nsa
&&
s
k
p
->
smk_mask
.
s_addr
==
mask
.
s_addr
)
{
list_for_each_entry_rcu
(
s
n
p
,
&
smk_netlbladdr_list
,
list
)
{
if
(
s
n
p
->
smk_host
.
sin_addr
.
s_addr
==
nsa
&&
s
n
p
->
smk_mask
.
s_addr
==
mask
.
s_addr
)
{
found
=
1
;
break
;
}
...
...
@@ -1254,26 +1265,26 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
smk_netlabel_audit_set
(
&
audit_info
);
if
(
found
==
0
)
{
s
kp
=
kzalloc
(
sizeof
(
*
sk
p
),
GFP_KERNEL
);
if
(
s
k
p
==
NULL
)
s
np
=
kzalloc
(
sizeof
(
*
sn
p
),
GFP_KERNEL
);
if
(
s
n
p
==
NULL
)
rc
=
-
ENOMEM
;
else
{
rc
=
0
;
s
k
p
->
smk_host
.
sin_addr
.
s_addr
=
newname
.
sin_addr
.
s_addr
;
s
k
p
->
smk_mask
.
s_addr
=
mask
.
s_addr
;
s
kp
->
smk_label
=
s
p
;
smk_netlbladdr_insert
(
s
k
p
);
s
n
p
->
smk_host
.
sin_addr
.
s_addr
=
newname
.
sin_addr
.
s_addr
;
s
n
p
->
smk_mask
.
s_addr
=
mask
.
s_addr
;
s
np
->
smk_label
=
sk
p
;
smk_netlbladdr_insert
(
s
n
p
);
}
}
else
{
/* we delete the unlabeled entry, only if the previous label
* wasn't the special CIPSO option */
if
(
s
kp
->
smk_label
!=
smack_cipso_option
)
if
(
s
np
->
smk_label
!=
&
smack_cipso_option
)
rc
=
netlbl_cfg_unlbl_static_del
(
&
init_net
,
NULL
,
&
s
kp
->
smk_host
.
sin_addr
,
&
sk
p
->
smk_mask
,
&
s
np
->
smk_host
.
sin_addr
,
&
sn
p
->
smk_mask
,
PF_INET
,
&
audit_info
);
else
rc
=
0
;
s
kp
->
smk_label
=
s
p
;
s
np
->
smk_label
=
sk
p
;
}
/*
...
...
@@ -1281,10 +1292,10 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
* this host so that incoming packets get labeled.
* but only if we didn't get the special CIPSO option
*/
if
(
rc
==
0
&&
s
p
!=
smack_cipso_option
)
if
(
rc
==
0
&&
s
kp
!=
&
smack_cipso_option
)
rc
=
netlbl_cfg_unlbl_static_add
(
&
init_net
,
NULL
,
&
s
kp
->
smk_host
.
sin_addr
,
&
sk
p
->
smk_mask
,
PF_INET
,
s
mack_to_secid
(
skp
->
smk_label
)
,
&
audit_info
);
&
s
np
->
smk_host
.
sin_addr
,
&
sn
p
->
smk_mask
,
PF_INET
,
s
np
->
smk_label
->
smk_secid
,
&
audit_info
);
if
(
rc
==
0
)
rc
=
count
;
...
...
@@ -1677,7 +1688,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
if
(
smack_onlycap
!=
NULL
&&
smack_onlycap
!=
skp
)
return
-
EPERM
;
data
=
kzalloc
(
count
,
GFP_KERNEL
);
data
=
kzalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
data
==
NULL
)
return
-
ENOMEM
;
...
...
@@ -1880,7 +1891,10 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
else
if
(
res
!=
-
ENOENT
)
return
-
EINVAL
;
data
[
0
]
=
res
==
0
?
'1'
:
'0'
;
/*
* smk_access() can return a value > 0 in the "bringup" case.
*/
data
[
0
]
=
res
>=
0
?
'1'
:
'0'
;
data
[
1
]
=
'\0'
;
simple_transaction_set
(
file
,
2
);
...
...
@@ -2228,7 +2242,7 @@ static ssize_t smk_write_syslog(struct file *file, const char __user *buf,
if
(
!
smack_privileged
(
CAP_MAC_ADMIN
))
return
-
EPERM
;
data
=
kzalloc
(
count
,
GFP_KERNEL
);
data
=
kzalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
data
==
NULL
)
return
-
ENOMEM
;
...
...
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