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
103ae675
Commit
103ae675
authored
Aug 02, 2014
by
James Morris
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'next' of
git://git.infradead.org/users/pcmoore/selinux
into next
parents
a3d64df8
4fbe63d1
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
366 additions
and
274 deletions
+366
-274
include/net/netlabel.h
include/net/netlabel.h
+53
-41
net/ipv4/cipso_ipv4.c
net/ipv4/cipso_ipv4.c
+16
-31
net/netlabel/netlabel_kapi.c
net/netlabel/netlabel_kapi.c
+227
-100
security/selinux/ss/ebitmap.c
security/selinux/ss/ebitmap.c
+52
-81
security/selinux/ss/ebitmap.h
security/selinux/ss/ebitmap.h
+4
-4
security/smack/smack_access.c
security/smack/smack_access.c
+4
-7
security/smack/smack_lsm.c
security/smack/smack_lsm.c
+3
-3
security/smack/smackfs.c
security/smack/smackfs.c
+7
-7
No files found.
include/net/netlabel.h
View file @
103ae675
...
...
@@ -139,7 +139,7 @@ struct netlbl_lsm_cache {
};
/**
* struct netlbl_lsm_
secattr_
catmap - NetLabel LSM secattr category bitmap
* struct netlbl_lsm_catmap - NetLabel LSM secattr category bitmap
* @startbit: the value of the lowest order bit in the bitmap
* @bitmap: the category bitmap
* @next: pointer to the next bitmap "node" or NULL
...
...
@@ -162,10 +162,10 @@ struct netlbl_lsm_cache {
#define NETLBL_CATMAP_SIZE (NETLBL_CATMAP_MAPSIZE * \
NETLBL_CATMAP_MAPCNT)
#define NETLBL_CATMAP_BIT (NETLBL_CATMAP_MAPTYPE)0x01
struct
netlbl_lsm_
secattr_
catmap
{
struct
netlbl_lsm_catmap
{
u32
startbit
;
NETLBL_CATMAP_MAPTYPE
bitmap
[
NETLBL_CATMAP_MAPCNT
];
struct
netlbl_lsm_
secattr_
catmap
*
next
;
struct
netlbl_lsm_catmap
*
next
;
};
/**
...
...
@@ -209,7 +209,7 @@ struct netlbl_lsm_secattr {
struct
netlbl_lsm_cache
*
cache
;
struct
{
struct
{
struct
netlbl_lsm_
secattr_
catmap
*
cat
;
struct
netlbl_lsm_catmap
*
cat
;
u32
lvl
;
}
mls
;
u32
secid
;
...
...
@@ -258,7 +258,7 @@ static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache)
}
/**
* netlbl_
secattr_
catmap_alloc - Allocate a LSM secattr catmap
* netlbl_catmap_alloc - Allocate a LSM secattr catmap
* @flags: memory allocation flags
*
* Description:
...
...
@@ -266,30 +266,28 @@ static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache)
* on failure.
*
*/
static
inline
struct
netlbl_lsm_secattr_catmap
*
netlbl_secattr_catmap_alloc
(
gfp_t
flags
)
static
inline
struct
netlbl_lsm_catmap
*
netlbl_catmap_alloc
(
gfp_t
flags
)
{
return
kzalloc
(
sizeof
(
struct
netlbl_lsm_
secattr_
catmap
),
flags
);
return
kzalloc
(
sizeof
(
struct
netlbl_lsm_catmap
),
flags
);
}
/**
* netlbl_
secattr_
catmap_free - Free a LSM secattr catmap
* netlbl_catmap_free - Free a LSM secattr catmap
* @catmap: the category bitmap
*
* Description:
* Free a LSM secattr catmap.
*
*/
static
inline
void
netlbl_secattr_catmap_free
(
struct
netlbl_lsm_secattr_catmap
*
catmap
)
static
inline
void
netlbl_catmap_free
(
struct
netlbl_lsm_catmap
*
catmap
)
{
struct
netlbl_lsm_
secattr_
catmap
*
iter
;
struct
netlbl_lsm_catmap
*
iter
;
do
{
while
(
catmap
)
{
iter
=
catmap
;
catmap
=
catmap
->
next
;
kfree
(
iter
);
}
while
(
catmap
);
}
}
/**
...
...
@@ -321,7 +319,7 @@ static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr)
if
(
secattr
->
flags
&
NETLBL_SECATTR_CACHE
)
netlbl_secattr_cache_free
(
secattr
->
cache
);
if
(
secattr
->
flags
&
NETLBL_SECATTR_MLS_CAT
)
netlbl_
secattr_
catmap_free
(
secattr
->
attr
.
mls
.
cat
);
netlbl_catmap_free
(
secattr
->
attr
.
mls
.
cat
);
}
/**
...
...
@@ -390,17 +388,22 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
/*
* LSM security attribute operations
*/
int
netlbl_secattr_catmap_walk
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
offset
);
int
netlbl_secattr_catmap_walk_rng
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
offset
);
int
netlbl_secattr_catmap_setbit
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
bit
,
gfp_t
flags
);
int
netlbl_secattr_catmap_setrng
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
start
,
u32
end
,
gfp_t
flags
);
int
netlbl_catmap_walk
(
struct
netlbl_lsm_catmap
*
catmap
,
u32
offset
);
int
netlbl_catmap_walkrng
(
struct
netlbl_lsm_catmap
*
catmap
,
u32
offset
);
int
netlbl_catmap_getlong
(
struct
netlbl_lsm_catmap
*
catmap
,
u32
*
offset
,
unsigned
long
*
bitmap
);
int
netlbl_catmap_setbit
(
struct
netlbl_lsm_catmap
**
catmap
,
u32
bit
,
gfp_t
flags
);
int
netlbl_catmap_setrng
(
struct
netlbl_lsm_catmap
**
catmap
,
u32
start
,
u32
end
,
gfp_t
flags
);
int
netlbl_catmap_setlong
(
struct
netlbl_lsm_catmap
**
catmap
,
u32
offset
,
unsigned
long
bitmap
,
gfp_t
flags
);
/*
* LSM protocol operations (NetLabel LSM/kernel API)
...
...
@@ -492,30 +495,39 @@ static inline int netlbl_cfg_cipsov4_map_add(u32 doi,
{
return
-
ENOSYS
;
}
static
inline
int
netlbl_secattr_catmap_walk
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
offset
)
static
inline
int
netlbl_catmap_walk
(
struct
netlbl_lsm_catmap
*
catmap
,
u32
offset
)
{
return
-
ENOENT
;
}
static
inline
int
netlbl_secattr_catmap_walk_rng
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
offset
)
static
inline
int
netlbl_catmap_walkrng
(
struct
netlbl_lsm_catmap
*
catmap
,
u32
offset
)
{
return
-
ENOENT
;
}
static
inline
int
netlbl_secattr_catmap_setbit
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
bit
,
gfp_t
flags
)
static
inline
int
netlbl_catmap_getlong
(
struct
netlbl_lsm_catmap
*
catmap
,
u32
*
offset
,
unsigned
long
*
bitmap
)
{
return
0
;
}
static
inline
int
netlbl_secattr_catmap_setrng
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
start
,
u32
end
,
gfp_t
flags
)
static
inline
int
netlbl_catmap_setbit
(
struct
netlbl_lsm_catmap
**
catmap
,
u32
bit
,
gfp_t
flags
)
{
return
0
;
}
static
inline
int
netlbl_catmap_setrng
(
struct
netlbl_lsm_catmap
**
catmap
,
u32
start
,
u32
end
,
gfp_t
flags
)
{
return
0
;
}
static
int
netlbl_catmap_setlong
(
struct
netlbl_lsm_catmap
**
catmap
,
u32
offset
,
unsigned
long
bitmap
,
gfp_t
flags
)
{
return
0
;
}
...
...
net/ipv4/cipso_ipv4.c
View file @
103ae675
...
...
@@ -890,8 +890,8 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
}
for
(;;)
{
host_spot
=
netlbl_
secattr_
catmap_walk
(
secattr
->
attr
.
mls
.
cat
,
host_spot
+
1
);
host_spot
=
netlbl_catmap_walk
(
secattr
->
attr
.
mls
.
cat
,
host_spot
+
1
);
if
(
host_spot
<
0
)
break
;
...
...
@@ -973,7 +973,7 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
return
-
EPERM
;
break
;
}
ret_val
=
netlbl_
secattr_catmap_setbit
(
secattr
->
attr
.
mls
.
cat
,
ret_val
=
netlbl_
catmap_setbit
(
&
secattr
->
attr
.
mls
.
cat
,
host_spot
,
GFP_ATOMIC
);
if
(
ret_val
!=
0
)
...
...
@@ -1039,8 +1039,7 @@ static int cipso_v4_map_cat_enum_hton(const struct cipso_v4_doi *doi_def,
u32
cat_iter
=
0
;
for
(;;)
{
cat
=
netlbl_secattr_catmap_walk
(
secattr
->
attr
.
mls
.
cat
,
cat
+
1
);
cat
=
netlbl_catmap_walk
(
secattr
->
attr
.
mls
.
cat
,
cat
+
1
);
if
(
cat
<
0
)
break
;
if
((
cat_iter
+
2
)
>
net_cat_len
)
...
...
@@ -1075,9 +1074,9 @@ static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
u32
iter
;
for
(
iter
=
0
;
iter
<
net_cat_len
;
iter
+=
2
)
{
ret_val
=
netlbl_
secattr_catmap_setbit
(
secattr
->
attr
.
mls
.
cat
,
get_unaligned_be16
(
&
net_cat
[
iter
]),
GFP_ATOMIC
);
ret_val
=
netlbl_
catmap_setbit
(
&
secattr
->
attr
.
mls
.
cat
,
get_unaligned_be16
(
&
net_cat
[
iter
]),
GFP_ATOMIC
);
if
(
ret_val
!=
0
)
return
ret_val
;
}
...
...
@@ -1155,8 +1154,7 @@ static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
return
-
ENOSPC
;
for
(;;)
{
iter
=
netlbl_secattr_catmap_walk
(
secattr
->
attr
.
mls
.
cat
,
iter
+
1
);
iter
=
netlbl_catmap_walk
(
secattr
->
attr
.
mls
.
cat
,
iter
+
1
);
if
(
iter
<
0
)
break
;
cat_size
+=
(
iter
==
0
?
0
:
sizeof
(
u16
));
...
...
@@ -1164,8 +1162,7 @@ static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
return
-
ENOSPC
;
array
[
array_cnt
++
]
=
iter
;
iter
=
netlbl_secattr_catmap_walk_rng
(
secattr
->
attr
.
mls
.
cat
,
iter
);
iter
=
netlbl_catmap_walkrng
(
secattr
->
attr
.
mls
.
cat
,
iter
);
if
(
iter
<
0
)
return
-
EFAULT
;
cat_size
+=
sizeof
(
u16
);
...
...
@@ -1217,10 +1214,10 @@ static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
else
cat_low
=
0
;
ret_val
=
netlbl_
secattr_catmap_setrng
(
secattr
->
attr
.
mls
.
cat
,
cat_low
,
cat_high
,
GFP_ATOMIC
);
ret_val
=
netlbl_
catmap_setrng
(
&
secattr
->
attr
.
mls
.
cat
,
cat_low
,
cat_high
,
GFP_ATOMIC
);
if
(
ret_val
!=
0
)
return
ret_val
;
}
...
...
@@ -1335,16 +1332,12 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
secattr
->
flags
|=
NETLBL_SECATTR_MLS_LVL
;
if
(
tag_len
>
4
)
{
secattr
->
attr
.
mls
.
cat
=
netlbl_secattr_catmap_alloc
(
GFP_ATOMIC
);
if
(
secattr
->
attr
.
mls
.
cat
==
NULL
)
return
-
ENOMEM
;
ret_val
=
cipso_v4_map_cat_rbm_ntoh
(
doi_def
,
&
tag
[
4
],
tag_len
-
4
,
secattr
);
if
(
ret_val
!=
0
)
{
netlbl_
secattr_
catmap_free
(
secattr
->
attr
.
mls
.
cat
);
netlbl_catmap_free
(
secattr
->
attr
.
mls
.
cat
);
return
ret_val
;
}
...
...
@@ -1430,16 +1423,12 @@ static int cipso_v4_parsetag_enum(const struct cipso_v4_doi *doi_def,
secattr
->
flags
|=
NETLBL_SECATTR_MLS_LVL
;
if
(
tag_len
>
4
)
{
secattr
->
attr
.
mls
.
cat
=
netlbl_secattr_catmap_alloc
(
GFP_ATOMIC
);
if
(
secattr
->
attr
.
mls
.
cat
==
NULL
)
return
-
ENOMEM
;
ret_val
=
cipso_v4_map_cat_enum_ntoh
(
doi_def
,
&
tag
[
4
],
tag_len
-
4
,
secattr
);
if
(
ret_val
!=
0
)
{
netlbl_
secattr_
catmap_free
(
secattr
->
attr
.
mls
.
cat
);
netlbl_catmap_free
(
secattr
->
attr
.
mls
.
cat
);
return
ret_val
;
}
...
...
@@ -1524,16 +1513,12 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
secattr
->
flags
|=
NETLBL_SECATTR_MLS_LVL
;
if
(
tag_len
>
4
)
{
secattr
->
attr
.
mls
.
cat
=
netlbl_secattr_catmap_alloc
(
GFP_ATOMIC
);
if
(
secattr
->
attr
.
mls
.
cat
==
NULL
)
return
-
ENOMEM
;
ret_val
=
cipso_v4_map_cat_rng_ntoh
(
doi_def
,
&
tag
[
4
],
tag_len
-
4
,
secattr
);
if
(
ret_val
!=
0
)
{
netlbl_
secattr_
catmap_free
(
secattr
->
attr
.
mls
.
cat
);
netlbl_catmap_free
(
secattr
->
attr
.
mls
.
cat
);
return
ret_val
;
}
...
...
net/netlabel/netlabel_kapi.c
View file @
103ae675
...
...
@@ -405,8 +405,72 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
* Security Attribute Functions
*/
#define _CM_F_NONE 0x00000000
#define _CM_F_ALLOC 0x00000001
#define _CM_F_WALK 0x00000002
/**
* netlbl_secattr_catmap_walk - Walk a LSM secattr catmap looking for a bit
* _netlbl_catmap_getnode - Get a individual node from a catmap
* @catmap: pointer to the category bitmap
* @offset: the requested offset
* @cm_flags: catmap flags, see _CM_F_*
* @gfp_flags: memory allocation flags
*
* Description:
* Iterate through the catmap looking for the node associated with @offset.
* If the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node,
* one will be created and inserted into the catmap. If the _CM_F_WALK flag is
* set in @cm_flags and there is no associated node, the next highest node will
* be returned. Returns a pointer to the node on success, NULL on failure.
*
*/
static
struct
netlbl_lsm_catmap
*
_netlbl_catmap_getnode
(
struct
netlbl_lsm_catmap
**
catmap
,
u32
offset
,
unsigned
int
cm_flags
,
gfp_t
gfp_flags
)
{
struct
netlbl_lsm_catmap
*
iter
=
*
catmap
;
struct
netlbl_lsm_catmap
*
prev
=
NULL
;
if
(
iter
==
NULL
)
goto
catmap_getnode_alloc
;
if
(
offset
<
iter
->
startbit
)
goto
catmap_getnode_walk
;
while
(
iter
&&
offset
>=
(
iter
->
startbit
+
NETLBL_CATMAP_SIZE
))
{
prev
=
iter
;
iter
=
iter
->
next
;
}
if
(
iter
==
NULL
||
offset
<
iter
->
startbit
)
goto
catmap_getnode_walk
;
return
iter
;
catmap_getnode_walk:
if
(
cm_flags
&
_CM_F_WALK
)
return
iter
;
catmap_getnode_alloc:
if
(
!
(
cm_flags
&
_CM_F_ALLOC
))
return
NULL
;
iter
=
netlbl_catmap_alloc
(
gfp_flags
);
if
(
iter
==
NULL
)
return
NULL
;
iter
->
startbit
=
offset
&
~
(
NETLBL_CATMAP_SIZE
-
1
);
if
(
prev
==
NULL
)
{
iter
->
next
=
*
catmap
;
*
catmap
=
iter
;
}
else
{
iter
->
next
=
prev
->
next
;
prev
->
next
=
iter
;
}
return
iter
;
}
/**
* netlbl_catmap_walk - Walk a LSM secattr catmap looking for a bit
* @catmap: the category bitmap
* @offset: the offset to start searching at, in bits
*
...
...
@@ -415,54 +479,51 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
* returns the spot of the first set bit or -ENOENT if no bits are set.
*
*/
int
netlbl_secattr_catmap_walk
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
offset
)
int
netlbl_catmap_walk
(
struct
netlbl_lsm_catmap
*
catmap
,
u32
offset
)
{
struct
netlbl_lsm_
secattr_
catmap
*
iter
=
catmap
;
u32
node_
idx
;
u32
node_
bit
;
struct
netlbl_lsm_catmap
*
iter
=
catmap
;
u32
idx
;
u32
bit
;
NETLBL_CATMAP_MAPTYPE
bitmap
;
iter
=
_netlbl_catmap_getnode
(
&
catmap
,
offset
,
_CM_F_WALK
,
0
);
if
(
iter
==
NULL
)
return
-
ENOENT
;
if
(
offset
>
iter
->
startbit
)
{
while
(
offset
>=
(
iter
->
startbit
+
NETLBL_CATMAP_SIZE
))
{
iter
=
iter
->
next
;
if
(
iter
==
NULL
)
return
-
ENOENT
;
}
node_idx
=
(
offset
-
iter
->
startbit
)
/
NETLBL_CATMAP_MAPSIZE
;
node_bit
=
offset
-
iter
->
startbit
-
(
NETLBL_CATMAP_MAPSIZE
*
node_idx
);
offset
-=
iter
->
startbit
;
idx
=
offset
/
NETLBL_CATMAP_MAPSIZE
;
bit
=
offset
%
NETLBL_CATMAP_MAPSIZE
;
}
else
{
node_
idx
=
0
;
node_
bit
=
0
;
idx
=
0
;
bit
=
0
;
}
bitmap
=
iter
->
bitmap
[
node_idx
]
>>
node_
bit
;
bitmap
=
iter
->
bitmap
[
idx
]
>>
bit
;
for
(;;)
{
if
(
bitmap
!=
0
)
{
while
((
bitmap
&
NETLBL_CATMAP_BIT
)
==
0
)
{
bitmap
>>=
1
;
node_
bit
++
;
bit
++
;
}
return
iter
->
startbit
+
(
NETLBL_CATMAP_MAPSIZE
*
node_idx
)
+
node_
bit
;
(
NETLBL_CATMAP_MAPSIZE
*
idx
)
+
bit
;
}
if
(
++
node_
idx
>=
NETLBL_CATMAP_MAPCNT
)
{
if
(
++
idx
>=
NETLBL_CATMAP_MAPCNT
)
{
if
(
iter
->
next
!=
NULL
)
{
iter
=
iter
->
next
;
node_
idx
=
0
;
idx
=
0
;
}
else
return
-
ENOENT
;
}
bitmap
=
iter
->
bitmap
[
node_
idx
];
node_
bit
=
0
;
bitmap
=
iter
->
bitmap
[
idx
];
bit
=
0
;
}
return
-
ENOENT
;
}
/**
* netlbl_
secattr_catmap_walk_
rng - Find the end of a string of set bits
* netlbl_
catmap_walk
rng - Find the end of a string of set bits
* @catmap: the category bitmap
* @offset: the offset to start searching at, in bits
*
...
...
@@ -472,57 +533,105 @@ int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
* the end of the bitmap.
*
*/
int
netlbl_secattr_catmap_walk_rng
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
offset
)
int
netlbl_catmap_walkrng
(
struct
netlbl_lsm_catmap
*
catmap
,
u32
offset
)
{
struct
netlbl_lsm_secattr_catmap
*
iter
=
catmap
;
u32
node_idx
;
u32
node_bit
;
struct
netlbl_lsm_catmap
*
iter
;
struct
netlbl_lsm_catmap
*
prev
=
NULL
;
u32
idx
;
u32
bit
;
NETLBL_CATMAP_MAPTYPE
bitmask
;
NETLBL_CATMAP_MAPTYPE
bitmap
;
iter
=
_netlbl_catmap_getnode
(
&
catmap
,
offset
,
_CM_F_WALK
,
0
);
if
(
iter
==
NULL
)
return
-
ENOENT
;
if
(
offset
>
iter
->
startbit
)
{
while
(
offset
>=
(
iter
->
startbit
+
NETLBL_CATMAP_SIZE
))
{
iter
=
iter
->
next
;
if
(
iter
==
NULL
)
return
-
ENOENT
;
}
node_idx
=
(
offset
-
iter
->
startbit
)
/
NETLBL_CATMAP_MAPSIZE
;
node_bit
=
offset
-
iter
->
startbit
-
(
NETLBL_CATMAP_MAPSIZE
*
node_idx
);
offset
-=
iter
->
startbit
;
idx
=
offset
/
NETLBL_CATMAP_MAPSIZE
;
bit
=
offset
%
NETLBL_CATMAP_MAPSIZE
;
}
else
{
node_
idx
=
0
;
node_
bit
=
0
;
idx
=
0
;
bit
=
0
;
}
bitmask
=
NETLBL_CATMAP_BIT
<<
node_
bit
;
bitmask
=
NETLBL_CATMAP_BIT
<<
bit
;
for
(;;)
{
bitmap
=
iter
->
bitmap
[
node_
idx
];
bitmap
=
iter
->
bitmap
[
idx
];
while
(
bitmask
!=
0
&&
(
bitmap
&
bitmask
)
!=
0
)
{
bitmask
<<=
1
;
node_
bit
++
;
bit
++
;
}
if
(
bitmask
!=
0
)
if
(
prev
&&
idx
==
0
&&
bit
==
0
)
return
prev
->
startbit
+
NETLBL_CATMAP_SIZE
-
1
;
else
if
(
bitmask
!=
0
)
return
iter
->
startbit
+
(
NETLBL_CATMAP_MAPSIZE
*
node_idx
)
+
node_bit
-
1
;
else
if
(
++
node_idx
>=
NETLBL_CATMAP_MAPCNT
)
{
(
NETLBL_CATMAP_MAPSIZE
*
idx
)
+
bit
-
1
;
else
if
(
++
idx
>=
NETLBL_CATMAP_MAPCNT
)
{
if
(
iter
->
next
==
NULL
)
return
iter
->
startbit
+
NETLBL_CATMAP_SIZE
-
1
;
return
iter
->
startbit
+
NETLBL_CATMAP_SIZE
-
1
;
prev
=
iter
;
iter
=
iter
->
next
;
node_
idx
=
0
;
idx
=
0
;
}
bitmask
=
NETLBL_CATMAP_BIT
;
node_
bit
=
0
;
bit
=
0
;
}
return
-
ENOENT
;
}
/**
* netlbl_secattr_catmap_setbit - Set a bit in a LSM secattr catmap
* @catmap: the category bitmap
* netlbl_catmap_getlong - Export an unsigned long bitmap
* @catmap: pointer to the category bitmap
* @offset: pointer to the requested offset
* @bitmap: the exported bitmap
*
* Description:
* Export a bitmap with an offset greater than or equal to @offset and return
* it in @bitmap. The @offset must be aligned to an unsigned long and will be
* updated on return if different from what was requested; if the catmap is
* empty at the requested offset and beyond, the @offset is set to (u32)-1.
* Returns zero on sucess, negative values on failure.
*
*/
int
netlbl_catmap_getlong
(
struct
netlbl_lsm_catmap
*
catmap
,
u32
*
offset
,
unsigned
long
*
bitmap
)
{
struct
netlbl_lsm_catmap
*
iter
;
u32
off
=
*
offset
;
u32
idx
;
/* only allow aligned offsets */
if
((
off
&
(
BITS_PER_LONG
-
1
))
!=
0
)
return
-
EINVAL
;
if
(
off
<
catmap
->
startbit
)
{
off
=
catmap
->
startbit
;
*
offset
=
off
;
}
iter
=
_netlbl_catmap_getnode
(
&
catmap
,
off
,
_CM_F_NONE
,
0
);
if
(
iter
==
NULL
)
{
*
offset
=
(
u32
)
-
1
;
return
0
;
}
if
(
off
<
iter
->
startbit
)
{
off
=
iter
->
startbit
;
*
offset
=
off
;
}
else
off
-=
iter
->
startbit
;
idx
=
off
/
NETLBL_CATMAP_MAPSIZE
;
*
bitmap
=
iter
->
bitmap
[
idx
]
>>
(
off
%
NETLBL_CATMAP_SIZE
);
return
0
;
}
/**
* netlbl_catmap_setbit - Set a bit in a LSM secattr catmap
* @catmap: pointer to the category bitmap
* @bit: the bit to set
* @flags: memory allocation flags
*
...
...
@@ -531,36 +640,27 @@ int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
* negative values on failure.
*
*/
int
netlbl_
secattr_catmap_setbit
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
bit
,
gfp_t
flags
)
int
netlbl_
catmap_setbit
(
struct
netlbl_lsm_catmap
*
*
catmap
,
u32
bit
,
gfp_t
flags
)
{
struct
netlbl_lsm_secattr_catmap
*
iter
=
catmap
;
u32
node_bit
;
u32
node_idx
;
struct
netlbl_lsm_catmap
*
iter
;
u32
idx
;
while
(
iter
->
next
!=
NULL
&&
bit
>=
(
iter
->
startbit
+
NETLBL_CATMAP_SIZE
))
iter
=
iter
->
next
;
if
(
bit
>=
(
iter
->
startbit
+
NETLBL_CATMAP_SIZE
))
{
iter
->
next
=
netlbl_secattr_catmap_alloc
(
flags
);
if
(
iter
->
next
==
NULL
)
return
-
ENOMEM
;
iter
=
iter
->
next
;
iter
->
startbit
=
bit
&
~
(
NETLBL_CATMAP_SIZE
-
1
);
}
iter
=
_netlbl_catmap_getnode
(
catmap
,
bit
,
_CM_F_ALLOC
,
flags
);
if
(
iter
==
NULL
)
return
-
ENOMEM
;
/* gcc always rounds to zero when doing integer division */
node_idx
=
(
bit
-
iter
->
startbit
)
/
NETLBL_CATMAP_MAPSIZE
;
node_bit
=
bit
-
iter
->
startbit
-
(
NETLBL_CATMAP_MAPSIZE
*
node_idx
);
iter
->
bitmap
[
node_idx
]
|=
NETLBL_CATMAP_BIT
<<
node_bit
;
bit
-=
iter
->
startbit
;
idx
=
bit
/
NETLBL_CATMAP_MAPSIZE
;
iter
->
bitmap
[
idx
]
|=
NETLBL_CATMAP_BIT
<<
(
bit
%
NETLBL_CATMAP_MAPSIZE
);
return
0
;
}
/**
* netlbl_
secattr_
catmap_setrng - Set a range of bits in a LSM secattr catmap
* @catmap: the category bitmap
* netlbl_catmap_setrng - Set a range of bits in a LSM secattr catmap
* @catmap:
pointer to
the category bitmap
* @start: the starting bit
* @end: the last bit in the string
* @flags: memory allocation flags
...
...
@@ -570,36 +670,63 @@ int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
* on success, negative values on failure.
*
*/
int
netlbl_
secattr_catmap_setrng
(
struct
netlbl_lsm_secattr_catmap
*
catmap
,
u32
start
,
u32
end
,
gfp_t
flags
)
int
netlbl_
catmap_setrng
(
struct
netlbl_lsm_catmap
*
*
catmap
,
u32
start
,
u32
end
,
gfp_t
flags
)
{
int
ret_val
=
0
;
struct
netlbl_lsm_secattr_catmap
*
iter
=
catmap
;
u32
iter_max_spot
;
u32
spot
;
/* XXX - This could probably be made a bit faster by combining writes
* to the catmap instead of setting a single bit each time, but for
* right now skipping to the start of the range in the catmap should
* be a nice improvement over calling the individual setbit function
* repeatedly from a loop. */
while
(
iter
->
next
!=
NULL
&&
start
>=
(
iter
->
startbit
+
NETLBL_CATMAP_SIZE
))
iter
=
iter
->
next
;
iter_max_spot
=
iter
->
startbit
+
NETLBL_CATMAP_SIZE
;
for
(
spot
=
start
;
spot
<=
end
&&
ret_val
==
0
;
spot
++
)
{
if
(
spot
>=
iter_max_spot
&&
iter
->
next
!=
NULL
)
{
iter
=
iter
->
next
;
iter_max_spot
=
iter
->
startbit
+
NETLBL_CATMAP_SIZE
;
}
ret_val
=
netlbl_secattr_catmap_setbit
(
iter
,
spot
,
flags
);
int
rc
=
0
;
u32
spot
=
start
;
while
(
rc
==
0
&&
spot
<=
end
)
{
if
(((
spot
&
(
BITS_PER_LONG
-
1
))
!=
0
)
&&
((
end
-
spot
)
>
BITS_PER_LONG
))
{
rc
=
netlbl_catmap_setlong
(
catmap
,
spot
,
(
unsigned
long
)
-
1
,
flags
);
spot
+=
BITS_PER_LONG
;
}
else
rc
=
netlbl_catmap_setbit
(
catmap
,
spot
++
,
flags
);
}
return
ret_val
;
return
rc
;
}
/**
* netlbl_catmap_setlong - Import an unsigned long bitmap
* @catmap: pointer to the category bitmap
* @offset: offset to the start of the imported bitmap
* @bitmap: the bitmap to import
* @flags: memory allocation flags
*
* Description:
* Import the bitmap specified in @bitmap into @catmap, using the offset
* in @offset. The offset must be aligned to an unsigned long. Returns zero
* on success, negative values on failure.
*
*/
int
netlbl_catmap_setlong
(
struct
netlbl_lsm_catmap
**
catmap
,
u32
offset
,
unsigned
long
bitmap
,
gfp_t
flags
)
{
struct
netlbl_lsm_catmap
*
iter
;
u32
idx
;
/* only allow aligned offsets */
if
((
offset
&
(
BITS_PER_LONG
-
1
))
!=
0
)
return
-
EINVAL
;
iter
=
_netlbl_catmap_getnode
(
catmap
,
offset
,
_CM_F_ALLOC
,
flags
);
if
(
iter
==
NULL
)
return
-
ENOMEM
;
offset
-=
iter
->
startbit
;
idx
=
offset
/
NETLBL_CATMAP_MAPSIZE
;
iter
->
bitmap
[
idx
]
|=
bitmap
<<
(
offset
%
NETLBL_CATMAP_MAPSIZE
);
return
0
;
}
/*
...
...
security/selinux/ss/ebitmap.c
View file @
103ae675
...
...
@@ -86,51 +86,36 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
*
*/
int
ebitmap_netlbl_export
(
struct
ebitmap
*
ebmap
,
struct
netlbl_lsm_
secattr_
catmap
**
catmap
)
struct
netlbl_lsm_catmap
**
catmap
)
{
struct
ebitmap_node
*
e_iter
=
ebmap
->
node
;
struct
netlbl_lsm_secattr_catmap
*
c_iter
;
u32
cmap_idx
,
cmap_sft
;
int
i
;
/* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64,
* however, it is not always compatible with an array of unsigned long
* in ebitmap_node.
* In addition, you should pay attention the following implementation
* assumes unsigned long has a width equal with or less than 64-bit.
*/
unsigned
long
e_map
;
u32
offset
;
unsigned
int
iter
;
int
rc
;
if
(
e_iter
==
NULL
)
{
*
catmap
=
NULL
;
return
0
;
}
c_iter
=
netlbl_secattr_catmap_alloc
(
GFP_ATOMIC
);
if
(
c_iter
==
NULL
)
return
-
ENOMEM
;
*
catmap
=
c_iter
;
c_iter
->
startbit
=
e_iter
->
startbit
&
~
(
NETLBL_CATMAP_SIZE
-
1
);
if
(
*
catmap
!=
NULL
)
netlbl_catmap_free
(
*
catmap
);
*
catmap
=
NULL
;
while
(
e_iter
)
{
for
(
i
=
0
;
i
<
EBITMAP_UNIT_NUMS
;
i
++
)
{
unsigned
int
delta
,
e_startbit
,
c_endbit
;
e_startbit
=
e_iter
->
startbit
+
i
*
EBITMAP_UNIT_SIZE
;
c_endbit
=
c_iter
->
startbit
+
NETLBL_CATMAP_SIZE
;
if
(
e_startbit
>=
c_endbit
)
{
c_iter
->
next
=
netlbl_secattr_catmap_alloc
(
GFP_ATOMIC
);
if
(
c_iter
->
next
==
NULL
)
offset
=
e_iter
->
startbit
;
for
(
iter
=
0
;
iter
<
EBITMAP_UNIT_NUMS
;
iter
++
)
{
e_map
=
e_iter
->
maps
[
iter
];
if
(
e_map
!=
0
)
{
rc
=
netlbl_catmap_setlong
(
catmap
,
offset
,
e_map
,
GFP_ATOMIC
);
if
(
rc
!=
0
)
goto
netlbl_export_failure
;
c_iter
=
c_iter
->
next
;
c_iter
->
startbit
=
e_startbit
&
~
(
NETLBL_CATMAP_SIZE
-
1
);
}
delta
=
e_startbit
-
c_iter
->
startbit
;
cmap_idx
=
delta
/
NETLBL_CATMAP_MAPSIZE
;
cmap_sft
=
delta
%
NETLBL_CATMAP_MAPSIZE
;
c_iter
->
bitmap
[
cmap_idx
]
|=
e_iter
->
maps
[
i
]
<<
cmap_sft
;
offset
+=
EBITMAP_UNIT_SIZE
;
}
e_iter
=
e_iter
->
next
;
}
...
...
@@ -138,7 +123,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
return
0
;
netlbl_export_failure:
netlbl_
secattr_
catmap_free
(
*
catmap
);
netlbl_catmap_free
(
*
catmap
);
return
-
ENOMEM
;
}
...
...
@@ -153,58 +138,44 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
*
*/
int
ebitmap_netlbl_import
(
struct
ebitmap
*
ebmap
,
struct
netlbl_lsm_
secattr_
catmap
*
catmap
)
struct
netlbl_lsm_catmap
*
catmap
)
{
int
rc
;
struct
ebitmap_node
*
e_iter
=
NULL
;
struct
ebitmap_node
*
emap_prev
=
NULL
;
struct
netlbl_lsm_secattr_catmap
*
c_iter
=
catmap
;
u32
c_idx
,
c_pos
,
e_idx
,
e_sft
;
/* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64,
* however, it is not always compatible with an array of unsigned long
* in ebitmap_node.
* In addition, you should pay attention the following implementation
* assumes unsigned long has a width equal with or less than 64-bit.
*/
do
{
for
(
c_idx
=
0
;
c_idx
<
NETLBL_CATMAP_MAPCNT
;
c_idx
++
)
{
unsigned
int
delta
;
u64
map
=
c_iter
->
bitmap
[
c_idx
];
if
(
!
map
)
continue
;
struct
ebitmap_node
*
e_prev
=
NULL
;
u32
offset
=
0
,
idx
;
unsigned
long
bitmap
;
for
(;;)
{
rc
=
netlbl_catmap_getlong
(
catmap
,
&
offset
,
&
bitmap
);
if
(
rc
<
0
)
goto
netlbl_import_failure
;
if
(
offset
==
(
u32
)
-
1
)
return
0
;
c_pos
=
c_iter
->
startbit
+
c_idx
*
NETLBL_CATMAP_MAPSIZE
;
if
(
!
e_iter
||
c_pos
>=
e_iter
->
startbit
+
EBITMAP_SIZE
)
{
e_iter
=
kzalloc
(
sizeof
(
*
e_iter
),
GFP_ATOMIC
);
if
(
!
e_iter
)
goto
netlbl_import_failure
;
e_iter
->
startbit
=
c_pos
-
(
c_pos
%
EBITMAP_SIZE
);
if
(
emap_prev
==
NULL
)
ebmap
->
node
=
e_iter
;
else
emap_prev
->
next
=
e_iter
;
emap_prev
=
e_iter
;
}
delta
=
c_pos
-
e_iter
->
startbit
;
e_idx
=
delta
/
EBITMAP_UNIT_SIZE
;
e_sft
=
delta
%
EBITMAP_UNIT_SIZE
;
while
(
map
)
{
e_iter
->
maps
[
e_idx
++
]
|=
map
&
(
-
1UL
);
map
=
EBITMAP_SHIFT_UNIT_SIZE
(
map
);
}
if
(
e_iter
==
NULL
||
offset
>=
e_iter
->
startbit
+
EBITMAP_SIZE
)
{
e_prev
=
e_iter
;
e_iter
=
kzalloc
(
sizeof
(
*
e_iter
),
GFP_ATOMIC
);
if
(
e_iter
==
NULL
)
goto
netlbl_import_failure
;
e_iter
->
startbit
=
offset
&
~
(
EBITMAP_SIZE
-
1
);
if
(
e_prev
==
NULL
)
ebmap
->
node
=
e_iter
;
else
e_prev
->
next
=
e_iter
;
ebmap
->
highbit
=
e_iter
->
startbit
+
EBITMAP_SIZE
;
}
c_iter
=
c_iter
->
next
;
}
while
(
c_iter
);
if
(
e_iter
!=
NULL
)
ebmap
->
highbit
=
e_iter
->
startbit
+
EBITMAP_SIZE
;
else
ebitmap_destroy
(
ebmap
);
/* offset will always be aligned to an unsigned long */
idx
=
EBITMAP_NODE_INDEX
(
e_iter
,
offset
);
e_iter
->
maps
[
idx
]
=
bitmap
;
/* next */
offset
+=
EBITMAP_UNIT_SIZE
;
}
/* NOTE: we should never reach this return */
return
0
;
netlbl_import_failure:
...
...
security/selinux/ss/ebitmap.h
View file @
103ae675
...
...
@@ -132,17 +132,17 @@ int ebitmap_write(struct ebitmap *e, void *fp);
#ifdef CONFIG_NETLABEL
int
ebitmap_netlbl_export
(
struct
ebitmap
*
ebmap
,
struct
netlbl_lsm_
secattr_
catmap
**
catmap
);
struct
netlbl_lsm_catmap
**
catmap
);
int
ebitmap_netlbl_import
(
struct
ebitmap
*
ebmap
,
struct
netlbl_lsm_
secattr_
catmap
*
catmap
);
struct
netlbl_lsm_catmap
*
catmap
);
#else
static
inline
int
ebitmap_netlbl_export
(
struct
ebitmap
*
ebmap
,
struct
netlbl_lsm_secattr
_catmap
**
catmap
)
struct
netlbl_lsm
_catmap
**
catmap
)
{
return
-
ENOMEM
;
}
static
inline
int
ebitmap_netlbl_import
(
struct
ebitmap
*
ebmap
,
struct
netlbl_lsm_secattr
_catmap
*
catmap
)
struct
netlbl_lsm
_catmap
*
catmap
)
{
return
-
ENOMEM
;
}
...
...
security/smack/smack_access.c
View file @
103ae675
...
...
@@ -457,19 +457,16 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
sap
->
flags
|=
NETLBL_SECATTR_MLS_CAT
;
sap
->
attr
.
mls
.
lvl
=
level
;
sap
->
attr
.
mls
.
cat
=
netlbl_secattr_catmap_alloc
(
GFP_ATOMIC
);
if
(
!
sap
->
attr
.
mls
.
cat
)
return
-
ENOMEM
;
sap
->
attr
.
mls
.
cat
->
startbit
=
0
;
sap
->
attr
.
mls
.
cat
=
NULL
;
for
(
cat
=
1
,
cp
=
catset
,
byte
=
0
;
byte
<
len
;
cp
++
,
byte
++
)
for
(
m
=
0x80
;
m
!=
0
;
m
>>=
1
,
cat
++
)
{
if
((
m
&
*
cp
)
==
0
)
continue
;
rc
=
netlbl_
secattr_catmap_setbit
(
sap
->
attr
.
mls
.
cat
,
cat
,
GFP_ATOMIC
);
rc
=
netlbl_
catmap_setbit
(
&
sap
->
attr
.
mls
.
cat
,
cat
,
GFP_ATOMIC
);
if
(
rc
<
0
)
{
netlbl_
secattr_
catmap_free
(
sap
->
attr
.
mls
.
cat
);
netlbl_catmap_free
(
sap
->
attr
.
mls
.
cat
);
return
rc
;
}
}
...
...
security/smack/smack_lsm.c
View file @
103ae675
...
...
@@ -3209,9 +3209,9 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
break
;
}
for
(
acat
=
-
1
,
kcat
=
-
1
;
acat
==
kcat
;
)
{
acat
=
netlbl_
secattr_catmap_walk
(
sap
->
attr
.
mls
.
cat
,
acat
+
1
);
kcat
=
netlbl_
secattr_
catmap_walk
(
acat
=
netlbl_
catmap_walk
(
sap
->
attr
.
mls
.
cat
,
acat
+
1
);
kcat
=
netlbl_catmap_walk
(
skp
->
smk_netlabel
.
attr
.
mls
.
cat
,
kcat
+
1
);
if
(
acat
<
0
||
kcat
<
0
)
...
...
security/smack/smackfs.c
View file @
103ae675
...
...
@@ -787,7 +787,7 @@ static int cipso_seq_show(struct seq_file *s, void *v)
struct
list_head
*
list
=
v
;
struct
smack_known
*
skp
=
list_entry
(
list
,
struct
smack_known
,
list
);
struct
netlbl_lsm_
secattr_
catmap
*
cmp
=
skp
->
smk_netlabel
.
attr
.
mls
.
cat
;
struct
netlbl_lsm_catmap
*
cmp
=
skp
->
smk_netlabel
.
attr
.
mls
.
cat
;
char
sep
=
'/'
;
int
i
;
...
...
@@ -804,8 +804,8 @@ static int cipso_seq_show(struct seq_file *s, void *v)
seq_printf
(
s
,
"%s %3d"
,
skp
->
smk_known
,
skp
->
smk_netlabel
.
attr
.
mls
.
lvl
);
for
(
i
=
netlbl_
secattr_
catmap_walk
(
cmp
,
0
);
i
>=
0
;
i
=
netlbl_
secattr_
catmap_walk
(
cmp
,
i
+
1
))
{
for
(
i
=
netlbl_catmap_walk
(
cmp
,
0
);
i
>=
0
;
i
=
netlbl_catmap_walk
(
cmp
,
i
+
1
))
{
seq_printf
(
s
,
"%c%d"
,
sep
,
i
);
sep
=
','
;
}
...
...
@@ -926,7 +926,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
rc
=
smk_netlbl_mls
(
maplevel
,
mapcatset
,
&
ncats
,
SMK_CIPSOLEN
);
if
(
rc
>=
0
)
{
netlbl_
secattr_
catmap_free
(
skp
->
smk_netlabel
.
attr
.
mls
.
cat
);
netlbl_catmap_free
(
skp
->
smk_netlabel
.
attr
.
mls
.
cat
);
skp
->
smk_netlabel
.
attr
.
mls
.
cat
=
ncats
.
attr
.
mls
.
cat
;
skp
->
smk_netlabel
.
attr
.
mls
.
lvl
=
ncats
.
attr
.
mls
.
lvl
;
rc
=
count
;
...
...
@@ -976,14 +976,14 @@ static int cipso2_seq_show(struct seq_file *s, void *v)
struct
list_head
*
list
=
v
;
struct
smack_known
*
skp
=
list_entry
(
list
,
struct
smack_known
,
list
);
struct
netlbl_lsm_
secattr_
catmap
*
cmp
=
skp
->
smk_netlabel
.
attr
.
mls
.
cat
;
struct
netlbl_lsm_catmap
*
cmp
=
skp
->
smk_netlabel
.
attr
.
mls
.
cat
;
char
sep
=
'/'
;
int
i
;
seq_printf
(
s
,
"%s %3d"
,
skp
->
smk_known
,
skp
->
smk_netlabel
.
attr
.
mls
.
lvl
);
for
(
i
=
netlbl_
secattr_
catmap_walk
(
cmp
,
0
);
i
>=
0
;
i
=
netlbl_
secattr_
catmap_walk
(
cmp
,
i
+
1
))
{
for
(
i
=
netlbl_catmap_walk
(
cmp
,
0
);
i
>=
0
;
i
=
netlbl_catmap_walk
(
cmp
,
i
+
1
))
{
seq_printf
(
s
,
"%c%d"
,
sep
,
i
);
sep
=
','
;
}
...
...
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