Fix app request issue
This commit is contained in:
parent
f31d2486c9
commit
04fcb33d7e
121
daemon.c
121
daemon.c
@ -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
7
su.c
@ -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()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user