forked from tiann/KernelSU
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
893 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
4.14 KernelSU Hook Patch | ||
* Make sure to disable CONFIG_KPROBE in your device's defconfig | ||
|
||
--- a/fs/exec.c | ||
+++ b/fs/exec.c | ||
@@ -1890,11 +1890,14 @@ static int __do_execve_file(int fd, struct filename *filename, | ||
return retval; | ||
} | ||
|
||
+#ifdef CONFIG_KSU | ||
+extern bool ksu_execveat_hook __read_mostly; | ||
+extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, | ||
+ void *envp, int *flags); | ||
+extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, | ||
+ void *argv, void *envp, int *flags); | ||
+#endif | ||
|
||
/* | ||
* sys_execve() executes a new program. | ||
*/ | ||
static int do_execveat_common(int fd, struct filename *filename, | ||
struct user_arg_ptr argv, | ||
struct user_arg_ptr envp, | ||
int flags) | ||
{ | ||
char *pathbuf = NULL; | ||
struct linux_binprm *bprm; | ||
struct file *file; | ||
struct files_struct *displaced; | ||
int retval; | ||
|
||
+#ifdef CONFIG_KSU | ||
+ if (unlikely(ksu_execveat_hook)) | ||
+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); | ||
+ else | ||
+ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags); | ||
+#endif | ||
|
||
--- a/fs/open.c | ||
+++ b/fs/open.c | ||
@@ -348,6 +348,8 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) | ||
return ksys_fallocate(fd, mode, offset, len); | ||
} | ||
|
||
+#ifdef CONFIG_KSU | ||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, | ||
+ int *flags); | ||
+#endif | ||
/* | ||
* access() needs to use the real uid/gid, not the effective uid/gid. | ||
* We do this by temporarily clearing all FS-related capabilities and | ||
@@ -355,6 +357,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) | ||
*/ | ||
SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) | ||
{ | ||
const struct cred *old_cred; | ||
struct cred *override_cred; | ||
struct path path; | ||
struct inode *inode; | ||
struct vfsmount *mnt; | ||
int res; | ||
unsigned int lookup_flags = LOOKUP_FOLLOW; | ||
+#ifdef CONFIG_KSU | ||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL); | ||
+#endif | ||
|
||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ | ||
return -EINVAL; | ||
|
||
--- a/fs/read_write.c | ||
+++ b/fs/read_write.c | ||
@@ -434,10 +434,14 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos) | ||
} | ||
EXPORT_SYMBOL(kernel_read); | ||
|
||
+#ifdef CONFIG_KSU | ||
+extern bool ksu_vfs_read_hook __read_mostly; | ||
+extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, | ||
+ size_t *count_ptr, loff_t **pos); | ||
+#endif | ||
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) | ||
{ | ||
ssize_t ret; | ||
+#ifdef CONFIG_KSU | ||
+ if (unlikely(ksu_vfs_read_hook)) | ||
+ ksu_handle_vfs_read(&file, &buf, &count, &pos); | ||
+#endif | ||
+ | ||
if (!(file->f_mode & FMODE_READ)) | ||
return -EBADF; | ||
if (!(file->f_mode & FMODE_CAN_READ)) | ||
|
||
--- a/fs/stat.c | ||
+++ b/fs/stat.c | ||
@@ -148,6 +148,8 @@ int vfs_statx_fd(unsigned int fd, struct kstat *stat, | ||
} | ||
EXPORT_SYMBOL(vfs_statx_fd); | ||
|
||
+#ifdef CONFIG_KSU | ||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); | ||
+#endif | ||
+ | ||
/** | ||
* vfs_statx - Get basic and extra attributes by filename | ||
* @dfd: A file descriptor representing the base dir for a relative filename | ||
@@ -170,6 +172,7 @@ int vfs_statx(int dfd, const char __user *filename, int flags, | ||
int error = -EINVAL; | ||
unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT; | ||
|
||
+#ifdef CONFIG_KSU | ||
+ ksu_handle_stat(&dfd, &filename, &flags); | ||
+#endif | ||
if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | | ||
AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0) | ||
return -EINVAL; | ||
|
||
--- a/drivers/input/input.c | ||
+++ b/drivers/input/input.c | ||
@@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev, | ||
return disposition; | ||
} | ||
|
||
+#ifdef CONFIG_KSU | ||
+extern bool ksu_input_hook __read_mostly; | ||
+extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); | ||
+#endif | ||
+ | ||
static void input_handle_event(struct input_dev *dev, | ||
unsigned int type, unsigned int code, int value) | ||
{ | ||
int disposition = input_get_disposition(dev, type, code, &value); | ||
+#ifdef CONFIG_KSU | ||
+ if (unlikely(ksu_input_hook)) | ||
+ ksu_handle_input_handle_event(&type, &code, &value); | ||
+#endif | ||
|
||
if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) | ||
add_input_randomness(type, code, value); | ||
|
||
--- a/fs/devpts/inode.c | ||
+++ b/fs/devpts/inode.c | ||
@@ -602,6 +602,8 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv) | ||
return dentry; | ||
} | ||
|
||
+#ifdef CONFIG_KSU | ||
+extern int ksu_handle_devpts(struct inode*); | ||
+#endif | ||
+ | ||
/** | ||
* devpts_get_priv -- get private data for a slave | ||
* @pts_inode: inode of the slave | ||
@@ -610,6 +612,7 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv) | ||
*/ | ||
void *devpts_get_priv(struct dentry *dentry) | ||
{ | ||
+#ifdef CONFIG_KSU | ||
+ ksu_handle_devpts(dentry->d_inode); | ||
+#endif | ||
if (dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC) | ||
return NULL; | ||
return dentry->d_fsdata; | ||
|
||
--- a/fs/namespace.c | ||
+++ b/fs/namespace.c | ||
@@ -1739,6 +1739,39 @@ static inline bool may_mandlock(void) | ||
} | ||
#endif | ||
|
||
+#ifdef CONFIG_KSU | ||
+static int can_umount(const struct path *path, int flags) | ||
+{ | ||
+ struct mount *mnt = real_mount(path->mnt); | ||
+ | ||
+ if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW)) | ||
+ return -EINVAL; | ||
+ if (!may_mount()) | ||
+ return -EPERM; | ||
+ if (path->dentry != path->mnt->mnt_root) | ||
+ return -EINVAL; | ||
+ if (!check_mnt(mnt)) | ||
+ return -EINVAL; | ||
+ if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */ | ||
+ return -EINVAL; | ||
+ if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) | ||
+ return -EPERM; | ||
+ return 0; | ||
+} | ||
+ | ||
+int path_umount(struct path *path, int flags) | ||
+{ | ||
+ struct mount *mnt = real_mount(path->mnt); | ||
+ int ret; | ||
+ | ||
+ ret = can_umount(path, flags); | ||
+ if (!ret) | ||
+ ret = do_umount(mnt, flags); | ||
+ | ||
+ /* we mustn't call path_put() as that would clear mnt_expiry_mark */ | ||
+ dput(path->dentry); | ||
+ mntput_no_expire(mnt); | ||
+ return ret; | ||
+} | ||
+#endif | ||
+ | ||
/* | ||
* Now umount can handle mount points as well as block devices. | ||
* This is important for filesystems which use unnamed block devices. |
Oops, something went wrong.