Cleanup and add more xwraps

This commit is contained in:
topjohnwu 2017-10-14 00:08:12 +08:00
parent cddeaffada
commit 594a67fe28
7 changed files with 107 additions and 79 deletions

View File

@ -145,7 +145,7 @@ static void exec_common_script(const char* stage) {
struct dirent *entry;
snprintf(buf, PATH_MAX, "%s/%s.d", COREDIR, stage);
if (!(dir = opendir(buf)))
if (!(dir = xopendir(buf)))
return;
while ((entry = xreaddir(dir))) {
@ -190,7 +190,7 @@ static void construct_tree(const char *module, struct node_entry *parent) {
char *parent_path = get_full_path(parent);
snprintf(buf, PATH_MAX, "%s/%s%s", MOUNTPOINT, module, parent_path);
if (!(dir = opendir(buf)))
if (!(dir = xopendir(buf)))
goto cleanup;
while ((entry = xreaddir(dir))) {
@ -258,7 +258,7 @@ static void clone_skeleton(struct node_entry *node) {
// Clone the structure
char *full_path = get_full_path(node);
snprintf(buf, PATH_MAX, "%s%s", MIRRDIR, full_path);
if (!(dir = opendir(buf)))
if (!(dir = xopendir(buf)))
goto cleanup;
while ((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
@ -278,7 +278,7 @@ static void clone_skeleton(struct node_entry *node) {
xstat(full_path, &s);
getfilecon(full_path, &con);
LOGI("tmpfs: %s\n", full_path);
mount("tmpfs", full_path, "tmpfs", 0, NULL);
xmount("tmpfs", full_path, "tmpfs", 0, NULL);
chmod(full_path, s.st_mode & 0777);
chown(full_path, s.st_uid, s.st_gid);
setfilecon(full_path, con);
@ -405,11 +405,11 @@ static void daemon_init() {
// Setup links under /sbin
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
xmkdir("/root", 0755);
xchmod("/root", 0755);
chmod("/root", 0755);
root = xopen("/root", O_RDONLY | O_CLOEXEC);
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
dir = fdopendir(sbin);
while((entry = readdir(dir))) {
dir = xfdopendir(sbin);
while((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
linkat(sbin, entry->d_name, root, entry->d_name, 0);
if (strcmp(entry->d_name, "magisk") == 0)
@ -420,16 +420,16 @@ static void daemon_init() {
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
fchmod(sbin, 0755);
fsetfilecon(sbin, "u:object_r:rootfs:s0");
dir = fdopendir(root);
while((entry = readdir(dir))) {
dir = xfdopendir(root);
while((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
snprintf(target, sizeof(target), "/root/%s", entry->d_name);
snprintf(linkpath, sizeof(linkpath), "/sbin/%s", entry->d_name);
symlink(target, linkpath);
xsymlink(target, linkpath);
}
for (int i = 0; applet[i]; ++i) {
snprintf(linkpath, sizeof(linkpath), "/sbin/%s", applet[i]);
symlink("/root/magisk", linkpath);
xsymlink("/root/magisk", linkpath);
}
xmkdir("/magisk", 0755);
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
@ -476,20 +476,20 @@ static void daemon_init() {
}
vec_deep_destroy(&mounts);
if (!seperate_vendor) {
symlink(MIRRDIR "/system/vendor", MIRRDIR "/vendor");
xsymlink(MIRRDIR "/system/vendor", MIRRDIR "/vendor");
#ifdef MAGISK_DEBUG
LOGI("link: %s -> %s\n", MIRRDIR "/system/vendor", MIRRDIR "/vendor");
#else
LOGI("link: %s\n", MIRRDIR "/vendor");
#endif
}
mkdir_p(MIRRDIR "/bin", 0755);
xmkdir_p(MIRRDIR "/bin", 0755);
bind_mount(DATABIN, MIRRDIR "/bin");
LOGI("* Setting up internal busybox");
mkdir_p(BBPATH, 0755);
xmkdir_p(BBPATH, 0755);
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
symlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
}
static int prepare_img() {
@ -569,7 +569,7 @@ void fix_filecon() {
****************/
static void unblock_boot_process() {
close(open(UNBLOCKFILE, O_RDONLY | O_CREAT));
close(xopen(UNBLOCKFILE, O_RDONLY | O_CREAT));
pthread_exit(NULL);
}
@ -689,7 +689,7 @@ void post_fs_data(int client) {
if (access(buf, F_OK) == 0) {
snprintf(buf2, PATH_MAX, "%s/%s/vendor", MOUNTPOINT, module);
unlink(buf2);
symlink(buf, buf2);
xsymlink(buf, buf2);
}
construct_tree(module, sys_root);
}
@ -729,7 +729,6 @@ core_only:
auto_start_magiskhide();
unblock:
unblock_boot_process();
}

View File

@ -155,7 +155,7 @@ void start_daemon() {
dump_policydb(SELINUX_LOAD);
// Continue the larger patch in another thread, we will join later
pthread_create(&sepol_patch, NULL, large_sepol_patch, NULL);
xpthread_create(&sepol_patch, NULL, large_sepol_patch, NULL);
struct sockaddr_un sun;
fd = setup_socket(&sun);
@ -170,7 +170,7 @@ void start_daemon() {
unlock_blocks();
// Notifiy init the daemon is started
close(open(UNBLOCKFILE, O_RDONLY));
close(xopen(UNBLOCKFILE, O_RDONLY));
// Loop forever to listen for requests
while(1) {
@ -187,25 +187,19 @@ void start_daemon() {
int connect_daemon() {
struct sockaddr_un sun;
int fd = setup_socket(&sun);
if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
if (xconnect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
// If we cannot access the daemon, we start a daemon in the child process if possible
if (getuid() != UID_ROOT || getgid() != UID_ROOT) {
fprintf(stderr, "Starting daemon requires root: %s\n", strerror(errno));
PLOGE("start daemon");
fprintf(stderr, "No daemon is currently running!\n");
exit(1);
}
switch (fork()) {
case -1:
PLOGE("fork");
case 0:
if (xfork() == 0) {
LOGD("client: connect fail, try launching new daemon process\n");
close(fd);
xsetsid();
start_daemon();
break;
default:
break;
}
do {

View File

@ -24,12 +24,14 @@ FILE *xfdopen(int fd, const char *mode);
#define xopen(...) GET_MACRO(__VA_ARGS__, xopen3, xopen2)(__VA_ARGS__)
int xopen2(const char *pathname, int flags);
int xopen3(const char *pathname, int flags, mode_t mode);
int xopenat(int dirfd, const char *pathname, int flags);
ssize_t xwrite(int fd, const void *buf, size_t count);
ssize_t xread(int fd, void *buf, size_t count);
ssize_t xxread(int fd, void *buf, size_t count);
int xpipe2(int pipefd[2], int flags);
int xsetns(int fd, int nstype);
DIR *xopendir(const char *name);
DIR *xfdopendir(int fd);
struct dirent *xreaddir(DIR *dirp);
pid_t xsetsid();
int xsocket(int domain, int type, int protocol);
@ -49,19 +51,21 @@ int xstat(const char *pathname, struct stat *buf);
int xlstat(const char *pathname, struct stat *buf);
int xdup2(int oldfd, int newfd);
ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz);
ssize_t xreadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz);
int xsymlink(const char *target, const char *linkpath);
int xmount(const char *source, const char *target,
const char *filesystemtype, unsigned long mountflags,
const void *data);
int xumount(const char *target);
int xumount2(const char *target, int flags);
int xchmod(const char *pathname, mode_t mode);
int xrename(const char *oldpath, const char *newpath);
int xmkdir(const char *pathname, mode_t mode);
int xmkdir_p(const char *pathname, mode_t mode);
int xmkdirat(int dirfd, const char *pathname, mode_t mode);
void *xmmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
ssize_t xsendfile(int out_fd, int in_fd, off_t *offset, size_t count);
int xmkdir_p(const char *pathname, mode_t mode);
pid_t xfork();
// misc.c

View File

@ -50,16 +50,16 @@ void rm_rf(const char *path) {
void frm_rf(int dirfd) {
struct dirent *entry;
int newfd;
DIR *dir = fdopendir(dirfd);
DIR *dir = xfdopendir(dirfd);
while ((entry = readdir(dir))) {
while ((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
if (is_excl(entry->d_name))
continue;
switch (entry->d_type) {
case DT_DIR:
newfd = openat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
newfd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
frm_rf(newfd);
close(newfd);
unlinkat(dirfd, entry->d_name, AT_REMOVEDIR);
@ -88,7 +88,7 @@ void mv_f(const char *source, const char *destination) {
close(dest);
} else{
getattr(source, &a);
rename(source, destination);
xrename(source, destination);
setattr(destination, &a);
}
rmdir(source);
@ -101,8 +101,8 @@ void mv_dir(int src, int dest) {
int newsrc, newdest;
struct file_attr a;
dir = fdopendir(src);
while ((entry = readdir(dir))) {
dir = xfdopendir(src);
while ((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
if (is_excl(entry->d_name))
@ -110,9 +110,9 @@ void mv_dir(int src, int dest) {
getattrat(src, entry->d_name, &a);
switch (entry->d_type) {
case DT_DIR:
mkdirat(dest, entry->d_name, a.st.st_mode & 0777);
newsrc = openat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
newdest = openat(dest, entry->d_name, O_RDONLY | O_CLOEXEC);
xmkdirat(dest, entry->d_name, a.st.st_mode & 0777);
newsrc = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
newdest = xopenat(dest, entry->d_name, O_RDONLY | O_CLOEXEC);
fsetattr(newdest, &a);
mv_dir(newsrc, newdest);
close(newsrc);
@ -164,11 +164,10 @@ void clone_dir(int src, int dest) {
DIR *dir;
int srcfd, destfd, newsrc, newdest;
char buf[PATH_MAX];
ssize_t size;
struct file_attr a;
dir = fdopendir(src);
while ((entry = readdir(dir))) {
dir = xfdopendir(src);
while ((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
if (is_excl(entry->d_name))
@ -176,25 +175,24 @@ void clone_dir(int src, int dest) {
getattrat(src, entry->d_name, &a);
switch (entry->d_type) {
case DT_DIR:
mkdirat(dest, entry->d_name, a.st.st_mode & 0777);
xmkdirat(dest, entry->d_name, a.st.st_mode & 0777);
setattrat(dest, entry->d_name, &a);
newsrc = openat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
newdest = openat(dest, entry->d_name, O_RDONLY | O_CLOEXEC);
newsrc = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
newdest = xopenat(dest, entry->d_name, O_RDONLY | O_CLOEXEC);
clone_dir(newsrc, newdest);
close(newsrc);
close(newdest);
break;
case DT_REG:
destfd = openat(dest, entry->d_name, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, a.st.st_mode & 0777);
srcfd = openat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
sendfile(destfd, srcfd, 0, a.st.st_size);
destfd = xopenat(dest, entry->d_name, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC);
srcfd = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
xsendfile(destfd, srcfd, 0, a.st.st_size);
fsetattr(destfd, &a);
close(destfd);
close(srcfd);
break;
case DT_LNK:
size = readlinkat(src, entry->d_name, buf, sizeof(buf));
buf[size] = '\0';
xreadlinkat(src, entry->d_name, buf, sizeof(buf));
symlinkat(buf, dest, entry->d_name);
setattrat(dest, entry->d_name, &a);
break;
@ -285,15 +283,15 @@ void restorecon(int dirfd, int force) {
fsetfilecon(dirfd, SYSTEM_CON);
freecon(con);
dir = fdopendir(dirfd);
while ((entry = readdir(dir))) {
dir = xfdopendir(dirfd);
while ((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
if (entry->d_type == DT_DIR) {
fd = openat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
restorecon(fd, force);
} else {
fd = openat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC);
fd = xopenat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC);
fgetfilecon(fd, &con);
if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
fsetfilecon(fd, SYSTEM_CON);

View File

@ -164,7 +164,7 @@ int merge_img(const char *source, const char *target) {
if (access(source, F_OK) == -1)
return 0;
if (access(target, F_OK) == -1) {
rename(source, target);
xrename(source, target);
return 0;
}
@ -188,7 +188,7 @@ int merge_img(const char *source, const char *target) {
DIR *dir;
struct dirent *entry;
if (!(dir = opendir(SOURCE_TMP)))
if (!(dir = xopendir(SOURCE_TMP)))
return 1;
while ((entry = xreaddir(dir))) {
if (entry->d_type == DT_DIR) {

View File

@ -140,12 +140,12 @@ static void proc_name_filter(int pid) {
char buf[64];
int fd;
snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
if ((fd = open(buf, O_RDONLY)) == -1)
if (access(buf, R_OK) == -1 || (fd = xopen(buf, O_RDONLY)) == -1)
return;
if (fdgets(buf, sizeof(buf), fd) == 0) {
snprintf(buf, sizeof(buf), "/proc/%d/comm", pid);
close(fd);
if ((fd = open(buf, O_RDONLY)) == -1)
if (access(buf, R_OK) == -1 || (fd = xopen(buf, O_RDONLY)) == -1)
return;
fdgets(buf, sizeof(buf), fd);
}
@ -169,7 +169,7 @@ void unlock_blocks() {
if ((dev = xopen("/dev/block", O_RDONLY | O_CLOEXEC)) < 0)
return;
dir = fdopendir(dev);
dir = xfdopendir(dev);
while((entry = readdir(dir))) {
if (entry->d_type == DT_BLK) {
@ -231,7 +231,7 @@ static int v_exec_command(int err, int *fd, void (*setupenv)(struct vector*), co
envp = environ;
}
int pid = fork();
int pid = xfork();
if (pid != 0) {
if (fd && *fd < 0) {
// Give the read end and close write end
@ -308,11 +308,11 @@ int switch_mnt_ns(int pid) {
}
int fork_dont_care() {
int pid = fork();
int pid = xfork();
if (pid) {
waitpid(pid, NULL, 0);
return pid;
} else if ((pid = fork())) {
} else if ((pid = xfork())) {
exit(0);
}
return 0;

View File

@ -1,8 +1,8 @@
/* xwrap.c - wrappers around existing library functions.
*
* Functions with the x prefix are wrappers that either succeed or kill the
* program with an error message, but never return failure. They usually have
* the same arguments and return value as the function they wrap.
* Functions with the x prefix are wrappers that either succeed or log the
* error message. They usually have the same arguments and return value
* as the function they wrap.
*
*/
@ -57,6 +57,14 @@ int xopen3(const char *pathname, int flags, mode_t mode) {
return fd;
}
int xopenat(int dirfd, const char *pathname, int flags) {
int fd = openat(dirfd, pathname, flags);
if (fd < 0) {
PLOGE("openat: %s", pathname);
}
return fd;
}
ssize_t xwrite(int fd, const void *buf, size_t count) {
int ret = write(fd, buf, count);
if (count != ret) {
@ -107,6 +115,14 @@ DIR *xopendir(const char *name) {
return d;
}
DIR *xfdopendir(int fd) {
DIR *d = fdopendir(fd);
if (d == NULL) {
PLOGE("fdopendir");
}
return d;
}
struct dirent *xreaddir(DIR *dirp) {
errno = 0;
struct dirent *e = readdir(dirp);
@ -251,7 +267,16 @@ ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz) {
PLOGE("readlink %s", pathname);
} else {
buf[ret] = '\0';
++ret;
}
return ret;
}
ssize_t xreadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) {
ssize_t ret = readlinkat(dirfd, pathname, buf, bufsiz);
if (ret == -1) {
PLOGE("readlinkat %s", pathname);
} else {
buf[ret] = '\0';
}
return ret;
}
@ -290,14 +315,6 @@ int xumount2(const char *target, int flags) {
return ret;
}
int xchmod(const char *pathname, mode_t mode) {
int ret = chmod(pathname, mode);
if (ret == -1) {
PLOGE("chmod %s %u", pathname, mode);
}
return ret;
}
int xrename(const char *oldpath, const char *newpath) {
int ret = rename(oldpath, newpath);
if (ret == -1) {
@ -314,6 +331,22 @@ int xmkdir(const char *pathname, mode_t mode) {
return ret;
}
int xmkdir_p(const char *pathname, mode_t mode) {
int ret = mkdir_p(pathname, mode);
if (ret == -1) {
PLOGE("mkdir_p %s", pathname);
}
return ret;
}
int xmkdirat(int dirfd, const char *pathname, mode_t mode) {
int ret = mkdirat(dirfd, pathname, mode);
if (ret == -1 && errno != EEXIST) {
PLOGE("mkdirat %s %u", pathname, mode);
}
return ret;
}
void *xmmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset) {
void *ret = mmap(addr, length, prot, flags, fd, offset);
@ -331,10 +364,10 @@ ssize_t xsendfile(int out_fd, int in_fd, off_t *offset, size_t count) {
return ret;
}
int xmkdir_p(const char *pathname, mode_t mode) {
int ret = mkdir_p(pathname, mode);
pid_t xfork() {
int ret = fork();
if (ret == -1) {
PLOGE("mkdir_p %s", pathname);
PLOGE("fork");
}
return ret;
}