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
6900c197
Commit
6900c197
authored
Jan 31, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Project restructure
parent
7dea6827
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
526 additions
and
489 deletions
+526
-489
Android.mk
Android.mk
+1
-1
main.c
main.c
+247
-0
rules.c
rules.c
+26
-63
sepolicy-inject.h
sepolicy-inject.h
+50
-0
sepolicy.c
sepolicy.c
+154
-425
utils.c
utils.c
+48
-0
No files found.
Android.mk
View file @
6900c197
...
...
@@ -4,7 +4,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE := sepolicy-inject
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_LIBRARIES := libsepol
LOCAL_SRC_FILES :=
sepolicy-inject.c builtin_rule
s.c
LOCAL_SRC_FILES :=
main.c sepolicy.c rules.c util
s.c
LOCAL_C_INCLUDES := jni/selinux/libsepol/include/
LOCAL_CFLAGS += -std=gnu11
include $(BUILD_EXECUTABLE)
main.c
0 → 100644
View file @
6900c197
#include "sepolicy-inject.h"
static
void
usage
(
char
*
arg0
)
{
fprintf
(
stderr
,
"%s -s <source type> -t <target type> -c <class> -p <perm_list> -P <policy file>
\n
"
,
arg0
);
fprintf
(
stderr
,
"
\t
Inject a rule
\n\n
"
);
fprintf
(
stderr
,
"%s -s <source type> -a <type_attribute> -P <policy file>
\n
"
,
arg0
);
fprintf
(
stderr
,
"
\t
Add a type_attribute to a domain
\n\n
"
);
fprintf
(
stderr
,
"%s -Z <source type> -P <policy file>
\n
"
,
arg0
);
fprintf
(
stderr
,
"
\t
Inject a permissive domain
\n\n
"
);
fprintf
(
stderr
,
"%s -z <source type> -P <policy file>
\n
"
,
arg0
);
fprintf
(
stderr
,
"
\t
Inject a non-permissive domain
\n\n
"
);
fprintf
(
stderr
,
"%s -e -s <source type> -P <policy file>
\n
"
,
arg0
);
fprintf
(
stderr
,
"
\t
Check if a SELinux type exists
\n\n
"
);
fprintf
(
stderr
,
"%s -e -c <class> -P <policy file>
\n
"
,
arg0
);
fprintf
(
stderr
,
"
\t
Check if a SELinux class exists
\n\n
"
);
fprintf
(
stderr
,
"All options can add -o <output file> to output to another file
\n
"
);
exit
(
1
);
}
int
main
(
int
argc
,
char
**
argv
)
{
char
*
infile
=
NULL
,
*
source
=
NULL
,
*
target
=
NULL
,
*
class
=
NULL
,
*
perm
=
NULL
;
char
*
fcon
=
NULL
,
*
outfile
=
NULL
,
*
permissive
=
NULL
,
*
attr
=
NULL
,
*
filetrans
=
NULL
;
int
exists
=
0
,
not
=
0
,
live
=
0
,
builtin
=
0
,
magisk
=
0
;
policydb_t
policydb
;
struct
policy_file
pf
,
outpf
;
sidtab_t
sidtab
;
int
ch
;
FILE
*
fp
;
int
permissive_value
=
0
,
noaudit
=
0
;
struct
option
long_options
[]
=
{
{
"attr"
,
required_argument
,
NULL
,
'a'
},
{
"exists"
,
no_argument
,
NULL
,
'e'
},
{
"source"
,
required_argument
,
NULL
,
's'
},
{
"target"
,
required_argument
,
NULL
,
't'
},
{
"class"
,
required_argument
,
NULL
,
'c'
},
{
"perm"
,
required_argument
,
NULL
,
'p'
},
{
"fcon"
,
required_argument
,
NULL
,
'f'
},
{
"filetransition"
,
required_argument
,
NULL
,
'g'
},
{
"noaudit"
,
no_argument
,
NULL
,
'n'
},
{
"file"
,
required_argument
,
NULL
,
'P'
},
{
"output"
,
required_argument
,
NULL
,
'o'
},
{
"permissive"
,
required_argument
,
NULL
,
'Z'
},
{
"not-permissive"
,
required_argument
,
NULL
,
'z'
},
{
"not"
,
no_argument
,
NULL
,
0
},
{
"live"
,
no_argument
,
NULL
,
0
},
{
"magisk"
,
no_argument
,
NULL
,
0
},
{
NULL
,
0
,
NULL
,
0
}
};
int
option_index
=
-
1
;
while
((
ch
=
getopt_long
(
argc
,
argv
,
"a:c:ef:g:s:t:p:P:o:Z:z:n"
,
long_options
,
&
option_index
))
!=
-
1
)
{
switch
(
ch
)
{
case
0
:
if
(
strcmp
(
long_options
[
option_index
].
name
,
"not"
)
==
0
)
not
=
1
;
else
if
(
strcmp
(
long_options
[
option_index
].
name
,
"live"
)
==
0
)
live
=
1
;
else
if
(
strcmp
(
long_options
[
option_index
].
name
,
"magisk"
)
==
0
)
magisk
=
1
;
else
usage
(
argv
[
0
]);
break
;
case
'a'
:
attr
=
optarg
;
break
;
case
'e'
:
exists
=
1
;
break
;
case
'f'
:
fcon
=
optarg
;
break
;
case
'g'
:
filetrans
=
optarg
;
break
;
case
's'
:
source
=
optarg
;
break
;
case
't'
:
target
=
optarg
;
break
;
case
'c'
:
class
=
optarg
;
break
;
case
'p'
:
perm
=
optarg
;
break
;
case
'P'
:
infile
=
optarg
;
break
;
case
'o'
:
outfile
=
optarg
;
break
;
case
'Z'
:
permissive
=
optarg
;
permissive_value
=
1
;
break
;
case
'z'
:
permissive
=
optarg
;
permissive_value
=
0
;
break
;
case
'n'
:
noaudit
=
1
;
break
;
default:
usage
(
argv
[
0
]);
}
}
// Use builtin rules if nothing specified
if
(
!
magisk
&&
!
source
&&
!
target
&&
!
class
&&
!
perm
&&
!
permissive
&&
!
fcon
&&
!
attr
&&!
filetrans
&&
!
exists
)
builtin
=
1
;
// Overwrite original if not specified
if
(
!
outfile
)
outfile
=
infile
;
// Use current policy if not specified
if
(
!
infile
)
infile
=
"/sys/fs/selinux/policy"
;
sepol_set_policydb
(
&
policydb
);
sepol_set_sidtab
(
&
sidtab
);
if
(
load_policy
(
infile
,
&
policydb
,
&
pf
))
{
fprintf
(
stderr
,
"Could not load policy
\n
"
);
return
1
;
}
if
(
policydb_load_isids
(
&
policydb
,
&
sidtab
))
return
1
;
policy
=
&
policydb
;
if
(
builtin
)
{
su_rules
();
}
else
if
(
magisk
)
{
magisk_rules
();
}
else
if
(
permissive
)
{
type_datum_t
*
type
;
create_domain
(
permissive
);
type
=
hashtab_search
(
policydb
.
p_types
.
table
,
permissive
);
if
(
type
==
NULL
)
{
fprintf
(
stderr
,
"type %s does not exist
\n
"
,
permissive
);
return
1
;
}
if
(
ebitmap_set_bit
(
&
policydb
.
permissive_map
,
type
->
s
.
value
,
permissive_value
))
{
fprintf
(
stderr
,
"Could not set bit in permissive map
\n
"
);
return
1
;
}
}
else
if
(
exists
)
{
if
(
source
)
{
type_datum_t
*
tmp
=
hashtab_search
(
policydb
.
p_types
.
table
,
source
);
if
(
!
tmp
)
exit
(
1
);
else
exit
(
0
);
}
else
if
(
class
)
{
class_datum_t
*
tmp
=
hashtab_search
(
policydb
.
p_classes
.
table
,
class
);
if
(
!
tmp
)
exit
(
1
);
else
exit
(
0
);
}
else
{
usage
(
argv
[
0
]);
}
}
else
if
(
filetrans
)
{
if
(
add_file_transition
(
source
,
fcon
,
target
,
class
,
filetrans
))
return
1
;
}
else
if
(
fcon
)
{
if
(
add_transition
(
source
,
fcon
,
target
,
class
))
return
1
;
}
else
if
(
attr
)
{
if
(
add_type
(
source
,
attr
))
return
1
;
}
else
if
(
noaudit
)
{
if
(
add_rule
(
source
,
target
,
class
,
perm
,
AVTAB_AUDITDENY
,
not
))
return
1
;
}
else
{
//Add a rule to a whole set of typeattribute, not just a type
if
(
target
!=
NULL
)
{
if
(
*
target
==
'='
)
{
char
*
saveptr
=
NULL
;
char
*
targetAttribute
=
strtok_r
(
target
,
"-"
,
&
saveptr
);
char
*
vals
[
64
];
int
i
=
0
;
char
*
m
=
NULL
;
while
(
(
m
=
strtok_r
(
NULL
,
"-"
,
&
saveptr
))
!=
NULL
)
{
vals
[
i
++
]
=
m
;
}
vals
[
i
]
=
NULL
;
if
(
add_typerule
(
source
,
targetAttribute
+
1
,
vals
,
class
,
perm
,
AVTAB_ALLOWED
,
not
))
return
1
;
}
}
if
(
perm
!=
NULL
)
{
char
*
saveptr
=
NULL
;
char
*
p
=
strtok_r
(
perm
,
","
,
&
saveptr
);
do
{
if
(
add_rule
(
source
,
target
,
class
,
p
,
AVTAB_ALLOWED
,
not
))
{
fprintf
(
stderr
,
"Could not add rule
\n
"
);
return
1
;
}
}
while
(
(
p
=
strtok_r
(
NULL
,
","
,
&
saveptr
))
!=
NULL
);
}
else
{
if
(
add_rule
(
source
,
target
,
class
,
perm
,
AVTAB_ALLOWED
,
not
))
{
fprintf
(
stderr
,
"Could not add rule
\n
"
);
return
1
;
}
}
}
if
(
live
)
{
if
(
live_patch
())
{
fprintf
(
stderr
,
"Could not load new policy into kernel
\n
"
);
return
1
;
}
}
if
(
outfile
)
{
fp
=
fopen
(
outfile
,
"w"
);
if
(
!
fp
)
{
fprintf
(
stderr
,
"Could not open outfile
\n
"
);
return
1
;
}
policy_file_init
(
&
outpf
);
outpf
.
type
=
PF_USE_STDIO
;
outpf
.
fp
=
fp
;
if
(
policydb_write
(
&
policydb
,
&
outpf
))
{
fprintf
(
stderr
,
"Could not write policy
\n
"
);
return
1
;
}
fclose
(
fp
);
}
policydb_destroy
(
&
policydb
);
return
0
;
}
builtin_
rules.c
→
rules.c
View file @
6900c197
#include <stdio.h>
#include <sepol/policydb/policydb.h>
#define ALL NULL
extern
int
add_rule
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
,
int
effect
,
int
not
,
policydb_t
*
policy
);
extern
void
create_domain
(
char
*
d
,
policydb_t
*
policy
);
extern
int
add_transition
(
char
*
srcS
,
char
*
origS
,
char
*
tgtS
,
char
*
c
,
policydb_t
*
policy
);
extern
int
add_type
(
char
*
domainS
,
char
*
typeS
,
policydb_t
*
policy
);
policydb_t
*
policy
;
void
allow
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
)
{
add_rule
(
s
,
t
,
c
,
p
,
AVTAB_ALLOWED
,
0
,
policy
);
}
void
noaudit
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
)
{
add_rule
(
s
,
t
,
c
,
p
,
AVTAB_AUDITDENY
,
0
,
policy
);
}
void
deny
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
)
{
add_rule
(
s
,
t
,
c
,
p
,
AVTAB_ALLOWED
,
1
,
policy
);
}
void
setPermissive
(
char
*
permissive
,
int
permissive_value
)
{
type_datum_t
*
type
;
create_domain
(
permissive
,
policy
);
type
=
hashtab_search
(
policy
->
p_types
.
table
,
permissive
);
if
(
type
==
NULL
)
{
fprintf
(
stderr
,
"type %s does not exist
\n
"
,
permissive
);
return
;
}
if
(
ebitmap_set_bit
(
&
policy
->
permissive_map
,
type
->
s
.
value
,
permissive_value
))
{
fprintf
(
stderr
,
"Could not set bit in permissive map
\n
"
);
return
;
}
}
int
exists
(
char
*
source
)
{
return
(
int
)
hashtab_search
(
policy
->
p_types
.
table
,
source
);
}
#include "sepolicy-inject.h"
void
samsung
()
{
deny
(
"init"
,
"kernel"
,
"security"
,
"load_policy"
);
...
...
@@ -222,6 +182,12 @@ void suDaemonRights() {
allow
(
"su_daemon"
,
"proc"
,
"file"
,
"open"
);
allow
(
"su_daemon"
,
"su_daemon"
,
"process"
,
"setcurrent"
);
allow
(
"su_daemon"
,
"system_file"
,
"file"
,
"execute_no_trans"
);
// Allow to adb shell su
allow
(
"su_daemon"
,
"adbd"
,
"fd"
,
"use"
);
allow
(
"su_daemon"
,
"adbd"
,
"unix_stream_socket"
,
"read"
);
allow
(
"su_daemon"
,
"adbd"
,
"unix_stream_socket"
,
"write"
);
allow
(
"su_daemon"
,
"adbd"
,
"unix_stream_socket"
,
"ioctl"
);
}
void
suBind
()
{
...
...
@@ -274,36 +240,34 @@ void otherToSU() {
allow
(
ALL
,
"su"
,
"process"
,
"sigchld"
);
// uNetworkL0
add_type
(
"su"
,
"netdomain"
,
policy
);
add_type
(
"su"
,
"bluetoothdomain"
,
policy
);
add_type
(
"su"
,
"netdomain"
);
add_type
(
"su"
,
"bluetoothdomain"
);
// suBackL6
allow
(
"surfaceflinger"
,
"app_data_file"
,
"dir"
,
ALL
);
allow
(
"surfaceflinger"
,
"app_data_file"
,
"file"
,
ALL
);
allow
(
"surfaceflinger"
,
"app_data_file"
,
"lnk_file"
,
ALL
);
add_type
(
"surfaceflinger"
,
"mlstrustedsubject"
,
policy
);
add_type
(
"surfaceflinger"
,
"mlstrustedsubject"
);
// suMiscL6
if
(
exists
(
"audioserver"
))
allow
(
"audioserver"
,
"audioserver"
,
"process"
,
"execmem"
);
}
void
phh_rules
(
policydb_t
*
policydb
)
{
policy
=
policydb
;
void
su_rules
()
{
// Samsung specific
// Prevent system from loading policy
if
(
exists
(
"knox_system_app"
))
samsung
();
// Create domains if they don't exist
setPermissive
(
"su"
,
1
);
setPermissive
(
"su_device"
,
0
);
setPermissive
(
"su_daemon"
,
0
);
permissive
(
"su"
);
enforce
(
"su_device"
);
enforce
(
"su_daemon"
);
// Autotransition su's socket to su_device
add_transition
(
"su_daemon"
,
"device"
,
"su_device"
,
"file"
,
policy
);
add_transition
(
"su_daemon"
,
"device"
,
"su_device"
,
"dir"
,
policy
);
add_transition
(
"su_daemon"
,
"device"
,
"su_device"
,
"file"
);
add_transition
(
"su_daemon"
,
"device"
,
"su_device"
,
"dir"
);
allow
(
"su_device"
,
"tmpfs"
,
"filesystem"
,
"associate"
);
// Transition from untrusted_app to su_client
...
...
@@ -329,22 +293,21 @@ void phh_rules(policydb_t *policydb) {
otherToSU
();
// Need to set su_device/su as trusted to be accessible from other categories
a
dd_type
(
"su_device"
,
"mlstrustedobject"
,
policy
);
a
dd_type
(
"su_daemon"
,
"mlstrustedsubject"
,
policy
);
a
dd_type
(
"su"
,
"mlstrustedsubject"
,
policy
);
a
ttradd
(
"su_device"
,
"mlstrustedobject"
);
a
ttradd
(
"su_daemon"
,
"mlstrustedsubject"
);
a
ttradd
(
"su"
,
"mlstrustedsubject"
);
// Allow chcon to
rootfs
allow
(
"rootfs"
,
"labeledfs"
,
"filesystem"
,
"associate"
);
// Allow chcon to
anything
allow
(
ALL
,
"labeledfs"
,
"filesystem"
,
"associate"
);
}
// Minimal to run Magisk script before live patching
void
magisk_rules
(
policydb_t
*
policydb
)
{
policy
=
policydb
;
void
magisk_rules
()
{
setPermissive
(
"su"
,
1
);
setPermissive
(
"init"
,
1
);
permissive
(
"su"
);
permissive
(
"init"
);
a
dd_type
(
"su"
,
"mlstrustedsubject"
,
policy
);
a
ttradd
(
"su"
,
"mlstrustedsubject"
);
allow
(
"kernel"
,
"su"
,
"fd"
,
"use"
);
allow
(
"init"
,
"su"
,
"process"
,
ALL
);
...
...
@@ -427,4 +390,4 @@ void magisk_rules(policydb_t *policydb) {
allow
(
"init"
,
"su"
,
"fd"
,
"use"
);
allow
(
"init"
,
"kernel"
,
"security"
,
"read_policy"
);
allow
(
"init"
,
"kernel"
,
"security"
,
"load_policy"
);
}
\ No newline at end of file
}
sepolicy-inject.h
0 → 100644
View file @
6900c197
#ifndef SEPOLICY_INJECT_H
#define SEPOLICY_INJECT_H
#define ALL NULL
#include <getopt.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sepol/debug.h>
#include <sepol/policydb/policydb.h>
#include <sepol/policydb/expand.h>
#include <sepol/policydb/link.h>
#include <sepol/policydb/services.h>
#include <sepol/policydb/avrule_block.h>
#include <sepol/policydb/conditional.h>
#include <sepol/policydb/constraint.h>
// Global policydb
policydb_t
*
policy
;
// sepolicy manipulation functions
int
load_policy
(
char
*
filename
,
policydb_t
*
policydb
,
struct
policy_file
*
pf
);
void
create_domain
(
char
*
d
);
int
add_file_transition
(
char
*
srcS
,
char
*
origS
,
char
*
tgtS
,
char
*
c
,
char
*
filename
);
int
add_transition
(
char
*
srcS
,
char
*
origS
,
char
*
tgtS
,
char
*
c
);
int
add_type
(
char
*
domainS
,
char
*
typeS
);
int
add_rule
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
,
int
effect
,
int
not
);
int
add_typerule
(
char
*
s
,
char
*
targetAttribute
,
char
**
minusses
,
char
*
c
,
char
*
p
,
int
effect
,
int
not
);
int
live_patch
();
// Handy functions
void
allow
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
);
void
deny
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
);
void
auditallow
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
);
void
auditdeny
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
);
void
permissive
(
char
*
s
);
void
enforce
(
char
*
s
);
void
attradd
(
char
*
s
,
char
*
a
);
int
exists
(
char
*
source
);
// Built in rules
void
su_rules
();
void
magisk_rules
();
#endif
sepolicy
-inject
.c
→
sepolicy.c
View file @
6900c197
This diff is collapsed.
Click to expand it.
utils.c
0 → 100644
View file @
6900c197
#include "sepolicy-inject.h"
static
void
set_domain
(
char
*
s
,
int
value
)
{
type_datum_t
*
type
;
if
(
!
exists
(
s
))
create_domain
(
s
);
type
=
hashtab_search
(
policy
->
p_types
.
table
,
s
);
if
(
type
==
NULL
)
{
fprintf
(
stderr
,
"type %s does not exist
\n
"
,
s
);
return
;
}
if
(
ebitmap_set_bit
(
&
policy
->
permissive_map
,
type
->
s
.
value
,
value
))
{
fprintf
(
stderr
,
"Could not set bit in permissive map
\n
"
);
return
;
}
}
void
allow
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
)
{
add_rule
(
s
,
t
,
c
,
p
,
AVTAB_ALLOWED
,
0
);
}
void
deny
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
)
{
add_rule
(
s
,
t
,
c
,
p
,
AVTAB_ALLOWED
,
1
);
}
void
auditallow
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
)
{
add_rule
(
s
,
t
,
c
,
p
,
AVTAB_AUDITALLOW
,
0
);
}
void
auditdeny
(
char
*
s
,
char
*
t
,
char
*
c
,
char
*
p
)
{
add_rule
(
s
,
t
,
c
,
p
,
AVTAB_AUDITDENY
,
0
);
}
void
permissive
(
char
*
s
)
{
set_domain
(
s
,
1
);
}
void
enforce
(
char
*
s
)
{
set_domain
(
s
,
0
);
}
void
attradd
(
char
*
s
,
char
*
a
)
{
add_type
(
s
,
a
);
}
int
exists
(
char
*
source
)
{
return
!!
hashtab_search
(
policy
->
p_types
.
table
,
source
);
}
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