Skip to content

Commit aad473e

Browse files
authored
Update KernelSU Next integration guide for non-GKI
Updated the integration guide for non-GKI devices to reflect that KernelSU Next is backported to 4.14 and earlier versions instead of 5.4. Adjusted references to kernel versions throughout the document.
1 parent 8737e61 commit aad473e

1 file changed

Lines changed: 63 additions & 128 deletions

File tree

docs/pages/how-to-integrate-for-non-gki.md

Lines changed: 63 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Integrate for non-GKI devices
22

3-
KernelSU Next can be integrated into non-GKI kernels and was backported to 5.4 and earlier versions.
3+
KernelSU Next can be integrated into non-GKI kernels and was backported to 4.14 and earlier versions.
44

55
Due to the fragmentation of non-GKI kernels, we don't have a universal way to build them; therefore, we cannot provide a non-GKI boot.img. However, you can build the kernel with KernelSU Next integrated on your own.
66

@@ -42,7 +42,7 @@ Comment out `ksu_sucompat_init()` and `ksu_ksud_init()` in `KernelSU/kernel/ksu.
4242

4343
## Manually modify the kernel source
4444

45-
If kprobe doesn't work on your kernel—either because of an upstream bug or because your kernel is older than 5.4 you can try the following approach:
45+
If kprobe doesn't work on your kernel—either because of an upstream bug or because your kernel is older than 4.14 you can try the following approach:
4646

4747
First, add KernelSU Next to your kernel source tree:
4848

@@ -65,36 +65,39 @@ Next, add KernelSU Next calls to the kernel source. Below are some patches for r
6565
diff --git a/fs/exec.c b/fs/exec.c
6666
--- a/fs/exec.c
6767
+++ b/fs/exec.c
68-
--- a/fs/exec.c
69-
+++ b/fs/exec.c
70-
/*
71-
* sys_execve() executes a new program.
72-
*/
68+
@@ -1886,12 +1886,26 @@ static int do_execveat_common(int fd, struct filename *filename,
69+
return retval;
70+
}
71+
7372
+#ifdef CONFIG_KSU
7473
+__attribute__((hot))
75-
+extern int ksu_handle_execveat(int *fd,
76-
+ struct filename **filename_ptr,
77-
+ void *argv, void *envp, int *flags);
74+
+extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr,
75+
+ void *argv, void *envp, int *flags);
7876
+#endif
7977
+
80-
static int do_execve_common(struct filename *filename,
81-
struct user_arg_ptr argv,
82-
struct user_arg_ptr envp)
83-
{
84-
struct linux_binprm *bprm;
85-
struct file *file;
86-
struct files_struct *displaced;
87-
int retval;
88-
89-
if (IS_ERR(filename))
90-
return PTR_ERR(filename);
91-
78+
int do_execve(struct filename *filename,
79+
const char __user *const __user *__argv,
80+
const char __user *const __user *__envp)
81+
{
82+
struct user_arg_ptr argv = { .ptr.native = __argv };
83+
struct user_arg_ptr envp = { .ptr.native = __envp };
9284
+#ifdef CONFIG_KSU
9385
+ ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0);
9486
+#endif
95-
/*
96-
* We move the actual failure in case of RLIMIT_NPROC excess from
97-
* set*uid() to execve() because too many poorly written programs
87+
return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
88+
}
89+
90+
@@ -1919,6 +1933,10 @@
91+
static int compat_do_execve(struct filename *filename,
92+
.is_compat = true,
93+
.ptr.compat = __envp,
94+
};
95+
+#ifdef CONFIG_KSU // 32-bit ksud and 32-on-64 support
96+
+ ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0);
97+
+#endif
98+
return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
99+
}
100+
98101
```
99102
```diff[open.c]
100103
diff --git a/fs/open.c b/fs/open.c
@@ -130,69 +133,60 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
130133
```diff[read_write.c]
131134
--- a/fs/read_write.c
132135
+++ b/fs/read_write.c
133-
@@ -429,10 +429,19 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
136+
@@ -568,11 +568,21 @@ static inline void file_pos_write(struct file *file, loff_t pos)
137+
file->f_pos = pos;
134138
}
135-
EXPORT_SYMBOL(kernel_read);
136139
137140
+#ifdef CONFIG_KSU
138141
+extern bool ksu_vfs_read_hook __read_mostly;
139-
+extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
140-
+ size_t *count_ptr, loff_t **pos);
142+
+extern __attribute__((cold)) int ksu_handle_sys_read(unsigned int fd,
143+
+ char __user **buf_ptr, size_t *count_ptr);
141144
+#endif
142-
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
145+
+
146+
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
143147
{
144-
ssize_t ret;
148+
struct fd f = fdget_pos(fd);
149+
ssize_t ret = -EBADF;
145150
146-
+#ifdef CONFIG_KSU
147-
+ if (unlikely(ksu_vfs_read_hook))
148-
+ ksu_handle_vfs_read(&file, &buf, &count, &pos);
151+
+#ifdef CONFIG_KSU
152+
+ if (unlikely(ksu_vfs_read_hook))
153+
+ ksu_handle_sys_read(fd, &buf, &count);
149154
+#endif
150-
if (!(file->f_mode & FMODE_READ))
151-
return -EBADF;
152-
if (!(file->f_mode & FMODE_CAN_READ)))
155+
if (f.file) {
156+
loff_t pos = file_pos_read(f.file);
157+
ret = vfs_read(f.file, buf, count, &pos);
153158
```
154159
```diff[stat.c]
155160
diff --git a/fs/stat.c b/fs/stat.c
156161
--- a/fs/stat.c
157162
+++ b/fs/stat.c
158-
@@ -364,X +364,XX @@
163+
@@ -353,6 +353,10 @@ SYSCALL_DEFINE2(newlstat, const char __user *, filename,
164+
return cp_new_stat(&stat, statbuf);
165+
}
166+
159167
+#ifdef CONFIG_KSU
160-
+extern void ksu_handle_newfstat_ret(unsigned int *fd, struct stat __user **statbuf_ptr);
161-
+#if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64)
162-
+extern void ksu_handle_fstat64_ret(unsigned long *fd, struct stat64 __user **statbuf_ptr); // optional
163-
+#endif
168+
+__attribute__((hot))
169+
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user,
170+
+ int *flags);
164171
+#endif
165172
+
166-
SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf)
167-
{
168-
struct kstat stat;
169-
int error = vfs_fstat(fd, &stat);
170-
171-
if (!error)
172-
error = cp_new_stat(&stat, statbuf);
173173
174-
+#ifdef CONFIG_KSU
175-
+ ksu_handle_newfstat_ret(&fd, &statbuf);
176-
+#endif
177-
return error;
178-
179-
180-
@@ -490,X +497,X @@
181-
SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf)
174+
#if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
175+
SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,
176+
struct stat __user *, statbuf, int, flag)
182177
{
183178
struct kstat stat;
184-
int error = vfs_fstat(fd, &stat);
185-
186-
if (!error)
187-
error = cp_new_stat64(&stat, statbuf);
179+
int error;
188180
189-
+#ifdef CONFIG_KSU // for 32-bit
190-
+ ksu_handle_fstat64_ret(&fd, &statbuf);
181+
+#ifdef CONFIG_KSU
182+
+ ksu_handle_stat(&dfd, &filename, &flag);
191183
+#endif
192-
return error;
193-
}
184+
error = vfs_fstatat(dfd, filename, &stat, flag);
185+
if (error)
186+
return error;
194187
```
195188
```diff[reboot.c]
189+
diff --git a/kernel/reboot.c b/kernel/reboot.c
196190
--- a/kernel/reboot.c
197191
+++ b/kernel/reboot.c
198192
@@ -277,6 +277,11 @@
@@ -222,70 +216,11 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
222216

223217
You should find the five functions in kernel source:
224218

225-
1. `do_faccessat`, usually in `fs/open.c`
226-
2. `do_execveat_common`, usually in `fs/exec.c`
219+
1. `do_execve`, usually in `fs/exec.c`
220+
2. `SYSCALL_DEFINE3`, usually in `fs/open.c`
227221
3. `vfs_read`, usually in `fs/read_write.c`
228-
4. `vfs_statx`, usually in `fs/stat.c`
229-
5. `sys_reboot`, usually in `kernel/reboot.c`
230-
231-
If your kernel doesn't have the `vfs_statx` function, use `vfs_fstatat` instead:
232-
233-
```diff
234-
diff --git a/fs/stat.c b/fs/stat.c
235-
index 068fdbcc9e26..5348b7bb9db2 100644
236-
--- a/fs/stat.c
237-
+++ b/fs/stat.c
238-
@@ -87,6 +87,8 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
239-
}
240-
EXPORT_SYMBOL(vfs_fstat);
241-
242-
+#ifdef CONFIG_KSU
243-
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
244-
+#endif
245-
int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
246-
int flag)
247-
{
248-
@@ -94,6 +96,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
249-
int error = -EINVAL;
250-
unsigned int lookup_flags = 0;
251-
+ #ifdef CONFIG_KSU
252-
+ ksu_handle_stat(&dfd, &filename, &flag);
253-
+ #endif
254-
+
255-
if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
256-
AT_EMPTY_PATH)) != 0)
257-
goto out;
258-
```
259-
260-
For kernels eariler than 4.17, if you cannot find `do_faccessat`, just go to the definition of the `faccessat` syscall and place the call there:
261-
262-
```diff
263-
diff --git a/fs/open.c b/fs/open.c
264-
index 2ff887661237..e758d7db7663 100644
265-
--- a/fs/open.c
266-
+++ b/fs/open.c
267-
@@ -355,6 +355,9 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
268-
return error;
269-
}
270-
271-
+#ifdef CONFIG_KSU
272-
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
273-
+ int *flags);
274-
+#endif
275-
+
276-
/*
277-
* access() needs to use the real uid/gid, not the effective uid/gid.
278-
* We do this by temporarily clearing all FS-related capabilities and
279-
@@ -370,6 +373,8 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
280-
int res;
281-
unsigned int lookup_flags = LOOKUP_FOLLOW;
282-
+ #ifdef CONFIG_KSU
283-
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
284-
+ #endif
285-
+
286-
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
287-
return -EINVAL;
288-
```
222+
4. `SYSCALL_DEFINE4`, usually in `fs/stat.c`
223+
5. `SYSCALL_DEFINE4`, usually in `kernel/reboot.c`
289224

290225
Finally, build your kernel again, and KernelSU Next should work correctly.
291226

0 commit comments

Comments
 (0)