diff --git a/Superuser/assets/update-binary b/Superuser/assets/update-binary index 50929425..3485229a 100755 --- a/Superuser/assets/update-binary +++ b/Superuser/assets/update-binary @@ -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 @@ -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 @@ -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 diff --git a/Superuser/build-zip.sh b/Superuser/build-zip.sh index 4246dfa5..8dc12f7a 100644 --- a/Superuser/build-zip.sh +++ b/Superuser/build-zip.sh @@ -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 diff --git a/Superuser/jni/Application.mk b/Superuser/jni/Application.mk index 9651e05d..dffadc2d 100644 --- a/Superuser/jni/Application.mk +++ b/Superuser/jni/Application.mk @@ -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 \ No newline at end of file +APP_PIE = true diff --git a/Superuser/jni/placeholder/placeholder.c b/Superuser/jni/placeholder/placeholder.c index 99d50af6..d169535f 100644 --- a/Superuser/jni/placeholder/placeholder.c +++ b/Superuser/jni/placeholder/placeholder.c @@ -35,6 +35,8 @@ #include #include +#include "placeholder.h" + static int copy_file(const char* src, const char *dst) { int ifd = open(src, O_RDONLY); if(ifd == -1) @@ -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() { @@ -80,12 +79,13 @@ 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"); @@ -93,20 +93,30 @@ int main(int argc, char *argv[], char *envp[]) { 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; } diff --git a/Superuser/jni/placeholder/placeholder.h b/Superuser/jni/placeholder/placeholder.h new file mode 100644 index 00000000..f76ab904 --- /dev/null +++ b/Superuser/jni/placeholder/placeholder.h @@ -0,0 +1,6 @@ +#ifndef _PLACEHOLDER_H_ +#define _PLACEHOLDER_H_ 1 + +extern int setup_policy(void); + +#endif diff --git a/Superuser/jni/placeholder/policy.c b/Superuser/jni/placeholder/policy.c index 4bb4a269..6f164db2 100644 --- a/Superuser/jni/placeholder/policy.c +++ b/Superuser/jni/placeholder/policy.c @@ -22,6 +22,8 @@ #include #include +#include "placeholder.h" + void usage(char *arg0) { fprintf(stderr, "%s -s -t -c -p -P -o \n", arg0); fprintf(stderr, "%s -Z permissive_type -P -o \n", arg0); @@ -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); @@ -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; @@ -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); @@ -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; @@ -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) { @@ -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;