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);
|
||||
}
|
||||
|
||||
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() {
|
||||
if (getuid() != 0 || getgid() != 0) {
|
||||
PLOGE("daemon requires root. uid/gid not root");
|
||||
return -1;
|
||||
}
|
||||
|
||||
prepare();
|
||||
|
||||
switch (fork()) {
|
||||
case 0:
|
||||
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,
|
||||
.base_path = REQUESTOR_DATA_PATH REQUESTOR
|
||||
},
|
||||
.bind = {
|
||||
.from = "",
|
||||
.to = "",
|
||||
},
|
||||
.init = "",
|
||||
};
|
||||
struct stat st;
|
||||
int c, socket_serv_fd, fd;
|
||||
@ -751,7 +756,7 @@ int su_main_nodaemon(int argc, char **argv) {
|
||||
printf("%d\n", VERSION_CODE);
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'v':
|
||||
printf("%s (topjohnwu v1)\n", VERSION);
|
||||
printf("%s\n", VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'u':
|
||||
switch (get_multiuser_mode()) {
|
||||
|
Loading…
Reference in New Issue
Block a user