kernel: Syncronize upstream changes (#198)
* Cherry-picked range: (kernel)
ebea31daa8..6915b62b9a
* Also merged unmerged pr:
https://github.com/tiann/KernelSU/pull/ 2909
Co-authored-by: Ylarod <me@ylarod.cn>
Co-authored-by: 5ec1cff <56485584+5ec1cff@users.noreply.github.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-authored-by: u9521 <63995396+u9521@users.noreply.github.com>
Co-authored-by: Wang Han <416810799@qq.com>
This commit is contained in:
@@ -1,188 +1,160 @@
|
||||
#include "linux/export.h"
|
||||
#include <linux/export.h>
|
||||
#include <linux/anon_inodes.h>
|
||||
#include <linux/aio.h> // kernel 3.18
|
||||
#include <linux/capability.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include "allowlist.h"
|
||||
#include "klog.h" // IWYU pragma: keep
|
||||
#include "ksu.h"
|
||||
#include "ksud.h"
|
||||
#include "manager.h"
|
||||
#include "selinux/selinux.h"
|
||||
#include "core_hook.h"
|
||||
#include "objsec.h"
|
||||
|
||||
#include "file_wrapper.h"
|
||||
|
||||
#ifdef KSU_NO___POLL_T
|
||||
typedef unsigned int ksu_poll_t;
|
||||
#else
|
||||
typedef __poll_t ksu_poll_t;
|
||||
#endif
|
||||
|
||||
static loff_t ksu_wrapper_llseek(struct file *fp, loff_t off, int flags)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static loff_t ksu_wrapper_llseek(struct file *fp, loff_t off, int flags) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->llseek(data->orig, off, flags);
|
||||
}
|
||||
|
||||
static ssize_t ksu_wrapper_read(struct file *fp, char __user *ptr, size_t sz,
|
||||
loff_t *off)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static ssize_t ksu_wrapper_read(struct file *fp, char __user *ptr, size_t sz, loff_t *off) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->read(orig, ptr, sz, off);
|
||||
}
|
||||
|
||||
static ssize_t ksu_wrapper_write(struct file *fp, const char __user *ptr,
|
||||
size_t sz, loff_t *off)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static ssize_t ksu_wrapper_write(struct file *fp, const char __user *ptr, size_t sz, loff_t *off) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->write(orig, ptr, sz, off);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
|
||||
static ssize_t ksu_wrapper_read_iter(struct kiocb *iocb, struct iov_iter *iovi)
|
||||
{
|
||||
struct ksu_file_wrapper *data = iocb->ki_filp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static ssize_t ksu_wrapper_read_iter(struct kiocb *iocb, struct iov_iter *iovi) {
|
||||
struct ksu_file_wrapper* data = iocb->ki_filp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
iocb->ki_filp = orig;
|
||||
return orig->f_op->read_iter(iocb, iovi);
|
||||
}
|
||||
|
||||
static ssize_t ksu_wrapper_write_iter(struct kiocb *iocb,
|
||||
struct iov_iter *iovi)
|
||||
{
|
||||
struct ksu_file_wrapper *data = iocb->ki_filp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static ssize_t ksu_wrapper_write_iter(struct kiocb *iocb, struct iov_iter *iovi) {
|
||||
struct ksu_file_wrapper* data = iocb->ki_filp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
iocb->ki_filp = orig;
|
||||
return orig->f_op->write_iter(iocb, iovi);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||
static int ksu_wrapper_iopoll(struct kiocb *kiocb, struct io_comp_batch *icb,
|
||||
unsigned int v)
|
||||
{
|
||||
struct ksu_file_wrapper *data = kiocb->ki_filp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_iopoll(struct kiocb *kiocb, struct io_comp_batch* icb, unsigned int v) {
|
||||
struct ksu_file_wrapper* data = kiocb->ki_filp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
kiocb->ki_filp = orig;
|
||||
return orig->f_op->iopoll(kiocb, icb, v);
|
||||
}
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
|
||||
static int ksu_wrapper_iopoll(struct kiocb *kiocb, bool spin)
|
||||
{
|
||||
struct ksu_file_wrapper *data = kiocb->ki_filp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_iopoll(struct kiocb *kiocb, bool spin) {
|
||||
struct ksu_file_wrapper* data = kiocb->ki_filp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
kiocb->ki_filp = orig;
|
||||
return orig->f_op->iopoll(kiocb, spin);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
|
||||
static int ksu_wrapper_iterate(struct file *fp, struct dir_context *dc)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && (LINUX_VERSION_CODE > KERNEL_VERSION(3, 11, 0) || defined(KSU_HAS_ITERATE_DIR))
|
||||
static int ksu_wrapper_iterate (struct file *fp, struct dir_context *dc) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->iterate(orig, dc);
|
||||
}
|
||||
#endif
|
||||
|
||||
// int (*readdir) (struct file *, void *, filldir_t);
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) && !defined(KSU_HAS_ITERATE_DIR)
|
||||
static int ksu_wrapper_readdir(struct file *fp, void *ptr, filldir_t filler) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->readdir(orig, ptr, filler);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
|
||||
static int ksu_wrapper_iterate_shared(struct file *fp, struct dir_context *dc)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_iterate_shared(struct file *fp, struct dir_context *dc) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->iterate_shared(orig, dc);
|
||||
}
|
||||
#endif
|
||||
|
||||
static ksu_poll_t ksu_wrapper_poll(struct file *fp,
|
||||
struct poll_table_struct *pts)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
// typedef unsigned __bitwise __poll_t;
|
||||
static unsigned __bitwise ksu_wrapper_poll(struct file *fp, struct poll_table_struct *pts) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->poll(orig, pts);
|
||||
}
|
||||
|
||||
static long ksu_wrapper_unlocked_ioctl(struct file *fp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static long ksu_wrapper_unlocked_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->unlocked_ioctl(orig, cmd, arg);
|
||||
}
|
||||
|
||||
static long ksu_wrapper_compat_ioctl(struct file *fp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static long ksu_wrapper_compat_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->compat_ioctl(orig, cmd, arg);
|
||||
}
|
||||
|
||||
static int ksu_wrapper_mmap(struct file *fp, struct vm_area_struct *vma)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_mmap(struct file *fp, struct vm_area_struct * vma) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->mmap(orig, vma);
|
||||
}
|
||||
|
||||
// static unsigned long mmap_supported_flags {}
|
||||
|
||||
static int ksu_wrapper_open(struct inode *ino, struct file *fp)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_open(struct inode *ino, struct file *fp) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
struct inode *orig_ino = file_inode(orig);
|
||||
return orig->f_op->open(orig_ino, orig);
|
||||
}
|
||||
|
||||
static int ksu_wrapper_flush(struct file *fp, fl_owner_t id)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_flush(struct file *fp, fl_owner_t id) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->flush(orig, id);
|
||||
}
|
||||
|
||||
static int ksu_wrapper_fsync(struct file *fp, loff_t off1, loff_t off2,
|
||||
int datasync)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
|
||||
static int ksu_wrapper_fsync(struct file *fp, loff_t off1, loff_t off2, int datasync) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->fsync(orig, off1, off2, datasync);
|
||||
}
|
||||
|
||||
static int ksu_wrapper_fasync(int arg, struct file *fp, int arg2)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_fasync(int arg, struct file *fp, int arg2) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->fasync(arg, orig, arg2);
|
||||
}
|
||||
|
||||
static int ksu_wrapper_lock(struct file *fp, int arg1, struct file_lock *fl)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_lock(struct file *fp, int arg1, struct file_lock *fl) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->lock(orig, arg1, fl);
|
||||
}
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
|
||||
static ssize_t ksu_wrapper_sendpage(struct file *fp, struct page *pg, int arg1,
|
||||
size_t sz, loff_t *off, int arg2)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static ssize_t ksu_wrapper_sendpage(struct file *fp, struct page *pg, int arg1, size_t sz, loff_t *off, int arg2) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->sendpage) {
|
||||
return orig->f_op->sendpage(orig, pg, arg1, sz, off, arg2);
|
||||
}
|
||||
@@ -190,51 +162,38 @@ static ssize_t ksu_wrapper_sendpage(struct file *fp, struct page *pg, int arg1,
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned long ksu_wrapper_get_unmapped_area(struct file *fp,
|
||||
unsigned long arg1,
|
||||
unsigned long arg2,
|
||||
unsigned long arg3,
|
||||
unsigned long arg4)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static unsigned long ksu_wrapper_get_unmapped_area(struct file *fp, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->get_unmapped_area) {
|
||||
return orig->f_op->get_unmapped_area(orig, arg1, arg2, arg3,
|
||||
arg4);
|
||||
return orig->f_op->get_unmapped_area(orig, arg1, arg2, arg3, arg4);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// static int ksu_wrapper_check_flags(int arg) {}
|
||||
|
||||
static int ksu_wrapper_flock(struct file *fp, int arg1, struct file_lock *fl)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_flock(struct file *fp, int arg1, struct file_lock *fl) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->flock) {
|
||||
return orig->f_op->flock(orig, arg1, fl);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static ssize_t ksu_wrapper_splice_write(struct pipe_inode_info *pii,
|
||||
struct file *fp, loff_t *off,
|
||||
size_t sz, unsigned int arg1)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static ssize_t ksu_wrapper_splice_write(struct pipe_inode_info * pii, struct file *fp, loff_t *off, size_t sz, unsigned int arg1) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->splice_write) {
|
||||
return orig->f_op->splice_write(pii, orig, off, sz, arg1);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static ssize_t ksu_wrapper_splice_read(struct file *fp, loff_t *off,
|
||||
struct pipe_inode_info *pii, size_t sz,
|
||||
unsigned int arg1)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static ssize_t ksu_wrapper_splice_read(struct file *fp, loff_t *off, struct pipe_inode_info *pii, size_t sz, unsigned int arg1) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->splice_read) {
|
||||
return orig->f_op->splice_read(orig, off, pii, sz, arg1);
|
||||
}
|
||||
@@ -242,10 +201,9 @@ static ssize_t ksu_wrapper_splice_read(struct file *fp, loff_t *off,
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
|
||||
void ksu_wrapper_splice_eof(struct file *fp)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
void ksu_wrapper_splice_eof(struct file *fp) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->splice_eof) {
|
||||
return orig->f_op->splice_eof(orig);
|
||||
}
|
||||
@@ -253,45 +211,36 @@ void ksu_wrapper_splice_eof(struct file *fp)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||
static int ksu_wrapper_setlease(struct file *fp, int arg1,
|
||||
struct file_lease **fl, void **p)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_setlease(struct file *fp, int arg1, struct file_lease **fl, void **p) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->setlease) {
|
||||
return orig->f_op->setlease(orig, arg1, fl, p);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
|
||||
static int ksu_wrapper_setlease(struct file *fp, int arg1,
|
||||
struct file_lock **fl, void **p)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_setlease(struct file *fp, int arg1, struct file_lock **fl, void **p) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->setlease) {
|
||||
return orig->f_op->setlease(orig, arg1, fl, p);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
// int (*setlease)(struct file *, long, struct file_lock **, void **);
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
|
||||
static int ksu_wrapper_setlease(struct file *fp, long arg1,
|
||||
struct file_lock **fl, void **p)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) // int (*setlease)(struct file *, long, struct file_lock **, void **);
|
||||
static int ksu_wrapper_setlease(struct file *fp, long arg1, struct file_lock **fl, void **p) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->setlease) {
|
||||
return orig->f_op->setlease(orig, arg1, fl, p);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
#else // int (*setlease)(struct file *, long, struct file_lock **);
|
||||
static int ksu_wrapper_setlease(struct file *fp, long arg1,
|
||||
struct file_lock **fl)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_setlease(struct file *fp, long arg1, struct file_lock **fl) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->setlease) {
|
||||
return orig->f_op->setlease(orig, arg1, fl);
|
||||
}
|
||||
@@ -299,11 +248,9 @@ static int ksu_wrapper_setlease(struct file *fp, long arg1,
|
||||
}
|
||||
#endif
|
||||
|
||||
static long ksu_wrapper_fallocate(struct file *fp, int mode, loff_t offset,
|
||||
loff_t len)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static long ksu_wrapper_fallocate(struct file *fp, int mode, loff_t offset, loff_t len) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->fallocate) {
|
||||
return orig->f_op->fallocate(orig, mode, offset, len);
|
||||
}
|
||||
@@ -311,20 +258,17 @@ static long ksu_wrapper_fallocate(struct file *fp, int mode, loff_t offset,
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
|
||||
static void ksu_wrapper_show_fdinfo(struct seq_file *m, struct file *f)
|
||||
{
|
||||
struct ksu_file_wrapper *data = m->file->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static void ksu_wrapper_show_fdinfo(struct seq_file *m, struct file *f) {
|
||||
struct ksu_file_wrapper* data = f->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->show_fdinfo) {
|
||||
orig->f_op->show_fdinfo(m, orig);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
static int ksu_wrapper_show_fdinfo(struct seq_file *m, struct file *f)
|
||||
{
|
||||
struct ksu_file_wrapper *data = m->file->private_data;
|
||||
struct file *orig = data->orig;
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
|
||||
static int ksu_wrapper_show_fdinfo(struct seq_file *m, struct file *f) {
|
||||
struct ksu_file_wrapper* data = f->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->show_fdinfo) {
|
||||
orig->f_op->show_fdinfo(m, orig);
|
||||
}
|
||||
@@ -333,44 +277,40 @@ static int ksu_wrapper_show_fdinfo(struct seq_file *m, struct file *f)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
|
||||
static ssize_t ksu_wrapper_copy_file_range(struct file *f1, loff_t off1,
|
||||
struct file *f2, loff_t off2,
|
||||
size_t sz, unsigned int flags)
|
||||
{
|
||||
// TODO: determine which file to use
|
||||
struct ksu_file_wrapper *data = f1->private_data;
|
||||
struct file *orig = data->orig;
|
||||
if (orig->f_op->copy_file_range) {
|
||||
return orig->f_op->copy_file_range(orig, off1, f2, off2, sz,
|
||||
flags);
|
||||
}
|
||||
return -EINVAL;
|
||||
// https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/fs/read_write.c;l=1593-1606;drc=398da7defe218d3e51b0f3bdff75147e28125b60
|
||||
static ssize_t ksu_wrapper_copy_file_range(struct file *file_in, loff_t pos_in, struct file *file_out,
|
||||
loff_t pos_out, size_t len, unsigned int flags) {
|
||||
struct ksu_file_wrapper* data = file_out->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->copy_file_range(file_in, pos_in, orig, pos_out, len, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
|
||||
// no REMAP_FILE_DEDUP: use file_in
|
||||
// https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/fs/read_write.c;l=1598-1599;drc=398da7defe218d3e51b0f3bdff75147e28125b60
|
||||
// https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/fs/remap_range.c;l=403-404;drc=398da7defe218d3e51b0f3bdff75147e28125b60
|
||||
// REMAP_FILE_DEDUP: use file_out
|
||||
// https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/fs/remap_range.c;l=483-484;drc=398da7defe218d3e51b0f3bdff75147e28125b60
|
||||
static loff_t ksu_wrapper_remap_file_range(struct file *file_in, loff_t pos_in,
|
||||
struct file *file_out,
|
||||
loff_t pos_out, loff_t len,
|
||||
unsigned int remap_flags)
|
||||
{
|
||||
// TODO: determine which file to use
|
||||
struct ksu_file_wrapper *data = file_in->private_data;
|
||||
struct file *orig = data->orig;
|
||||
if (orig->f_op->remap_file_range) {
|
||||
return orig->f_op->remap_file_range(orig, pos_in, file_out,
|
||||
pos_out, len, remap_flags);
|
||||
struct file *file_out, loff_t pos_out,
|
||||
loff_t len, unsigned int remap_flags) {
|
||||
if (remap_flags & REMAP_FILE_DEDUP) {
|
||||
struct ksu_file_wrapper* data = file_out->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->remap_file_range(file_in, pos_in, orig, pos_out, len, remap_flags);
|
||||
} else {
|
||||
struct ksu_file_wrapper* data = file_in->private_data;
|
||||
struct file* orig = data->orig;
|
||||
return orig->f_op->remap_file_range(orig, pos_in, file_out, pos_out, len, remap_flags);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
|
||||
static int ksu_wrapper_fadvise(struct file *fp, loff_t off1, loff_t off2,
|
||||
int flags)
|
||||
{
|
||||
struct ksu_file_wrapper *data = fp->private_data;
|
||||
struct file *orig = data->orig;
|
||||
static int ksu_wrapper_fadvise(struct file *fp, loff_t off1, loff_t off2, int flags) {
|
||||
struct ksu_file_wrapper* data = fp->private_data;
|
||||
struct file* orig = data->orig;
|
||||
if (orig->f_op->fadvise) {
|
||||
return orig->f_op->fadvise(orig, off1, off2, flags);
|
||||
}
|
||||
@@ -378,16 +318,13 @@ static int ksu_wrapper_fadvise(struct file *fp, loff_t off1, loff_t off2,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ksu_wrapper_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
static int ksu_wrapper_release(struct inode *inode, struct file *filp) {
|
||||
ksu_delete_file_wrapper(filp->private_data);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ksu_file_wrapper *ksu_create_file_wrapper(struct file *fp)
|
||||
{
|
||||
struct ksu_file_wrapper *p =
|
||||
kcalloc(sizeof(struct ksu_file_wrapper), 1, GFP_KERNEL);
|
||||
struct ksu_file_wrapper* ksu_create_file_wrapper(struct file* fp) {
|
||||
struct ksu_file_wrapper* p = kcalloc(sizeof(struct ksu_file_wrapper), 1, GFP_KERNEL);
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -401,24 +338,23 @@ struct ksu_file_wrapper *ksu_create_file_wrapper(struct file *fp)
|
||||
p->ops.write = fp->f_op->write ? ksu_wrapper_write : NULL;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
|
||||
p->ops.read_iter = fp->f_op->read_iter ? ksu_wrapper_read_iter : NULL;
|
||||
p->ops.write_iter =
|
||||
fp->f_op->write_iter ? ksu_wrapper_write_iter : NULL;
|
||||
p->ops.write_iter = fp->f_op->write_iter ? ksu_wrapper_write_iter : NULL;
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||
p->ops.iopoll = fp->f_op->iopoll ? ksu_wrapper_iopoll : NULL;
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && (LINUX_VERSION_CODE > KERNEL_VERSION(3, 11, 0) || defined(KSU_HAS_ITERATE_DIR))
|
||||
p->ops.iterate = fp->f_op->iterate ? ksu_wrapper_iterate : NULL;
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) && !defined(KSU_HAS_ITERATE_DIR)
|
||||
p->ops.readdir = fp->f_op->readdir ? ksu_wrapper_readdir : NULL;
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
|
||||
p->ops.iterate_shared =
|
||||
fp->f_op->iterate_shared ? ksu_wrapper_iterate_shared : NULL;
|
||||
p->ops.iterate_shared = fp->f_op->iterate_shared ? ksu_wrapper_iterate_shared : NULL;
|
||||
#endif
|
||||
p->ops.poll = fp->f_op->poll ? ksu_wrapper_poll : NULL;
|
||||
p->ops.unlocked_ioctl =
|
||||
fp->f_op->unlocked_ioctl ? ksu_wrapper_unlocked_ioctl : NULL;
|
||||
p->ops.compat_ioctl =
|
||||
fp->f_op->compat_ioctl ? ksu_wrapper_compat_ioctl : NULL;
|
||||
p->ops.unlocked_ioctl = fp->f_op->unlocked_ioctl ? ksu_wrapper_unlocked_ioctl : NULL;
|
||||
p->ops.compat_ioctl = fp->f_op->compat_ioctl ? ksu_wrapper_compat_ioctl : NULL;
|
||||
p->ops.mmap = fp->f_op->mmap ? ksu_wrapper_mmap : NULL;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||
p->ops.fop_flags = fp->f_op->fop_flags;
|
||||
@@ -434,42 +370,33 @@ struct ksu_file_wrapper *ksu_create_file_wrapper(struct file *fp)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
|
||||
p->ops.sendpage = fp->f_op->sendpage ? ksu_wrapper_sendpage : NULL;
|
||||
#endif
|
||||
p->ops.get_unmapped_area = fp->f_op->get_unmapped_area ?
|
||||
ksu_wrapper_get_unmapped_area :
|
||||
NULL;
|
||||
p->ops.get_unmapped_area = fp->f_op->get_unmapped_area ? ksu_wrapper_get_unmapped_area : NULL;
|
||||
p->ops.check_flags = fp->f_op->check_flags;
|
||||
p->ops.flock = fp->f_op->flock ? ksu_wrapper_flock : NULL;
|
||||
p->ops.splice_write =
|
||||
fp->f_op->splice_write ? ksu_wrapper_splice_write : NULL;
|
||||
p->ops.splice_read =
|
||||
fp->f_op->splice_read ? ksu_wrapper_splice_read : NULL;
|
||||
p->ops.splice_write = fp->f_op->splice_write ? ksu_wrapper_splice_write : NULL;
|
||||
p->ops.splice_read = fp->f_op->splice_read ? ksu_wrapper_splice_read : NULL;
|
||||
p->ops.setlease = fp->f_op->setlease ? ksu_wrapper_setlease : NULL;
|
||||
p->ops.fallocate = fp->f_op->fallocate ? ksu_wrapper_fallocate : NULL;
|
||||
p->ops.show_fdinfo =
|
||||
fp->f_op->show_fdinfo ? ksu_wrapper_show_fdinfo : NULL;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
|
||||
p->ops.show_fdinfo = fp->f_op->show_fdinfo ? ksu_wrapper_show_fdinfo : NULL;
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
|
||||
p->ops.copy_file_range =
|
||||
fp->f_op->copy_file_range ? ksu_wrapper_copy_file_range : NULL;
|
||||
p->ops.copy_file_range = fp->f_op->copy_file_range ? ksu_wrapper_copy_file_range : NULL;
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
|
||||
p->ops.remap_file_range = fp->f_op->remap_file_range ?
|
||||
ksu_wrapper_remap_file_range :
|
||||
NULL;
|
||||
p->ops.remap_file_range = fp->f_op->remap_file_range ? ksu_wrapper_remap_file_range : NULL;
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
|
||||
p->ops.fadvise = fp->f_op->fadvise ? ksu_wrapper_fadvise : NULL;
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
|
||||
p->ops.splice_eof =
|
||||
fp->f_op->splice_eof ? ksu_wrapper_splice_eof : NULL;
|
||||
p->ops.splice_eof = fp->f_op->splice_eof ? ksu_wrapper_splice_eof : NULL;
|
||||
#endif
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void ksu_delete_file_wrapper(struct ksu_file_wrapper *data)
|
||||
{
|
||||
fput((struct file *)data->orig);
|
||||
void ksu_delete_file_wrapper(struct ksu_file_wrapper* data) {
|
||||
fput((struct file*) data->orig);
|
||||
kfree(data);
|
||||
}
|
||||
Reference in New Issue
Block a user