Fix app request issue

This commit is contained in:
topjohnwu 2016-12-31 01:05:20 +08:00
parent f31d2486c9
commit 04fcb33d7e
3 changed files with 42 additions and 158 deletions

121
daemon.c
View File

@ -444,133 +444,12 @@ static int daemon_accept(int fd) {
return run_daemon_child(infd, outfd, errfd, argc, argv); return run_daemon_child(infd, outfd, errfd, argc, argv);
} }
static int copy_file(const char* src, const char* dst, int mode) {
int ifd = open(src, O_RDONLY);
if(ifd<0)
return 1;
if(mode == 0) {
struct stat stbuf;
if(fstat(ifd, &stbuf))
return 1;
mode = stbuf.st_mode & 0777;
LOGE("File %s found mode %o", src, mode);
}
int ofd = open(dst, O_WRONLY|O_CREAT, mode);
if(ofd<0)
return 1;
size_t s = lseek(ifd, 0, SEEK_END);
if(s<0)
return 1;
lseek(ifd, 0, SEEK_SET);
int ret = sendfile(ofd, ifd, NULL, s);
if(ret<0)
return 1;
close(ofd);
close(ifd);
return 0;
}
static void prepare_su_bind() {
int ret = 0;
//Check if there is a use to mount bind
if(access("/system/xbin/su", R_OK) != 0)
return;
ret = copy_file("/sbin/su", "/dev/su/su", 0755);
if(ret) {
PLOGE("Failed to copy su");
return;
}
chmod("/dev/su/su", 0755);
ret = setfilecon("/dev/su/su", "u:object_r:system_file:s0");
if(ret) {
LOGE("Failed to set file context");
return;
}
ret = mount("/dev/su/su", "/system/xbin/su", "", MS_BIND, NULL);
if(ret) {
LOGE("Failed to mount bind");
return;
}
}
static void bind_cb_func(void *arg, int uid, const char *src, const char *dst) {
int ret = 0, i = 0;
char *tmpfile = NULL;
asprintf(&tmpfile, "/dev/su/bind%d", i++);
struct stat stbuf;
ret = stat(src, &stbuf);
if(ret) {
free(tmpfile);
LOGE("Failed to stat src %s file", src);
return;
}
//Only shell uid is allowed to bind files not his own
if(uid != 2000 && uid != stbuf.st_uid) {
LOGE("File %s has wrong owner: %d vs %d", src, uid, stbuf.st_uid);
return;
}
ret = copy_file(src, tmpfile, 0);
if(ret) {
free(tmpfile);
PLOGE("Failed to copy su");
return;
}
chmod(tmpfile, stbuf.st_mode);
ret = setfilecon(tmpfile, "u:object_r:system_file:s0");
if(ret) {
LOGE("Failed to set file context");
return;
}
ret = mount(tmpfile, dst, "", MS_BIND, NULL);
if(ret) {
LOGE("Failed to mount bind");
return;
}
}
static void init_cb_func(void *arg, int uid, const char *path) {
int ret = 0;
int p = fork();
if(p)
return;
while(access("/system/bin/sh", R_OK)) sleep(1);
ret = setexeccon("u:r:su:s0");
execl(path, path, NULL);
LOGE("Failed to execute %s. Trying as shell script, ret = %d", path, ret);
ret = setexeccon("u:r:su:s0");
execl("/system/bin/sh", "/system/bin/sh", path, NULL);
LOGE("Failed to execute %s as shell script", path);
_exit(1);
}
static void prepare() {
setfscreatecon("u:object_r:su_daemon:s0");
mkdir("/dev/su", 0700);
prepare_su_bind();
setfscreatecon(NULL);
}
int run_daemon() { int run_daemon() {
if (getuid() != 0 || getgid() != 0) { if (getuid() != 0 || getgid() != 0) {
PLOGE("daemon requires root. uid/gid not root"); PLOGE("daemon requires root. uid/gid not root");
return -1; return -1;
} }
prepare();
switch (fork()) { switch (fork()) {
case 0: case 0:
break; break;

7
su.c
View File

@ -712,6 +712,11 @@ int su_main_nodaemon(int argc, char **argv) {
.database_path = REQUESTOR_DATA_PATH REQUESTOR_DATABASE_PATH, .database_path = REQUESTOR_DATA_PATH REQUESTOR_DATABASE_PATH,
.base_path = REQUESTOR_DATA_PATH REQUESTOR .base_path = REQUESTOR_DATA_PATH REQUESTOR
}, },
.bind = {
.from = "",
.to = "",
},
.init = "",
}; };
struct stat st; struct stat st;
int c, socket_serv_fd, fd; int c, socket_serv_fd, fd;
@ -751,7 +756,7 @@ int su_main_nodaemon(int argc, char **argv) {
printf("%d\n", VERSION_CODE); printf("%d\n", VERSION_CODE);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
case 'v': case 'v':
printf("%s (topjohnwu v1)\n", VERSION); printf("%s\n", VERSION);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
case 'u': case 'u':
switch (get_multiuser_mode()) { switch (get_multiuser_mode()) {

2
su.h
View File

@ -79,7 +79,7 @@
#ifndef VERSION_CODE #ifndef VERSION_CODE
#define VERSION_CODE 1 #define VERSION_CODE 1
#endif #endif
#define VERSION xstr(VERSION_CODE) " " REQUESTOR #define VERSION REQUESTOR " topjohnwu r" xstr(VERSION_CODE)
#define PROTO_VERSION 1 #define PROTO_VERSION 1