mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-05 19:31:57 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
543775015a | ||
|
|
b95186ce17 | ||
|
|
676d5d17df | ||
|
|
d622d068b8 | ||
|
|
14cfb1b990 | ||
|
|
c3c71b8ff6 | ||
|
|
662196de01 |
22 changed files with 2191 additions and 3 deletions
|
|
@ -48,3 +48,20 @@ CONFIG_QCA_CLD_WLAN=m
|
|||
|
||||
# ZRAM
|
||||
CONFIG_ZRAM_WRITEBACK=y
|
||||
|
||||
# KernelSU-Next
|
||||
CONFIG_KSU=y
|
||||
CONFIG_KSU_MANUAL_HOOK=y
|
||||
|
||||
# KernelSU-Next SUSFS
|
||||
CONFIG_KSU_SUSFS=y
|
||||
CONFIG_KSU_SUSFS_SUS_PATH=y
|
||||
CONFIG_KSU_SUSFS_SUS_MOUNT=y
|
||||
# CONFIG_KSU_SUSFS_SUS_MOUNT_MNT_ID_REORDER is not set
|
||||
CONFIG_KSU_SUSFS_SUS_KSTAT=y
|
||||
CONFIG_KSU_SUSFS_SUS_MAPS=y
|
||||
# CONFIG_KSU_SUSFS_SUS_PROC_FD_LINK is not set
|
||||
# CONFIG_KSU_SUSFS_SUS_MEMFD is not set
|
||||
CONFIG_KSU_SUSFS_TRY_UMOUNT=y
|
||||
CONFIG_KSU_SUSFS_SPOOF_UNAME=y
|
||||
CONFIG_KSU_SUSFS_ENABLE_LOG=y
|
||||
|
|
|
|||
|
|
@ -244,4 +244,5 @@ source "drivers/mmi_relay/Kconfig"
|
|||
|
||||
source "drivers/sensors/Kconfig"
|
||||
|
||||
source "drivers/kernelsu/Kconfig"
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -194,3 +194,5 @@ obj-$(CONFIG_MMI_ANNOTATE) += mmi_annotate/
|
|||
obj-$(CONFIG_MMI_INFO) += mmi_info/
|
||||
obj-$(CONFIG_MMI_RELAY) += mmi_relay/
|
||||
obj-$(CONFIG_SENSORS_CLASS) += sensors/
|
||||
|
||||
obj-$(CONFIG_KSU) += kernelsu/
|
||||
|
|
|
|||
|
|
@ -375,10 +375,21 @@ static int input_get_disposition(struct input_dev *dev,
|
|||
return disposition;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
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);
|
||||
int disposition;
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
ksu_handle_input_handle_event(&type, &code, &value);
|
||||
#endif
|
||||
disposition = input_get_disposition(dev, type, code, &value);
|
||||
|
||||
if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
|
||||
add_input_randomness(type, code, value);
|
||||
|
|
|
|||
1
drivers/kernelsu
Symbolic link
1
drivers/kernelsu
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../KernelSU-Next/kernel
|
||||
|
|
@ -14,8 +14,11 @@ obj-y := open.o read_write.o file_table.o super.o \
|
|||
attr.o bad_inode.o file.o filesystems.o namespace.o \
|
||||
seq_file.o xattr.o libfs.o fs-writeback.o \
|
||||
pnode.o splice.o sync.o utimes.o d_path.o \
|
||||
stack.o fs_struct.o statfs.o fs_pin.o nsfs.o \
|
||||
fs_types.o fs_context.o fs_parser.o fsopen.o
|
||||
stack.o fs_struct.o statfs.o fs_pin.o nsfs.o
|
||||
|
||||
obj-$(CONFIG_KSU_SUSFS) += susfs.o
|
||||
|
||||
obj-y += fs_types.o fs_context.o fs_parser.o fsopen.o
|
||||
|
||||
ifeq ($(CONFIG_BLOCK),y)
|
||||
obj-y += buffer.o block_dev.o direct-io.o mpage.o
|
||||
|
|
|
|||
|
|
@ -1904,11 +1904,19 @@ out_ret:
|
|||
return retval;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr,
|
||||
void *argv, void *envp, int *flags);
|
||||
#endif
|
||||
|
||||
static int do_execveat_common(int fd, struct filename *filename,
|
||||
struct user_arg_ptr argv,
|
||||
struct user_arg_ptr envp,
|
||||
int flags)
|
||||
{
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags);
|
||||
#endif
|
||||
return __do_execve_file(fd, filename, argv, envp, flags, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,11 @@ extern int __mnt_want_write_file(struct file *);
|
|||
extern void __mnt_drop_write_file(struct file *);
|
||||
|
||||
extern void dissolve_on_fput(struct vfsmount *);
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
int path_umount(struct path *path, int flags);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fs_struct.c
|
||||
*/
|
||||
|
|
|
|||
118
fs/namei.c
118
fs/namei.c
|
|
@ -46,6 +46,10 @@
|
|||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/namei.h>
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#include <linux/susfs.h>
|
||||
#endif
|
||||
|
||||
/* [Feb-1997 T. Schoebel-Theuer]
|
||||
* Fundamental changes in the pathname lookup mechanisms (namei)
|
||||
* were necessary because of omirr. The reason is that omirr needs
|
||||
|
|
@ -3709,6 +3713,13 @@ struct file *do_filp_open(int dfd, struct filename *pathname,
|
|||
int flags = op->lookup_flags;
|
||||
struct file *filp;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
int error;
|
||||
if (susfs_sus_path_by_filename(pathname, &error, SYSCALL_FAMILY_ALL_ENOENT)) {
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
#endif
|
||||
|
||||
set_nameidata(&nd, dfd, pathname);
|
||||
filp = path_openat(&nd, op, flags | LOOKUP_RCU);
|
||||
if (unlikely(filp == ERR_PTR(-ECHILD)))
|
||||
|
|
@ -3897,6 +3908,19 @@ long do_mknodat(int dfd, const char __user *filename, umode_t mode,
|
|||
int error;
|
||||
unsigned int lookup_flags = 0;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct filename* fname;
|
||||
int status;
|
||||
|
||||
fname = getname_safe(filename);
|
||||
status = susfs_sus_path_by_filename(fname, &error, SYSCALL_FAMILY_MKNOD);
|
||||
putname_safe(fname);
|
||||
|
||||
if (status) {
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
error = may_mknod(mode);
|
||||
if (error)
|
||||
return error;
|
||||
|
|
@ -3976,6 +4000,19 @@ long do_mkdirat(int dfd, const char __user *pathname, umode_t mode)
|
|||
int error;
|
||||
unsigned int lookup_flags = LOOKUP_DIRECTORY;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct filename* fname;
|
||||
int status;
|
||||
|
||||
fname = getname_safe(pathname);
|
||||
status = susfs_sus_path_by_filename(fname, &error, SYSCALL_FAMILY_MKDIRAT);
|
||||
putname_safe(fname);
|
||||
|
||||
if (status) {
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
retry:
|
||||
dentry = user_path_create(dfd, pathname, &path, lookup_flags);
|
||||
if (IS_ERR(dentry))
|
||||
|
|
@ -4051,6 +4088,21 @@ long do_rmdir(int dfd, const char __user *pathname)
|
|||
struct qstr last;
|
||||
int type;
|
||||
unsigned int lookup_flags = 0;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct filename* fname;
|
||||
int status;
|
||||
|
||||
fname = getname_safe(pathname);
|
||||
status = susfs_sus_path_by_filename(fname, &error, SYSCALL_FAMILY_RMDIR);
|
||||
putname_safe(fname);
|
||||
|
||||
if (status) {
|
||||
return error;
|
||||
}
|
||||
error = 0;
|
||||
#endif
|
||||
|
||||
retry:
|
||||
name = filename_parentat(dfd, getname(pathname), lookup_flags,
|
||||
&path, &last, &type);
|
||||
|
|
@ -4182,6 +4234,17 @@ long do_unlinkat(int dfd, struct filename *name)
|
|||
struct inode *inode = NULL;
|
||||
struct inode *delegated_inode = NULL;
|
||||
unsigned int lookup_flags = 0;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
int status;
|
||||
|
||||
status = susfs_sus_path_by_filename(name, &error, SYSCALL_FAMILY_UNLINKAT);
|
||||
|
||||
if (status) {
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
retry:
|
||||
name = filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
|
||||
if (IS_ERR(name))
|
||||
|
|
@ -4289,6 +4352,19 @@ long do_symlinkat(const char __user *oldname, int newdfd,
|
|||
struct path path;
|
||||
unsigned int lookup_flags = 0;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct filename* fname;
|
||||
int status;
|
||||
|
||||
fname = getname_safe(newname);
|
||||
status = susfs_sus_path_by_filename(fname, &error, SYSCALL_FAMILY_SYMLINKAT_NEWNAME);
|
||||
putname_safe(fname);
|
||||
|
||||
if (status) {
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
from = getname(oldname);
|
||||
if (IS_ERR(from))
|
||||
return PTR_ERR(from);
|
||||
|
|
@ -4420,6 +4496,27 @@ int do_linkat(int olddfd, const char __user *oldname, int newdfd,
|
|||
int how = 0;
|
||||
int error;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct filename* fname;
|
||||
int status;
|
||||
|
||||
fname = getname_safe(oldname);
|
||||
status = susfs_sus_path_by_filename(fname, &error, SYSCALL_FAMILY_LINKAT_OLDNAME);
|
||||
putname_safe(fname);
|
||||
|
||||
if (status) {
|
||||
return error;
|
||||
}
|
||||
|
||||
fname = getname_safe(newname);
|
||||
status = susfs_sus_path_by_filename(fname, &error, SYSCALL_FAMILY_LINKAT_NEWNAME);
|
||||
putname_safe(fname);
|
||||
|
||||
if (status) {
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
|
||||
return -EINVAL;
|
||||
/*
|
||||
|
|
@ -4702,6 +4799,27 @@ static int do_renameat2(int olddfd, const char __user *oldname, int newdfd,
|
|||
bool should_retry = false;
|
||||
int error;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct filename* fname;
|
||||
int status;
|
||||
|
||||
fname = getname_safe(oldname);
|
||||
status = susfs_sus_path_by_filename(fname, &error, SYSCALL_FAMILY_RENAMEAT2_OLDNAME);
|
||||
putname_safe(fname);
|
||||
|
||||
if (status) {
|
||||
return error;
|
||||
}
|
||||
|
||||
fname = getname_safe(newname);
|
||||
status = susfs_sus_path_by_filename(fname, &error, SYSCALL_FAMILY_RENAMEAT2_NEWNAME);
|
||||
putname_safe(fname);
|
||||
|
||||
if (status) {
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -1756,6 +1756,43 @@ SYSCALL_DEFINE1(oldumount, char __user *, name)
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
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)
|
||||
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);
|
||||
|
||||
dput(path->dentry);
|
||||
mntput_no_expire(mnt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool is_mnt_ns_file(struct dentry *dentry)
|
||||
{
|
||||
/* Is this a proxy for a mount namespace? */
|
||||
|
|
|
|||
56
fs/open.c
56
fs/open.c
|
|
@ -35,6 +35,10 @@
|
|||
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#include <linux/susfs.h>
|
||||
#endif
|
||||
|
||||
int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
|
||||
struct file *filp)
|
||||
{
|
||||
|
|
@ -123,6 +127,18 @@ long do_sys_truncate(const char __user *pathname, loff_t length)
|
|||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
struct path path;
|
||||
int error;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct filename* fname;
|
||||
int status;
|
||||
|
||||
fname = getname_safe(pathname);
|
||||
status = susfs_sus_path_by_filename(fname, &error, SYSCALL_FAMILY_ALL_ENOENT);
|
||||
putname_safe(fname);
|
||||
|
||||
if (status) {
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (length < 0) /* sorry, but loff_t says... */
|
||||
return -EINVAL;
|
||||
|
|
@ -345,6 +361,12 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
|||
* We do this by temporarily clearing all FS-related capabilities and
|
||||
* switching the fsuid/fsgid around to the real ones.
|
||||
*/
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
extern int ksu_handle_faccessat(int *dfd,
|
||||
const char __user **filename_user,
|
||||
int *mode, int *flags);
|
||||
#endif
|
||||
|
||||
long do_faccessat(int dfd, const char __user *filename, int mode)
|
||||
{
|
||||
const struct cred *old_cred;
|
||||
|
|
@ -354,6 +376,26 @@ long do_faccessat(int dfd, const char __user *filename, int mode)
|
|||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct filename *fname;
|
||||
int status;
|
||||
int error;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
fname = getname_safe(filename);
|
||||
status = susfs_sus_path_by_filename(fname, &error,
|
||||
SYSCALL_FAMILY_ALL_ENOENT);
|
||||
putname_safe(fname);
|
||||
|
||||
if (status)
|
||||
return error;
|
||||
#endif
|
||||
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -455,6 +497,20 @@ int ksys_chdir(const char __user *filename)
|
|||
struct path path;
|
||||
int error;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct filename* fname;
|
||||
int status;
|
||||
|
||||
fname = getname_safe(filename);
|
||||
status = susfs_sus_path_by_filename(fname, &error, SYSCALL_FAMILY_ALL_ENOENT);
|
||||
putname_safe(fname);
|
||||
|
||||
if (status) {
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
retry:
|
||||
error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
|
||||
if (error)
|
||||
|
|
|
|||
|
|
@ -103,6 +103,10 @@
|
|||
|
||||
#include "../../lib/kstrtox.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#include <linux/susfs.h>
|
||||
#endif
|
||||
|
||||
/* NOTE:
|
||||
* Implementing inode permission operations in /proc is almost
|
||||
* certainly an error. Permission checks need to happen during
|
||||
|
|
@ -1793,6 +1797,15 @@ static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
|
|||
char *pathname;
|
||||
int len;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MAPS
|
||||
struct mm_struct *mm;
|
||||
struct vm_area_struct *vma;
|
||||
struct file *vma_file;
|
||||
struct dentry *vma_dentry;
|
||||
struct inode *vma_inode;
|
||||
unsigned long ino;
|
||||
#endif
|
||||
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -1804,6 +1817,39 @@ static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
|
|||
|
||||
if (len > buflen)
|
||||
len = buflen;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PROC_FD_LINK
|
||||
if (!susfs_is_sus_proc_fd_link_list_empty()) {
|
||||
if (susfs_sus_proc_fd_link(pathname, len))
|
||||
goto orig_flow;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MAPS
|
||||
if (!susfs_is_sus_maps_list_empty()) {
|
||||
mm = current->mm;
|
||||
down_read(&mm->mmap_sem);
|
||||
for (vma = mm->mmap; vma; vma = vma->vm_next) {
|
||||
if (vma->vm_file) {
|
||||
vma_file = vma->vm_file;
|
||||
vma_dentry = vma_file->f_path.dentry;
|
||||
if (vma_dentry == path->dentry) {
|
||||
vma_inode = file_inode(vma_file);
|
||||
ino = vma_inode->i_ino;
|
||||
susfs_sus_map_files_readlink(ino, pathname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
up_read(&mm->mmap_sem);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PROC_FD_LINK
|
||||
orig_flow:
|
||||
#endif
|
||||
|
||||
if (copy_to_user(buffer, pathname, len))
|
||||
len = -EFAULT;
|
||||
out:
|
||||
|
|
@ -2208,6 +2254,9 @@ struct map_files_info {
|
|||
unsigned long start;
|
||||
unsigned long end;
|
||||
fmode_t mode;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MAPS
|
||||
int susfs_action;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -2268,6 +2317,10 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
|
|||
struct dentry *result;
|
||||
struct mm_struct *mm;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MAPS
|
||||
int ret = 0;
|
||||
#endif
|
||||
|
||||
result = ERR_PTR(-ENOENT);
|
||||
task = get_proc_task(dir);
|
||||
if (!task)
|
||||
|
|
@ -2294,6 +2347,23 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
|
|||
if (!vma)
|
||||
goto out_no_vma;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MAPS
|
||||
if (vma->vm_file) {
|
||||
ret = susfs_sus_map_files_instantiate(vma);
|
||||
if (ret == 1) {
|
||||
if (vma->vm_file->f_mode & FMODE_WRITE) {
|
||||
vma->vm_file->f_mode &= ~FMODE_WRITE;
|
||||
}
|
||||
goto orig_flow;
|
||||
}
|
||||
if (ret == 2) {
|
||||
result = ERR_PTR(-ENOENT);
|
||||
goto out_no_vma;
|
||||
}
|
||||
}
|
||||
orig_flow:
|
||||
#endif
|
||||
|
||||
if (vma->vm_file)
|
||||
result = proc_map_files_instantiate(dentry, task,
|
||||
(void *)(unsigned long)vma->vm_file->f_mode);
|
||||
|
|
@ -2379,6 +2449,10 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
|
|||
p->start = vma->vm_start;
|
||||
p->end = VMA_PAD_START(vma);
|
||||
p->mode = vma->vm_file->f_mode;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MAPS
|
||||
p->susfs_action = susfs_sus_map_files_instantiate(vma);
|
||||
#endif
|
||||
}
|
||||
up_read(&mm->mmap_sem);
|
||||
mmput(mm);
|
||||
|
|
@ -2389,12 +2463,28 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
|
|||
|
||||
p = genradix_ptr(&fa, i);
|
||||
len = snprintf(buf, sizeof(buf), "%lx-%lx", p->start, p->end);
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MAPS
|
||||
if (p->susfs_action == SUSFS_MAP_FILES_ACTION_REMOVE_WRITE_PERM) {
|
||||
if (p->mode & FMODE_WRITE) {
|
||||
p->mode &= ~FMODE_WRITE;
|
||||
}
|
||||
} else if (p->susfs_action == SUSFS_MAP_FILES_ACTION_HIDE_DENTRY) {
|
||||
goto skip_proc_fill_cache;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!proc_fill_cache(file, ctx,
|
||||
buf, len,
|
||||
proc_map_files_instantiate,
|
||||
task,
|
||||
(void *)(unsigned long)p->mode))
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MAPS
|
||||
skip_proc_fill_cache:
|
||||
#endif
|
||||
|
||||
ctx->pos++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@
|
|||
#include <asm/tlbflush.h>
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#include <linux/susfs.h>
|
||||
#endif
|
||||
|
||||
#define SEQ_PUT_DEC(str, val) \
|
||||
seq_put_decimal_ull_width(m, str, (val) << (PAGE_SHIFT-10), 8)
|
||||
void task_mem(struct seq_file *m, struct mm_struct *mm)
|
||||
|
|
@ -360,6 +364,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
|
|||
unsigned long start, end;
|
||||
dev_t dev = 0;
|
||||
const char *name = NULL;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MAPS
|
||||
char *out_name = NULL;
|
||||
int ret = 0;
|
||||
#endif
|
||||
|
||||
if (file) {
|
||||
struct inode *inode = file_inode(vma->vm_file);
|
||||
|
|
@ -370,8 +378,32 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
|
|||
|
||||
start = vma->vm_start;
|
||||
end = VMA_PAD_START(vma);
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MAPS
|
||||
out_name = kmalloc(SUSFS_MAX_LEN_PATHNAME, GFP_KERNEL);
|
||||
if (!out_name)
|
||||
goto orig_flow;
|
||||
|
||||
ret = susfs_sus_maps(ino, vma->vm_end - vma->vm_start,
|
||||
&ino, &dev, &flags, &pgoff, vma, out_name);
|
||||
|
||||
orig_flow:
|
||||
#endif
|
||||
|
||||
show_vma_header_prefix(m, start, end, flags, pgoff, dev, ino);
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MAPS
|
||||
if (ret == 2) {
|
||||
seq_pad(m, ' ');
|
||||
seq_puts(m, out_name);
|
||||
seq_putc(m, '\n');
|
||||
kfree(out_name);
|
||||
return;
|
||||
}
|
||||
|
||||
kfree(out_name);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Print the dentry name for named mappings, and a
|
||||
* special [heap] marker for the heap:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@
|
|||
#include "pnode.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#include <linux/susfs.h>
|
||||
#endif
|
||||
|
||||
static __poll_t mounts_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
|
|
@ -102,6 +106,11 @@ static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt)
|
|||
struct super_block *sb = mnt_path.dentry->d_sb;
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (susfs_sus_mount(mnt, &p->root))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (sb->s_op->show_devname) {
|
||||
err = sb->s_op->show_devname(m, mnt_path.dentry);
|
||||
if (err)
|
||||
|
|
@ -138,8 +147,31 @@ static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt)
|
|||
struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT_MNT_ID_REORDER
|
||||
int out_mnt_id = 0, out_parent_mnt_id = 0;
|
||||
int status = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (susfs_sus_mount(mnt, &p->root))
|
||||
return 0;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT_MNT_ID_REORDER
|
||||
if (!uid_matches_proc_need_to_reorder_mnt_id())
|
||||
goto orig_flow;
|
||||
status = susfs_get_fake_mnt_id(r->mnt_id, &out_mnt_id, &out_parent_mnt_id);
|
||||
if (status)
|
||||
goto orig_flow;
|
||||
seq_printf(m, "%i %i %u:%u ", out_mnt_id, out_parent_mnt_id,
|
||||
MAJOR(sb->s_dev), MINOR(sb->s_dev));
|
||||
goto bypass_orig_flow;
|
||||
orig_flow:
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT_MNT_ID_REORDER
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
|
||||
MAJOR(sb->s_dev), MINOR(sb->s_dev));
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT_MNT_ID_REORDER
|
||||
bypass_orig_flow:
|
||||
#endif
|
||||
|
||||
if (sb->s_op->show_path) {
|
||||
err = sb->s_op->show_path(m, mnt->mnt_root);
|
||||
if (err)
|
||||
|
|
@ -202,6 +234,11 @@ static int show_vfsstat(struct seq_file *m, struct vfsmount *mnt)
|
|||
struct super_block *sb = mnt_path.dentry->d_sb;
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (susfs_sus_mount(mnt, &p->root))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* device */
|
||||
if (sb->s_op->show_devname) {
|
||||
seq_puts(m, "device ");
|
||||
|
|
@ -285,6 +322,12 @@ static int mounts_open_common(struct inode *inode, struct file *file,
|
|||
p->show = show;
|
||||
p->cached_event = ~0ULL;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT_MNT_ID_REORDER
|
||||
if (uid_matches_proc_need_to_reorder_mnt_id()) {
|
||||
susfs_add_mnt_id_recorder(p->ns);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
err_put_path:
|
||||
|
|
@ -299,6 +342,13 @@ static int mounts_release(struct inode *inode, struct file *file)
|
|||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct proc_mounts *p = m->private;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT_MNT_ID_REORDER
|
||||
if (uid_matches_proc_need_to_reorder_mnt_id()) {
|
||||
susfs_remove_mnt_id_recorder();
|
||||
}
|
||||
#endif
|
||||
|
||||
path_put(&p->root);
|
||||
put_mnt_ns(p->ns);
|
||||
return seq_release_private(inode, file);
|
||||
|
|
|
|||
|
|
@ -443,10 +443,20 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
|
|||
}
|
||||
EXPORT_SYMBOL_NS(kernel_read, ANDROID_GKI_VFS_EXPORT_ONLY);
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
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_MANUAL_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))
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@
|
|||
#include <linux/compat.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#include <linux/susfs.h>
|
||||
#endif
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
/*
|
||||
|
|
@ -328,6 +332,11 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
|
|||
prev_reclen = buf->prev_reclen;
|
||||
if (prev_reclen && signal_pending(current))
|
||||
return -EINTR;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (susfs_sus_ino_for_filldir64(ino)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
dirent = buf->current_dir;
|
||||
prev = (void __user *)dirent - prev_reclen;
|
||||
if (!user_access_begin(prev, reclen + prev_reclen))
|
||||
|
|
|
|||
39
fs/stat.c
39
fs/stat.c
|
|
@ -21,6 +21,10 @@
|
|||
#include <linux/uaccess.h>
|
||||
#include <asm/unistd.h>
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#include <linux/susfs.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* generic_fillattr - Fill in the basic attributes from the inode struct
|
||||
* @inode: Inode to use as the source
|
||||
|
|
@ -112,6 +116,12 @@ int vfs_getattr(const struct path *path, struct kstat *stat,
|
|||
{
|
||||
int retval;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (susfs_sus_path_by_path(path, &retval, SYSCALL_FAMILY_ALL_ENOENT)) {
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
retval = security_inode_getattr(path);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
|
@ -165,6 +175,18 @@ EXPORT_SYMBOL(vfs_statx_fd);
|
|||
*
|
||||
* 0 will be returned on success, and a -ve error code if unsuccessful.
|
||||
*/
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
extern int ksu_handle_stat(int *dfd,
|
||||
const char __user **filename_user,
|
||||
int *flags);
|
||||
extern void ksu_handle_newfstat_ret(unsigned int *fd,
|
||||
struct stat __user **statbuf_ptr);
|
||||
#if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64)
|
||||
extern void ksu_handle_fstat64_ret(unsigned long *fd,
|
||||
struct stat64 __user **statbuf_ptr);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int vfs_statx(int dfd, const char __user *filename, int flags,
|
||||
struct kstat *stat, u32 request_mask)
|
||||
{
|
||||
|
|
@ -172,6 +194,10 @@ 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_MANUAL_HOOK
|
||||
ksu_handle_stat(&dfd, &filename, &flags);
|
||||
#endif
|
||||
|
||||
if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0)
|
||||
return -EINVAL;
|
||||
|
|
@ -330,6 +356,9 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
|
|||
#endif
|
||||
tmp.st_blocks = stat->blocks;
|
||||
tmp.st_blksize = stat->blksize;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
susfs_sus_kstat(tmp.st_ino, &tmp);
|
||||
#endif
|
||||
return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
|
|
@ -379,6 +408,11 @@ SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf)
|
|||
if (!error)
|
||||
error = cp_new_stat(&stat, statbuf);
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
if (!error)
|
||||
ksu_handle_newfstat_ret(&fd, &statbuf);
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -506,6 +540,11 @@ SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf)
|
|||
if (!error)
|
||||
error = cp_new_stat64(&stat, statbuf);
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
if (!error)
|
||||
ksu_handle_fstat64_ret(&fd, &statbuf);
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
|||
1446
fs/susfs.c
Normal file
1446
fs/susfs.c
Normal file
File diff suppressed because it is too large
Load diff
216
include/linux/susfs.h
Normal file
216
include/linux/susfs.h
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
#ifndef KSU_SUSFS_H
|
||||
#define KSU_SUSFS_H
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/mount.h>
|
||||
|
||||
/* shared with userspace ksu_susfs tool */
|
||||
#define CMD_SUSFS_ADD_SUS_PATH 0x55555
|
||||
#define CMD_SUSFS_ADD_SUS_MOUNT 0x55556
|
||||
#define CMD_SUSFS_ADD_SUS_KSTAT 0x55558
|
||||
#define CMD_SUSFS_UPDATE_SUS_KSTAT 0x55559
|
||||
#define CMD_SUSFS_ADD_TRY_UMOUNT 0x5555a
|
||||
#define CMD_SUSFS_SET_UNAME 0x5555b
|
||||
#define CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY 0x5555c
|
||||
#define CMD_SUSFS_ENABLE_LOG 0x5555d
|
||||
#define CMD_SUSFS_ADD_SUS_MAPS_STATICALLY 0x5555e
|
||||
#define CMD_SUSFS_ADD_SUS_PROC_FD_LINK 0x5555f
|
||||
#define CMD_SUSFS_ADD_SUS_MAPS 0x55560
|
||||
#define CMD_SUSFS_UPDATE_SUS_MAPS 0x55561
|
||||
#define CMD_SUSFS_ADD_SUS_MEMFD 0x55562
|
||||
|
||||
#define SUSFS_MAX_LEN_PATHNAME 256 // 256 should address many paths already unless you are doing some strange experimental stuff, then set your own desired length
|
||||
#define SUSFS_MAX_LEN_MFD_NAME 248
|
||||
#define SUSFS_MAX_SUS_MNTS 300 // I think 300 is now enough? This includes the mount entries for each process and sus mounts added by user
|
||||
#define SUSFS_MAX_SUS_MAPS 200 // I think 200 is now enough? Tell me why if you have over 200 entries
|
||||
|
||||
#define SUSFS_MAP_FILES_ACTION_REMOVE_WRITE_PERM 1
|
||||
#define SUSFS_MAP_FILES_ACTION_HIDE_DENTRY 2
|
||||
|
||||
/* non shared to userspace ksu_susfs tool */
|
||||
#define SYSCALL_FAMILY_ALL_ENOENT 0
|
||||
#define SYSCALL_FAMILY_OPENAT 1
|
||||
#define SYSCALL_FAMILY_MKNOD 2
|
||||
#define SYSCALL_FAMILY_MKDIRAT 3
|
||||
#define SYSCALL_FAMILY_RMDIR 4
|
||||
#define SYSCALL_FAMILY_UNLINKAT 5
|
||||
#define SYSCALL_FAMILY_SYMLINKAT_NEWNAME 6
|
||||
#define SYSCALL_FAMILY_LINKAT_OLDNAME 7
|
||||
#define SYSCALL_FAMILY_LINKAT_NEWNAME 8
|
||||
#define SYSCALL_FAMILY_RENAMEAT2_OLDNAME 9
|
||||
#define SYSCALL_FAMILY_RENAMEAT2_NEWNAME 10
|
||||
#define SYSCALL_FAMILY_TRUNCATE 11
|
||||
#define SYSCALL_FAMILY_FACCESSAT 12
|
||||
#define SYSCALL_FAMILY_CHDIR 13
|
||||
|
||||
#define getname_safe(name) (name == NULL ? ERR_PTR(-EINVAL) : getname(name))
|
||||
#define putname_safe(name) (IS_ERR(name) ? NULL : putname(name))
|
||||
|
||||
#define uid_matches_suspicious_path() (current_uid().val >= 2000)
|
||||
#define uid_matches_suspicious_kstat() (current_uid().val >= 2000)
|
||||
#define uid_matches_proc_need_to_reorder_mnt_id() (current_uid().val >= 10000)
|
||||
|
||||
struct st_susfs_sus_path {
|
||||
char target_pathname[SUSFS_MAX_LEN_PATHNAME];
|
||||
unsigned long target_ino;
|
||||
};
|
||||
|
||||
struct st_susfs_sus_mount {
|
||||
char target_pathname[SUSFS_MAX_LEN_PATHNAME];
|
||||
};
|
||||
|
||||
struct st_susfs_sus_kstat {
|
||||
unsigned long target_ino; // the ino after bind mounted or overlayed
|
||||
char target_pathname[SUSFS_MAX_LEN_PATHNAME];
|
||||
char spoofed_pathname[SUSFS_MAX_LEN_PATHNAME];
|
||||
unsigned long spoofed_ino;
|
||||
unsigned long spoofed_dev;
|
||||
unsigned int spoofed_nlink;
|
||||
long spoofed_atime_tv_sec;
|
||||
long spoofed_mtime_tv_sec;
|
||||
long spoofed_ctime_tv_sec;
|
||||
long spoofed_atime_tv_nsec;
|
||||
long spoofed_mtime_tv_nsec;
|
||||
long spoofed_ctime_tv_nsec;
|
||||
};
|
||||
|
||||
struct st_susfs_sus_maps {
|
||||
bool is_statically;
|
||||
int compare_mode;
|
||||
bool is_isolated_entry;
|
||||
bool is_file;
|
||||
unsigned long prev_target_ino;
|
||||
unsigned long next_target_ino;
|
||||
char target_pathname[SUSFS_MAX_LEN_PATHNAME];
|
||||
unsigned long target_ino;
|
||||
unsigned long target_dev;
|
||||
unsigned long long target_pgoff;
|
||||
unsigned long target_prot;
|
||||
unsigned long target_addr_size;
|
||||
char spoofed_pathname[SUSFS_MAX_LEN_PATHNAME];
|
||||
unsigned long spoofed_ino;
|
||||
unsigned long spoofed_dev;
|
||||
unsigned long long spoofed_pgoff;
|
||||
unsigned long spoofed_prot;
|
||||
bool need_to_spoof_pathname;
|
||||
bool need_to_spoof_ino;
|
||||
bool need_to_spoof_dev;
|
||||
bool need_to_spoof_pgoff;
|
||||
bool need_to_spoof_prot;
|
||||
};
|
||||
|
||||
struct st_susfs_try_umount {
|
||||
char target_pathname[SUSFS_MAX_LEN_PATHNAME];
|
||||
int mnt_mode;
|
||||
};
|
||||
|
||||
struct st_susfs_sus_proc_fd_link {
|
||||
char target_link_name[SUSFS_MAX_LEN_PATHNAME];
|
||||
char spoofed_link_name[SUSFS_MAX_LEN_PATHNAME];
|
||||
};
|
||||
|
||||
struct st_susfs_sus_memfd {
|
||||
char target_pathname[SUSFS_MAX_LEN_MFD_NAME];
|
||||
};
|
||||
|
||||
struct st_susfs_mnt_id_recorder {
|
||||
int target_mnt_id[SUSFS_MAX_SUS_MNTS];
|
||||
int spoofed_mnt_id[SUSFS_MAX_SUS_MNTS];
|
||||
int spoofed_parent_mnt_id[SUSFS_MAX_SUS_MNTS];
|
||||
int count;
|
||||
};
|
||||
|
||||
struct st_susfs_sus_path_list {
|
||||
struct list_head list;
|
||||
struct st_susfs_sus_path info;
|
||||
};
|
||||
|
||||
struct st_susfs_sus_mount_list {
|
||||
struct list_head list;
|
||||
struct st_susfs_sus_mount info;
|
||||
};
|
||||
|
||||
struct st_susfs_sus_kstat_list {
|
||||
struct list_head list;
|
||||
struct st_susfs_sus_kstat info;
|
||||
};
|
||||
|
||||
struct st_susfs_sus_maps_list {
|
||||
struct list_head list;
|
||||
struct st_susfs_sus_maps info;
|
||||
};
|
||||
|
||||
struct st_susfs_try_umount_list {
|
||||
struct list_head list;
|
||||
struct st_susfs_try_umount info;
|
||||
};
|
||||
|
||||
struct st_susfs_sus_proc_fd_link_list {
|
||||
struct list_head list;
|
||||
struct st_susfs_sus_proc_fd_link info;
|
||||
};
|
||||
|
||||
struct st_susfs_sus_memfd_list {
|
||||
struct list_head list;
|
||||
struct st_susfs_sus_memfd info;
|
||||
};
|
||||
|
||||
struct st_susfs_mnt_id_recorder_list {
|
||||
struct list_head list;
|
||||
int pid;
|
||||
int opened_count;
|
||||
struct st_susfs_mnt_id_recorder info;
|
||||
};
|
||||
|
||||
struct st_susfs_uname {
|
||||
char sysname[__NEW_UTS_LEN+1];
|
||||
char nodename[__NEW_UTS_LEN+1];
|
||||
char release[__NEW_UTS_LEN+1];
|
||||
char version[__NEW_UTS_LEN+1];
|
||||
char machine[__NEW_UTS_LEN+1];
|
||||
};
|
||||
|
||||
int susfs_add_sus_path(struct st_susfs_sus_path* __user user_info);
|
||||
int susfs_add_sus_mount(struct st_susfs_sus_mount* __user user_info);
|
||||
int susfs_add_sus_kstat(struct st_susfs_sus_kstat* __user user_info);
|
||||
int susfs_update_sus_kstat(struct st_susfs_sus_kstat* __user user_info);
|
||||
int susfs_add_sus_maps(struct st_susfs_sus_maps* __user user_info);
|
||||
int susfs_update_sus_maps(struct st_susfs_sus_maps* __user user_info);
|
||||
int susfs_add_sus_proc_fd_link(struct st_susfs_sus_proc_fd_link* __user user_info);
|
||||
int susfs_add_sus_memfd(struct st_susfs_sus_memfd* __user user_info);
|
||||
int susfs_add_try_umount(struct st_susfs_try_umount* __user user_info);
|
||||
int susfs_set_uname(struct st_susfs_uname* __user user_info);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
|
||||
int susfs_sus_path_by_path(struct path* file, int* errno_to_be_changed, int syscall_family);
|
||||
#else
|
||||
int susfs_sus_path_by_path(const struct path* file, int* errno_to_be_changed, int syscall_family);
|
||||
#endif
|
||||
int susfs_sus_path_by_filename(struct filename* name, int* errno_to_be_changed, int syscall_family);
|
||||
int susfs_sus_mount(struct vfsmount* mnt, struct path* root);
|
||||
int susfs_sus_ino_for_filldir64(unsigned long ino);
|
||||
void susfs_sus_kstat(unsigned long ino, struct stat* out_stat);
|
||||
int susfs_sus_maps(unsigned long target_ino, unsigned long target_addr_size,
|
||||
unsigned long* orig_ino, dev_t* orig_dev, vm_flags_t* flags,
|
||||
unsigned long long* pgoff, struct vm_area_struct* vma, char* out_name);
|
||||
void susfs_sus_map_files_readlink(unsigned long target_ino, char* pathname);
|
||||
int susfs_sus_map_files_instantiate(struct vm_area_struct* vma);
|
||||
int susfs_is_sus_maps_list_empty(void);
|
||||
int susfs_sus_proc_fd_link(char *pathname, int len);
|
||||
int susfs_is_sus_proc_fd_link_list_empty(void);
|
||||
int susfs_sus_memfd(char *memfd_name);
|
||||
void susfs_try_umount(uid_t target_uid);
|
||||
void susfs_spoof_uname(struct new_utsname* tmp);
|
||||
void susfs_add_mnt_id_recorder(struct mnt_namespace *ns);
|
||||
int susfs_get_fake_mnt_id(int mnt_id, int *out_mnt_id, int *out_parent_mnt_id);
|
||||
void susfs_remove_mnt_id_recorder(void);
|
||||
|
||||
void susfs_set_log(bool enabled);
|
||||
|
||||
void susfs_change_error_no_by_pathname(char* pathname, int* errno_to_be_changed, int syscall_family);
|
||||
|
||||
void __init susfs_init(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -310,6 +310,11 @@ DEFINE_MUTEX(system_transition_mutex);
|
|||
*
|
||||
* reboot doesn't sync: do that yourself before calling this.
|
||||
*/
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
extern int ksu_handle_sys_reboot(int magic1, int magic2, unsigned int cmd,
|
||||
void __user **arg);
|
||||
#endif
|
||||
|
||||
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
|
||||
void __user *, arg)
|
||||
{
|
||||
|
|
@ -317,6 +322,10 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
|
|||
char buffer[256];
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_HOOK
|
||||
ksu_handle_sys_reboot(magic1, magic2, cmd, &arg);
|
||||
#endif
|
||||
|
||||
/* We only trust the superuser with rebooting the system. */
|
||||
if (!ns_capable(pid_ns->user_ns, CAP_SYS_BOOT))
|
||||
return -EPERM;
|
||||
|
|
|
|||
17
kernel/sys.c
17
kernel/sys.c
|
|
@ -75,6 +75,14 @@
|
|||
|
||||
#include "uid16.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#include <linux/susfs.h>
|
||||
|
||||
extern long ksu_handle_susfs_prctl(int option, unsigned long arg2,
|
||||
unsigned long arg3, unsigned long arg4,
|
||||
unsigned long arg5);
|
||||
#endif
|
||||
|
||||
#include <trace/hooks/sys.h>
|
||||
|
||||
#ifndef SET_UNALIGN_CTL
|
||||
|
|
@ -1247,6 +1255,9 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
|
|||
down_read(&uts_sem);
|
||||
memcpy(&tmp, utsname(), sizeof(tmp));
|
||||
up_read(&uts_sem);
|
||||
#ifdef CONFIG_KSU_SUSFS_SPOOF_UNAME
|
||||
susfs_spoof_uname(&tmp);
|
||||
#endif
|
||||
if (copy_to_user(name, &tmp, sizeof(tmp)))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -2430,6 +2441,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
|
|||
unsigned char comm[sizeof(me->comm)];
|
||||
long error;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
error = ksu_handle_susfs_prctl(option, arg2, arg3, arg4, arg5);
|
||||
if (error != -ENOSYS)
|
||||
return error;
|
||||
#endif
|
||||
|
||||
error = security_task_prctl(option, arg2, arg3, arg4, arg5);
|
||||
if (error != -ENOSYS)
|
||||
return error;
|
||||
|
|
|
|||
11
mm/memfd.c
11
mm/memfd.c
|
|
@ -20,6 +20,10 @@
|
|||
#include <linux/memfd.h>
|
||||
#include <uapi/linux/memfd.h>
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#include <linux/susfs.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We need a tag: a new tag would expand every xa_node by 8 bytes,
|
||||
* so reuse a tag which we firmly believe is never set or cleared on tmpfs
|
||||
|
|
@ -306,6 +310,13 @@ SYSCALL_DEFINE2(memfd_create,
|
|||
goto err_name;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MEMFD
|
||||
if (susfs_sus_memfd(name)) {
|
||||
error = -EFAULT;
|
||||
goto err_name;
|
||||
}
|
||||
#endif
|
||||
|
||||
fd = get_unused_fd_flags((flags & MFD_CLOEXEC) ? O_CLOEXEC : 0);
|
||||
if (fd < 0) {
|
||||
error = fd;
|
||||
|
|
|
|||
Loading…
Reference in a new issue