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
73203361
Commit
73203361
authored
Aug 23, 2013
by
James Morris
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'smack-for-3.12' of
git://git.gitorious.org/smack-next/kernel
into ra-next
parents
f8eb8a13
10289b0f
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
150 additions
and
114 deletions
+150
-114
security/smack/smack.h
security/smack/smack.h
+11
-2
security/smack/smack_access.c
security/smack/smack_access.c
+26
-3
security/smack/smack_lsm.c
security/smack/smack_lsm.c
+30
-12
security/smack/smackfs.c
security/smack/smackfs.c
+83
-97
No files found.
security/smack/smack.h
View file @
73203361
...
...
@@ -53,6 +53,7 @@
*/
struct
smack_known
{
struct
list_head
list
;
struct
hlist_node
smk_hashed
;
char
*
smk_known
;
u32
smk_secid
;
struct
netlbl_lsm_secattr
smk_netlabel
;
/* on wire labels */
...
...
@@ -167,9 +168,13 @@ struct smk_port_label {
#define SMACK_CIPSO_DOI_INVALID -1
/* Not a DOI */
#define SMACK_CIPSO_DIRECT_DEFAULT 250
/* Arbitrary */
#define SMACK_CIPSO_MAPPED_DEFAULT 251
/* Also arbitrary */
#define SMACK_CIPSO_MAXCATVAL 63
/* Bigger gets harder */
#define SMACK_CIPSO_MAXLEVEL 255
/* CIPSO 2.2 standard */
#define SMACK_CIPSO_MAXCATNUM 239
/* CIPSO 2.2 standard */
/*
* CIPSO 2.2 standard is 239, but Smack wants to use the
* categories in a structured way that limits the value to
* the bits in 23 bytes, hence the unusual number.
*/
#define SMACK_CIPSO_MAXCATNUM 184
/* 23 * 8 */
/*
* Flag for transmute access
...
...
@@ -222,6 +227,7 @@ 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
*
);
...
...
@@ -247,6 +253,9 @@ extern struct list_head smk_netlbladdr_list;
extern
struct
security_operations
smack_ops
;
#define SMACK_HASH_SLOTS 16
extern
struct
hlist_head
smack_known_hash
[
SMACK_HASH_SLOTS
];
/*
* Is the directory transmuting?
*/
...
...
security/smack/smack_access.c
View file @
73203361
...
...
@@ -325,6 +325,25 @@ void smack_log(char *subject_label, char *object_label, int request,
DEFINE_MUTEX
(
smack_known_lock
);
struct
hlist_head
smack_known_hash
[
SMACK_HASH_SLOTS
];
/**
* smk_insert_entry - insert a smack label into a hash map,
*
* this function must be called under smack_known_lock
*/
void
smk_insert_entry
(
struct
smack_known
*
skp
)
{
unsigned
int
hash
;
struct
hlist_head
*
head
;
hash
=
full_name_hash
(
skp
->
smk_known
,
strlen
(
skp
->
smk_known
));
head
=
&
smack_known_hash
[
hash
&
(
SMACK_HASH_SLOTS
-
1
)];
hlist_add_head_rcu
(
&
skp
->
smk_hashed
,
head
);
list_add_rcu
(
&
skp
->
list
,
&
smack_known_list
);
}
/**
* smk_find_entry - find a label on the list, return the list entry
* @string: a text string that might be a Smack label
...
...
@@ -334,12 +353,16 @@ DEFINE_MUTEX(smack_known_lock);
*/
struct
smack_known
*
smk_find_entry
(
const
char
*
string
)
{
unsigned
int
hash
;
struct
hlist_head
*
head
;
struct
smack_known
*
skp
;
list_for_each_entry_rcu
(
skp
,
&
smack_known_list
,
list
)
{
hash
=
full_name_hash
(
string
,
strlen
(
string
));
head
=
&
smack_known_hash
[
hash
&
(
SMACK_HASH_SLOTS
-
1
)];
hlist_for_each_entry_rcu
(
skp
,
head
,
smk_hashed
)
if
(
strcmp
(
skp
->
smk_known
,
string
)
==
0
)
return
skp
;
}
return
NULL
;
}
...
...
@@ -475,7 +498,7 @@ struct smack_known *smk_import_entry(const char *string, int len)
* Make sure that the entry is actually
* filled before putting it on the list.
*/
list_add_rcu
(
&
skp
->
list
,
&
smack_known_list
);
smk_insert_entry
(
skp
);
goto
unlockout
;
}
/*
...
...
security/smack/smack_lsm.c
View file @
73203361
...
...
@@ -3063,6 +3063,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
{
struct
smack_known
*
skp
;
int
found
=
0
;
int
acat
;
int
kcat
;
if
((
sap
->
flags
&
NETLBL_SECATTR_MLS_LVL
)
!=
0
)
{
/*
...
...
@@ -3079,12 +3081,28 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
list_for_each_entry
(
skp
,
&
smack_known_list
,
list
)
{
if
(
sap
->
attr
.
mls
.
lvl
!=
skp
->
smk_netlabel
.
attr
.
mls
.
lvl
)
continue
;
if
(
memcmp
(
sap
->
attr
.
mls
.
cat
,
skp
->
smk_netlabel
.
attr
.
mls
.
cat
,
SMK_CIPSOLEN
)
!=
0
)
continue
;
found
=
1
;
break
;
/*
* Compare the catsets. Use the netlbl APIs.
*/
if
((
sap
->
flags
&
NETLBL_SECATTR_MLS_CAT
)
==
0
)
{
if
((
skp
->
smk_netlabel
.
flags
&
NETLBL_SECATTR_MLS_CAT
)
==
0
)
found
=
1
;
break
;
}
for
(
acat
=
-
1
,
kcat
=
-
1
;
acat
==
kcat
;
)
{
acat
=
netlbl_secattr_catmap_walk
(
sap
->
attr
.
mls
.
cat
,
acat
+
1
);
kcat
=
netlbl_secattr_catmap_walk
(
skp
->
smk_netlabel
.
attr
.
mls
.
cat
,
kcat
+
1
);
if
(
acat
<
0
||
kcat
<
0
)
break
;
}
if
(
acat
==
kcat
)
{
found
=
1
;
break
;
}
}
rcu_read_unlock
();
...
...
@@ -3876,12 +3894,12 @@ static __init void init_smack_known_list(void)
/*
* Create the known labels list
*/
list_add
(
&
smack_known_huh
.
list
,
&
smack_known_list
);
list_add
(
&
smack_known_hat
.
list
,
&
smack_known_lis
t
);
list_add
(
&
smack_known_star
.
list
,
&
smack_known_list
);
list_add
(
&
smack_known_floor
.
list
,
&
smack_known_list
);
list_add
(
&
smack_known_invalid
.
list
,
&
smack_known_list
);
list_add
(
&
smack_known_web
.
list
,
&
smack_known_list
);
smk_insert_entry
(
&
smack_known_huh
);
smk_insert_entry
(
&
smack_known_ha
t
);
smk_insert_entry
(
&
smack_known_star
);
smk_insert_entry
(
&
smack_known_floor
);
smk_insert_entry
(
&
smack_known_invalid
);
smk_insert_entry
(
&
smack_known_web
);
}
/**
...
...
security/smack/smackfs.c
View file @
73203361
...
...
@@ -368,56 +368,43 @@ static int smk_parse_rule(const char *data, struct smack_parsed_rule *rule,
* @data: string to be parsed, null terminated
* @rule: Will be filled with Smack parsed rule
* @import: if non-zero, import labels
* @
change: if non-zero, data is from /smack/change-rule
* @
tokens: numer of substrings expected in data
*
* Returns
0 on success, -1 on failure
* Returns
number of processed bytes on success, -1 on failure.
*/
static
int
smk_parse_long_rule
(
const
char
*
data
,
struct
smack_parsed_rule
*
rule
,
int
import
,
int
change
)
static
ssize_t
smk_parse_long_rule
(
char
*
data
,
struct
smack_parsed_rule
*
rule
,
int
import
,
int
tokens
)
{
char
*
subject
;
char
*
object
;
char
*
access1
;
char
*
access2
;
int
datalen
;
int
rc
=
-
1
;
ssize_t
cnt
=
0
;
char
*
tok
[
4
];
int
i
;
/* This is inefficient */
datalen
=
strlen
(
data
);
/*
* Parsing the rule in-place, filling all white-spaces with '\0'
*/
for
(
i
=
0
;
i
<
tokens
;
++
i
)
{
while
(
isspace
(
data
[
cnt
]))
data
[
cnt
++
]
=
'\0'
;
/* Our first element can be 64 + \0 with no spaces */
subject
=
kzalloc
(
datalen
+
1
,
GFP_KERNEL
);
if
(
subject
==
NULL
)
return
-
1
;
object
=
kzalloc
(
datalen
,
GFP_KERNEL
);
if
(
object
==
NULL
)
goto
free_out_s
;
access1
=
kzalloc
(
datalen
,
GFP_KERNEL
);
if
(
access1
==
NULL
)
goto
free_out_o
;
access2
=
kzalloc
(
datalen
,
GFP_KERNEL
);
if
(
access2
==
NULL
)
goto
free_out_a
;
if
(
change
)
{
if
(
sscanf
(
data
,
"%s %s %s %s"
,
subject
,
object
,
access1
,
access2
)
==
4
)
rc
=
smk_fill_rule
(
subject
,
object
,
access1
,
access2
,
rule
,
import
,
0
);
}
else
{
if
(
sscanf
(
data
,
"%s %s %s"
,
subject
,
object
,
access1
)
==
3
)
rc
=
smk_fill_rule
(
subject
,
object
,
access1
,
NULL
,
rule
,
import
,
0
);
if
(
data
[
cnt
]
==
'\0'
)
/* Unexpected end of data */
return
-
1
;
tok
[
i
]
=
data
+
cnt
;
while
(
data
[
cnt
]
&&
!
isspace
(
data
[
cnt
]))
++
cnt
;
}
while
(
isspace
(
data
[
cnt
]))
data
[
cnt
++
]
=
'\0'
;
kfree
(
access2
);
free_out_a:
kfree
(
access1
);
free_out_o:
kfree
(
object
);
free_out_s:
kfree
(
subject
);
return
rc
;
while
(
i
<
4
)
tok
[
i
++
]
=
NULL
;
if
(
smk_fill_rule
(
tok
[
0
],
tok
[
1
],
tok
[
2
],
tok
[
3
],
rule
,
import
,
0
))
return
-
1
;
return
cnt
;
}
#define SMK_FIXED24_FMT 0
/* Fixed 24byte label format */
...
...
@@ -447,11 +434,12 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
struct
list_head
*
rule_list
,
struct
mutex
*
rule_lock
,
int
format
)
{
struct
smack_parsed_rule
*
rule
;
struct
smack_parsed_rule
rule
;
char
*
data
;
int
datalen
;
int
rc
=
-
EINVAL
;
int
load
=
0
;
int
rc
;
int
trunc
=
0
;
int
tokens
;
ssize_t
cnt
=
0
;
/*
* No partial writes.
...
...
@@ -466,11 +454,14 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
*/
if
(
count
!=
SMK_OLOADLEN
&&
count
!=
SMK_LOADLEN
)
return
-
EINVAL
;
datalen
=
SMK_LOADLEN
;
}
else
datalen
=
count
+
1
;
}
else
{
if
(
count
>=
PAGE_SIZE
)
{
count
=
PAGE_SIZE
-
1
;
trunc
=
1
;
}
}
data
=
k
zalloc
(
datalen
,
GFP_KERNEL
);
data
=
k
malloc
(
count
+
1
,
GFP_KERNEL
);
if
(
data
==
NULL
)
return
-
ENOMEM
;
...
...
@@ -479,47 +470,49 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
goto
out
;
}
rule
=
kzalloc
(
sizeof
(
*
rule
),
GFP_KERNEL
);
if
(
rule
==
NULL
)
{
rc
=
-
ENOMEM
;
goto
out
;
/*
* In case of parsing only part of user buf,
* avoid having partial rule at the data buffer
*/
if
(
trunc
)
{
while
(
count
>
0
&&
(
data
[
count
-
1
]
!=
'\n'
))
--
count
;
if
(
count
==
0
)
{
rc
=
-
EINVAL
;
goto
out
;
}
}
if
(
format
==
SMK_LONG_FMT
)
{
/*
* Be sure the data string is terminated.
*/
data
[
count
]
=
'\0'
;
if
(
smk_parse_long_rule
(
data
,
rule
,
1
,
0
))
goto
out_free_rule
;
}
else
if
(
format
==
SMK_CHANGE_FMT
)
{
data
[
count
]
=
'\0'
;
if
(
smk_parse_long_rule
(
data
,
rule
,
1
,
1
))
goto
out_free_rule
;
}
else
{
/*
* More on the minor hack for backward compatibility
*/
if
(
count
==
(
SMK_OLOADLEN
))
data
[
SMK_OLOADLEN
]
=
'-'
;
if
(
smk_parse_rule
(
data
,
rule
,
1
))
goto
out_free_rule
;
}
data
[
count
]
=
'\0'
;
tokens
=
(
format
==
SMK_CHANGE_FMT
?
4
:
3
);
while
(
cnt
<
count
)
{
if
(
format
==
SMK_FIXED24_FMT
)
{
rc
=
smk_parse_rule
(
data
,
&
rule
,
1
);
if
(
rc
!=
0
)
{
rc
=
-
EINVAL
;
goto
out
;
}
cnt
=
count
;
}
else
{
rc
=
smk_parse_long_rule
(
data
+
cnt
,
&
rule
,
1
,
tokens
);
if
(
rc
<=
0
)
{
rc
=
-
EINVAL
;
goto
out
;
}
cnt
+=
rc
;
}
if
(
rule_list
==
NULL
)
{
load
=
1
;
rule_list
=
&
rule
->
smk_subject
->
smk_rules
;
rule_lock
=
&
rule
->
smk_subject
->
smk_rules_lock
;
}
if
(
rule_list
==
NULL
)
rc
=
smk_set_access
(
&
rule
,
&
rule
.
smk_subject
->
smk_rules
,
&
rule
.
smk_subject
->
smk_rules_lock
,
1
)
;
else
rc
=
smk_set_access
(
&
rule
,
rule_list
,
rule_lock
,
0
);
rc
=
smk_set_access
(
rule
,
rule_list
,
rule_lock
,
load
);
if
(
rc
==
0
)
{
rc
=
count
;
goto
out
;
if
(
rc
)
goto
out
;
}
out_free_rule:
kfree
(
rule
);
rc
=
cnt
;
out:
kfree
(
data
);
return
rc
;
...
...
@@ -901,7 +894,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
for
(
i
=
0
;
i
<
catlen
;
i
++
)
{
rule
+=
SMK_DIGITLEN
;
ret
=
sscanf
(
rule
,
"%u"
,
&
cat
);
if
(
ret
!=
1
||
cat
>
SMACK_CIPSO_MAXCAT
VAL
)
if
(
ret
!=
1
||
cat
>
SMACK_CIPSO_MAXCAT
NUM
)
goto
out
;
smack_catset_bit
(
cat
,
mapcatset
);
...
...
@@ -1840,7 +1833,6 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
{
struct
smack_parsed_rule
rule
;
char
*
data
;
char
*
cod
;
int
res
;
data
=
simple_transaction_get
(
file
,
buf
,
count
);
...
...
@@ -1853,18 +1845,12 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
res
=
smk_parse_rule
(
data
,
&
rule
,
0
);
}
else
{
/*
*
Copy the data to make sure the string is terminated.
*
simple_transaction_get() returns null-terminated data
*/
cod
=
kzalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
cod
==
NULL
)
return
-
ENOMEM
;
memcpy
(
cod
,
data
,
count
);
cod
[
count
]
=
'\0'
;
res
=
smk_parse_long_rule
(
cod
,
&
rule
,
0
,
0
);
kfree
(
cod
);
res
=
smk_parse_long_rule
(
data
,
&
rule
,
0
,
3
);
}
if
(
res
)
if
(
res
<
0
)
return
-
EINVAL
;
res
=
smk_access
(
rule
.
smk_subject
,
rule
.
smk_object
,
...
...
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