Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
d4baae41
Commit
d4baae41
authored
May 21, 2020
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Modernize magiskpolicy
parent
e02e46d0
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
587 additions
and
743 deletions
+587
-743
magiskpolicy.hpp
native/jni/include/magiskpolicy.hpp
+52
-35
rootdir.cpp
native/jni/init/rootdir.cpp
+8
-7
api.cpp
native/jni/magiskpolicy/api.cpp
+40
-40
magiskpolicy.cpp
native/jni/magiskpolicy/magiskpolicy.cpp
+14
-10
policydb.cpp
native/jni/magiskpolicy/policydb.cpp
+59
-58
rules.cpp
native/jni/magiskpolicy/rules.cpp
+128
-128
sepolicy.c
native/jni/magiskpolicy/sepolicy.c
+96
-96
sepolicy.h
native/jni/magiskpolicy/sepolicy.h
+15
-11
statement.cpp
native/jni/magiskpolicy/statement.cpp
+175
-358
No files found.
native/jni/include/magiskpolicy.hpp
View file @
d4baae41
...
@@ -3,38 +3,55 @@
...
@@ -3,38 +3,55 @@
#include <stdlib.h>
#include <stdlib.h>
#include <selinux.hpp>
#include <selinux.hpp>
#define ALL NULL
#define ALL nullptr
// policydb functions
struct
policydb
;
int
load_policydb
(
const
char
*
file
);
int
load_split_cil
();
class
sepolicy
{
int
compile_split_cil
();
public
:
int
dump_policydb
(
const
char
*
file
);
typedef
const
char
*
c_str
;
void
destroy_policydb
();
~
sepolicy
();
// Handy functions
// Public static factory functions
int
sepol_allow
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
);
static
sepolicy
*
from_file
(
c_str
file
);
int
sepol_deny
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
);
static
sepolicy
*
from_split
();
int
sepol_auditallow
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
);
static
sepolicy
*
compile_split
();
int
sepol_dontaudit
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
);
int
sepol_typetrans
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
);
// External APIs
int
sepol_typechange
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
);
int
to_file
(
c_str
file
);
int
sepol_typemember
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
);
void
parse_statement
(
c_str
stmt
);
int
sepol_nametrans
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
,
const
char
*
o
);
void
load_rule_file
(
c_str
file
);
int
sepol_allowxperm
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
);
int
sepol_auditallowxperm
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
);
// Operation on types
int
sepol_dontauditxperm
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
);
int
create
(
c_str
type
);
int
sepol_create
(
const
char
*
s
);
int
permissive
(
c_str
type
);
int
sepol_permissive
(
const
char
*
s
);
int
enforce
(
c_str
type
);
int
sepol_enforce
(
const
char
*
s
);
int
typeattribute
(
c_str
type
,
c_str
attr
);
int
sepol_attradd
(
const
char
*
s
,
const
char
*
a
);
int
exists
(
c_str
type
);
int
sepol_genfscon
(
const
char
*
name
,
const
char
*
path
,
const
char
*
context
);
int
sepol_exists
(
const
char
*
source
);
// Access vector rules
int
allow
(
c_str
src
,
c_str
tgt
,
c_str
cls
,
c_str
perm
);
// Built in rules
int
deny
(
c_str
src
,
c_str
tgt
,
c_str
cls
,
c_str
perm
);
void
sepol_magisk_rules
();
int
auditallow
(
c_str
src
,
c_str
tgt
,
c_str
cls
,
c_str
perm
);
int
dontaudit
(
c_str
src
,
c_str
tgt
,
c_str
cls
,
c_str
perm
);
// Statement parsing
void
parse_statement
(
const
char
*
statement
);
// Extended permissions access vector rules
void
load_rule_file
(
const
char
*
file
);
int
allowxperm
(
c_str
src
,
c_str
tgt
,
c_str
cls
,
c_str
range
);
void
statement_help
();
int
auditallowxperm
(
c_str
src
,
c_str
tgt
,
c_str
cls
,
c_str
range
);
int
dontauditxperm
(
c_str
src
,
c_str
tgt
,
c_str
cls
,
c_str
range
);
// Type rules
int
type_transition
(
c_str
src
,
c_str
tgt
,
c_str
cls
,
c_str
def
,
c_str
obj
=
nullptr
);
int
type_change
(
c_str
src
,
c_str
tgt
,
c_str
cls
,
c_str
def
);
int
type_member
(
c_str
src
,
c_str
tgt
,
c_str
cls
,
c_str
def
);
// File system labeling
int
genfscon
(
c_str
fs_name
,
c_str
path
,
c_str
ctx
);
// Magisk
void
magisk_rules
();
void
allow_su_client
(
c_str
type
);
private
:
policydb
*
db
;
};
native/jni/init/rootdir.cpp
View file @
d4baae41
...
@@ -129,13 +129,14 @@ void RootFSInit::setup_rootfs() {
...
@@ -129,13 +129,14 @@ void RootFSInit::setup_rootfs() {
bool
MagiskInit
::
patch_sepolicy
(
const
char
*
file
)
{
bool
MagiskInit
::
patch_sepolicy
(
const
char
*
file
)
{
bool
patch_init
=
false
;
bool
patch_init
=
false
;
sepolicy
*
sepol
=
nullptr
;
if
(
access
(
SPLIT_PLAT_CIL
,
R_OK
)
==
0
)
{
if
(
access
(
SPLIT_PLAT_CIL
,
R_OK
)
==
0
)
{
LOGD
(
"sepol: split policy
\n
"
);
LOGD
(
"sepol: split policy
\n
"
);
patch_init
=
true
;
patch_init
=
true
;
}
else
if
(
access
(
"/sepolicy"
,
R_OK
)
==
0
)
{
}
else
if
(
access
(
"/sepolicy"
,
R_OK
)
==
0
)
{
LOGD
(
"sepol: monolithic policy
\n
"
);
LOGD
(
"sepol: monolithic policy
\n
"
);
load_policydb
(
"/sepolicy"
);
sepol
=
sepolicy
::
from_file
(
"/sepolicy"
);
}
else
{
}
else
{
LOGD
(
"sepol: no selinux
\n
"
);
LOGD
(
"sepol: no selinux
\n
"
);
return
false
;
return
false
;
...
@@ -148,10 +149,10 @@ bool MagiskInit::patch_sepolicy(const char *file) {
...
@@ -148,10 +149,10 @@ bool MagiskInit::patch_sepolicy(const char *file) {
}
}
if
(
patch_init
)
if
(
patch_init
)
load_split_cil
();
sepol
=
sepolicy
::
from_split
();
sepol
_
magisk_rules
();
sepol
->
magisk_rules
();
sepol
_
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
ALL
,
ALL
);
sepol
->
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
ALL
,
ALL
);
// Custom rules
// Custom rules
if
(
auto
dir
=
open_dir
(
persist_dir
.
data
());
dir
)
{
if
(
auto
dir
=
open_dir
(
persist_dir
.
data
());
dir
)
{
...
@@ -159,13 +160,13 @@ bool MagiskInit::patch_sepolicy(const char *file) {
...
@@ -159,13 +160,13 @@ bool MagiskInit::patch_sepolicy(const char *file) {
auto
rule
=
persist_dir
+
"/"
+
entry
->
d_name
+
"/sepolicy.rule"
;
auto
rule
=
persist_dir
+
"/"
+
entry
->
d_name
+
"/sepolicy.rule"
;
if
(
access
(
rule
.
data
(),
R_OK
)
==
0
)
{
if
(
access
(
rule
.
data
(),
R_OK
)
==
0
)
{
LOGD
(
"Loading custom sepolicy patch: %s
\n
"
,
rule
.
data
());
LOGD
(
"Loading custom sepolicy patch: %s
\n
"
,
rule
.
data
());
load_rule_file
(
rule
.
data
());
sepol
->
load_rule_file
(
rule
.
data
());
}
}
}
}
}
}
dump_policydb
(
file
);
sepol
->
to_file
(
file
);
de
stroy_policydb
()
;
de
lete
sepol
;
// Remove OnePlus stupid debug sepolicy and use our own
// Remove OnePlus stupid debug sepolicy and use our own
if
(
access
(
"/sepolicy_debug"
,
F_OK
)
==
0
)
{
if
(
access
(
"/sepolicy_debug"
,
F_OK
)
==
0
)
{
...
...
native/jni/magiskpolicy/api.cpp
View file @
d4baae41
...
@@ -5,86 +5,86 @@
...
@@ -5,86 +5,86 @@
//#define vprint(fmt, ...) printf(fmt, __VA_ARGS__)
//#define vprint(fmt, ...) printf(fmt, __VA_ARGS__)
#define vprint(...)
#define vprint(...)
int
sepol
_
allow
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
)
{
int
sepol
icy
::
allow
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
)
{
vprint
(
"allow %s %s %s %s
\n
"
,
s
,
t
,
c
,
p
);
vprint
(
"allow %s %s %s %s
\n
"
,
s
,
t
,
c
,
p
);
return
add_rule
(
s
,
t
,
c
,
p
,
AVTAB_ALLOWED
,
0
);
return
add_rule
(
db
,
s
,
t
,
c
,
p
,
AVTAB_ALLOWED
,
0
);
}
}
int
sepol
_
deny
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
)
{
int
sepol
icy
::
deny
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
)
{
vprint
(
"deny %s %s %s %s
\n
"
,
s
,
t
,
c
,
p
);
vprint
(
"deny %s %s %s %s
\n
"
,
s
,
t
,
c
,
p
);
return
add_rule
(
s
,
t
,
c
,
p
,
AVTAB_ALLOWED
,
1
);
return
add_rule
(
db
,
s
,
t
,
c
,
p
,
AVTAB_ALLOWED
,
1
);
}
}
int
sepol
_
auditallow
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
)
{
int
sepol
icy
::
auditallow
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
)
{
vprint
(
"auditallow %s %s %s %s
\n
"
,
s
,
t
,
c
,
p
);
vprint
(
"auditallow %s %s %s %s
\n
"
,
s
,
t
,
c
,
p
);
return
add_rule
(
s
,
t
,
c
,
p
,
AVTAB_AUDITALLOW
,
0
);
return
add_rule
(
db
,
s
,
t
,
c
,
p
,
AVTAB_AUDITALLOW
,
0
);
}
}
int
sepol
_
dontaudit
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
)
{
int
sepol
icy
::
dontaudit
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
)
{
vprint
(
"dontaudit %s %s %s %s
\n
"
,
s
,
t
,
c
,
p
);
vprint
(
"dontaudit %s %s %s %s
\n
"
,
s
,
t
,
c
,
p
);
return
add_rule
(
s
,
t
,
c
,
p
,
AVTAB_AUDITDENY
,
1
);
return
add_rule
(
db
,
s
,
t
,
c
,
p
,
AVTAB_AUDITDENY
,
1
);
}
}
int
sepol
_
allowxperm
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
)
{
int
sepol
icy
::
allowxperm
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
)
{
vprint
(
"allowxperm %s %s %s %s
\n
"
,
s
,
t
,
c
,
range
);
vprint
(
"allowxperm %s %s %s %s
\n
"
,
s
,
t
,
c
,
range
);
return
add_xperm_rule
(
s
,
t
,
c
,
range
,
AVTAB_XPERMS_ALLOWED
,
0
);
return
add_xperm_rule
(
db
,
s
,
t
,
c
,
range
,
AVTAB_XPERMS_ALLOWED
,
0
);
}
}
int
sepol
_
auditallowxperm
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
)
{
int
sepol
icy
::
auditallowxperm
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
)
{
vprint
(
"auditallowxperm %s %s %s %s
\n
"
,
s
,
t
,
c
,
range
);
vprint
(
"auditallowxperm %s %s %s %s
\n
"
,
s
,
t
,
c
,
range
);
return
add_xperm_rule
(
s
,
t
,
c
,
range
,
AVTAB_XPERMS_AUDITALLOW
,
0
);
return
add_xperm_rule
(
db
,
s
,
t
,
c
,
range
,
AVTAB_XPERMS_AUDITALLOW
,
0
);
}
}
int
sepol
_
dontauditxperm
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
)
{
int
sepol
icy
::
dontauditxperm
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
)
{
vprint
(
"dontauditxperm %s %s %s %s
\n
"
,
s
,
t
,
c
,
range
);
vprint
(
"dontauditxperm %s %s %s %s
\n
"
,
s
,
t
,
c
,
range
);
return
add_xperm_rule
(
s
,
t
,
c
,
range
,
AVTAB_XPERMS_DONTAUDIT
,
0
);
return
add_xperm_rule
(
db
,
s
,
t
,
c
,
range
,
AVTAB_XPERMS_DONTAUDIT
,
0
);
}
}
int
sepol_typetrans
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
)
{
int
sepolicy
::
type_change
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
)
{
vprint
(
"type_transition %s %s %s %s
\n
"
,
s
,
t
,
c
,
d
);
return
add_type_rule
(
s
,
t
,
c
,
d
,
AVTAB_TRANSITION
);
}
int
sepol_typechange
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
)
{
vprint
(
"type_change %s %s %s %s
\n
"
,
s
,
t
,
c
,
d
);
vprint
(
"type_change %s %s %s %s
\n
"
,
s
,
t
,
c
,
d
);
return
add_type_rule
(
s
,
t
,
c
,
d
,
AVTAB_CHANGE
);
return
add_type_rule
(
db
,
s
,
t
,
c
,
d
,
AVTAB_CHANGE
);
}
}
int
sepol
_type
member
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
)
{
int
sepol
icy
::
type_
member
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
)
{
vprint
(
"type_member %s %s %s %s
\n
"
,
s
,
t
,
c
,
d
);
vprint
(
"type_member %s %s %s %s
\n
"
,
s
,
t
,
c
,
d
);
return
add_type_rule
(
s
,
t
,
c
,
d
,
AVTAB_MEMBER
);
return
add_type_rule
(
db
,
s
,
t
,
c
,
d
,
AVTAB_MEMBER
);
}
}
int
sepol_nametrans
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
,
const
char
*
o
)
{
int
sepolicy
::
type_transition
(
const
char
*
src
,
const
char
*
tgt
,
const
char
*
cls
,
const
char
*
def
,
const
char
*
obj
)
{
vprint
(
"name_trans %s %s %s %s %s
\n
"
,
s
,
t
,
c
,
d
,
o
);
if
(
obj
)
{
return
add_filename_trans
(
s
,
t
,
c
,
d
,
o
);
vprint
(
"type_transition %s %s %s %s
\n
"
,
src
,
tgt
,
cls
,
def
);
return
add_type_rule
(
db
,
src
,
tgt
,
cls
,
def
,
AVTAB_TRANSITION
);
}
else
{
vprint
(
"type_transition %s %s %s %s %s
\n
"
,
src
,
tgt
,
cls
,
def
,
obj
);
return
add_filename_trans
(
db
,
src
,
tgt
,
cls
,
def
,
obj
);
}
}
}
int
sepol
_
permissive
(
const
char
*
s
)
{
int
sepol
icy
::
permissive
(
const
char
*
s
)
{
vprint
(
"permissive %s
\n
"
,
s
);
vprint
(
"permissive %s
\n
"
,
s
);
return
set_domain_state
(
s
,
1
);
return
set_domain_state
(
db
,
s
,
1
);
}
}
int
sepol
_
enforce
(
const
char
*
s
)
{
int
sepol
icy
::
enforce
(
const
char
*
s
)
{
vprint
(
"enforce %s
\n
"
,
s
);
vprint
(
"enforce %s
\n
"
,
s
);
return
set_domain_state
(
s
,
0
);
return
set_domain_state
(
db
,
s
,
0
);
}
}
int
sepol
_
create
(
const
char
*
s
)
{
int
sepol
icy
::
create
(
const
char
*
s
)
{
vprint
(
"create %s
\n
"
,
s
);
vprint
(
"create %s
\n
"
,
s
);
return
create_domain
(
s
);
return
create_domain
(
db
,
s
);
}
}
int
sepol
_attradd
(
const
char
*
s
,
const
char
*
a
)
{
int
sepol
icy
::
typeattribute
(
const
char
*
type
,
const
char
*
attr
)
{
vprint
(
"
attradd %s %s
\n
"
,
s
,
a
);
vprint
(
"
typeattribute %s %s
\n
"
,
type
,
attr
);
return
add_typeattribute
(
s
,
a
);
return
add_typeattribute
(
db
,
type
,
attr
);
}
}
int
sepol
_genfscon
(
const
char
*
name
,
const
char
*
path
,
const
char
*
context
)
{
int
sepol
icy
::
genfscon
(
const
char
*
fs_name
,
const
char
*
path
,
const
char
*
ctx
)
{
vprint
(
"genfscon %s %s %s
\n
"
,
name
,
path
,
context
);
vprint
(
"genfscon %s %s %s
\n
"
,
fs_name
,
path
,
ctx
);
return
add_genfscon
(
name
,
path
,
context
);
return
add_genfscon
(
db
,
fs_name
,
path
,
ctx
);
}
}
int
sepol
_
exists
(
const
char
*
source
)
{
int
sepol
icy
::
exists
(
const
char
*
source
)
{
return
hashtab_search
(
magisk_policy
db
->
p_types
.
table
,
source
)
!=
nullptr
;
return
hashtab_search
(
db
->
p_types
.
table
,
source
)
!=
nullptr
;
}
}
native/jni/magiskpolicy/magiskpolicy.cpp
View file @
d4baae41
...
@@ -40,6 +40,7 @@ int magiskpolicy_main(int argc, char *argv[]) {
...
@@ -40,6 +40,7 @@ int magiskpolicy_main(int argc, char *argv[]) {
cmdline_logging
();
cmdline_logging
();
const
char
*
out_file
=
nullptr
;
const
char
*
out_file
=
nullptr
;
const
char
*
rule_file
=
nullptr
;
const
char
*
rule_file
=
nullptr
;
sepolicy
*
sepol
=
nullptr
;
bool
magisk
=
false
;
bool
magisk
=
false
;
bool
live
=
false
;
bool
live
=
false
;
...
@@ -56,18 +57,21 @@ int magiskpolicy_main(int argc, char *argv[]) {
...
@@ -56,18 +57,21 @@ int magiskpolicy_main(int argc, char *argv[]) {
else
if
(
option
==
"load"
sv
)
{
else
if
(
option
==
"load"
sv
)
{
if
(
argv
[
i
+
1
]
==
nullptr
)
if
(
argv
[
i
+
1
]
==
nullptr
)
usage
(
argv
[
0
]);
usage
(
argv
[
0
]);
if
(
load_policydb
(
argv
[
i
+
1
]))
{
sepol
=
sepolicy
::
from_file
(
argv
[
i
+
1
]);
if
(
!
sepol
)
{
fprintf
(
stderr
,
"Cannot load policy from %s
\n
"
,
argv
[
i
+
1
]);
fprintf
(
stderr
,
"Cannot load policy from %s
\n
"
,
argv
[
i
+
1
]);
return
1
;
return
1
;
}
}
++
i
;
++
i
;
}
else
if
(
option
==
"load-split"
sv
)
{
}
else
if
(
option
==
"load-split"
sv
)
{
if
(
load_split_cil
())
{
sepol
=
sepolicy
::
from_split
();
if
(
!
sepol
)
{
fprintf
(
stderr
,
"Cannot load split cil
\n
"
);
fprintf
(
stderr
,
"Cannot load split cil
\n
"
);
return
1
;
return
1
;
}
}
}
else
if
(
option
==
"compile-split"
sv
)
{
}
else
if
(
option
==
"compile-split"
sv
)
{
if
(
compile_split_cil
())
{
sepol
=
sepolicy
::
compile_split
();
if
(
!
sepol
)
{
fprintf
(
stderr
,
"Cannot compile split cil
\n
"
);
fprintf
(
stderr
,
"Cannot compile split cil
\n
"
);
return
1
;
return
1
;
}
}
...
@@ -92,30 +96,30 @@ int magiskpolicy_main(int argc, char *argv[]) {
...
@@ -92,30 +96,30 @@ int magiskpolicy_main(int argc, char *argv[]) {
}
}
// Use current policy if nothing is loaded
// Use current policy if nothing is loaded
if
(
magisk_policydb
==
nullptr
&&
load_policydb
(
SELINUX_POLICY
))
{
if
(
sepol
==
nullptr
&&
!
(
sepol
=
sepolicy
::
from_file
(
SELINUX_POLICY
)
))
{
fprintf
(
stderr
,
"Cannot load policy from "
SELINUX_POLICY
"
\n
"
);
fprintf
(
stderr
,
"Cannot load policy from "
SELINUX_POLICY
"
\n
"
);
return
1
;
return
1
;
}
}
if
(
magisk
)
if
(
magisk
)
sepol
_
magisk_rules
();
sepol
->
magisk_rules
();
if
(
rule_file
)
if
(
rule_file
)
load_rule_file
(
rule_file
);
sepol
->
load_rule_file
(
rule_file
);
for
(;
i
<
argc
;
++
i
)
for
(;
i
<
argc
;
++
i
)
parse_statement
(
argv
[
i
]);
sepol
->
parse_statement
(
argv
[
i
]);
if
(
live
&&
dump_policydb
(
SELINUX_LOAD
))
{
if
(
live
&&
sepol
->
to_file
(
SELINUX_LOAD
))
{
fprintf
(
stderr
,
"Cannot apply policy
\n
"
);
fprintf
(
stderr
,
"Cannot apply policy
\n
"
);
return
1
;
return
1
;
}
}
if
(
out_file
&&
dump_policydb
(
out_file
))
{
if
(
out_file
&&
sepol
->
to_file
(
out_file
))
{
fprintf
(
stderr
,
"Cannot dump policy to %s
\n
"
,
out_file
);
fprintf
(
stderr
,
"Cannot dump policy to %s
\n
"
,
out_file
);
return
1
;
return
1
;
}
}
de
stroy_policydb
()
;
de
lete
sepol
;
return
0
;
return
0
;
}
}
native/jni/magiskpolicy/policydb.cpp
View file @
d4baae41
...
@@ -12,26 +12,6 @@
...
@@ -12,26 +12,6 @@
#include "sepolicy.h"
#include "sepolicy.h"
int
load_policydb
(
const
char
*
file
)
{
LOGD
(
"Load policy from: %s
\n
"
,
file
);
if
(
magisk_policydb
)
destroy_policydb
();
struct
policy_file
pf
;
policy_file_init
(
&
pf
);
pf
.
fp
=
xfopen
(
file
,
"re"
);
pf
.
type
=
PF_USE_STDIO
;
magisk_policydb
=
static_cast
<
policydb_t
*>
(
xmalloc
(
sizeof
(
policydb_t
)));
if
(
policydb_init
(
magisk_policydb
)
||
policydb_read
(
magisk_policydb
,
&
pf
,
0
))
{
LOGE
(
"Fail to load policy from %s
\n
"
,
file
);
return
1
;
}
fclose
(
pf
.
fp
);
return
0
;
}
#define SHALEN 64
#define SHALEN 64
static
bool
cmp_sha256
(
const
char
*
a
,
const
char
*
b
)
{
static
bool
cmp_sha256
(
const
char
*
a
,
const
char
*
b
)
{
char
id_a
[
SHALEN
]
=
{
0
};
char
id_a
[
SHALEN
]
=
{
0
};
...
@@ -94,17 +74,6 @@ static bool check_precompiled(const char *precompiled) {
...
@@ -94,17 +74,6 @@ static bool check_precompiled(const char *precompiled) {
return
ok
;
return
ok
;
}
}
int
load_split_cil
()
{
const
char
*
odm_pre
=
ODM_POLICY_DIR
"precompiled_sepolicy"
;
const
char
*
vend_pre
=
VEND_POLICY_DIR
"precompiled_sepolicy"
;
if
(
access
(
odm_pre
,
R_OK
)
==
0
&&
check_precompiled
(
odm_pre
))
return
load_policydb
(
odm_pre
);
else
if
(
access
(
vend_pre
,
R_OK
)
==
0
&&
check_precompiled
(
vend_pre
))
return
load_policydb
(
vend_pre
);
else
return
compile_split_cil
();
}
static
void
load_cil
(
struct
cil_db
*
db
,
const
char
*
file
)
{
static
void
load_cil
(
struct
cil_db
*
db
,
const
char
*
file
)
{
char
*
addr
;
char
*
addr
;
size_t
size
;
size_t
size
;
...
@@ -114,15 +83,37 @@ static void load_cil(struct cil_db *db, const char *file) {
...
@@ -114,15 +83,37 @@ static void load_cil(struct cil_db *db, const char *file) {
munmap
(
addr
,
size
);
munmap
(
addr
,
size
);
}
}
int
compile_split_cil
()
{
sepolicy
*
sepolicy
::
from_file
(
const
char
*
file
)
{
LOGD
(
"Load policy from: %s
\n
"
,
file
);
policy_file_t
pf
;
policy_file_init
(
&
pf
);
auto
fp
=
xopen_file
(
file
,
"re"
);
pf
.
fp
=
fp
.
get
();
pf
.
type
=
PF_USE_STDIO
;
auto
db
=
static_cast
<
policydb_t
*>
(
xmalloc
(
sizeof
(
policydb_t
)));
if
(
policydb_init
(
db
)
||
policydb_read
(
db
,
&
pf
,
0
))
{
LOGE
(
"Fail to load policy from %s
\n
"
,
file
);
free
(
db
);
return
nullptr
;
}
auto
sepol
=
new
sepolicy
();
sepol
->
db
=
db
;
return
sepol
;
}
sepolicy
*
sepolicy
::
compile_split
()
{
char
path
[
128
],
plat_ver
[
10
];
char
path
[
128
],
plat_ver
[
10
];
struct
cil_db
*
db
=
nullptr
;
cil_db_t
*
db
=
nullptr
;
sepol_policydb_t
*
pdb
=
nullptr
;
sepol_policydb_t
*
pdb
=
nullptr
;
FILE
*
f
;
FILE
*
f
;
int
policy_ver
;
int
policy_ver
;
const
char
*
cil_file
;
const
char
*
cil_file
;
cil_db_init
(
&
db
);
cil_db_init
(
&
db
);
run_finally
fin
([
db_ptr
=
&
db
]{
cil_db_destroy
(
db_ptr
);
});
cil_set_mls
(
db
,
1
);
cil_set_mls
(
db
,
1
);
cil_set_multiple_decls
(
db
,
1
);
cil_set_multiple_decls
(
db
,
1
);
cil_set_disable_neverallow
(
db
,
1
);
cil_set_disable_neverallow
(
db
,
1
);
...
@@ -173,29 +164,48 @@ int compile_split_cil() {
...
@@ -173,29 +164,48 @@ int compile_split_cil() {
load_cil
(
db
,
cil_file
);
load_cil
(
db
,
cil_file
);
if
(
cil_compile
(
db
))
if
(
cil_compile
(
db
))
return
1
;
return
nullptr
;
if
(
cil_build_policydb
(
db
,
&
pdb
))
if
(
cil_build_policydb
(
db
,
&
pdb
))
return
1
;
return
nullptr
;
cil_db_destroy
(
&
db
);
auto
sepol
=
new
sepolicy
();
magisk_policydb
=
&
pdb
->
p
;
sepol
->
db
=
&
pdb
->
p
;
return
0
;
return
sepol
;
}
sepolicy
*
sepolicy
::
from_split
()
{
const
char
*
odm_pre
=
ODM_POLICY_DIR
"precompiled_sepolicy"
;
const
char
*
vend_pre
=
VEND_POLICY_DIR
"precompiled_sepolicy"
;
if
(
access
(
odm_pre
,
R_OK
)
==
0
&&
check_precompiled
(
odm_pre
))
return
sepolicy
::
from_file
(
odm_pre
);
else
if
(
access
(
vend_pre
,
R_OK
)
==
0
&&
check_precompiled
(
vend_pre
))
return
sepolicy
::
from_file
(
vend_pre
);
else
return
sepolicy
::
compile_split
();
}
sepolicy
::~
sepolicy
()
{
policydb_destroy
(
db
);
free
(
db
);
}
}
int
dump_policydb
(
const
char
*
file
)
{
int
sepolicy
::
to_file
(
const
char
*
file
)
{
uint8_t
*
data
;
uint8_t
*
data
;
size_t
len
;
size_t
len
;
{
/* No partial writes are allowed to /sys/fs/selinux/load, thus the reason why we
auto
fp
=
make_stream_fp
<
byte_stream
>
(
data
,
len
);
* first dump everything into memory, then directly call write system call */
struct
policy_file
pf
;
policy_file_init
(
&
pf
);
auto
fp
=
make_stream_fp
<
byte_stream
>
(
data
,
len
);
pf
.
type
=
PF_USE_STDIO
;
run_finally
fin
([
=
]{
free
(
data
);
});
pf
.
fp
=
fp
.
get
();
if
(
policydb_write
(
magisk_policydb
,
&
pf
))
{
policy_file_t
pf
;
LOGE
(
"Fail to create policy image
\n
"
);
policy_file_init
(
&
pf
);
return
1
;
pf
.
type
=
PF_USE_STDIO
;
}
pf
.
fp
=
fp
.
get
();
if
(
policydb_write
(
db
,
&
pf
))
{
LOGE
(
"Fail to create policy image
\n
"
);
return
1
;
}
}
int
fd
=
xopen
(
file
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
|
O_CLOEXEC
,
0644
);
int
fd
=
xopen
(
file
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
|
O_CLOEXEC
,
0644
);
...
@@ -204,14 +214,5 @@ int dump_policydb(const char *file) {
...
@@ -204,14 +214,5 @@ int dump_policydb(const char *file) {
xwrite
(
fd
,
data
,
len
);
xwrite
(
fd
,
data
,
len
);
close
(
fd
);
close
(
fd
);
free
(
data
);
return
0
;
return
0
;
}
}
void
destroy_policydb
()
{
if
(
magisk_policydb
)
{
policydb_destroy
(
magisk_policydb
);
free
(
magisk_policydb
);
magisk_policydb
=
nullptr
;
}
}
native/jni/magiskpolicy/rules.cpp
View file @
d4baae41
...
@@ -4,202 +4,202 @@
...
@@ -4,202 +4,202 @@
#include "sepolicy.h"
#include "sepolicy.h"
static
void
allowSuClient
(
const
char
*
target
)
{
void
sepolicy
::
allow_su_client
(
const
char
*
type
)
{
if
(
!
sepol_exists
(
target
))
if
(
!
exists
(
type
))
return
;
return
;
sepol_allow
(
target
,
SEPOL_PROC_DOMAIN
,
"unix_stream_socket"
,
"connectto"
);
allow
(
type
,
SEPOL_PROC_DOMAIN
,
"unix_stream_socket"
,
"connectto"
);
sepol_allow
(
target
,
SEPOL_PROC_DOMAIN
,
"unix_stream_socket"
,
"getopt"
);
allow
(
type
,
SEPOL_PROC_DOMAIN
,
"unix_stream_socket"
,
"getopt"
);
sepol_allow
(
SEPOL_PROC_DOMAIN
,
target
,
"fd"
,
"use"
);
allow
(
SEPOL_PROC_DOMAIN
,
type
,
"fd"
,
"use"
);
sepol_allow
(
SEPOL_PROC_DOMAIN
,
target
,
"fifo_file"
,
ALL
);
allow
(
SEPOL_PROC_DOMAIN
,
type
,
"fifo_file"
,
ALL
);
// Allow binder service
// Allow binder service
sepol_allow
(
target
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"call"
);
allow
(
type
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"call"
);
sepol_allow
(
target
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"transfer"
);
allow
(
type
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"transfer"
);
// Allow termios ioctl
// Allow termios ioctl
sepol_allow
(
target
,
"devpts"
,
"chr_file"
,
"ioctl"
);
allow
(
type
,
"devpts"
,
"chr_file"
,
"ioctl"
);
sepol_allow
(
target
,
"untrusted_app_devpts"
,
"chr_file"
,
"ioctl"
);
allow
(
type
,
"untrusted_app_devpts"
,
"chr_file"
,
"ioctl"
);
sepol_allow
(
target
,
"untrusted_app_25_devpts"
,
"chr_file"
,
"ioctl"
);
allow
(
type
,
"untrusted_app_25_devpts"
,
"chr_file"
,
"ioctl"
);
sepol_allow
(
target
,
"untrusted_app_all_devpts"
,
"chr_file"
,
"ioctl"
);
allow
(
type
,
"untrusted_app_all_devpts"
,
"chr_file"
,
"ioctl"
);
if
(
magisk_policy
db
->
policyvers
>=
POLICYDB_VERSION_XPERMS_IOCTL
)
{
if
(
db
->
policyvers
>=
POLICYDB_VERSION_XPERMS_IOCTL
)
{
sepol_allowxperm
(
target
,
"devpts"
,
"chr_file"
,
"0x5400-0x54FF"
);
allowxperm
(
type
,
"devpts"
,
"chr_file"
,
"0x5400-0x54FF"
);
sepol_allowxperm
(
target
,
"untrusted_app_devpts"
,
"chr_file"
,
"0x5400-0x54FF"
);
allowxperm
(
type
,
"untrusted_app_devpts"
,
"chr_file"
,
"0x5400-0x54FF"
);
sepol_allowxperm
(
target
,
"untrusted_app_25_devpts"
,
"chr_file"
,
"0x5400-0x54FF"
);
allowxperm
(
type
,
"untrusted_app_25_devpts"
,
"chr_file"
,
"0x5400-0x54FF"
);
sepol_allowxperm
(
target
,
"untrusted_app_all_devpts"
,
"chr_file"
,
"0x5400-0x54FF"
);
allowxperm
(
type
,
"untrusted_app_all_devpts"
,
"chr_file"
,
"0x5400-0x54FF"
);
}
}
}
}
void
sepol
_
magisk_rules
()
{
void
sepol
icy
::
magisk_rules
()
{
// Temp suppress warnings
// Temp suppress warnings
auto
bak
=
log_cb
.
w
;
auto
bak
=
log_cb
.
w
;
log_cb
.
w
=
nop_log
;
log_cb
.
w
=
nop_log
;
// First prevent anything to change sepolicy except ourselves
// First prevent anything to change sepolicy except ourselves
sepol_
deny
(
ALL
,
"kernel"
,
"security"
,
"load_policy"
);
deny
(
ALL
,
"kernel"
,
"security"
,
"load_policy"
);
if
(
!
sepol_
exists
(
SEPOL_PROC_DOMAIN
))
if
(
!
exists
(
SEPOL_PROC_DOMAIN
))
sepol_
create
(
SEPOL_PROC_DOMAIN
);
create
(
SEPOL_PROC_DOMAIN
);
if
(
!
sepol_
exists
(
SEPOL_FILE_DOMAIN
))
if
(
!
exists
(
SEPOL_FILE_DOMAIN
))
sepol_
create
(
SEPOL_FILE_DOMAIN
);
create
(
SEPOL_FILE_DOMAIN
);
sepol_
permissive
(
SEPOL_PROC_DOMAIN
);
permissive
(
SEPOL_PROC_DOMAIN
);
sepol_attradd
(
SEPOL_PROC_DOMAIN
,
"mlstrustedsubject"
);
typeattribute
(
SEPOL_PROC_DOMAIN
,
"mlstrustedsubject"
);
sepol_attradd
(
SEPOL_PROC_DOMAIN
,
"netdomain"
);
typeattribute
(
SEPOL_PROC_DOMAIN
,
"netdomain"
);
sepol_attradd
(
SEPOL_PROC_DOMAIN
,
"bluetoothdomain"
);
typeattribute
(
SEPOL_PROC_DOMAIN
,
"bluetoothdomain"
);
sepol_attradd
(
SEPOL_FILE_DOMAIN
,
"mlstrustedobject"
);
typeattribute
(
SEPOL_FILE_DOMAIN
,
"mlstrustedobject"
);
// Let everyone access tmpfs files (for SAR sbin overlay)
// Let everyone access tmpfs files (for SAR sbin overlay)
sepol_
allow
(
ALL
,
"tmpfs"
,
"file"
,
ALL
);
allow
(
ALL
,
"tmpfs"
,
"file"
,
ALL
);
// For normal rootfs file/directory operations when rw (for SAR / overlay)
// For normal rootfs file/directory operations when rw (for SAR / overlay)
sepol_
allow
(
"rootfs"
,
"labeledfs"
,
"filesystem"
,
"associate"
);
allow
(
"rootfs"
,
"labeledfs"
,
"filesystem"
,
"associate"
);
// Let init transit to SEPOL_PROC_DOMAIN
// Let init transit to SEPOL_PROC_DOMAIN
sepol_
allow
(
"kernel"
,
"kernel"
,
"process"
,
"setcurrent"
);
allow
(
"kernel"
,
"kernel"
,
"process"
,
"setcurrent"
);
sepol_
allow
(
"kernel"
,
SEPOL_PROC_DOMAIN
,
"process"
,
"dyntransition"
);
allow
(
"kernel"
,
SEPOL_PROC_DOMAIN
,
"process"
,
"dyntransition"
);
// Let init run stuffs
// Let init run stuffs
sepol_
allow
(
"kernel"
,
SEPOL_PROC_DOMAIN
,
"fd"
,
"use"
);
allow
(
"kernel"
,
SEPOL_PROC_DOMAIN
,
"fd"
,
"use"
);
sepol_
allow
(
"init"
,
SEPOL_PROC_DOMAIN
,
"process"
,
ALL
);
allow
(
"init"
,
SEPOL_PROC_DOMAIN
,
"process"
,
ALL
);
sepol_
allow
(
"init"
,
"tmpfs"
,
"file"
,
"getattr"
);
allow
(
"init"
,
"tmpfs"
,
"file"
,
"getattr"
);
sepol_
allow
(
"init"
,
"tmpfs"
,
"file"
,
"execute"
);
allow
(
"init"
,
"tmpfs"
,
"file"
,
"execute"
);
// Shell, properties, logs
// Shell, properties, logs
if
(
sepol_
exists
(
"default_prop"
))
if
(
exists
(
"default_prop"
))
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"default_prop"
,
"property_service"
,
"set"
);
allow
(
SEPOL_PROC_DOMAIN
,
"default_prop"
,
"property_service"
,
"set"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"init"
,
"unix_stream_socket"
,
"connectto"
);
allow
(
SEPOL_PROC_DOMAIN
,
"init"
,
"unix_stream_socket"
,
"connectto"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"rootfs"
,
"filesystem"
,
"remount"
);
allow
(
SEPOL_PROC_DOMAIN
,
"rootfs"
,
"filesystem"
,
"remount"
);
if
(
sepol_
exists
(
"logd"
))
if
(
exists
(
"logd"
))
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"logd"
,
"unix_stream_socket"
,
"connectto"
);
allow
(
SEPOL_PROC_DOMAIN
,
"logd"
,
"unix_stream_socket"
,
"connectto"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
SEPOL_PROC_DOMAIN
,
ALL
,
ALL
);
allow
(
SEPOL_PROC_DOMAIN
,
SEPOL_PROC_DOMAIN
,
ALL
,
ALL
);
// For sepolicy live patching
// For sepolicy live patching
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"kernel"
,
"security"
,
"read_policy"
);
allow
(
SEPOL_PROC_DOMAIN
,
"kernel"
,
"security"
,
"read_policy"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"kernel"
,
"security"
,
"load_policy"
);
allow
(
SEPOL_PROC_DOMAIN
,
"kernel"
,
"security"
,
"load_policy"
);
// Allow these processes to access MagiskSU
// Allow these processes to access MagiskSU
allow
SuC
lient
(
"init"
);
allow
_su_c
lient
(
"init"
);
allow
SuC
lient
(
"shell"
);
allow
_su_c
lient
(
"shell"
);
allow
SuC
lient
(
"system_app"
);
allow
_su_c
lient
(
"system_app"
);
allow
SuC
lient
(
"priv_app"
);
allow
_su_c
lient
(
"priv_app"
);
allow
SuC
lient
(
"platform_app"
);
allow
_su_c
lient
(
"platform_app"
);
allow
SuC
lient
(
"untrusted_app"
);
allow
_su_c
lient
(
"untrusted_app"
);
allow
SuC
lient
(
"untrusted_app_25"
);
allow
_su_c
lient
(
"untrusted_app_25"
);
allow
SuC
lient
(
"untrusted_app_27"
);
allow
_su_c
lient
(
"untrusted_app_27"
);
allow
SuC
lient
(
"untrusted_app_29"
);
allow
_su_c
lient
(
"untrusted_app_29"
);
allow
SuC
lient
(
"update_engine"
);
allow
_su_c
lient
(
"update_engine"
);
// suRights
// suRights
sepol_
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"dir"
,
"search"
);
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"dir"
,
"search"
);
sepol_
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"dir"
,
"read"
);
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"dir"
,
"read"
);
sepol_
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"open"
);
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"open"
);
sepol_
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"read"
);
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"read"
);
sepol_
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"process"
,
"getattr"
);
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"process"
,
"getattr"
);
sepol_
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"transfer"
);
allow
(
"servicemanager"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"transfer"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"dir"
,
"search"
);
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"dir"
,
"search"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"dir"
,
"read"
);
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"dir"
,
"read"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"file"
,
"open"
);
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"file"
,
"open"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"file"
,
"read"
);
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"file"
,
"read"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"process"
,
"getattr"
);
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"process"
,
"getattr"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"binder"
,
"transfer"
);
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"binder"
,
"transfer"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"binder"
,
"call"
);
allow
(
SEPOL_PROC_DOMAIN
,
"servicemanager"
,
"binder"
,
"call"
);
sepol_
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"process"
,
"sigchld"
);
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"process"
,
"sigchld"
);
// allowLog
// allowLog
sepol_
allow
(
"logd"
,
SEPOL_PROC_DOMAIN
,
"dir"
,
"search"
);
allow
(
"logd"
,
SEPOL_PROC_DOMAIN
,
"dir"
,
"search"
);
sepol_
allow
(
"logd"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"read"
);
allow
(
"logd"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"read"
);
sepol_
allow
(
"logd"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"open"
);
allow
(
"logd"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"open"
);
sepol_
allow
(
"logd"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"getattr"
);
allow
(
"logd"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"getattr"
);
// suBackL0
// suBackL0
sepol_
allow
(
"system_server"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"call"
);
allow
(
"system_server"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"call"
);
sepol_
allow
(
"system_server"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"transfer"
);
allow
(
"system_server"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"transfer"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"system_server"
,
"binder"
,
"call"
);
allow
(
SEPOL_PROC_DOMAIN
,
"system_server"
,
"binder"
,
"call"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"system_server"
,
"binder"
,
"transfer"
);
allow
(
SEPOL_PROC_DOMAIN
,
"system_server"
,
"binder"
,
"transfer"
);
// suBackL6
// suBackL6
sepol_
allow
(
"surfaceflinger"
,
"app_data_file"
,
"dir"
,
ALL
);
allow
(
"surfaceflinger"
,
"app_data_file"
,
"dir"
,
ALL
);
sepol_
allow
(
"surfaceflinger"
,
"app_data_file"
,
"file"
,
ALL
);
allow
(
"surfaceflinger"
,
"app_data_file"
,
"file"
,
ALL
);
sepol_
allow
(
"surfaceflinger"
,
"app_data_file"
,
"lnk_file"
,
ALL
);
allow
(
"surfaceflinger"
,
"app_data_file"
,
"lnk_file"
,
ALL
);
sepol_attradd
(
"surfaceflinger"
,
"mlstrustedsubject"
);
typeattribute
(
"surfaceflinger"
,
"mlstrustedsubject"
);
// suMiscL6
// suMiscL6
if
(
sepol_
exists
(
"audioserver"
))
if
(
exists
(
"audioserver"
))
sepol_
allow
(
"audioserver"
,
"audioserver"
,
"process"
,
"execmem"
);
allow
(
"audioserver"
,
"audioserver"
,
"process"
,
"execmem"
);
// Liveboot
// Liveboot
sepol_
allow
(
"surfaceflinger"
,
SEPOL_PROC_DOMAIN
,
"process"
,
"ptrace"
);
allow
(
"surfaceflinger"
,
SEPOL_PROC_DOMAIN
,
"process"
,
"ptrace"
);
sepol_
allow
(
"surfaceflinger"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"transfer"
);
allow
(
"surfaceflinger"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"transfer"
);
sepol_
allow
(
"surfaceflinger"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"call"
);
allow
(
"surfaceflinger"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"call"
);
sepol_
allow
(
"surfaceflinger"
,
SEPOL_PROC_DOMAIN
,
"fd"
,
"use"
);
allow
(
"surfaceflinger"
,
SEPOL_PROC_DOMAIN
,
"fd"
,
"use"
);
sepol_
allow
(
"debuggerd"
,
SEPOL_PROC_DOMAIN
,
"process"
,
"ptrace"
);
allow
(
"debuggerd"
,
SEPOL_PROC_DOMAIN
,
"process"
,
"ptrace"
);
// dumpsys
// dumpsys
sepol_
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"fd"
,
"use"
);
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"fd"
,
"use"
);
sepol_
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"fifo_file"
,
"write"
);
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"fifo_file"
,
"write"
);
sepol_
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"fifo_file"
,
"read"
);
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"fifo_file"
,
"read"
);
sepol_
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"fifo_file"
,
"open"
);
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"fifo_file"
,
"open"
);
sepol_
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"fifo_file"
,
"getattr"
);
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"fifo_file"
,
"getattr"
);
// bootctl
// bootctl
sepol_
allow
(
"hwservicemanager"
,
SEPOL_PROC_DOMAIN
,
"dir"
,
"search"
);
allow
(
"hwservicemanager"
,
SEPOL_PROC_DOMAIN
,
"dir"
,
"search"
);
sepol_
allow
(
"hwservicemanager"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"read"
);
allow
(
"hwservicemanager"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"read"
);
sepol_
allow
(
"hwservicemanager"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"open"
);
allow
(
"hwservicemanager"
,
SEPOL_PROC_DOMAIN
,
"file"
,
"open"
);
sepol_
allow
(
"hwservicemanager"
,
SEPOL_PROC_DOMAIN
,
"process"
,
"getattr"
);
allow
(
"hwservicemanager"
,
SEPOL_PROC_DOMAIN
,
"process"
,
"getattr"
);
sepol_
allow
(
"hwservicemanager"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"transfer"
);
allow
(
"hwservicemanager"
,
SEPOL_PROC_DOMAIN
,
"binder"
,
"transfer"
);
// For mounting loop devices, mirrors, tmpfs
// For mounting loop devices, mirrors, tmpfs
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"kernel"
,
"process"
,
"setsched"
);
allow
(
SEPOL_PROC_DOMAIN
,
"kernel"
,
"process"
,
"setsched"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"labeledfs"
,
"filesystem"
,
"mount"
);
allow
(
SEPOL_PROC_DOMAIN
,
"labeledfs"
,
"filesystem"
,
"mount"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"labeledfs"
,
"filesystem"
,
"unmount"
);
allow
(
SEPOL_PROC_DOMAIN
,
"labeledfs"
,
"filesystem"
,
"unmount"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"tmpfs"
,
"filesystem"
,
"mount"
);
allow
(
SEPOL_PROC_DOMAIN
,
"tmpfs"
,
"filesystem"
,
"mount"
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
"tmpfs"
,
"filesystem"
,
"unmount"
);
allow
(
SEPOL_PROC_DOMAIN
,
"tmpfs"
,
"filesystem"
,
"unmount"
);
sepol_
allow
(
"kernel"
,
ALL
,
"file"
,
"read"
);
allow
(
"kernel"
,
ALL
,
"file"
,
"read"
);
sepol_
allow
(
"kernel"
,
ALL
,
"file"
,
"write"
);
allow
(
"kernel"
,
ALL
,
"file"
,
"write"
);
// Allow us to do anything to any files/dir/links
// Allow us to do anything to any files/dir/links
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"file"
,
ALL
);
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"file"
,
ALL
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"dir"
,
ALL
);
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"dir"
,
ALL
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"lnk_file"
,
ALL
);
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"lnk_file"
,
ALL
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"blk_file"
,
ALL
);
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"blk_file"
,
ALL
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"sock_file"
,
ALL
);
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"sock_file"
,
ALL
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"chr_file"
,
ALL
);
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"chr_file"
,
ALL
);
sepol_
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"fifo_file"
,
ALL
);
allow
(
SEPOL_PROC_DOMAIN
,
ALL
,
"fifo_file"
,
ALL
);
// Allow us to do any ioctl on all block devices
// Allow us to do any ioctl on all block devices
if
(
magisk_policy
db
->
policyvers
>=
POLICYDB_VERSION_XPERMS_IOCTL
)
if
(
db
->
policyvers
>=
POLICYDB_VERSION_XPERMS_IOCTL
)
sepol_
allowxperm
(
SEPOL_PROC_DOMAIN
,
ALL
,
"blk_file"
,
"0x0000-0xFFFF"
);
allowxperm
(
SEPOL_PROC_DOMAIN
,
ALL
,
"blk_file"
,
"0x0000-0xFFFF"
);
// Allow all binder transactions
// Allow all binder transactions
sepol_
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"binder"
,
ALL
);
allow
(
ALL
,
SEPOL_PROC_DOMAIN
,
"binder"
,
ALL
);
// Super files
// Super files
sepol_
allow
(
ALL
,
SEPOL_FILE_DOMAIN
,
"file"
,
ALL
);
allow
(
ALL
,
SEPOL_FILE_DOMAIN
,
"file"
,
ALL
);
sepol_
allow
(
ALL
,
SEPOL_FILE_DOMAIN
,
"dir"
,
ALL
);
allow
(
ALL
,
SEPOL_FILE_DOMAIN
,
"dir"
,
ALL
);
sepol_
allow
(
ALL
,
SEPOL_FILE_DOMAIN
,
"fifo_file"
,
ALL
);
allow
(
ALL
,
SEPOL_FILE_DOMAIN
,
"fifo_file"
,
ALL
);
sepol_
allow
(
ALL
,
SEPOL_FILE_DOMAIN
,
"chr_file"
,
ALL
);
allow
(
ALL
,
SEPOL_FILE_DOMAIN
,
"chr_file"
,
ALL
);
sepol_
allow
(
SEPOL_FILE_DOMAIN
,
ALL
,
"filesystem"
,
"associate"
);
allow
(
SEPOL_FILE_DOMAIN
,
ALL
,
"filesystem"
,
"associate"
);
// For changing attributes
// For changing attributes
sepol_
allow
(
"rootfs"
,
"tmpfs"
,
"filesystem"
,
"associate"
);
allow
(
"rootfs"
,
"tmpfs"
,
"filesystem"
,
"associate"
);
// Xposed
// Xposed
sepol_
allow
(
"untrusted_app"
,
"untrusted_app"
,
"capability"
,
"setgid"
);
allow
(
"untrusted_app"
,
"untrusted_app"
,
"capability"
,
"setgid"
);
sepol_
allow
(
"system_server"
,
"dex2oat_exec"
,
"file"
,
ALL
);
allow
(
"system_server"
,
"dex2oat_exec"
,
"file"
,
ALL
);
// Support deodexed ROM on Oreo
// Support deodexed ROM on Oreo
sepol_
allow
(
"zygote"
,
"dalvikcache_data_file"
,
"file"
,
"execute"
);
allow
(
"zygote"
,
"dalvikcache_data_file"
,
"file"
,
"execute"
);
// Support deodexed ROM on Pie (Samsung)
// Support deodexed ROM on Pie (Samsung)
sepol_
allow
(
"system_server"
,
"dalvikcache_data_file"
,
"file"
,
"write"
);
allow
(
"system_server"
,
"dalvikcache_data_file"
,
"file"
,
"write"
);
sepol_
allow
(
"system_server"
,
"dalvikcache_data_file"
,
"file"
,
"execute"
);
allow
(
"system_server"
,
"dalvikcache_data_file"
,
"file"
,
"execute"
);
// Allow update_engine/addon.d-v2 to run permissive on all ROMs
// Allow update_engine/addon.d-v2 to run permissive on all ROMs
sepol_
permissive
(
"update_engine"
);
permissive
(
"update_engine"
);
#if 0
#if 0
// Remove all dontaudit in debug mode
// Remove all dontaudit in debug mode
strip_dontaudit();
strip_dontaudit(
db
);
#endif
#endif
log_cb
.
w
=
bak
;
log_cb
.
w
=
bak
;
...
...
native/jni/magiskpolicy/sepolicy.c
View file @
d4baae41
...
@@ -5,9 +5,6 @@
...
@@ -5,9 +5,6 @@
#include "sepolicy.h"
#include "sepolicy.h"
policydb_t
*
magisk_policydb
=
NULL
;
#define mpdb magisk_policydb
extern
void
*
xmalloc
(
size_t
size
);
extern
void
*
xmalloc
(
size_t
size
);
extern
void
*
xcalloc
(
size_t
nmemb
,
size_t
size
);
extern
void
*
xcalloc
(
size_t
nmemb
,
size_t
size
);
extern
void
*
xrealloc
(
void
*
ptr
,
size_t
size
);
extern
void
*
xrealloc
(
void
*
ptr
,
size_t
size
);
...
@@ -39,20 +36,20 @@ hash_for_each(htable, size, hashtab, block)
...
@@ -39,20 +36,20 @@ hash_for_each(htable, size, hashtab, block)
#define avtab_for_each(avtab, block) \
#define avtab_for_each(avtab, block) \
hash_for_each(htable, nslot, avtab, block)
hash_for_each(htable, nslot, avtab, block)
static
int
set_attr
(
const
char
*
type
,
int
value
)
{
static
int
set_attr
(
policydb_t
*
db
,
const
char
*
type
,
int
value
)
{
type_datum_t
*
attr
=
hashtab_search
(
mp
db
->
p_types
.
table
,
type
);
type_datum_t
*
attr
=
hashtab_search
(
db
->
p_types
.
table
,
type
);
if
(
!
attr
||
attr
->
flavor
!=
TYPE_ATTRIB
)
if
(
!
attr
||
attr
->
flavor
!=
TYPE_ATTRIB
)
return
-
1
;
return
-
1
;
if
(
ebitmap_set_bit
(
&
mp
db
->
type_attr_map
[
value
-
1
],
attr
->
s
.
value
-
1
,
1
))
if
(
ebitmap_set_bit
(
&
db
->
type_attr_map
[
value
-
1
],
attr
->
s
.
value
-
1
,
1
))
return
-
1
;
return
-
1
;
if
(
ebitmap_set_bit
(
&
mp
db
->
attr_type_map
[
attr
->
s
.
value
-
1
],
value
-
1
,
1
))
if
(
ebitmap_set_bit
(
&
db
->
attr_type_map
[
attr
->
s
.
value
-
1
],
value
-
1
,
1
))
return
-
1
;
return
-
1
;
return
attr
->
s
.
value
;
return
attr
->
s
.
value
;
}
}
static
void
check_avtab_node
(
avtab_ptr_t
node
)
{
static
void
check_avtab_node
(
policydb_t
*
db
,
avtab_ptr_t
node
)
{
int
redundant
=
0
;
int
redundant
=
0
;
if
(
node
->
key
.
specified
==
AVTAB_AUDITDENY
)
if
(
node
->
key
.
specified
==
AVTAB_AUDITDENY
)
redundant
=
node
->
datum
.
data
==
~
0U
;
redundant
=
node
->
datum
.
data
==
~
0U
;
...
@@ -61,17 +58,17 @@ static void check_avtab_node(avtab_ptr_t node) {
...
@@ -61,17 +58,17 @@ static void check_avtab_node(avtab_ptr_t node) {
else
else
redundant
=
node
->
datum
.
data
==
0U
;
redundant
=
node
->
datum
.
data
==
0U
;
if
(
redundant
)
if
(
redundant
)
avtab_remove_node
(
&
mp
db
->
te_avtab
,
node
);
avtab_remove_node
(
&
db
->
te_avtab
,
node
);
}
}
static
avtab_ptr_t
get_avtab_node
(
avtab_key_t
*
key
,
avtab_extended_perms_t
*
xperms
)
{
static
avtab_ptr_t
get_avtab_node
(
policydb_t
*
db
,
avtab_key_t
*
key
,
avtab_extended_perms_t
*
xperms
)
{
avtab_ptr_t
node
;
avtab_ptr_t
node
;
avtab_datum_t
avdatum
;
avtab_datum_t
avdatum
;
int
match
=
0
;
int
match
=
0
;
/* AVTAB_XPERMS entries are not necessarily unique */
/* AVTAB_XPERMS entries are not necessarily unique */
if
(
key
->
specified
&
AVTAB_XPERMS
)
{
if
(
key
->
specified
&
AVTAB_XPERMS
)
{
node
=
avtab_search_node
(
&
mp
db
->
te_avtab
,
key
);
node
=
avtab_search_node
(
&
db
->
te_avtab
,
key
);
while
(
node
)
{
while
(
node
)
{
if
((
node
->
datum
.
xperms
->
specified
==
xperms
->
specified
)
&&
if
((
node
->
datum
.
xperms
->
specified
==
xperms
->
specified
)
&&
(
node
->
datum
.
xperms
->
driver
==
xperms
->
driver
))
{
(
node
->
datum
.
xperms
->
driver
==
xperms
->
driver
))
{
...
@@ -83,7 +80,7 @@ static avtab_ptr_t get_avtab_node(avtab_key_t *key, avtab_extended_perms_t *xper
...
@@ -83,7 +80,7 @@ static avtab_ptr_t get_avtab_node(avtab_key_t *key, avtab_extended_perms_t *xper
if
(
!
match
)
if
(
!
match
)
node
=
NULL
;
node
=
NULL
;
}
else
{
}
else
{
node
=
avtab_search_node
(
&
mp
db
->
te_avtab
,
key
);
node
=
avtab_search_node
(
&
db
->
te_avtab
,
key
);
}
}
if
(
!
node
)
{
if
(
!
node
)
{
...
@@ -94,14 +91,14 @@ static avtab_ptr_t get_avtab_node(avtab_key_t *key, avtab_extended_perms_t *xper
...
@@ -94,14 +91,14 @@ static avtab_ptr_t get_avtab_node(avtab_key_t *key, avtab_extended_perms_t *xper
*/
*/
avdatum
.
data
=
key
->
specified
==
AVTAB_AUDITDENY
?
~
0U
:
0U
;
avdatum
.
data
=
key
->
specified
==
AVTAB_AUDITDENY
?
~
0U
:
0U
;
/* this is used to get the node - insertion is actually unique */
/* this is used to get the node - insertion is actually unique */
node
=
avtab_insert_nonunique
(
&
mp
db
->
te_avtab
,
key
,
&
avdatum
);
node
=
avtab_insert_nonunique
(
&
db
->
te_avtab
,
key
,
&
avdatum
);
}
}
return
node
;
return
node
;
}
}
static
int
add_avrule
(
avtab_key_t
*
key
,
int
val
,
int
not
)
{
static
int
add_avrule
(
policydb_t
*
db
,
avtab_key_t
*
key
,
int
val
,
int
not
)
{
avtab_ptr_t
node
=
get_avtab_node
(
key
,
NULL
);
avtab_ptr_t
node
=
get_avtab_node
(
NULL
,
key
,
NULL
);
if
(
not
)
{
if
(
not
)
{
if
(
val
<
0
)
if
(
val
<
0
)
...
@@ -115,36 +112,36 @@ static int add_avrule(avtab_key_t *key, int val, int not) {
...
@@ -115,36 +112,36 @@ static int add_avrule(avtab_key_t *key, int val, int not) {
node
->
datum
.
data
|=
1U
<<
(
val
-
1
);
node
->
datum
.
data
|=
1U
<<
(
val
-
1
);
}
}
check_avtab_node
(
node
);
check_avtab_node
(
db
,
node
);
return
0
;
return
0
;
}
}
static
int
add_rule_auto
(
type_datum_t
*
src
,
type_datum_t
*
tgt
,
class_datum_t
*
cls
,
static
int
add_rule_auto
(
policydb_t
*
db
,
type_datum_t
*
src
,
type_datum_t
*
tgt
,
class_datum_t
*
cls
,
perm_datum_t
*
perm
,
int
effect
,
int
not
)
{
perm_datum_t
*
perm
,
int
effect
,
int
not
)
{
avtab_key_t
key
;
avtab_key_t
key
;
int
ret
=
0
;
int
ret
=
0
;
if
(
src
==
NULL
)
{
if
(
src
==
NULL
)
{
hashtab_for_each
(
mp
db
->
p_types
.
table
,
{
hashtab_for_each
(
db
->
p_types
.
table
,
{
src
=
node
->
datum
;
src
=
node
->
datum
;
ret
|=
add_rule_auto
(
src
,
tgt
,
cls
,
perm
,
effect
,
not
);
ret
|=
add_rule_auto
(
db
,
src
,
tgt
,
cls
,
perm
,
effect
,
not
);
})
})
}
else
if
(
tgt
==
NULL
)
{
}
else
if
(
tgt
==
NULL
)
{
hashtab_for_each
(
mp
db
->
p_types
.
table
,
{
hashtab_for_each
(
db
->
p_types
.
table
,
{
tgt
=
node
->
datum
;
tgt
=
node
->
datum
;
ret
|=
add_rule_auto
(
src
,
tgt
,
cls
,
perm
,
effect
,
not
);
ret
|=
add_rule_auto
(
db
,
src
,
tgt
,
cls
,
perm
,
effect
,
not
);
})
})
}
else
if
(
cls
==
NULL
)
{
}
else
if
(
cls
==
NULL
)
{
hashtab_for_each
(
mp
db
->
p_classes
.
table
,
{
hashtab_for_each
(
db
->
p_classes
.
table
,
{
cls
=
node
->
datum
;
cls
=
node
->
datum
;
ret
|=
add_rule_auto
(
src
,
tgt
,
cls
,
perm
,
effect
,
not
);
ret
|=
add_rule_auto
(
db
,
src
,
tgt
,
cls
,
perm
,
effect
,
not
);
})
})
}
else
{
}
else
{
key
.
source_type
=
src
->
s
.
value
;
key
.
source_type
=
src
->
s
.
value
;
key
.
target_type
=
tgt
->
s
.
value
;
key
.
target_type
=
tgt
->
s
.
value
;
key
.
target_class
=
cls
->
s
.
value
;
key
.
target_class
=
cls
->
s
.
value
;
key
.
specified
=
effect
;
key
.
specified
=
effect
;
return
add_avrule
(
&
key
,
perm
?
perm
->
s
.
value
:
-
1
,
not
);
return
add_avrule
(
db
,
&
key
,
perm
?
perm
->
s
.
value
:
-
1
,
not
);
}
}
return
ret
;
return
ret
;
}
}
...
@@ -152,7 +149,7 @@ static int add_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum_t *cl
...
@@ -152,7 +149,7 @@ static int add_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum_t *cl
#define ioctl_driver(x) (x>>8 & 0xFF)
#define ioctl_driver(x) (x>>8 & 0xFF)
#define ioctl_func(x) (x & 0xFF)
#define ioctl_func(x) (x & 0xFF)
static
int
add_avxrule
(
avtab_key_t
*
key
,
uint16_t
low
,
uint16_t
high
,
int
not
)
{
static
int
add_avxrule
(
policydb_t
*
db
,
avtab_key_t
*
key
,
uint16_t
low
,
uint16_t
high
,
int
not
)
{
avtab_datum_t
*
datum
;
avtab_datum_t
*
datum
;
avtab_extended_perms_t
xperms
;
avtab_extended_perms_t
xperms
;
...
@@ -181,7 +178,7 @@ static int add_avxrule(avtab_key_t *key, uint16_t low, uint16_t high, int not) {
...
@@ -181,7 +178,7 @@ static int add_avxrule(avtab_key_t *key, uint16_t low, uint16_t high, int not) {
}
}
}
}
datum
=
&
get_avtab_node
(
key
,
&
xperms
)
->
datum
;
datum
=
&
get_avtab_node
(
db
,
key
,
&
xperms
)
->
datum
;
if
(
datum
->
xperms
==
NULL
)
if
(
datum
->
xperms
==
NULL
)
datum
->
xperms
=
xmalloc
(
sizeof
(
xperms
));
datum
->
xperms
=
xmalloc
(
sizeof
(
xperms
));
...
@@ -190,38 +187,38 @@ static int add_avxrule(avtab_key_t *key, uint16_t low, uint16_t high, int not) {
...
@@ -190,38 +187,38 @@ static int add_avxrule(avtab_key_t *key, uint16_t low, uint16_t high, int not) {
return
0
;
return
0
;
}
}
static
int
add_xperm_rule_auto
(
type_datum_t
*
src
,
type_datum_t
*
tgt
,
class_datum_t
*
cls
,
static
int
add_xperm_rule_auto
(
policydb_t
*
db
,
type_datum_t
*
src
,
type_datum_t
*
tgt
,
uint16_t
low
,
uint16_t
high
,
int
effect
,
int
not
)
{
class_datum_t
*
cls
,
uint16_t
low
,
uint16_t
high
,
int
effect
,
int
not
)
{
avtab_key_t
key
;
avtab_key_t
key
;
int
ret
=
0
;
int
ret
=
0
;
if
(
src
==
NULL
)
{
if
(
src
==
NULL
)
{
hashtab_for_each
(
mp
db
->
p_types
.
table
,
{
hashtab_for_each
(
db
->
p_types
.
table
,
{
src
=
node
->
datum
;
src
=
node
->
datum
;
ret
|=
add_xperm_rule_auto
(
src
,
tgt
,
cls
,
low
,
high
,
effect
,
not
);
ret
|=
add_xperm_rule_auto
(
db
,
src
,
tgt
,
cls
,
low
,
high
,
effect
,
not
);
})
})
}
else
if
(
tgt
==
NULL
)
{
}
else
if
(
tgt
==
NULL
)
{
hashtab_for_each
(
mp
db
->
p_types
.
table
,
{
hashtab_for_each
(
db
->
p_types
.
table
,
{
tgt
=
node
->
datum
;
tgt
=
node
->
datum
;
ret
|=
add_xperm_rule_auto
(
src
,
tgt
,
cls
,
low
,
high
,
effect
,
not
);
ret
|=
add_xperm_rule_auto
(
db
,
src
,
tgt
,
cls
,
low
,
high
,
effect
,
not
);
})
})
}
else
if
(
cls
==
NULL
)
{
}
else
if
(
cls
==
NULL
)
{
hashtab_for_each
(
mp
db
->
p_classes
.
table
,
{
hashtab_for_each
(
db
->
p_classes
.
table
,
{
cls
=
node
->
datum
;
cls
=
node
->
datum
;
ret
|=
add_xperm_rule_auto
(
src
,
tgt
,
cls
,
low
,
high
,
effect
,
not
);
ret
|=
add_xperm_rule_auto
(
db
,
src
,
tgt
,
cls
,
low
,
high
,
effect
,
not
);
})
})
}
else
{
}
else
{
key
.
source_type
=
src
->
s
.
value
;
key
.
source_type
=
src
->
s
.
value
;
key
.
target_type
=
tgt
->
s
.
value
;
key
.
target_type
=
tgt
->
s
.
value
;
key
.
target_class
=
cls
->
s
.
value
;
key
.
target_class
=
cls
->
s
.
value
;
key
.
specified
=
effect
;
key
.
specified
=
effect
;
return
add_avxrule
(
&
key
,
low
,
high
,
not
);
return
add_avxrule
(
db
,
&
key
,
low
,
high
,
not
);
}
}
return
ret
;
return
ret
;
}
}
int
create_domain
(
const
char
*
d
)
{
int
create_domain
(
policydb_t
*
db
,
const
char
*
d
)
{
symtab_datum_t
*
src
=
hashtab_search
(
mp
db
->
p_types
.
table
,
d
);
symtab_datum_t
*
src
=
hashtab_search
(
db
->
p_types
.
table
,
d
);
if
(
src
)
{
if
(
src
)
{
LOGW
(
"Domain %s already exists
\n
"
,
d
);
LOGW
(
"Domain %s already exists
\n
"
,
d
);
return
0
;
return
0
;
...
@@ -233,60 +230,60 @@ int create_domain(const char *d) {
...
@@ -233,60 +230,60 @@ int create_domain(const char *d) {
typedatum
->
flavor
=
TYPE_TYPE
;
typedatum
->
flavor
=
TYPE_TYPE
;
uint32_t
value
=
0
;
uint32_t
value
=
0
;
symtab_insert
(
mp
db
,
SYM_TYPES
,
strdup
(
d
),
typedatum
,
SCOPE_DECL
,
1
,
&
value
);
symtab_insert
(
db
,
SYM_TYPES
,
strdup
(
d
),
typedatum
,
SCOPE_DECL
,
1
,
&
value
);
typedatum
->
s
.
value
=
value
;
typedatum
->
s
.
value
=
value
;
if
(
ebitmap_set_bit
(
&
mp
db
->
global
->
branch_list
->
declared
.
scope
[
SYM_TYPES
],
value
-
1
,
1
))
{
if
(
ebitmap_set_bit
(
&
db
->
global
->
branch_list
->
declared
.
scope
[
SYM_TYPES
],
value
-
1
,
1
))
{
return
1
;
return
1
;
}
}
mpdb
->
type_attr_map
=
xrealloc
(
mpdb
->
type_attr_map
,
sizeof
(
ebitmap_t
)
*
mp
db
->
p_types
.
nprim
);
db
->
type_attr_map
=
xrealloc
(
db
->
type_attr_map
,
sizeof
(
ebitmap_t
)
*
db
->
p_types
.
nprim
);
mpdb
->
attr_type_map
=
xrealloc
(
mpdb
->
attr_type_map
,
sizeof
(
ebitmap_t
)
*
mp
db
->
p_types
.
nprim
);
db
->
attr_type_map
=
xrealloc
(
db
->
attr_type_map
,
sizeof
(
ebitmap_t
)
*
db
->
p_types
.
nprim
);
ebitmap_init
(
&
mp
db
->
type_attr_map
[
value
-
1
]);
ebitmap_init
(
&
db
->
type_attr_map
[
value
-
1
]);
ebitmap_init
(
&
mp
db
->
attr_type_map
[
value
-
1
]);
ebitmap_init
(
&
db
->
attr_type_map
[
value
-
1
]);
ebitmap_set_bit
(
&
mp
db
->
type_attr_map
[
value
-
1
],
value
-
1
,
1
);
ebitmap_set_bit
(
&
db
->
type_attr_map
[
value
-
1
],
value
-
1
,
1
);
src
=
hashtab_search
(
mp
db
->
p_types
.
table
,
d
);
src
=
hashtab_search
(
db
->
p_types
.
table
,
d
);
if
(
!
src
)
if
(
!
src
)
return
1
;
return
1
;
if
(
policydb_index_decls
(
NULL
,
mp
db
))
if
(
policydb_index_decls
(
NULL
,
db
))
return
1
;
return
1
;
if
(
policydb_index_classes
(
mp
db
))
if
(
policydb_index_classes
(
db
))
return
1
;
return
1
;
if
(
policydb_index_others
(
NULL
,
mp
db
,
0
))
if
(
policydb_index_others
(
NULL
,
db
,
0
))
return
1
;
return
1
;
//Add the domain to all roles
//
Add the domain to all roles
for
(
unsigned
i
=
0
;
i
<
mp
db
->
p_roles
.
nprim
;
++
i
)
{
for
(
unsigned
i
=
0
;
i
<
db
->
p_roles
.
nprim
;
++
i
)
{
//Not sure all those three calls are needed
//
Not sure all those three calls are needed
ebitmap_set_bit
(
&
mp
db
->
role_val_to_struct
[
i
]
->
types
.
negset
,
value
-
1
,
0
);
ebitmap_set_bit
(
&
db
->
role_val_to_struct
[
i
]
->
types
.
negset
,
value
-
1
,
0
);
ebitmap_set_bit
(
&
mp
db
->
role_val_to_struct
[
i
]
->
types
.
types
,
value
-
1
,
1
);
ebitmap_set_bit
(
&
db
->
role_val_to_struct
[
i
]
->
types
.
types
,
value
-
1
,
1
);
type_set_expand
(
&
mpdb
->
role_val_to_struct
[
i
]
->
types
,
&
mpdb
->
role_val_to_struct
[
i
]
->
cache
,
mp
db
,
0
);
type_set_expand
(
&
db
->
role_val_to_struct
[
i
]
->
types
,
&
db
->
role_val_to_struct
[
i
]
->
cache
,
db
,
0
);
}
}
return
set_attr
(
"domain"
,
value
);
return
set_attr
(
db
,
"domain"
,
value
);
}
}
int
set_domain_state
(
const
char
*
s
,
int
state
)
{
int
set_domain_state
(
policydb_t
*
db
,
const
char
*
s
,
int
state
)
{
type_datum_t
*
type
;
type_datum_t
*
type
;
if
(
s
==
NULL
)
{
if
(
s
==
NULL
)
{
hashtab_for_each
(
mp
db
->
p_types
.
table
,
{
hashtab_for_each
(
db
->
p_types
.
table
,
{
type
=
node
->
datum
;
type
=
node
->
datum
;
if
(
ebitmap_set_bit
(
&
mp
db
->
permissive_map
,
type
->
s
.
value
,
state
))
{
if
(
ebitmap_set_bit
(
&
db
->
permissive_map
,
type
->
s
.
value
,
state
))
{
LOGW
(
"Could not set bit in permissive map
\n
"
);
LOGW
(
"Could not set bit in permissive map
\n
"
);
return
1
;
return
1
;
}
}
})
})
}
else
{
}
else
{
type
=
hashtab_search
(
mp
db
->
p_types
.
table
,
s
);
type
=
hashtab_search
(
db
->
p_types
.
table
,
s
);
if
(
type
==
NULL
)
{
if
(
type
==
NULL
)
{
LOGW
(
"type %s does not exist
\n
"
,
s
);
LOGW
(
"type %s does not exist
\n
"
,
s
);
return
1
;
return
1
;
}
}
if
(
ebitmap_set_bit
(
&
mp
db
->
permissive_map
,
type
->
s
.
value
,
state
))
{
if
(
ebitmap_set_bit
(
&
db
->
permissive_map
,
type
->
s
.
value
,
state
))
{
LOGW
(
"Could not set bit in permissive map
\n
"
);
LOGW
(
"Could not set bit in permissive map
\n
"
);
return
1
;
return
1
;
}
}
...
@@ -295,26 +292,27 @@ int set_domain_state(const char *s, int state) {
...
@@ -295,26 +292,27 @@ int set_domain_state(const char *s, int state) {
return
0
;
return
0
;
}
}
int
add_filename_trans
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
,
const
char
*
o
)
{
int
add_filename_trans
(
policydb_t
*
db
,
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
,
const
char
*
o
)
{
type_datum_t
*
src
,
*
tgt
,
*
def
;
type_datum_t
*
src
,
*
tgt
,
*
def
;
class_datum_t
*
cls
;
class_datum_t
*
cls
;
src
=
hashtab_search
(
mp
db
->
p_types
.
table
,
s
);
src
=
hashtab_search
(
db
->
p_types
.
table
,
s
);
if
(
src
==
NULL
)
{
if
(
src
==
NULL
)
{
LOGW
(
"source type %s does not exist
\n
"
,
s
);
LOGW
(
"source type %s does not exist
\n
"
,
s
);
return
1
;
return
1
;
}
}
tgt
=
hashtab_search
(
mp
db
->
p_types
.
table
,
t
);
tgt
=
hashtab_search
(
db
->
p_types
.
table
,
t
);
if
(
tgt
==
NULL
)
{
if
(
tgt
==
NULL
)
{
LOGW
(
"target type %s does not exist
\n
"
,
t
);
LOGW
(
"target type %s does not exist
\n
"
,
t
);
return
1
;
return
1
;
}
}
cls
=
hashtab_search
(
mp
db
->
p_classes
.
table
,
c
);
cls
=
hashtab_search
(
db
->
p_classes
.
table
,
c
);
if
(
cls
==
NULL
)
{
if
(
cls
==
NULL
)
{
LOGW
(
"class %s does not exist
\n
"
,
c
);
LOGW
(
"class %s does not exist
\n
"
,
c
);
return
1
;
return
1
;
}
}
def
=
hashtab_search
(
mp
db
->
p_types
.
table
,
d
);
def
=
hashtab_search
(
db
->
p_types
.
table
,
d
);
if
(
def
==
NULL
)
{
if
(
def
==
NULL
)
{
LOGW
(
"default type %s does not exist
\n
"
,
d
);
LOGW
(
"default type %s does not exist
\n
"
,
d
);
return
1
;
return
1
;
...
@@ -327,11 +325,11 @@ int add_filename_trans(const char *s, const char *t, const char *c, const char *
...
@@ -327,11 +325,11 @@ int add_filename_trans(const char *s, const char *t, const char *c, const char *
trans_key
.
name
=
(
char
*
)
o
;
trans_key
.
name
=
(
char
*
)
o
;
filename_trans_datum_t
*
trans_datum
;
filename_trans_datum_t
*
trans_datum
;
trans_datum
=
hashtab_search
(
mp
db
->
filename_trans
,
(
hashtab_key_t
)
&
trans_key
);
trans_datum
=
hashtab_search
(
db
->
filename_trans
,
(
hashtab_key_t
)
&
trans_key
);
if
(
trans_datum
==
NULL
)
{
if
(
trans_datum
==
NULL
)
{
trans_datum
=
xcalloc
(
sizeof
(
*
trans_datum
),
1
);
trans_datum
=
xcalloc
(
sizeof
(
*
trans_datum
),
1
);
hashtab_insert
(
mp
db
->
filename_trans
,
(
hashtab_key_t
)
&
trans_key
,
trans_datum
);
hashtab_insert
(
db
->
filename_trans
,
(
hashtab_key_t
)
&
trans_key
,
trans_datum
);
}
}
// Overwrite existing
// Overwrite existing
...
@@ -339,18 +337,18 @@ int add_filename_trans(const char *s, const char *t, const char *c, const char *
...
@@ -339,18 +337,18 @@ int add_filename_trans(const char *s, const char *t, const char *c, const char *
return
0
;
return
0
;
}
}
int
add_typeattribute
(
const
char
*
type
,
const
char
*
attr
)
{
int
add_typeattribute
(
policydb_t
*
db
,
const
char
*
type
,
const
char
*
attr
)
{
type_datum_t
*
domain
=
hashtab_search
(
mp
db
->
p_types
.
table
,
type
);
type_datum_t
*
domain
=
hashtab_search
(
db
->
p_types
.
table
,
type
);
if
(
domain
==
NULL
)
{
if
(
domain
==
NULL
)
{
LOGW
(
"type %s does not exist
\n
"
,
type
);
LOGW
(
"type %s does not exist
\n
"
,
type
);
return
1
;
return
1
;
}
}
int
attr_id
=
set_attr
(
attr
,
domain
->
s
.
value
);
int
attr_id
=
set_attr
(
db
,
attr
,
domain
->
s
.
value
);
if
(
attr_id
<
0
)
if
(
attr_id
<
0
)
return
1
;
return
1
;
hashtab_for_each
(
mp
db
->
p_classes
.
table
,
{
hashtab_for_each
(
db
->
p_classes
.
table
,
{
class_datum_t
*
cls
=
node
->
datum
;
class_datum_t
*
cls
=
node
->
datum
;
for
(
constraint_node_t
*
n
=
cls
->
constraints
;
n
;
n
=
n
->
next
)
{
for
(
constraint_node_t
*
n
=
cls
->
constraints
;
n
;
n
=
n
->
next
)
{
for
(
constraint_expr_t
*
e
=
n
->
expr
;
e
;
e
=
e
->
next
)
{
for
(
constraint_expr_t
*
e
=
n
->
expr
;
e
;
e
=
e
->
next
)
{
...
@@ -365,13 +363,14 @@ int add_typeattribute(const char *type, const char *attr) {
...
@@ -365,13 +363,14 @@ int add_typeattribute(const char *type, const char *attr) {
return
0
;
return
0
;
}
}
int
add_rule
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
,
int
effect
,
int
n
)
{
int
add_rule
(
policydb_t
*
db
,
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
,
int
effect
,
int
n
)
{
type_datum_t
*
src
=
NULL
,
*
tgt
=
NULL
;
type_datum_t
*
src
=
NULL
,
*
tgt
=
NULL
;
class_datum_t
*
cls
=
NULL
;
class_datum_t
*
cls
=
NULL
;
perm_datum_t
*
perm
=
NULL
;
perm_datum_t
*
perm
=
NULL
;
if
(
s
)
{
if
(
s
)
{
src
=
hashtab_search
(
mp
db
->
p_types
.
table
,
s
);
src
=
hashtab_search
(
db
->
p_types
.
table
,
s
);
if
(
src
==
NULL
)
{
if
(
src
==
NULL
)
{
LOGW
(
"source type %s does not exist
\n
"
,
s
);
LOGW
(
"source type %s does not exist
\n
"
,
s
);
return
1
;
return
1
;
...
@@ -379,7 +378,7 @@ int add_rule(const char *s, const char *t, const char *c, const char *p, int eff
...
@@ -379,7 +378,7 @@ int add_rule(const char *s, const char *t, const char *c, const char *p, int eff
}
}
if
(
t
)
{
if
(
t
)
{
tgt
=
hashtab_search
(
mp
db
->
p_types
.
table
,
t
);
tgt
=
hashtab_search
(
db
->
p_types
.
table
,
t
);
if
(
tgt
==
NULL
)
{
if
(
tgt
==
NULL
)
{
LOGW
(
"target type %s does not exist
\n
"
,
t
);
LOGW
(
"target type %s does not exist
\n
"
,
t
);
return
1
;
return
1
;
...
@@ -387,7 +386,7 @@ int add_rule(const char *s, const char *t, const char *c, const char *p, int eff
...
@@ -387,7 +386,7 @@ int add_rule(const char *s, const char *t, const char *c, const char *p, int eff
}
}
if
(
c
)
{
if
(
c
)
{
cls
=
hashtab_search
(
mp
db
->
p_classes
.
table
,
c
);
cls
=
hashtab_search
(
db
->
p_classes
.
table
,
c
);
if
(
cls
==
NULL
)
{
if
(
cls
==
NULL
)
{
LOGW
(
"class %s does not exist
\n
"
,
c
);
LOGW
(
"class %s does not exist
\n
"
,
c
);
return
1
;
return
1
;
...
@@ -409,16 +408,16 @@ int add_rule(const char *s, const char *t, const char *c, const char *p, int eff
...
@@ -409,16 +408,16 @@ int add_rule(const char *s, const char *t, const char *c, const char *p, int eff
return
1
;
return
1
;
}
}
}
}
return
add_rule_auto
(
src
,
tgt
,
cls
,
perm
,
effect
,
n
);
return
add_rule_auto
(
db
,
src
,
tgt
,
cls
,
perm
,
effect
,
n
);
}
}
int
add_xperm_rule
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
,
int
effect
,
int
add_xperm_rule
(
policydb_t
*
db
,
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
,
int
n
)
{
int
effect
,
int
n
)
{
type_datum_t
*
src
=
NULL
,
*
tgt
=
NULL
;
type_datum_t
*
src
=
NULL
,
*
tgt
=
NULL
;
class_datum_t
*
cls
=
NULL
;
class_datum_t
*
cls
=
NULL
;
if
(
s
)
{
if
(
s
)
{
src
=
hashtab_search
(
mp
db
->
p_types
.
table
,
s
);
src
=
hashtab_search
(
db
->
p_types
.
table
,
s
);
if
(
src
==
NULL
)
{
if
(
src
==
NULL
)
{
LOGW
(
"source type %s does not exist
\n
"
,
s
);
LOGW
(
"source type %s does not exist
\n
"
,
s
);
return
1
;
return
1
;
...
@@ -426,7 +425,7 @@ int add_xperm_rule(const char *s, const char *t, const char *c, const char *rang
...
@@ -426,7 +425,7 @@ int add_xperm_rule(const char *s, const char *t, const char *c, const char *rang
}
}
if
(
t
)
{
if
(
t
)
{
tgt
=
hashtab_search
(
mp
db
->
p_types
.
table
,
t
);
tgt
=
hashtab_search
(
db
->
p_types
.
table
,
t
);
if
(
tgt
==
NULL
)
{
if
(
tgt
==
NULL
)
{
LOGW
(
"target type %s does not exist
\n
"
,
t
);
LOGW
(
"target type %s does not exist
\n
"
,
t
);
return
1
;
return
1
;
...
@@ -434,7 +433,7 @@ int add_xperm_rule(const char *s, const char *t, const char *c, const char *rang
...
@@ -434,7 +433,7 @@ int add_xperm_rule(const char *s, const char *t, const char *c, const char *rang
}
}
if
(
c
)
{
if
(
c
)
{
cls
=
hashtab_search
(
mp
db
->
p_classes
.
table
,
c
);
cls
=
hashtab_search
(
db
->
p_classes
.
table
,
c
);
if
(
cls
==
NULL
)
{
if
(
cls
==
NULL
)
{
LOGW
(
"class %s does not exist
\n
"
,
c
);
LOGW
(
"class %s does not exist
\n
"
,
c
);
return
1
;
return
1
;
...
@@ -455,29 +454,30 @@ int add_xperm_rule(const char *s, const char *t, const char *c, const char *rang
...
@@ -455,29 +454,30 @@ int add_xperm_rule(const char *s, const char *t, const char *c, const char *rang
high
=
0xFFFF
;
high
=
0xFFFF
;
}
}
return
add_xperm_rule_auto
(
src
,
tgt
,
cls
,
low
,
high
,
effect
,
n
);
return
add_xperm_rule_auto
(
db
,
src
,
tgt
,
cls
,
low
,
high
,
effect
,
n
);
}
}
int
add_type_rule
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
,
int
effect
)
{
int
add_type_rule
(
policydb_t
*
db
,
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
,
int
effect
)
{
type_datum_t
*
src
,
*
tgt
,
*
def
;
type_datum_t
*
src
,
*
tgt
,
*
def
;
class_datum_t
*
cls
;
class_datum_t
*
cls
;
src
=
hashtab_search
(
mp
db
->
p_types
.
table
,
s
);
src
=
hashtab_search
(
db
->
p_types
.
table
,
s
);
if
(
src
==
NULL
)
{
if
(
src
==
NULL
)
{
LOGW
(
"source type %s does not exist
\n
"
,
s
);
LOGW
(
"source type %s does not exist
\n
"
,
s
);
return
1
;
return
1
;
}
}
tgt
=
hashtab_search
(
mp
db
->
p_types
.
table
,
t
);
tgt
=
hashtab_search
(
db
->
p_types
.
table
,
t
);
if
(
tgt
==
NULL
)
{
if
(
tgt
==
NULL
)
{
LOGW
(
"target type %s does not exist
\n
"
,
t
);
LOGW
(
"target type %s does not exist
\n
"
,
t
);
return
1
;
return
1
;
}
}
cls
=
hashtab_search
(
mp
db
->
p_classes
.
table
,
c
);
cls
=
hashtab_search
(
db
->
p_classes
.
table
,
c
);
if
(
cls
==
NULL
)
{
if
(
cls
==
NULL
)
{
LOGW
(
"class %s does not exist
\n
"
,
c
);
LOGW
(
"class %s does not exist
\n
"
,
c
);
return
1
;
return
1
;
}
}
def
=
hashtab_search
(
mp
db
->
p_types
.
table
,
d
);
def
=
hashtab_search
(
db
->
p_types
.
table
,
d
);
if
(
def
==
NULL
)
{
if
(
def
==
NULL
)
{
LOGW
(
"default type %s does not exist
\n
"
,
d
);
LOGW
(
"default type %s does not exist
\n
"
,
d
);
return
1
;
return
1
;
...
@@ -489,16 +489,16 @@ int add_type_rule(const char *s, const char *t, const char *c, const char *d, in
...
@@ -489,16 +489,16 @@ int add_type_rule(const char *s, const char *t, const char *c, const char *d, in
key
.
target_class
=
cls
->
s
.
value
;
key
.
target_class
=
cls
->
s
.
value
;
key
.
specified
=
effect
;
key
.
specified
=
effect
;
avtab_ptr_t
node
=
get_avtab_node
(
&
key
,
NULL
);
avtab_ptr_t
node
=
get_avtab_node
(
db
,
&
key
,
NULL
);
node
->
datum
.
data
=
def
->
s
.
value
;
node
->
datum
.
data
=
def
->
s
.
value
;
return
0
;
return
0
;
}
}
int
add_genfscon
(
const
char
*
name
,
const
char
*
path
,
const
char
*
context
)
{
int
add_genfscon
(
policydb_t
*
db
,
const
char
*
name
,
const
char
*
path
,
const
char
*
context
)
{
// First try to create context
// First try to create context
context_struct_t
*
ctx
;
context_struct_t
*
ctx
;
if
(
context_from_string
(
NULL
,
mp
db
,
&
ctx
,
context
,
strlen
(
context
)))
{
if
(
context_from_string
(
NULL
,
db
,
&
ctx
,
context
,
strlen
(
context
)))
{
LOGW
(
"Failed to create context from string [%s]
\n
"
,
context
);
LOGW
(
"Failed to create context from string [%s]
\n
"
,
context
);
return
1
;
return
1
;
}
}
...
@@ -512,7 +512,7 @@ int add_genfscon(const char *name, const char *path, const char *context) {
...
@@ -512,7 +512,7 @@ int add_genfscon(const char *name, const char *path, const char *context) {
// Find or allocate genfs
// Find or allocate genfs
genfs_t
*
last_gen
=
NULL
;
genfs_t
*
last_gen
=
NULL
;
genfs_t
*
newfs
=
NULL
;
genfs_t
*
newfs
=
NULL
;
for
(
genfs_t
*
node
=
mp
db
->
genfs
;
node
;
node
=
node
->
next
)
{
for
(
genfs_t
*
node
=
db
->
genfs
;
node
;
node
=
node
->
next
)
{
if
(
strcmp
(
node
->
fstype
,
name
)
==
0
)
{
if
(
strcmp
(
node
->
fstype
,
name
)
==
0
)
{
newfs
=
node
;
newfs
=
node
;
break
;
break
;
...
@@ -526,7 +526,7 @@ int add_genfscon(const char *name, const char *path, const char *context) {
...
@@ -526,7 +526,7 @@ int add_genfscon(const char *name, const char *path, const char *context) {
if
(
last_gen
)
if
(
last_gen
)
last_gen
->
next
=
newfs
;
last_gen
->
next
=
newfs
;
else
else
mp
db
->
genfs
=
newfs
;
db
->
genfs
=
newfs
;
}
}
// Insert or replace genfs context
// Insert or replace genfs context
...
@@ -555,9 +555,9 @@ int add_genfscon(const char *name, const char *path, const char *context) {
...
@@ -555,9 +555,9 @@ int add_genfscon(const char *name, const char *path, const char *context) {
return
0
;
return
0
;
}
}
void
strip_dontaudit
()
{
void
strip_dontaudit
(
policydb_t
*
db
)
{
avtab_for_each
(
&
mp
db
->
te_avtab
,
{
avtab_for_each
(
&
db
->
te_avtab
,
{
if
(
node
->
key
.
specified
==
AVTAB_AUDITDENY
||
node
->
key
.
specified
==
AVTAB_XPERMS_DONTAUDIT
)
if
(
node
->
key
.
specified
==
AVTAB_AUDITDENY
||
node
->
key
.
specified
==
AVTAB_XPERMS_DONTAUDIT
)
avtab_remove_node
(
&
magisk_policy
db
->
te_avtab
,
node
);
avtab_remove_node
(
&
db
->
te_avtab
,
node
);
})
})
}
}
native/jni/magiskpolicy/sepolicy.h
View file @
d4baae41
...
@@ -4,17 +4,21 @@
...
@@ -4,17 +4,21 @@
__BEGIN_DECLS
__BEGIN_DECLS
// Global policydb
// Internal C APIs, do not use directly
extern
policydb_t
*
magisk_policydb
;
int
create_domain
(
policydb_t
*
db
,
const
char
*
d
);
int
set_domain_state
(
policydb_t
*
db
,
const
char
*
s
,
int
state
);
int
add_typeattribute
(
policydb_t
*
db
,
const
char
*
type
,
const
char
*
attr
);
int
add_rule
(
policydb_t
*
db
,
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
,
int
effect
,
int
n
);
int
add_xperm_rule
(
policydb_t
*
db
,
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
,
int
effect
,
int
n
);
int
add_type_rule
(
policydb_t
*
db
,
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
,
int
effect
);
int
add_filename_trans
(
policydb_t
*
db
,
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
,
const
char
*
o
);
int
add_genfscon
(
policydb_t
*
db
,
const
char
*
name
,
const
char
*
path
,
const
char
*
context
);
void
strip_dontaudit
(
policydb_t
*
db
);
int
create_domain
(
const
char
*
d
);
void
statement_help
();
int
set_domain_state
(
const
char
*
s
,
int
state
);
int
add_typeattribute
(
const
char
*
type
,
const
char
*
attr
);
int
add_rule
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
p
,
int
effect
,
int
n
);
int
add_xperm_rule
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
range
,
int
effect
,
int
n
);
int
add_type_rule
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
,
int
effect
);
int
add_filename_trans
(
const
char
*
s
,
const
char
*
t
,
const
char
*
c
,
const
char
*
d
,
const
char
*
o
);
int
add_genfscon
(
const
char
*
name
,
const
char
*
path
,
const
char
*
context
);
void
strip_dontaudit
();
__END_DECLS
__END_DECLS
native/jni/magiskpolicy/statement.cpp
View file @
d4baae41
...
@@ -6,42 +6,45 @@
...
@@ -6,42 +6,45 @@
#include <logging.hpp>
#include <logging.hpp>
#include <utils.hpp>
#include <utils.hpp>
#include "sepolicy.h"
using
namespace
std
;
using
namespace
std
;
static
const
char
*
type_msg_1
=
static
const
char
*
type_msg_1
=
R"EOF(Type 1:
R"EOF(Type 1:
"<rule_name>
source_type target_type class
perm_set"
"<rule_name>
^source_type ^target_type ^class ^
perm_set"
Rules: allow, deny, auditallow, dontaudit
Rules: allow, deny, auditallow, dontaudit
)EOF"
;
)EOF"
;
static
const
char
*
type_msg_2
=
static
const
char
*
type_msg_2
=
R"EOF(Type 2:
R"EOF(Type 2:
"<rule_name>
source_type target_type
class operation xperm_set"
"<rule_name>
^source_type ^target_type ^
class operation xperm_set"
Rules: allowxperm, auditallowxperm, dontauditxperm
Rules: allowxperm, auditallowxperm, dontauditxperm
*
The only supported operation is ioctl
-
The only supported operation is ioctl
*
The only supported xperm_set format is range ([low-high])
-
The only supported xperm_set format is range ([low-high])
)EOF"
;
)EOF"
;
static
const
char
*
type_msg_3
=
static
const
char
*
type_msg_3
=
R"EOF(Type 3:
R"EOF(Type 3:
"<rule_name>
class
"
"<rule_name>
type
"
Rules: create, permissive, enforcing
Rules: create, permissive, enforcing
)EOF"
;
)EOF"
;
static
const
char
*
type_msg_4
=
static
const
char
*
type_msg_4
=
R"EOF(Type 4:
R"EOF(Type 4:
"
attradd class
attribute"
"
typeattribute type
attribute"
)EOF"
;
)EOF"
;
static
const
char
*
type_msg_5
=
static
const
char
*
type_msg_5
=
R"EOF(Type 5:
R"EOF(Type 5:
"<rule_name> source_type target_type class default_type"
"<rule_name> source_type target_type class default_type"
Rules: type_
transition, type_
change, type_member
Rules: type_change, type_member
)EOF"
;
)EOF"
;
static
const
char
*
type_msg_6
=
static
const
char
*
type_msg_6
=
R"EOF(Type 6:
R"EOF(Type 6:
"name_transition source_type target_type class default_type object_name"
"type_transition source_type target_type class default_type (object_name)"
- Entry 'object_name' is optional
)EOF"
;
)EOF"
;
static
const
char
*
type_msg_7
=
static
const
char
*
type_msg_7
=
...
@@ -52,13 +55,22 @@ R"EOF(Type 7:
...
@@ -52,13 +55,22 @@ R"EOF(Type 7:
void
statement_help
()
{
void
statement_help
()
{
fprintf
(
stderr
,
fprintf
(
stderr
,
R"EOF(One policy statement should be treated as one parameter;
R"EOF(One policy statement should be treated as one parameter;
this means
a full
policy statement should be enclosed in quotes.
this means
each
policy statement should be enclosed in quotes.
Multiple policy statements can be provided in a single command.
Multiple policy statements can be provided in a single command.
The statements has a format of "<rule_name> [args...]"
Statements has a format of "<rule_name> [args...]".
Multiple types and permissions can be grouped into collections
Arguments labeled with (^) can accept one or more entries. Multiple
wrapped in curly brackets.
entries consist of a space separated list enclosed in braces ({}).
'*' represents a collection containing all valid matches.
For args that support multiple entries, (*) can be used to
represent all valid matches.
Example: "allow { s1 s2 } { t1 t2 } class *"
Will be expanded to:
allow s1 t1 class { all-permissions-of-class }
allow s1 t2 class { all-permissions-of-class }
allow s2 t1 class { all-permissions-of-class }
allow s2 t2 class { all-permissions-of-class }
Supported policy statements:
Supported policy statements:
...
@@ -69,388 +81,193 @@ Supported policy statements:
...
@@ -69,388 +81,193 @@ Supported policy statements:
%s
%s
%s
%s
%s
%s
Notes:
* Type 4 - 7 does not support collections
* Object classes cannot be collections
* source_type and target_type can also be attributes
Example: allow { s1 s2 } { t1 t2 } class *
Will be expanded to:
allow s1 t1 class { all-permissions }
allow s1 t2 class { all-permissions }
allow s2 t1 class { all-permissions }
allow s2 t2 class { all-permissions }
)EOF"
,
type_msg_1
,
type_msg_2
,
type_msg_3
,
type_msg_4
,
type_msg_5
,
type_msg_6
,
type_msg_7
);
)EOF"
,
type_msg_1
,
type_msg_2
,
type_msg_3
,
type_msg_4
,
type_msg_5
,
type_msg_6
,
type_msg_7
);
exit
(
0
);
exit
(
0
);
}
}
static
int
parse_bracket
(
char
*
tok
,
char
*&
stmt
,
vector
<
const
char
*>
&
vec
)
{
static
bool
tokenize_string
(
char
*
stmt
,
vector
<
vector
<
char
*>>
&
arr
)
{
if
(
tok
==
nullptr
||
tok
[
0
]
!=
'{'
)
{
// cur is the pointer to where the top level is parsing
// Not in a bracket
char
*
cur
=
stmt
;
vec
.
push_back
(
tok
);
for
(
char
*
tok
;
(
tok
=
strtok_r
(
nullptr
,
" "
,
&
cur
))
!=
nullptr
;)
{
}
else
{
vector
<
char
*>
token
;
if
(
stmt
)
if
(
tok
[
0
]
==
'{'
)
{
stmt
[
-
1
]
=
' '
;
// cur could point to somewhere in the braces, restore the string
tok
=
strchr
(
tok
,
'{'
)
+
1
;
cur
[
-
1
]
=
' '
;
char
*
end
=
strchr
(
tok
,
'}'
);
++
tok
;
if
(
end
==
nullptr
)
// Bracket not closed
char
*
end
=
strchr
(
tok
,
'}'
);
return
1
;
if
(
end
==
nullptr
)
{
*
end
=
'\0'
;
// Bracket not closed, syntax error
char
*
cur
;
LOGE
(
"Unclosed bracket detected
\n
"
);
while
((
cur
=
strtok_r
(
nullptr
,
" "
,
&
tok
))
!=
nullptr
)
return
false
;
vec
.
push_back
(
cur
);
}
stmt
=
end
+
1
;
*
end
=
'\0'
;
}
for
(
char
*
sub_tok
;
(
sub_tok
=
strtok_r
(
nullptr
,
" "
,
&
tok
))
!=
nullptr
;)
return
0
;
token
.
push_back
(
sub_tok
);
}
cur
=
end
+
1
;
}
else
if
(
tok
[
0
]
==
'*'
)
{
// Pattern 1: action { source } { target } class { permission }
token
.
push_back
(
nullptr
);
static
int
parse_pattern_1
(
int
action
,
const
char
*
action_str
,
char
*
stmt
)
{
}
else
{
int
(
*
action_func
)(
const
char
*
,
const
char
*
,
const
char
*
,
const
char
*
);
token
.
push_back
(
tok
);
switch
(
action
)
{
case
0
:
action_func
=
sepol_allow
;
break
;
case
1
:
action_func
=
sepol_deny
;
break
;
case
2
:
action_func
=
sepol_auditallow
;
break
;
case
3
:
action_func
=
sepol_dontaudit
;
break
;
default:
return
1
;
}
int
state
=
0
;
char
*
cur
,
*
cls
;
vector
<
const
char
*>
source
,
target
,
permission
;
while
((
cur
=
strtok_r
(
nullptr
,
" "
,
&
stmt
))
!=
nullptr
)
{
if
(
cur
[
0
]
==
'*'
)
cur
=
ALL
;
vector
<
const
char
*>
*
vec
;
switch
(
state
)
{
case
0
:
vec
=
&
source
;
break
;
case
1
:
vec
=
&
target
;
break
;
case
2
:
vec
=
nullptr
;
cls
=
cur
;
break
;
case
3
:
vec
=
&
permission
;
break
;
default:
return
1
;
}
}
arr
.
push_back
(
std
::
move
(
token
));
if
(
vec
&&
parse_bracket
(
cur
,
stmt
,
*
vec
))
return
1
;
++
state
;
}
}
if
(
state
!=
4
||
source
.
empty
()
||
target
.
empty
()
||
permission
.
empty
())
return
true
;
return
1
;
}
for
(
auto
src
:
source
)
for
(
auto
tgt
:
target
)
for
(
auto
perm
:
permission
)
if
(
action_func
(
src
,
tgt
,
cls
,
perm
))
LOGW
(
"Error in: %s %s %s %s %s
\n
"
,
action_str
,
src
,
tgt
,
cls
,
perm
);
return
0
;
// Pattern 1: action { source } { target } { class } { permission }
template
<
typename
Func
>
static
bool
parse_pattern_1
(
Func
fn
,
const
char
*
action
,
char
*
stmt
)
{
vector
<
vector
<
char
*>>
arr
;
if
(
!
tokenize_string
(
stmt
,
arr
))
return
false
;
if
(
arr
.
size
()
!=
4
)
return
false
;
for
(
char
*
src
:
arr
[
0
])
for
(
char
*
tgt
:
arr
[
1
])
for
(
char
*
cls
:
arr
[
2
])
for
(
char
*
perm
:
arr
[
3
])
if
(
fn
(
src
,
tgt
,
cls
,
perm
))
LOGW
(
"Error in: %s %s %s %s %s
\n
"
,
action
,
src
,
tgt
,
cls
,
perm
);
return
true
;
}
}
// Pattern 2: action { source } { target } { class } ioctl range
// Pattern 2: action { source } { target } { class } ioctl range
static
int
parse_pattern_2
(
int
action
,
const
char
*
action_str
,
char
*
stmt
)
{
template
<
typename
Func
>
int
(
*
action_func
)(
const
char
*
,
const
char
*
,
const
char
*
,
const
char
*
);
static
bool
parse_pattern_2
(
Func
fn
,
const
char
*
action
,
char
*
stmt
)
{
switch
(
action
)
{
vector
<
vector
<
char
*>>
arr
;
case
0
:
if
(
!
tokenize_string
(
stmt
,
arr
))
action_func
=
sepol_allowxperm
;
return
false
;
break
;
if
(
arr
.
size
()
!=
5
||
arr
[
3
].
size
()
!=
1
||
arr
[
3
][
0
]
!=
"ioctl"
sv
||
arr
[
4
].
size
()
!=
1
)
case
1
:
return
false
;
action_func
=
sepol_auditallowxperm
;
char
*
range
=
arr
[
4
][
0
];
break
;
for
(
char
*
src
:
arr
[
0
])
case
2
:
for
(
char
*
tgt
:
arr
[
1
])
action_func
=
sepol_dontauditxperm
;
for
(
char
*
cls
:
arr
[
2
])
break
;
if
(
fn
(
src
,
tgt
,
cls
,
range
))
default:
LOGW
(
"Error in: %s %s %s %s ioctl %s
\n
"
,
action
,
src
,
tgt
,
cls
,
range
);
return
1
;
return
true
;
}
int
state
=
0
;
char
*
cur
,
*
range
;
vector
<
const
char
*>
source
,
target
,
classes
;
while
((
cur
=
strtok_r
(
nullptr
,
" "
,
&
stmt
))
!=
nullptr
)
{
if
(
cur
[
0
]
==
'*'
)
cur
=
ALL
;
vector
<
const
char
*>
*
vec
;
switch
(
state
)
{
case
0
:
vec
=
&
source
;
break
;
case
1
:
vec
=
&
target
;
break
;
case
2
:
vec
=
&
classes
;
break
;
case
3
:
// Currently only support ioctl
if
(
strcmp
(
cur
,
"ioctl"
)
!=
0
)
return
1
;
vec
=
nullptr
;
break
;
case
4
:
vec
=
nullptr
;
range
=
cur
;
break
;
default:
return
1
;
}
if
(
vec
&&
parse_bracket
(
cur
,
stmt
,
*
vec
))
return
1
;
++
state
;
}
if
(
state
!=
5
||
source
.
empty
()
||
target
.
empty
()
||
classes
.
empty
())
return
1
;
for
(
auto
src
:
source
)
for
(
auto
tgt
:
target
)
for
(
auto
cls
:
classes
)
if
(
action_func
(
src
,
tgt
,
cls
,
range
))
LOGW
(
"Error in: %s %s %s %s %s
\n
"
,
action_str
,
src
,
tgt
,
cls
,
range
);
return
0
;
}
}
// Pattern 3: action { type }
// Pattern 3: action { type }
static
int
parse_pattern_3
(
int
action
,
const
char
*
action_str
,
char
*
stmt
)
{
template
<
typename
Func
>
int
(
*
action_func
)(
const
char
*
);
static
bool
parse_pattern_3
(
Func
fn
,
const
char
*
action
,
char
*
stmt
)
{
switch
(
action
)
{
vector
<
vector
<
char
*>>
arr
;
case
0
:
if
(
!
tokenize_string
(
stmt
,
arr
))
action_func
=
sepol_create
;
return
false
;
break
;
if
(
arr
.
size
()
!=
1
)
case
1
:
return
false
;
action_func
=
sepol_permissive
;
for
(
char
*
type
:
arr
[
0
])
break
;
if
(
fn
(
type
))
case
2
:
LOGW
(
"Error in: %s %s
\n
"
,
action
,
type
);
action_func
=
sepol_enforce
;
return
true
;
break
;
default:
return
1
;
}
char
*
cur
;
vector
<
const
char
*>
domains
;
while
((
cur
=
strtok_r
(
nullptr
,
" {}"
,
&
stmt
))
!=
nullptr
)
{
if
(
cur
[
0
]
==
'*'
)
cur
=
ALL
;
domains
.
push_back
(
cur
);
}
if
(
domains
.
empty
())
return
1
;
for
(
auto
dom
:
domains
)
if
(
action_func
(
dom
))
LOGW
(
"Error in: %s %s
\n
"
,
action_str
,
dom
);
return
0
;
}
}
// Pattern 4: action { class } { attribute }
// Pattern 4: action { type } { attribute }
static
int
parse_pattern_4
(
int
action
,
const
char
*
action_str
,
char
*
stmt
)
{
template
<
typename
Func
>
int
(
*
action_func
)(
const
char
*
,
const
char
*
);
static
bool
parse_pattern_4
(
Func
fn
,
const
char
*
action
,
char
*
stmt
)
{
switch
(
action
)
{
vector
<
vector
<
char
*>>
arr
;
case
0
:
if
(
!
tokenize_string
(
stmt
,
arr
))
action_func
=
sepol_attradd
;
return
false
;
break
;
if
(
arr
.
size
()
!=
2
)
default:
return
false
;
return
1
;
for
(
char
*
type
:
arr
[
0
])
}
for
(
char
*
attr
:
arr
[
1
])
if
(
fn
(
type
,
attr
))
int
state
=
0
;
LOGW
(
"Error in: %s %s %s
\n
"
,
action
,
type
,
attr
);
char
*
cur
;
return
true
;
vector
<
const
char
*>
classes
,
attribute
;
while
((
cur
=
strtok_r
(
nullptr
,
" "
,
&
stmt
))
!=
nullptr
)
{
if
(
cur
[
0
]
==
'*'
)
cur
=
ALL
;
vector
<
const
char
*>
*
vec
;
switch
(
state
)
{
case
0
:
vec
=
&
classes
;
break
;
case
1
:
vec
=
&
attribute
;
break
;
default:
return
1
;
}
if
(
parse_bracket
(
cur
,
stmt
,
*
vec
))
return
1
;
++
state
;
}
if
(
state
!=
2
||
classes
.
empty
()
||
attribute
.
empty
())
return
1
;
for
(
auto
cls
:
classes
)
for
(
auto
attr
:
attribute
)
if
(
action_func
(
cls
,
attr
))
LOGW
(
"Error in: %s %s %s
\n
"
,
action_str
,
cls
,
attr
);
return
0
;
}
}
// Pattern 5: action source target class default
// Pattern 5: action source target class default
static
int
parse_pattern_5
(
int
action
,
const
char
*
action_str
,
char
*
stmt
)
{
template
<
typename
Func
>
int
(
*
action_func
)(
const
char
*
,
const
char
*
,
const
char
*
,
const
char
*
);
static
bool
parse_pattern_5
(
Func
fn
,
const
char
*
action
,
char
*
stmt
)
{
switch
(
action
)
{
vector
<
vector
<
char
*>>
arr
;
case
0
:
if
(
!
tokenize_string
(
stmt
,
arr
))
action_func
=
sepol_typetrans
;
return
false
;
break
;
if
(
arr
.
size
()
!=
4
||
case
1
:
arr
[
0
].
size
()
!=
1
||
arr
[
1
].
size
()
!=
1
||
arr
[
2
].
size
()
!=
1
||
arr
[
3
].
size
()
!=
1
)
action_func
=
sepol_typechange
;
return
false
;
break
;
if
(
fn
(
arr
[
0
][
0
],
arr
[
1
][
0
],
arr
[
2
][
0
],
arr
[
3
][
0
]))
case
2
:
LOGW
(
"Error in: %s %s %s %s %s
\n
"
,
action
,
arr
[
0
][
0
],
arr
[
1
][
0
],
arr
[
2
][
0
],
arr
[
3
][
0
]);
action_func
=
sepol_typemember
;
return
true
;
break
;
default:
return
1
;
}
int
state
=
0
;
char
*
cur
;
char
*
source
,
*
target
,
*
cls
,
*
def
;
while
((
cur
=
strtok_r
(
nullptr
,
" "
,
&
stmt
))
!=
nullptr
)
{
switch
(
state
)
{
case
0
:
source
=
cur
;
break
;
case
1
:
target
=
cur
;
break
;
case
2
:
cls
=
cur
;
break
;
case
3
:
def
=
cur
;
break
;
default:
return
1
;
}
++
state
;
}
if
(
state
<
4
)
return
1
;
if
(
action_func
(
source
,
target
,
cls
,
def
))
LOGW
(
"Error in: %s %s %s %s %s
\n
"
,
action_str
,
source
,
target
,
cls
,
def
);
return
0
;
}
}
// Pattern 6: action source target class default filename
// Pattern 6: action source target class default (filename)
static
int
parse_pattern_6
(
int
action
,
const
char
*
action_str
,
char
*
stmt
)
{
template
<
typename
Func
>
int
state
=
0
;
static
bool
parse_pattern_6
(
Func
fn
,
const
char
*
action
,
char
*
stmt
)
{
char
*
cur
;
vector
<
vector
<
char
*>>
arr
;
char
*
source
,
*
target
,
*
cls
,
*
def
,
*
filename
;
if
(
!
tokenize_string
(
stmt
,
arr
))
while
((
cur
=
strtok_r
(
nullptr
,
" "
,
&
stmt
))
!=
nullptr
)
{
return
false
;
switch
(
state
)
{
if
(
arr
.
size
()
==
4
)
case
0
:
arr
.
emplace_back
(
initializer_list
<
char
*>
{
nullptr
});
source
=
cur
;
if
(
arr
.
size
()
!=
5
||
break
;
arr
[
0
].
size
()
!=
1
||
arr
[
1
].
size
()
!=
1
||
arr
[
2
].
size
()
!=
1
||
case
1
:
arr
[
3
].
size
()
!=
1
||
arr
[
4
].
size
()
!=
1
)
target
=
cur
;
return
false
;
break
;
if
(
fn
(
arr
[
0
][
0
],
arr
[
1
][
0
],
arr
[
2
][
0
],
arr
[
3
][
0
],
arr
[
4
][
0
]))
case
2
:
LOGW
(
"Error in: %s %s %s %s %s %s
\n
"
,
action
,
cls
=
cur
;
arr
[
0
][
0
],
arr
[
1
][
0
],
arr
[
2
][
0
],
arr
[
3
][
0
],
arr
[
4
][
0
]
?
arr
[
4
][
0
]
:
""
);
break
;
return
true
;
case
3
:
def
=
cur
;
break
;
case
4
:
filename
=
cur
;
break
;
default:
return
1
;
}
++
state
;
}
if
(
state
<
5
)
return
1
;
if
(
sepol_nametrans
(
source
,
target
,
cls
,
def
,
filename
))
LOGW
(
"Error in: %s %s %s %s %s %s
\n
"
,
action_str
,
source
,
target
,
cls
,
def
,
filename
);
return
0
;
}
}
// Pattern 7: action name path context
// Pattern 7: action name path context
static
int
parse_pattern_7
(
int
action
,
const
char
*
action_str
,
char
*
stmt
)
{
template
<
typename
Func
>
int
state
=
0
;
static
bool
parse_pattern_7
(
Func
fn
,
const
char
*
action
,
char
*
stmt
)
{
char
*
cur
;
vector
<
vector
<
char
*>>
arr
;
char
*
name
,
*
path
,
*
context
;
if
(
!
tokenize_string
(
stmt
,
arr
))
while
((
cur
=
strtok_r
(
nullptr
,
" "
,
&
stmt
))
!=
nullptr
)
{
return
false
;
switch
(
state
)
{
if
(
arr
.
size
()
!=
3
||
arr
[
0
].
size
()
!=
1
||
arr
[
1
].
size
()
!=
1
||
arr
[
2
].
size
()
!=
1
)
case
0
:
return
false
;
name
=
cur
;
if
(
fn
(
arr
[
0
][
0
],
arr
[
1
][
0
],
arr
[
2
][
0
]))
break
;
LOGW
(
"Error in: %s %s %s %s
\n
"
,
action
,
arr
[
0
][
0
],
arr
[
1
][
0
],
arr
[
2
][
0
]);
case
1
:
return
true
;
path
=
cur
;
break
;
case
2
:
context
=
cur
;
break
;
default:
return
1
;
}
++
state
;
}
if
(
state
<
3
)
return
1
;
if
(
sepol_genfscon
(
name
,
path
,
context
))
LOGW
(
"Error in: %s %s %s %s
\n
"
,
action_str
,
name
,
path
,
context
);
return
0
;
}
}
#define add_action
(name, type, num
) \
#define add_action
_func(name, type, fn
) \
else if (strcmp(name, action) == 0) { \
else if (strcmp(name, action) == 0) { \
if (parse_pattern_##type(num, name, remain)) \
auto __fn = [=](auto && ...args){ return (fn)(args...); };\
LOGW("Syntax error in '%s'\n\n%s\n", statement, type_msg_##type); \
if (!parse_pattern_##type(__fn, name, remain)) \
LOGW("Syntax error in '%s'\n\n%s\n", stmt, type_msg_##type); \
}
}
void
parse_statement
(
const
char
*
statement
)
{
#define add_action(act, type) add_action_func(#act, type, act)
char
*
action
,
*
remain
;
// strtok will modify strings, duplicate the statement
string
stmt
(
statement
);
action
=
strtok_r
(
stmt
.
data
(),
" "
,
&
remain
);
void
sepolicy
::
parse_statement
(
const
char
*
stmt
)
{
// strtok modify strings, create a copy
string
cpy
(
stmt
);
char
*
remain
;
char
*
action
=
strtok_r
(
cpy
.
data
(),
" "
,
&
remain
);
if
(
remain
==
nullptr
)
{
if
(
remain
==
nullptr
)
{
LOG
E
(
"Syntax error in '%s'
\n\n
"
,
statemen
t
);
LOG
W
(
"Syntax error in '%s'
\n\n
"
,
stm
t
);
return
;
return
;
}
}
if
(
0
)
{}
if
(
0
)
{}
add_action
(
"allow"
,
1
,
0
)
add_action
(
allow
,
1
)
add_action
(
"deny"
,
1
,
1
)
add_action
(
deny
,
1
)
add_action
(
"auditallow"
,
1
,
2
)
add_action
(
auditallow
,
1
)
add_action
(
"dontaudit"
,
1
,
3
)
add_action
(
dontaudit
,
1
)
add_action
(
"allowxperm"
,
2
,
0
)
add_action
(
allowxperm
,
2
)
add_action
(
"auditallowxperm"
,
2
,
1
)
add_action
(
auditallowxperm
,
2
)
add_action
(
"dontauditxperm"
,
2
,
2
)
add_action
(
dontauditxperm
,
2
)
add_action
(
"create"
,
3
,
0
)
add_action
(
create
,
3
)
add_action
(
"permissive"
,
3
,
1
)
add_action
(
permissive
,
3
)
add_action
(
"enforce"
,
3
,
2
)
add_action
(
enforce
,
3
)
add_action
(
"attradd"
,
4
,
0
)
add_action
(
typeattribute
,
4
)
add_action
(
"type_transition"
,
5
,
0
)
add_action
(
type_change
,
5
)
add_action
(
"type_change"
,
5
,
1
)
add_action
(
type_member
,
5
)
add_action
(
"type_member"
,
5
,
2
)
add_action
(
type_transition
,
6
)
add_action
(
"name_transition"
,
6
,
0
)
add_action
(
genfscon
,
7
)
add_action
(
"genfscon"
,
7
,
0
)
else
{
LOGW
(
"Unknown statement: '%s'
\n\n
"
,
statement
);
}
// Backwards compatible syntax
add_action_func
(
"attradd"
,
4
,
typeattribute
)
add_action_func
(
"name_transition"
,
6
,
type_transition
)
else
{
LOGW
(
"Syntax error in '%s'
\n\n
"
,
stmt
);
}
}
}
void
load_rule_file
(
const
char
*
file
)
{
void
sepolicy
::
load_rule_file
(
const
char
*
file
)
{
file_readline
(
true
,
file
,
[](
string_view
line
)
->
bool
{
file_readline
(
true
,
file
,
[
=
](
string_view
line
)
->
bool
{
if
(
line
.
empty
()
||
line
[
0
]
==
'#'
)
if
(
line
.
empty
()
||
line
[
0
]
==
'#'
)
return
true
;
return
true
;
parse_statement
(
line
.
data
());
parse_statement
(
line
.
data
());
...
...
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