kernel: optimize vfs_read probe.

This commit is contained in:
weishu
2023-02-23 12:12:50 +07:00
parent 09fb118d22
commit 40d7d62af2

View File

@@ -1,4 +1,5 @@
#include "asm/current.h" #include "asm/current.h"
#include "linux/string.h"
#include "linux/cred.h" #include "linux/cred.h"
#include "linux/dcache.h" #include "linux/dcache.h"
#include "linux/err.h" #include "linux/err.h"
@@ -62,7 +63,7 @@ void on_post_fs_data(void)
return; return;
} }
done = true; done = true;
pr_info("ksu_load_allow_list"); pr_info("on_post_fs_data!");
ksu_load_allow_list(); ksu_load_allow_list();
// sanity check, this may influence the performance // sanity check, this may influence the performance
stop_input_hook(); stop_input_hook();
@@ -113,6 +114,35 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
return 0; return 0;
} }
static ssize_t (*orig_read)(struct file *, char __user *, size_t, loff_t *);
static ssize_t (*orig_read_iter)(struct kiocb *, struct iov_iter *);
static struct file_operations fops_proxy;
static ssize_t read_count_append = 0;
static ssize_t read_proxy(struct file *file, char __user *buf, size_t count,
loff_t *pos)
{
bool first_read = file->f_pos == 0;
ssize_t ret = orig_read(file, buf, count, pos);
if (first_read) {
pr_info("read_proxy append %ld + %ld", ret, read_count_append);
ret += read_count_append;
}
return ret;
}
static ssize_t read_iter_proxy(struct kiocb *iocb, struct iov_iter *to)
{
bool first_read = iocb->ki_pos == 0;
ssize_t ret = orig_read_iter(iocb, to);
if (first_read) {
pr_info("read_iter_proxy append %ld + %ld", ret,
read_count_append);
ret += read_count_append;
}
return ret;
}
int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
size_t *count_ptr, loff_t **pos) size_t *count_ptr, loff_t **pos)
{ {
@@ -185,6 +215,22 @@ int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
return 0; return 0;
} }
// we've succeed to insert ksud.rc, now we need to proxy the read and modify the result!
// But, we can not modify the file_operations directly, because it's in read-only memory.
// We just replace the whole file_operations with a proxy one.
memcpy(&fops_proxy, file->f_op, sizeof(struct file_operations));
orig_read = file->f_op->read;
if (orig_read) {
fops_proxy.read = read_proxy;
}
orig_read_iter = file->f_op->read_iter;
if (orig_read_iter) {
fops_proxy.read_iter = read_iter_proxy;
}
// replace the file_operations
file->f_op = &fops_proxy;
read_count_append = rc_count;
*buf_ptr = buf + rc_count; *buf_ptr = buf + rc_count;
*count_ptr = count - rc_count; *count_ptr = count - rc_count;
@@ -193,7 +239,8 @@ int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
static unsigned int volumedown_pressed_count = 0; static unsigned int volumedown_pressed_count = 0;
static bool is_volumedown_enough(unsigned int count) { static bool is_volumedown_enough(unsigned int count)
{
return count >= 3; return count >= 3;
} }
@@ -220,14 +267,14 @@ int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code,
return 0; return 0;
} }
bool ksu_is_safe_mode() { bool ksu_is_safe_mode()
{
static bool safe_mode = false; static bool safe_mode = false;
if (safe_mode) { if (safe_mode) {
// don't need to check again, userspace may call multiple times // don't need to check again, userspace may call multiple times
return true; return true;
} }
// stop hook first! // stop hook first!
stop_input_hook(); stop_input_hook();