diff options
| author | 2023-10-21 18:17:17 +0200 | |
|---|---|---|
| committer | 2023-10-21 18:26:15 +0200 | |
| commit | 262a4e6a32cef3673c0603044990d07a4329dba9 (patch) | |
| tree | 8e845d3fe09231d517ef417bae2429c4cbfd0e9d | |
| parent | Initial commit (diff) | |
| download | wireguard-vnet-hdr-zygisk-262a4e6a32cef3673c0603044990d07a4329dba9.tar.xz wireguard-vnet-hdr-zygisk-262a4e6a32cef3673c0603044990d07a4329dba9.zip | |
Let app handle offloads by changing selinux policy
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
| -rw-r--r-- | jni/tunflags.cpp | 129 | ||||
| -rw-r--r-- | magisk/sepolicy.rule | 1 |
2 files changed, 3 insertions, 127 deletions
diff --git a/jni/tunflags.cpp b/jni/tunflags.cpp index 1abdc5d..c7fe3b3 100644 --- a/jni/tunflags.cpp +++ b/jni/tunflags.cpp @@ -10,9 +10,6 @@ #include <dlfcn.h> #include <sys/ioctl.h> #include <sys/socket.h> -#include <sys/un.h> -#include <sys/stat.h> -#include <sys/xattr.h> #include <linux/if.h> #include <linux/if_tun.h> #include <android/log.h> @@ -24,91 +21,6 @@ using zygisk::ServerSpecializeArgs; #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, "WireGuard/TunFlags", __VA_ARGS__) -static int setfilecon(const char *path, const char *context) -{ - return setxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0); -} - -static int setsockcreatecon(const char *context) -{ - int fd = open("/proc/thread-self/attr/sockcreate", O_WRONLY | O_CLOEXEC); - if (fd < 0) - return fd; - size_t len = strlen(context) + 1; - int ret = write(fd, context, len); - close(fd); - return ret == len ? 0 : -1; -} - -static sockaddr_un offload_addr = { - .sun_family = AF_UNIX, - .sun_path = "/dev/socket/tunflags_setoffload_helper" -}; - -static void offload_setter(int companion_fd) -{ - jint ugid[2]; - if (read(companion_fd, ugid, sizeof(ugid)) != sizeof(ugid)) { - ALOGE("Cannot receive system server uid/gid: %s", strerror(errno)); - close(companion_fd); - return; - } - close(companion_fd); - - if (setsockcreatecon("u:r:system_server:s0") < 0) { - ALOGE("Cannot change thread socket creation context: %s", strerror(errno)); - return; - } - int listener = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (listener < 0) { - ALOGE("Cannot create persistent unix socket: %s", strerror(errno)); - return; - } - umask(0077); - unlink(offload_addr.sun_path); - if (bind(listener, reinterpret_cast<sockaddr *>(&offload_addr), sizeof(offload_addr)) < 0) { - close(listener); - ALOGE("Cannot bind to abstract domain: %s", strerror(errno)); - return; - } - if (chown(offload_addr.sun_path, ugid[0], ugid[1]) < 0) { - ALOGE("Cannot change ownership of %s: %s", offload_addr.sun_path, strerror(errno)); - close(listener); - return; - } - if (setfilecon(offload_addr.sun_path, "u:object_r:statsdw_socket:s0") < 0) { - ALOGE("Cannot set file context of %s: %s", offload_addr.sun_path, strerror(errno)); - close(listener); - return; - } - - for (;;) { - int tun; - char cmsgbuf[CMSG_SPACE(sizeof(tun))], x; - iovec iov = { - .iov_base = &x, - .iov_len = sizeof(x) - }; - msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = cmsgbuf, - .msg_controllen = sizeof(cmsgbuf) - }; - int ret = recvmsg(listener, &msg, MSG_WAITALL); - cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - if (ret < 0 || msg.msg_controllen != sizeof(cmsgbuf) || cmsg == nullptr || - cmsg->cmsg_len != CMSG_LEN(sizeof(tun)) || cmsg->cmsg_level != SOL_SOCKET || - cmsg->cmsg_type != SCM_RIGHTS) - continue; - memcpy(&tun, CMSG_DATA(cmsg), sizeof(tun)); - - if (ioctl(tun, TUNSETOFFLOAD, TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6) < 0) - ALOGE("Cannot set offloads on tunnel: %s", strerror(errno)); - close(tun); - } -} - static bool is_wireguard(JNIEnv *env, jobject vpn_obj) { jclass clazz = env->GetObjectClass(vpn_obj); @@ -145,28 +57,7 @@ static jint create(JNIEnv *env, jobject thiz, jint mtu) ALOGE("Using hooked function to create IFF_VNET_HDR tun device"); - static int companion = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); - static int inet4 = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - int tun; - char cmsgbuf[CMSG_SPACE(sizeof(tun))]; - iovec iov = { - .iov_base = &tun, /* Insignificant memory */ - .iov_len = 1 - }; - msghdr msg = { - .msg_name = &offload_addr, - .msg_namelen = sizeof(offload_addr), - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = cmsgbuf, - .msg_controllen = sizeof(cmsgbuf) - }; - cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_len = CMSG_LEN(sizeof(tun)); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - - tun = open("/dev/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC); + int tun = open("/dev/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC); if (tun < 0) { ALOGE("Cannot allocate TUN: %s", strerror(errno)); return -1; @@ -180,14 +71,8 @@ static jint create(JNIEnv *env, jobject thiz, jint mtu) goto error; } - /* Set offloads by passing the tun to the root companion helper */ - memcpy(CMSG_DATA(cmsg), &tun, sizeof(tun)); - if (sendmsg(companion, &msg, 0) < 0) { - ALOGE("Cannot send TUN fd to companion to set offloads: %s", strerror(errno)); - goto error; - } - /* Activate interface */ + static int inet4 = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); ifr4.ifr_flags = IFF_UP; if (ioctl(inet4, SIOCSIFFLAGS, &ifr4) < 0) { ALOGE("Cannot activate %s: %s", ifr4.ifr_name, strerror(errno)); @@ -243,15 +128,6 @@ public: this->env = env; } - void preServerSpecialize(ServerSpecializeArgs *args) override - { - jint ugid[2] = { args->uid, args->gid }; - int companion_fd = api->connectCompanion(); - if (write(companion_fd, ugid, sizeof(ugid)) != sizeof(ugid)) - ALOGE("Cannot communicate uid/gid of system server: %s", strerror(errno)); - close(companion_fd); - } - void postServerSpecialize(const ServerSpecializeArgs *args) override { orig_register_natives = env->functions->RegisterNatives; @@ -267,4 +143,3 @@ private: }; REGISTER_ZYGISK_MODULE(TunFlags) -REGISTER_ZYGISK_COMPANION(offload_setter) diff --git a/magisk/sepolicy.rule b/magisk/sepolicy.rule new file mode 100644 index 0000000..6c78f4b --- /dev/null +++ b/magisk/sepolicy.rule @@ -0,0 +1 @@ +allowxperm untrusted_app tun_device chr_file ioctl { 0x54D0 } |
