Skip to content

Commit 4b0b1b3

Browse files
KernelSU: Use scope-minimized manual hooks
This refactors original KSU hooks to replace deep kernel function hooks with targeted hooks. This backports KernelSU pr#1657 and having pr#2084 elements (32-bit sucompat). This transition reduces the scope of kernel function interception while still maintaining full functionality. references: backslashxx/KernelSU#5, tiann/KernelSU#1657, tiann/KernelSU#2084 https://kernelsu.org/guide/how-to-integrate-for-non-gki.html Co-Authored-by: backslashxx <[email protected]>
1 parent 0203cc9 commit 4b0b1b3

File tree

4 files changed

+51
-42
lines changed

4 files changed

+51
-42
lines changed

fs/exec.c

+22-14
Original file line numberDiff line numberDiff line change
@@ -1870,13 +1870,6 @@ static int bprm_execve(struct linux_binprm *bprm,
18701870

18711871
return retval;
18721872
}
1873-
#ifdef CONFIG_KSU_MANUAL_HOOK
1874-
extern bool ksu_execveat_hook __read_mostly;
1875-
extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv,
1876-
void *envp, int *flags);
1877-
extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
1878-
void *argv, void *envp, int *flags);
1879-
#endif
18801873

18811874
static int do_execveat_common(int fd, struct filename *filename,
18821875
struct user_arg_ptr argv,
@@ -1886,13 +1879,6 @@ static int do_execveat_common(int fd, struct filename *filename,
18861879
struct linux_binprm *bprm;
18871880
int retval;
18881881

1889-
#ifdef CONFIG_KSU_MANUAL_HOOK
1890-
if (unlikely(ksu_execveat_hook))
1891-
ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags);
1892-
else
1893-
ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags);
1894-
#endif
1895-
18961882
if (IS_ERR(filename))
18971883
return PTR_ERR(filename);
18981884

@@ -2025,12 +2011,28 @@ int kernel_execve(const char *kernel_filename,
20252011
return retval;
20262012
}
20272013

2014+
#ifdef CONFIG_KSU_MANUAL_HOOK
2015+
extern bool ksu_execveat_hook __read_mostly;
2016+
extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv,
2017+
void *envp, int *flags);
2018+
extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
2019+
void *argv, void *envp, int *flags);
2020+
#endif
2021+
20282022
static int do_execve(struct filename *filename,
20292023
const char __user *const __user *__argv,
20302024
const char __user *const __user *__envp)
20312025
{
20322026
struct user_arg_ptr argv = { .ptr.native = __argv };
20332027
struct user_arg_ptr envp = { .ptr.native = __envp };
2028+
2029+
#ifdef CONFIG_KSU_MANUAL_HOOK
2030+
if (unlikely(ksu_execveat_hook))
2031+
ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0);
2032+
else
2033+
ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL);
2034+
#endif
2035+
20342036
return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
20352037
}
20362038

@@ -2058,6 +2060,12 @@ static int compat_do_execve(struct filename *filename,
20582060
.is_compat = true,
20592061
.ptr.compat = __envp,
20602062
};
2063+
2064+
#ifdef CONFIG_KSU_MANUAL_HOOK
2065+
if (!ksu_execveat_hook)
2066+
ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit support */
2067+
#endif
2068+
20612069
return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
20622070
}
20632071

fs/open.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,6 @@ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
324324
}
325325
EXPORT_SYMBOL_GPL(vfs_fallocate);
326326

327-
#ifdef CONFIG_KSU_MANUAL_HOOK
328-
extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
329-
int *flags);
330-
#endif
331-
332327
int ksys_fallocate(int fd, int mode, loff_t offset, loff_t len)
333328
{
334329
struct fd f = fdget(fd);
@@ -346,6 +341,11 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
346341
return ksys_fallocate(fd, mode, offset, len);
347342
}
348343

344+
#ifdef CONFIG_KSU_MANUAL_HOOK
345+
extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
346+
int *flags);
347+
#endif
348+
349349
/*
350350
* access() needs to use the real uid/gid, not the effective uid/gid.
351351
* We do this by temporarily clearing all FS-related capabilities and
@@ -408,10 +408,6 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla
408408
unsigned int lookup_flags = LOOKUP_FOLLOW;
409409
const struct cred *old_cred = NULL;
410410

411-
#ifdef CONFIG_KSU_MANUAL_HOOK
412-
ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
413-
#endif
414-
415411
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
416412
return -EINVAL;
417413

@@ -478,9 +474,13 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla
478474

479475
SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
480476
{
477+
#ifdef CONFIG_KSU_MANUAL_HOOK
478+
ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
479+
#endif
481480
return do_faccessat(dfd, filename, mode, 0);
482481
}
483482

483+
484484
SYSCALL_DEFINE4(faccessat2, int, dfd, const char __user *, filename, int, mode,
485485
int, flags)
486486
{

fs/read_write.c

+10-11
Original file line numberDiff line numberDiff line change
@@ -473,21 +473,10 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
473473
}
474474
EXPORT_SYMBOL_NS(kernel_read, ANDROID_GKI_VFS_EXPORT_ONLY);
475475

476-
#ifdef CONFIG_KSU_MANUAL_HOOK
477-
extern bool ksu_vfs_read_hook __read_mostly;
478-
extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
479-
size_t *count_ptr, loff_t **pos);
480-
#endif
481-
482476
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
483477
{
484478
ssize_t ret;
485479

486-
#ifdef CONFIG_KSU_MANUAL_HOOK
487-
if (unlikely(ksu_vfs_read_hook))
488-
ksu_handle_vfs_read(&file, &buf, &count, &pos);
489-
#endif
490-
491480
if (!(file->f_mode & FMODE_READ))
492481
return -EBADF;
493482
if (!(file->f_mode & FMODE_CAN_READ))
@@ -650,8 +639,18 @@ ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count)
650639
return ret;
651640
}
652641

642+
#ifdef CONFIG_KSU_MANUAL_HOOK
643+
extern bool ksu_vfs_read_hook __read_mostly;
644+
extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr,
645+
size_t *count_ptr);
646+
#endif
647+
653648
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
654649
{
650+
#ifdef CONFIG_KSU_MANUAL_HOOK
651+
if (unlikely(ksu_vfs_read_hook))
652+
ksu_handle_sys_read(fd, &buf, &count);
653+
#endif
655654
return ksys_read(fd, buf, count);
656655
}
657656

fs/stat.c

+10-8
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,6 @@ int vfs_fstat(int fd, struct kstat *stat)
156156
return error;
157157
}
158158

159-
#ifdef CONFIG_KSU_MANUAL_HOOK
160-
extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
161-
#endif
162-
163159
/**
164160
* vfs_statx - Get basic and extra attributes by filename
165161
* @dfd: A file descriptor representing the base dir for a relative filename
@@ -182,10 +178,6 @@ static int vfs_statx(int dfd, const char __user *filename, int flags,
182178
unsigned lookup_flags = 0;
183179
int error;
184180

185-
#ifdef CONFIG_KSU_MANUAL_HOOK
186-
ksu_handle_stat(&dfd, &filename, &flags);
187-
#endif
188-
189181
if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
190182
AT_STATX_SYNC_TYPE))
191183
return -EINVAL;
@@ -381,13 +373,20 @@ SYSCALL_DEFINE2(newlstat, const char __user *, filename,
381373
return cp_new_stat(&stat, statbuf);
382374
}
383375

376+
#ifdef CONFIG_KSU_MANUAL_HOOK
377+
extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
378+
#endif
379+
384380
#if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
385381
SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,
386382
struct stat __user *, statbuf, int, flag)
387383
{
388384
struct kstat stat;
389385
int error;
390386

387+
#ifdef CONFIG_KSU_MANUAL_HOOK
388+
ksu_handle_stat(&dfd, &filename, &flag);
389+
#endif
391390
error = vfs_fstatat(dfd, filename, &stat, flag);
392391
if (error)
393392
return error;
@@ -539,6 +538,9 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename,
539538
struct kstat stat;
540539
int error;
541540

541+
#ifdef CONFIG_KSU_MANUAL_HOOK
542+
ksu_handle_stat(&dfd, &filename, &flag); /* 32-bit su support */
543+
#endif
542544
error = vfs_fstatat(dfd, filename, &stat, flag);
543545
if (error)
544546
return error;

0 commit comments

Comments
 (0)