Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
halo
external_libselinux
Commits
35b01083
Commit
35b01083
authored
13 years ago
by
Stephen Smalley
Browse files
Options
Download
Email Patches
Plain Diff
Define and implement Android property selabel backend.
parent
32ebfe86
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
309 additions
and
1 deletion
+309
-1
Android.mk
Android.mk
+2
-1
include/selinux/label.h
include/selinux/label.h
+2
-0
src/label.c
src/label.c
+7
-0
src/label_android_property.c
src/label_android_property.c
+296
-0
src/label_internal.h
src/label_internal.h
+2
-0
No files found.
Android.mk
View file @
35b01083
...
...
@@ -36,7 +36,8 @@ common_HOST_FILES := \
src/freecon.c
\
src/init.c
\
src/label.c
\
src/label_file.c
src/label_file.c
\
src/label_android_property.c
common_COPY_HEADERS_TO
:=
selinux
...
...
This diff is collapsed.
Click to expand it.
include/selinux/label.h
View file @
35b01083
...
...
@@ -31,6 +31,8 @@ struct selabel_handle;
#define SELABEL_CTX_X 2
/* db objects */
#define SELABEL_CTX_DB 3
/* Android property service contexts */
#define SELABEL_CTX_ANDROID_PROP 4
/*
* Available options
...
...
This diff is collapsed.
Click to expand it.
src/label.c
View file @
35b01083
...
...
@@ -21,6 +21,10 @@ typedef int (*selabel_initfunc)(struct selabel_handle *rec,
static
selabel_initfunc
initfuncs
[]
=
{
&
selabel_file_init
,
NULL
,
NULL
,
NULL
,
&
selabel_property_init
,
};
/*
...
...
@@ -67,6 +71,9 @@ struct selabel_handle *selabel_open(unsigned int backend,
goto
out
;
}
if
(
initfuncs
[
backend
]
==
NULL
)
goto
out
;
rec
=
(
struct
selabel_handle
*
)
malloc
(
sizeof
(
*
rec
));
if
(
!
rec
)
goto
out
;
...
...
This diff is collapsed.
Click to expand it.
src/label_android_property.c
0 → 100644
View file @
35b01083
/*
* Property Service contexts backend for labeling Android
* property keys
*/
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "callbacks.h"
#include "label_internal.h"
/* A property security context specification. */
typedef
struct
spec
{
struct
selabel_lookup_rec
lr
;
/* holds contexts for lookup result */
char
*
property_key
;
/* property key string */
}
spec_t
;
/* Our stored configuration */
struct
saved_data
{
/*
* The array of specifications is sorted for longest
* prefix match
*/
spec_t
*
spec_arr
;
unsigned
int
nspec
;
/* total number of specifications */
};
static
int
cmp
(
const
void
*
A
,
const
void
*
B
)
{
const
struct
spec
*
sp1
=
A
,
*
sp2
=
B
;
if
(
strncmp
(
sp1
->
property_key
,
"*"
,
1
)
==
0
)
return
1
;
if
(
strncmp
(
sp2
->
property_key
,
"*"
,
1
)
==
0
)
return
-
1
;
size_t
L1
=
strlen
(
sp1
->
property_key
);
size_t
L2
=
strlen
(
sp2
->
property_key
);
return
(
L1
<
L2
)
-
(
L1
>
L2
);
}
/*
* Warn about duplicate specifications.
*/
static
int
nodups_specs
(
struct
saved_data
*
data
,
const
char
*
path
)
{
int
rc
=
0
;
unsigned
int
ii
,
jj
;
struct
spec
*
curr_spec
,
*
spec_arr
=
data
->
spec_arr
;
for
(
ii
=
0
;
ii
<
data
->
nspec
;
ii
++
)
{
curr_spec
=
&
spec_arr
[
ii
];
for
(
jj
=
ii
+
1
;
jj
<
data
->
nspec
;
jj
++
)
{
if
((
!
strcmp
(
spec_arr
[
jj
].
property_key
,
curr_spec
->
property_key
)))
{
rc
=
-
1
;
errno
=
EINVAL
;
if
(
strcmp
(
spec_arr
[
jj
].
lr
.
ctx_raw
,
curr_spec
->
lr
.
ctx_raw
))
{
selinux_log
(
SELINUX_ERROR
,
"%s: Multiple different specifications for %s (%s and %s).
\n
"
,
path
,
curr_spec
->
property_key
,
spec_arr
[
jj
].
lr
.
ctx_raw
,
curr_spec
->
lr
.
ctx_raw
);
}
else
{
selinux_log
(
SELINUX_ERROR
,
"%s: Multiple same specifications for %s.
\n
"
,
path
,
curr_spec
->
property_key
);
}
}
}
}
return
rc
;
}
static
int
process_line
(
struct
selabel_handle
*
rec
,
const
char
*
path
,
char
*
line_buf
,
int
pass
,
unsigned
lineno
)
{
int
items
,
len
;
char
buf1
[
BUFSIZ
],
buf2
[
BUFSIZ
];
char
*
buf_p
,
*
prop
=
buf1
,
*
context
=
buf2
;
struct
saved_data
*
data
=
(
struct
saved_data
*
)
rec
->
data
;
spec_t
*
spec_arr
=
data
->
spec_arr
;
unsigned
int
nspec
=
data
->
nspec
;
len
=
strlen
(
line_buf
);
if
(
line_buf
[
len
-
1
]
==
'\n'
)
line_buf
[
len
-
1
]
=
0
;
buf_p
=
line_buf
;
while
(
isspace
(
*
buf_p
))
buf_p
++
;
/* Skip comment lines and empty lines. */
if
(
*
buf_p
==
'#'
||
*
buf_p
==
0
)
return
0
;
items
=
sscanf
(
line_buf
,
"%255s %255s"
,
prop
,
context
);
if
(
items
!=
2
)
{
selinux_log
(
SELINUX_WARNING
,
"%s: line %d is missing fields, skipping
\n
"
,
path
,
lineno
);
return
0
;
}
if
(
pass
==
1
)
{
/* On the second pass, process and store the specification in spec. */
spec_arr
[
nspec
].
property_key
=
strdup
(
prop
);
if
(
!
spec_arr
[
nspec
].
property_key
)
{
selinux_log
(
SELINUX_WARNING
,
"%s: out of memory at line %d on prop %s
\n
"
,
path
,
lineno
,
prop
);
return
-
1
;
}
spec_arr
[
nspec
].
lr
.
ctx_raw
=
strdup
(
context
);
if
(
!
spec_arr
[
nspec
].
lr
.
ctx_raw
)
{
selinux_log
(
SELINUX_WARNING
,
"%s: out of memory at line %d on context %s
\n
"
,
path
,
lineno
,
context
);
return
-
1
;
}
}
data
->
nspec
=
++
nspec
;
return
0
;
}
static
int
init
(
struct
selabel_handle
*
rec
,
struct
selinux_opt
*
opts
,
unsigned
n
)
{
struct
saved_data
*
data
=
(
struct
saved_data
*
)
rec
->
data
;
const
char
*
path
=
NULL
;
FILE
*
fp
;
char
line_buf
[
BUFSIZ
];
unsigned
int
lineno
=
0
,
maxnspec
,
pass
;
int
status
=
-
1
;
struct
stat
sb
;
/* Process arguments */
while
(
n
--
)
switch
(
opts
[
n
].
type
)
{
case
SELABEL_OPT_PATH
:
path
=
opts
[
n
].
value
;
break
;
default:
selinux_log
(
SELINUX_WARNING
,
"Argument type (%d) not recognized. Skipping
\n
"
,
opts
[
n
].
type
);
break
;
}
/* Open the specification file. */
if
((
fp
=
fopen
(
path
,
"r"
))
==
NULL
)
return
-
1
;
if
(
fstat
(
fileno
(
fp
),
&
sb
)
<
0
)
return
-
1
;
if
(
!
S_ISREG
(
sb
.
st_mode
))
{
errno
=
EINVAL
;
return
-
1
;
}
/*
* Two passes of the specification file. First is to get the size.
* After the first pass, the spec array is malloced to the appropriate
* size. Second pass is to populate the spec array and check for
* dups.
*/
maxnspec
=
UINT_MAX
/
sizeof
(
spec_t
);
for
(
pass
=
0
;
pass
<
2
;
pass
++
)
{
data
->
nspec
=
0
;
while
(
fgets
(
line_buf
,
sizeof
line_buf
-
1
,
fp
)
&&
data
->
nspec
<
maxnspec
)
{
if
(
process_line
(
rec
,
path
,
line_buf
,
pass
,
++
lineno
)
!=
0
)
{
goto
finish
;
}
}
if
(
pass
==
1
)
{
status
=
nodups_specs
(
data
,
path
);
if
(
status
)
goto
finish
;
}
if
(
pass
==
0
)
{
if
(
data
->
nspec
==
0
)
{
status
=
0
;
goto
finish
;
}
if
(
NULL
==
(
data
->
spec_arr
=
malloc
(
sizeof
(
spec_t
)
*
data
->
nspec
)))
goto
finish
;
memset
(
data
->
spec_arr
,
0
,
sizeof
(
spec_t
)
*
data
->
nspec
);
maxnspec
=
data
->
nspec
;
rewind
(
fp
);
}
}
qsort
(
data
->
spec_arr
,
data
->
nspec
,
sizeof
(
struct
spec
),
cmp
);
status
=
0
;
finish:
fclose
(
fp
);
return
status
;
}
/*
* Backend interface routines
*/
static
void
closef
(
struct
selabel_handle
*
rec
)
{
struct
saved_data
*
data
=
(
struct
saved_data
*
)
rec
->
data
;
struct
spec
*
spec
;
unsigned
int
i
;
for
(
i
=
0
;
i
<
data
->
nspec
;
i
++
)
{
spec
=
&
data
->
spec_arr
[
i
];
free
(
spec
->
property_key
);
free
(
spec
->
lr
.
ctx_raw
);
free
(
spec
->
lr
.
ctx_trans
);
}
if
(
data
->
spec_arr
)
free
(
data
->
spec_arr
);
free
(
data
);
}
static
struct
selabel_lookup_rec
*
lookup
(
struct
selabel_handle
*
rec
,
const
char
*
key
,
int
__attribute__
((
unused
))
type
)
{
struct
saved_data
*
data
=
(
struct
saved_data
*
)
rec
->
data
;
spec_t
*
spec_arr
=
data
->
spec_arr
;
unsigned
int
i
;
struct
selabel_lookup_rec
*
ret
=
NULL
;
if
(
!
data
->
nspec
)
{
errno
=
ENOENT
;
goto
finish
;
}
for
(
i
=
0
;
i
<
data
->
nspec
;
i
++
)
{
if
(
strncmp
(
spec_arr
[
i
].
property_key
,
key
,
strlen
(
spec_arr
[
i
].
property_key
))
==
0
)
{
break
;
}
if
(
strncmp
(
spec_arr
[
i
].
property_key
,
"*"
,
1
)
==
0
)
break
;
}
if
(
i
>=
data
->
nspec
)
{
/* No matching specification. */
errno
=
ENOENT
;
goto
finish
;
}
ret
=
&
spec_arr
[
i
].
lr
;
finish:
return
ret
;
}
static
void
stats
(
struct
selabel_handle
__attribute__
((
unused
))
*
rec
)
{
selinux_log
(
SELINUX_WARNING
,
"'stats' functionality not implemented.
\n
"
);
}
int
selabel_property_init
(
struct
selabel_handle
*
rec
,
struct
selinux_opt
*
opts
,
unsigned
nopts
)
{
struct
saved_data
*
data
;
data
=
(
struct
saved_data
*
)
malloc
(
sizeof
(
*
data
));
if
(
!
data
)
return
-
1
;
memset
(
data
,
0
,
sizeof
(
*
data
));
rec
->
data
=
data
;
rec
->
func_close
=
&
closef
;
rec
->
func_stats
=
&
stats
;
rec
->
func_lookup
=
&
lookup
;
return
init
(
rec
,
opts
,
nopts
);
}
This diff is collapsed.
Click to expand it.
src/label_internal.h
View file @
35b01083
...
...
@@ -25,6 +25,8 @@ int selabel_x_init(struct selabel_handle *rec, struct selinux_opt *opts,
unsigned
nopts
)
hidden
;
int
selabel_db_init
(
struct
selabel_handle
*
rec
,
struct
selinux_opt
*
opts
,
unsigned
nopts
)
hidden
;
int
selabel_property_init
(
struct
selabel_handle
*
rec
,
struct
selinux_opt
*
opts
,
unsigned
nopts
)
hidden
;
/*
* Labeling internal structures
...
...
This diff is collapsed.
Click to expand it.
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