Skip to content

Commit 6646dfc

Browse files
authored
add: KSU ioctl supercall support (ThePedroo#14)
This commit adds support to KernelSU environments that use the new supercall, "ioctl".
1 parent 0f7bbe6 commit 6646dfc

File tree

6 files changed

+135
-12
lines changed

6 files changed

+135
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
apache/build
12
apache/local/generated
23
.project
34
.settings

daemon/src/main/java/org/lsposed/lspd/service/ConfigManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,8 @@ public List<String> getDenyListPackages() {
12281228
.collect(Collectors.toList());
12291229
} catch (Throwable e) {
12301230
Log.e(TAG, "get denylist", e);
1231+
} finally {
1232+
DenylistManager.clearFd();
12311233
}
12321234
}
12331235
return result;

daemon/src/main/java/org/lsposed/lspd/service/DenylistManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@
2626
public class DenylistManager {
2727
native static boolean isInDenylist(String processName);
2828
native static boolean isInDenylistFromClasspathDir(String classpathDir);
29+
native static void clearFd();
2930
}

daemon/src/main/java/org/lsposed/lspd/service/Dex2OatService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import static org.lsposed.lspd.ILSPManagerService.DEX2OAT_SELINUX_PERMISSIVE;
2626
import static org.lsposed.lspd.ILSPManagerService.DEX2OAT_SEPOLICY_INCORRECT;
2727

28-
import static org.lsposed.lspd.service.DenylistManager.isInDenylist;
2928
import static org.lsposed.lspd.service.DenylistManager.isInDenylistFromClasspathDir;
3029

3130
import android.net.LocalServerSocket;
@@ -329,12 +328,14 @@ public void run() {
329328

330329
client.close();
331330
}
332-
} catch (IOException e) {
331+
} catch (Throwable e) {
333332
Log.e(TAG, "Dex2oat wrapper daemon crashed", e);
334333
if (compatibility == DEX2OAT_OK) {
335334
doMount(false);
336335
compatibility = DEX2OAT_CRASHED;
337336
}
337+
} finally {
338+
DenylistManager.clearFd();
338339
}
339340
}
340341

daemon/src/main/jni/denylist.cpp

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@
2626
#include <sys/prctl.h>
2727
#include <sys/wait.h>
2828
#include <sys/stat.h>
29+
#include <sys/syscall.h>
2930
#include <stdlib.h>
3031
#include <unistd.h>
3132

3233
#include <string>
3334

35+
#include "ksu.h"
3436
#include "logging.h"
3537
#include "packagename.h"
3638

@@ -78,33 +80,92 @@ bool exec_command(char *buf, size_t len, const char *file, const char *argv[]) {
7880
return true;
7981
}
8082

81-
#define KERNEL_SU_OPTION (int)0xdeadbeef
82-
#define KERNELSU_CMD_GET_VERSION 2
83-
#define KERNELSU_CMD_UID_SHOULD_UMOUNT 13
84-
83+
/*
84+
* Root implementation indicator
85+
*
86+
* -1 - None
87+
* 1 - KernelSU
88+
* 2 - Magisk
89+
* 3 - APatch
90+
*/
8591
static int root_impl = -1;
92+
93+
static int ksu_fd = -1;
94+
95+
static bool prepare_ksu_fd() {
96+
if (ksu_fd >= 0) goto ksu_fd_return_success;
97+
98+
LOGD("Prepare KSU fd: Trying to send ksu option");
99+
100+
syscall(SYS_reboot, KSU_INSTALL_MAGIC1, KSU_INSTALL_MAGIC2, 0, (void*)&ksu_fd);
101+
102+
LOGD("Prepare KSU fd: %x", ksu_fd);
103+
104+
return ksu_fd >= 0;
105+
106+
ksu_fd_return_success:
107+
return true;
108+
}
109+
110+
static void ksu_close_fd() {
111+
if (ksu_fd >= 0) {
112+
close(ksu_fd);
113+
ksu_fd = -1;
114+
}
115+
}
116+
86117
static bool ksu_get_existence() {
87118
int version = 0;
88119
int reply_ok = 0;
89120

121+
if (prepare_ksu_fd()) {
122+
struct ksu_get_info_cmd g_version {};
123+
124+
syscall(SYS_ioctl, ksu_fd, KSU_IOCTL_GET_INFO, &g_version);
125+
126+
if (g_version.version > 0) {
127+
LOGD("KernelSU version: %d (IOCTL)", g_version.version);
128+
129+
root_impl = 1;
130+
131+
goto ksu_exist_return_success;
132+
} else {
133+
ksu_close_fd();
134+
}
135+
}
136+
90137
prctl((signed int)KERNEL_SU_OPTION, KERNELSU_CMD_GET_VERSION, &version, 0, &reply_ok);
91138

92139
if (version != 0) {
93-
LOGD("KernelSU version: %d", version);
140+
LOGD("KernelSU version: %d (PRCTL)", version);
141+
94142
root_impl = 1;
95143

96-
return true;
144+
goto ksu_exist_return_success;
97145
}
98146

99147
return false;
148+
149+
ksu_exist_return_success:
150+
return true;
100151
}
101152

102153
static bool ksu_is_in_denylist(uid_t app_uid) {
103154
bool umount = false;
104-
105155
int reply_ok = 0;
156+
157+
if (prepare_ksu_fd()) {
158+
struct ksu_uid_should_umount_cmd cmd = { app_uid };
159+
160+
syscall(SYS_ioctl, ksu_fd, KSU_IOCTL_UID_SHOULD_UMOUNT, &cmd);
161+
162+
umount = !!cmd.should_umount;
163+
goto ksu_return_umount;
164+
}
165+
106166
prctl((signed int)KERNEL_SU_OPTION, KERNELSU_CMD_UID_SHOULD_UMOUNT, app_uid, &umount, &reply_ok);
107167

168+
ksu_return_umount:
108169
return umount;
109170
}
110171

@@ -337,7 +398,7 @@ bool apatch_uid_should_umount(const char *const process) {
337398
}
338399

339400
extern "C" JNIEXPORT jboolean JNICALL
340-
Java_org_lsposed_lspd_service_DenylistManager_isInDenylist(JNIEnv *env, jobject, jstring appName) {
401+
Java_org_lsposed_lspd_service_DenylistManager_isInDenylist(JNIEnv *env, jclass, jstring appName) {
341402
const char *app_name = env->GetStringUTFChars(appName, nullptr);
342403
if (app_name == nullptr) {
343404
LOGE("Failed to get app name string");
@@ -406,7 +467,7 @@ Java_org_lsposed_lspd_service_DenylistManager_isInDenylist(JNIEnv *env, jobject,
406467
}
407468

408469
extern "C" JNIEXPORT jboolean JNICALL
409-
Java_org_lsposed_lspd_service_DenylistManager_isInDenylistFromClasspathDir(JNIEnv *env, jobject, jstring classpathDirArg) {
470+
Java_org_lsposed_lspd_service_DenylistManager_isInDenylistFromClasspathDir(JNIEnv *env, jclass, jstring classpathDirArg) {
410471
const char *classpath_dir_arg = env->GetStringUTFChars(classpathDirArg, nullptr);
411472

412473
if (classpath_dir_arg == nullptr) {
@@ -478,4 +539,9 @@ Java_org_lsposed_lspd_service_DenylistManager_isInDenylistFromClasspathDir(JNIEn
478539

479540
app_in_denylist:
480541
return JNI_TRUE;
481-
}
542+
}
543+
544+
extern "C" JNIEXPORT void JNICALL
545+
Java_org_lsposed_lspd_service_DenylistManager_clearFd(JNIEnv *env, jclass) {
546+
ksu_close_fd();
547+
}

daemon/src/main/jni/ksu.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* This file is part of ReLSPosed.
3+
*
4+
* ReLSPosed is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* ReLSPosed is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with ReLSPosed. If not, see <https://www.gnu.org/licenses/>.
16+
*
17+
* Copyright (C) 2023 The PerformanC Organization Contributors
18+
*/
19+
// -------------------------------------------------------------------------------------------------------------
20+
/* INFO: Code below contains parts of the code of the KernelSU's Daemon. It is protected by its GPL-3.0 license.
21+
See https://github.com/tiann/KernelSU repository for more details. */
22+
// -------------------------------------------------------------------------------------------------------------
23+
24+
25+
#ifndef RELSPOSED_KSU_H
26+
#define RELSPOSED_KSU_H
27+
28+
#include <stdint.h>
29+
#include <sys/ioctl.h>
30+
31+
struct ksu_get_info_cmd {
32+
uint32_t version;
33+
uint32_t flags;
34+
uint32_t features;
35+
};
36+
37+
struct ksu_uid_should_umount_cmd {
38+
uint32_t uid;
39+
uint8_t should_umount;
40+
};
41+
42+
#define KERNEL_SU_OPTION (int)0xdeadbeef
43+
#define KERNELSU_CMD_GET_VERSION 2
44+
#define KERNELSU_CMD_UID_SHOULD_UMOUNT 13
45+
46+
#define KSU_INSTALL_MAGIC1 0xDEADBEEF
47+
#define KSU_INSTALL_MAGIC2 0xCAFEBABE
48+
49+
#define KSU_IOCTL_GET_INFO _IOC(_IOC_READ, 'K', 2, 0)
50+
#define KSU_IOCTL_UID_SHOULD_UMOUNT _IOC(_IOC_READ | _IOC_WRITE, 'K', 9, 0)
51+
52+
#endif //RELSPOSED_KSU_H

0 commit comments

Comments
 (0)