aboutsummaryrefslogtreecommitdiffstats
diff options
authorJason A. Donenfeld <Jason@zx2c4.com>2023-10-21 18:17:17 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2023-10-21 18:26:15 +0200
commit262a4e6a32cef3673c0603044990d07a4329dba9 (patch)
tree8e845d3fe09231d517ef417bae2429c4cbfd0e9d
parentInitial commit (diff)
downloadwireguard-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.cpp129
-rw-r--r--magisk/sepolicy.rule1
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 }