Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions Superuser/assets/update-binary
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ echo -n -e 'ui_print\n' > /proc/self/fd/$2
ARCH=$(uname -m)

# x86 needs to match: i486, i686, x86_64, ...
if echo "$ARCH" | grep -q 86; then
PLATFORM=x86
elif [ "$ARCH" = "mips" -o "$ARCH" = "mips64" ]; then
PLATFORM=mips
else
PLATFORM=armeabi
fi
case "${ARCH}" in
(i386|i686|x86_64|amd64|*86*)
PLATFORM=x86
;;
(arm|armel|armeabi|aarch64|arm64-v8a)
PLATFORM=armeabi
;;
(mips|mipsel|mips64|mips64el)
PLATFORM=mips
;;
esac

cd /tmp
mkdir superuser
Expand Down Expand Up @@ -45,8 +49,20 @@ cp $PLATFORM/su /system/xbin/su
chown 0:0 /system/xbin/su
chmod 0755 /system/xbin/su

cp Superuser.apk /system/app
chmod 644 /system/app/Superuser.apk
if test '/system/app/*/*.apk' != /system/app/*/*.apk 2>/dev/null
then
mkdir -m 755 -p /system/app/Superuser
cp Superuser.apk /system/app/Superuser
chmod 644 /system/app/Superuser/Superuser.apk
#elif test '/system/app/*.apk' != /system/app/*.apk 2>/dev/null
#then
else
cp Superuser.apk /system/app
chmod 644 /system/app/Superuser.apk
#else
# echo -n -e 'ui_print Install location for Superuser.apk unknown, failed\n' > /proc/self/fd/$2
# exit 1
fi

# if the system is at least 4.3, and there is no su daemon built in,
# let's try to install it using install-recovery.sh
Expand Down Expand Up @@ -75,6 +91,7 @@ for i in etc/install-recovery.sh bin/install-recovery.sh bin/install_recovery.sh
done

#Rename original app_process32
#TODO: add support for adding a hook into app_process64
if [ ! -f /system/bin/app_process32.old ];then
mv /system/bin/app_process32 /system/bin/app_process32.old
fi
Expand Down
2 changes: 1 addition & 1 deletion Superuser/build-zip.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pushd "$tmpdir"
mkdir -p META-INF/com/google/android
cp "$ORIG"/assets/update-binary META-INF/com/google/android/update-binary
cp "$ORIG"/assets/install-recovery.sh .
cp -R "$ORIG"/libs/{x86,mips,armeabi} .
cp -R "$ORIG"/libs/{x86,x86_64,armeabi,arm64-v8a,mips,mips64} .

zip -r "$ORIG"/update-su.zip *
popd
Expand Down
4 changes: 2 additions & 2 deletions Superuser/jni/Application.mk
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
APP_ABI := x86 armeabi mips
APP_ABI := x86 x86_64 armeabi arm64-v8a mips mips64
# NDK_TOOLCHAIN_VERSION=4.8
APP_PIE = true
APP_PIE = true
42 changes: 26 additions & 16 deletions Superuser/jni/placeholder/placeholder.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include <sys/sendfile.h>
#include <dlfcn.h>

#include "placeholder.h"

static int copy_file(const char* src, const char *dst) {
int ifd = open(src, O_RDONLY);
if(ifd == -1)
Expand All @@ -52,9 +54,6 @@ static int copy_file(const char* src, const char *dst) {
return 0;
}

//From placeholder.c
int setup_policy();

//This is calle das 1000:1000 system_server
//The only guy who has the rights to write to /data/security/current, and to set selinux.reload_policy
static void setup_selinux() {
Expand All @@ -80,33 +79,44 @@ static void setup_selinux() {
}

int main(int argc, char *argv[], char *envp[]) {
int pid, status;

if(geteuid() != 0)
return execve("/system/bin/app_process32.old", argv, envp);
goto failure;

(void)argc;
int p = fork();
if(!p) {
pid = fork();
if(!pid) { /* child process doing SELinux work */
setuid(1000);
seteuid(1000);
setcon("u:r:system_server:s0");
setup_selinux();
return 0;
}

//Wait for it...
int status = -1;
waitpid(p, &status, 0);
//TODO: Error checking ?
if(!fork()) {
setcon("u:r:system_server:s0");
execl("/system/xbin/su", "su", "--daemon", NULL);
/* otherwise we've got an error and can do little */
if(pid>0) {
//Wait for it...
status = -1;
waitpid(pid, &status, 0);
//TODO: Error checking ?
if(!fork()) {
const char *const su_exec="/system/xbin/su";
char *const su_argv[]={ "su", "--daemon", NULL, };
setcon("u:r:system_server:s0");
execve(su_exec, su_argv, envp);
}
}



failure:
//Exec original app_process32
//Should be useless, because it's current context ?
//setexeccon("u:r:zygote:s0");
execve("/system/bin/app_process32.old", argv, envp);
#define STR_HELP(s) #s
#define STR(s) STR_HELP(s)
execve("/system/bin/app_process"STR(__WORDSIZE)".old", argv, envp);
#undef STR_HELP
#undef STR

return 1;
}
6 changes: 6 additions & 0 deletions Superuser/jni/placeholder/placeholder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _PLACEHOLDER_H_
#define _PLACEHOLDER_H_ 1

extern int setup_policy(void);

#endif
19 changes: 11 additions & 8 deletions Superuser/jni/placeholder/policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <sepol/policydb/avrule_block.h>
#include <sepol/policydb/conditional.h>

#include "placeholder.h"

void usage(char *arg0) {
fprintf(stderr, "%s -s <source type> -t <target type> -c <class> -p <perm> -P <policy file> -o <output file>\n", arg0);
fprintf(stderr, "%s -Z permissive_type -P <policy file> -o <output file>\n", arg0);
Expand All @@ -37,7 +39,7 @@ void *cmalloc(size_t s) {
return t;
}

void set_attr(char *type, policydb_t *policy, int value) {
void set_attr(const hashtab_key_t type, policydb_t *policy, int value) {
type_datum_t *attr = hashtab_search(policy->p_types.table, type);
if (!attr)
exit(1);
Expand All @@ -49,7 +51,7 @@ void set_attr(char *type, policydb_t *policy, int value) {
exit(1);
}

void create_domain(char *d, policydb_t *policy) {
void create_domain(const hashtab_key_t d, policydb_t *policy) {
symtab_datum_t *src = hashtab_search(policy->p_types.table, d);
if(src)
return;
Expand Down Expand Up @@ -100,13 +102,14 @@ void create_domain(char *d, policydb_t *policy) {
set_attr("domain", policy, value);
}

int add_rule(char *s, char *t, char *c, char *p, policydb_t *policy) {
int add_rule(const hashtab_key_t s, const hashtab_key_t t,
const hashtab_key_t c, const hashtab_key_t p, policydb_t *policy) {
type_datum_t *src, *tgt;
class_datum_t *cls;
perm_datum_t *perm;
avtab_datum_t *av;
avtab_key_t key;

src = hashtab_search(policy->p_types.table, s);
if (src == NULL) {
fprintf(stderr, "source type %s does not exist\n", s);
Expand Down Expand Up @@ -156,7 +159,7 @@ int add_rule(char *s, char *t, char *c, char *p, policydb_t *policy) {

return 0;
}


int load_policy(char *filename, policydb_t *policydb, struct policy_file *pf) {
int fd;
Expand Down Expand Up @@ -199,8 +202,8 @@ int load_policy(char *filename, policydb_t *policydb, struct policy_file *pf) {

return 0;
}
int set_permissive(const char *domain, policydb_t* pdb) {

int set_permissive(const hashtab_key_t domain, policydb_t* pdb) {
type_datum_t *type;
type = hashtab_search(pdb->p_types.table, domain);
if (type == NULL) {
Expand All @@ -214,7 +217,7 @@ int set_permissive(const char *domain, policydb_t* pdb) {
return 0;
}

int setup_policy() {
int setup_policy(void) {
char *policy = NULL, *source = NULL, *target = NULL, *class = NULL, *perm = NULL, *outfile = NULL, *permissive = NULL;
policydb_t policydb;
struct policy_file pf, outpf;
Expand Down