treewide: patch for susfs 1.5.3
* Patch: 50_add_susfs_in_gki-android12-5.10.patch * Revision: ec6d3ae385059409a58d67bc2a10d762e740efcb Signed-off-by: Nahuel Gómez <nahuelgomez329@gmail.com>
This commit is contained in:
parent
b053429f04
commit
c7b62da18c
19 changed files with 512 additions and 0 deletions
|
@ -18,6 +18,9 @@ obj-y := open.o read_write.o file_table.o super.o \
|
|||
fs_types.o fs_context.o fs_parser.o fsopen.o init.o \
|
||||
kernel_read_file.o remap_range.o
|
||||
|
||||
obj-$(CONFIG_KSU_SUSFS) += susfs.o
|
||||
obj-$(CONFIG_KSU_SUSFS_SUS_SU) += sus_su.o
|
||||
|
||||
ifeq ($(CONFIG_BLOCK),y)
|
||||
obj-y += buffer.o block_dev.o direct-io.o mpage.o
|
||||
else
|
||||
|
|
12
fs/dcache.c
12
fs/dcache.c
|
@ -2318,6 +2318,12 @@ seqretry:
|
|||
continue;
|
||||
if (dentry_cmp(dentry, str, hashlen_len(hashlen)) != 0)
|
||||
continue;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (dentry->d_inode && unlikely(dentry->d_inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
*seqp = seq;
|
||||
return dentry;
|
||||
|
@ -2401,6 +2407,12 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name)
|
|||
if (dentry->d_name.hash != hash)
|
||||
continue;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (dentry->d_inode && unlikely(dentry->d_inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
spin_lock(&dentry->d_lock);
|
||||
if (dentry->d_parent != parent)
|
||||
goto next;
|
||||
|
|
|
@ -596,6 +596,11 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv)
|
|||
return dentry;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_KSU_SUSFS_SUS_SU) && !defined(CONFIG_KSU_SUSFS_HAS_MAGIC_MOUNT)
|
||||
extern bool ksu_devpts_hook;
|
||||
extern int ksu_handle_devpts(struct inode*);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* devpts_get_priv -- get private data for a slave
|
||||
* @pts_inode: inode of the slave
|
||||
|
@ -604,6 +609,12 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv)
|
|||
*/
|
||||
void *devpts_get_priv(struct dentry *dentry)
|
||||
{
|
||||
#if defined(CONFIG_KSU_SUSFS_SUS_SU) && !defined(CONFIG_KSU_SUSFS_HAS_MAGIC_MOUNT)
|
||||
if (likely(ksu_devpts_hook)) {
|
||||
ksu_handle_devpts(dentry->d_inode);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC)
|
||||
return NULL;
|
||||
return dentry->d_fsdata;
|
||||
|
|
11
fs/exec.c
11
fs/exec.c
|
@ -1876,6 +1876,12 @@ out_unmark:
|
|||
return retval;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
extern bool susfs_is_sus_su_hooks_enabled __read_mostly;
|
||||
extern int ksu_handle_execveat_sucompat(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,
|
||||
|
@ -1887,6 +1893,11 @@ static int do_execveat_common(int fd, struct filename *filename,
|
|||
if (IS_ERR(filename))
|
||||
return PTR_ERR(filename);
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
if (susfs_is_sus_su_hooks_enabled)
|
||||
ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We move the actual failure in case of RLIMIT_NPROC excess from
|
||||
* set*uid() to execve() because too many poorly written programs
|
||||
|
|
20
fs/inode.c
20
fs/inode.c
|
@ -24,6 +24,10 @@
|
|||
#include <trace/events/writeback.h>
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
extern bool susfs_is_current_ksu_domain(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Inode locking rules:
|
||||
*
|
||||
|
@ -1825,6 +1829,11 @@ int generic_update_time(struct inode *inode, struct timespec64 *time, int flags)
|
|||
int iflags = I_DIRTY_TIME;
|
||||
bool dirty = false;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
if (susfs_is_current_ksu_domain()) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (flags & S_ATIME)
|
||||
inode->i_atime = *time;
|
||||
if (flags & S_VERSION)
|
||||
|
@ -1850,6 +1859,11 @@ EXPORT_SYMBOL(generic_update_time);
|
|||
*/
|
||||
int inode_update_time(struct inode *inode, struct timespec64 *time, int flags)
|
||||
{
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
if (susfs_is_current_ksu_domain()) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (inode->i_op->update_time)
|
||||
return inode->i_op->update_time(inode, time, flags);
|
||||
return generic_update_time(inode, time, flags);
|
||||
|
@ -1906,6 +1920,12 @@ void touch_atime(const struct path *path)
|
|||
struct inode *inode = d_inode(path->dentry);
|
||||
struct timespec64 now;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
if (susfs_is_current_ksu_domain()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!atime_needs_update(path, inode))
|
||||
return;
|
||||
|
||||
|
|
140
fs/namei.c
140
fs/namei.c
|
@ -1052,6 +1052,12 @@ int sysctl_protected_regular __read_mostly;
|
|||
*/
|
||||
static inline int may_follow_link(struct nameidata *nd, const struct inode *inode)
|
||||
{
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (nd->inode && unlikely(nd->inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!sysctl_protected_symlinks)
|
||||
return 0;
|
||||
|
||||
|
@ -1126,6 +1132,12 @@ int may_linkat(struct path *link)
|
|||
{
|
||||
struct inode *inode = link->dentry->d_inode;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (inode && unlikely(inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Inode writeback is not safe when the uid or gid are invalid. */
|
||||
if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
|
||||
return -EOVERFLOW;
|
||||
|
@ -1167,6 +1179,12 @@ int may_linkat(struct path *link)
|
|||
static int may_create_in_sticky(umode_t dir_mode, kuid_t dir_uid,
|
||||
struct inode * const inode)
|
||||
{
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (unlikely(inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((!sysctl_protected_fifos && S_ISFIFO(inode->i_mode)) ||
|
||||
(!sysctl_protected_regular && S_ISREG(inode->i_mode)) ||
|
||||
likely(!(dir_mode & S_ISVTX)) ||
|
||||
|
@ -1555,6 +1573,9 @@ static struct dentry *__lookup_hash(const struct qstr *name,
|
|||
struct dentry *dentry = lookup_dcache(name, base, flags);
|
||||
struct dentry *old;
|
||||
struct inode *dir = base->d_inode;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
int error;
|
||||
#endif
|
||||
|
||||
if (dentry)
|
||||
return dentry;
|
||||
|
@ -1572,6 +1593,21 @@ static struct dentry *__lookup_hash(const struct qstr *name,
|
|||
dput(dentry);
|
||||
dentry = old;
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (!IS_ERR(dentry) && dentry->d_inode && unlikely(dentry->d_inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
if ((flags & (LOOKUP_CREATE | LOOKUP_EXCL))) {
|
||||
error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
|
||||
if (error) {
|
||||
dput(dentry);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
dput(dentry);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
dput(dentry);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
#endif
|
||||
return dentry;
|
||||
}
|
||||
|
||||
|
@ -1673,6 +1709,12 @@ again:
|
|||
dentry = old;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (!IS_ERR(dentry) && dentry->d_inode && unlikely(dentry->d_inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
dput(dentry);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
#endif
|
||||
return dentry;
|
||||
}
|
||||
|
||||
|
@ -2318,6 +2360,12 @@ OK:
|
|||
}
|
||||
return -ENOTDIR;
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
// we deal with sus sub path here
|
||||
if (nd->inode && unlikely(nd->inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2497,6 +2545,11 @@ int filename_lookup(int dfd, struct filename *name, unsigned flags,
|
|||
flags & LOOKUP_MOUNTPOINT ? AUDIT_INODE_NOEVAL : 0);
|
||||
restore_nameidata();
|
||||
putname(name);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (!retval && path->dentry->d_inode && unlikely(path->dentry->d_inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -2826,6 +2879,12 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir)
|
|||
if (IS_APPEND(dir))
|
||||
return -EPERM;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (unlikely(inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (check_sticky(dir, inode) || IS_APPEND(inode) ||
|
||||
IS_IMMUTABLE(inode) || IS_SWAPFILE(inode) || HAS_UNMAPPED_ID(inode))
|
||||
return -EPERM;
|
||||
|
@ -2854,8 +2913,22 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir)
|
|||
*/
|
||||
static inline int may_create(struct inode *dir, struct dentry *child)
|
||||
{
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
int error;
|
||||
#endif
|
||||
|
||||
struct user_namespace *s_user_ns;
|
||||
audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (child->d_inode && unlikely(child->d_inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (child->d_inode)
|
||||
return -EEXIST;
|
||||
if (IS_DEADDIR(dir))
|
||||
|
@ -3019,6 +3092,12 @@ static int may_open(const struct path *path, int acc_mode, int flag)
|
|||
if (!inode)
|
||||
return -ENOENT;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (unlikely(inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (inode->i_mode & S_IFMT) {
|
||||
case S_IFLNK:
|
||||
return -ELOOP;
|
||||
|
@ -3098,7 +3177,20 @@ static inline int open_to_namei_flags(int flag)
|
|||
static int may_o_create(const struct path *dir, struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct user_namespace *s_user_ns;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
int error;
|
||||
|
||||
if (dentry->d_inode && unlikely(dentry->d_inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
error = inode_permission(dir->dentry->d_inode, MAY_WRITE | MAY_EXEC);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
error = security_path_mknod(dir, dentry, mode, 0);
|
||||
#else
|
||||
int error = security_path_mknod(dir, dentry, mode, 0);
|
||||
#endif
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -3219,6 +3311,12 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
|
|||
}
|
||||
if (dentry->d_inode) {
|
||||
/* Cached positive dentry: will open in f_op->open */
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (unlikely(dentry->d_inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
dput(dentry);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
#endif
|
||||
return dentry;
|
||||
}
|
||||
|
||||
|
@ -3248,6 +3346,16 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
|
|||
dentry = atomic_open(nd, dentry, file, open_flag, mode);
|
||||
if (unlikely(create_error) && dentry == ERR_PTR(-ENOENT))
|
||||
dentry = ERR_PTR(create_error);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (!IS_ERR(dentry) && dentry->d_inode && unlikely(dentry->d_inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
if (create_error) {
|
||||
dput(dentry);
|
||||
return ERR_PTR(create_error);
|
||||
}
|
||||
dput(dentry);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
#endif
|
||||
return dentry;
|
||||
}
|
||||
|
||||
|
@ -3262,6 +3370,12 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
|
|||
}
|
||||
dput(dentry);
|
||||
dentry = res;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (dentry->d_inode && unlikely(dentry->d_inode->i_state & 16777216) && likely(current_cred()->user->android_kabi_reserved2 & 16777216)) {
|
||||
dput(dentry);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3554,12 +3668,19 @@ static struct file *path_openat(struct nameidata *nd,
|
|||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_OPEN_REDIRECT
|
||||
extern struct filename* susfs_get_redirected_path(unsigned long ino);
|
||||
#endif
|
||||
|
||||
struct file *do_filp_open(int dfd, struct filename *pathname,
|
||||
const struct open_flags *op)
|
||||
{
|
||||
struct nameidata nd;
|
||||
int flags = op->lookup_flags;
|
||||
struct file *filp;
|
||||
#ifdef CONFIG_KSU_SUSFS_OPEN_REDIRECT
|
||||
struct filename *fake_pathname;
|
||||
#endif
|
||||
|
||||
set_nameidata(&nd, dfd, pathname);
|
||||
filp = path_openat(&nd, op, flags | LOOKUP_RCU);
|
||||
|
@ -3567,6 +3688,25 @@ struct file *do_filp_open(int dfd, struct filename *pathname,
|
|||
filp = path_openat(&nd, op, flags);
|
||||
if (unlikely(filp == ERR_PTR(-ESTALE)))
|
||||
filp = path_openat(&nd, op, flags | LOOKUP_REVAL);
|
||||
#ifdef CONFIG_KSU_SUSFS_OPEN_REDIRECT
|
||||
if (!IS_ERR(filp) && unlikely(filp->f_inode->i_state & 134217728) && current_uid().val < 2000) {
|
||||
fake_pathname = susfs_get_redirected_path(filp->f_inode->i_ino);
|
||||
if (!IS_ERR(fake_pathname)) {
|
||||
restore_nameidata();
|
||||
filp_close(filp, NULL);
|
||||
// no need to do `putname(pathname);` here as it will be done by calling process
|
||||
set_nameidata(&nd, dfd, fake_pathname);
|
||||
filp = path_openat(&nd, op, flags | LOOKUP_RCU);
|
||||
if (unlikely(filp == ERR_PTR(-ECHILD)))
|
||||
filp = path_openat(&nd, op, flags);
|
||||
if (unlikely(filp == ERR_PTR(-ESTALE)))
|
||||
filp = path_openat(&nd, op, flags | LOOKUP_REVAL);
|
||||
restore_nameidata();
|
||||
putname(fake_pathname);
|
||||
return filp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
restore_nameidata();
|
||||
return filp;
|
||||
}
|
||||
|
|
151
fs/namespace.c
151
fs/namespace.c
|
@ -38,6 +38,23 @@
|
|||
#include "pnode.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
extern bool susfs_is_current_ksu_domain(void);
|
||||
extern bool susfs_is_current_zygote_domain(void);
|
||||
#define CL_SUSFS_COPY_MNT_NS 0x1000000
|
||||
#define DEFAULT_SUS_MNT_GROUP_ID 1000
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT
|
||||
extern int susfs_auto_add_sus_bind_mount(const char *pathname, struct path *path_target);
|
||||
#endif
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT
|
||||
extern void susfs_auto_add_try_umount_for_bind_mount(struct path *path);
|
||||
#endif
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
||||
extern void susfs_auto_add_sus_ksu_default_mount(const char __user *to_pathname);
|
||||
#endif
|
||||
|
||||
/* Maximum number of mounts in a mount namespace */
|
||||
unsigned int sysctl_mount_max __read_mostly = 100000;
|
||||
|
||||
|
@ -181,9 +198,25 @@ static int mnt_alloc_id(struct mount *mnt)
|
|||
|
||||
static void mnt_free_id(struct mount *mnt)
|
||||
{
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
// If mnt->mnt.android_kabi_reserved4 is not zero, it means mnt->mnt_id is spoofed,
|
||||
// so here we return the original mnt_id for being freed.
|
||||
if (unlikely(mnt->mnt.android_kabi_reserved4)) {
|
||||
ida_free(&mnt_id_ida, mnt->mnt.android_kabi_reserved4);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ida_free(&mnt_id_ida, mnt->mnt_id);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
static void susfs_mnt_alloc_group_id(struct mount *mnt)
|
||||
{
|
||||
// Just assign the same default sus mount_group_id to mnt->mnt_group_id
|
||||
mnt->mnt_group_id = DEFAULT_SUS_MNT_GROUP_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocate a new peer group ID
|
||||
*/
|
||||
|
@ -202,6 +235,14 @@ static int mnt_alloc_group_id(struct mount *mnt)
|
|||
*/
|
||||
void mnt_release_group_id(struct mount *mnt)
|
||||
{
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
// If mnt->mnt_group_id >= DEFAULT_SUS_MNT_GROUP_ID, it means 'mnt' is sus mount,
|
||||
// here we don't need to free the mnt_group_id and just simply return and do nothing.
|
||||
if (unlikely(mnt->mnt_group_id >= DEFAULT_SUS_MNT_GROUP_ID)) {
|
||||
mnt->mnt_group_id = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ida_free(&mnt_group_ida, mnt->mnt_group_id);
|
||||
mnt->mnt_group_id = 0;
|
||||
}
|
||||
|
@ -1098,6 +1139,13 @@ struct vfsmount *vfs_create_mount(struct fs_context *fc)
|
|||
#endif
|
||||
mnt->mnt_parent = mnt;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (susfs_is_current_zygote_domain()) {
|
||||
mnt->mnt.android_kabi_reserved4 = mnt->mnt_id;
|
||||
mnt->mnt_id = current->android_kabi_reserved8++;
|
||||
}
|
||||
#endif
|
||||
|
||||
lock_mount_hash();
|
||||
#ifdef CONFIG_KDP_NS
|
||||
list_add_tail(&mnt->mnt_instance, &((struct kdp_mount *)mnt)->mnt->mnt_sb->s_mounts);
|
||||
|
@ -1214,6 +1262,14 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
|
|||
mnt->mnt_mountpoint = mnt->mnt.mnt_root;
|
||||
#endif
|
||||
mnt->mnt_parent = mnt;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (susfs_is_current_zygote_domain() && !(flag & CL_SUSFS_COPY_MNT_NS)) {
|
||||
mnt->mnt.android_kabi_reserved4 = mnt->mnt_id;
|
||||
mnt->mnt_id = current->android_kabi_reserved8++;
|
||||
}
|
||||
#endif
|
||||
|
||||
lock_mount_hash();
|
||||
list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
|
||||
unlock_mount_hash();
|
||||
|
@ -2317,6 +2373,17 @@ static int invent_group_ids(struct mount *mnt, bool recurse)
|
|||
{
|
||||
struct mount *p;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (susfs_is_current_ksu_domain()) {
|
||||
for (p = mnt; p; p = recurse ? next_mnt(p, mnt) : NULL) {
|
||||
if (!p->mnt_group_id && !IS_MNT_SHARED(p)) {
|
||||
susfs_mnt_alloc_group_id(p);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (p = mnt; p; p = recurse ? next_mnt(p, mnt) : NULL) {
|
||||
if (!p->mnt_group_id && !IS_MNT_SHARED(p)) {
|
||||
int err = mnt_alloc_group_id(p);
|
||||
|
@ -2707,6 +2774,24 @@ static int do_loopback(struct path *path, const char *old_name,
|
|||
umount_tree(mnt, UMOUNT_SYNC);
|
||||
unlock_mount_hash();
|
||||
}
|
||||
#if defined(CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT) || defined(CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT)
|
||||
// Check if bind mounted path should be hidden and umounted automatically.
|
||||
// And we target only process with ksu domain.
|
||||
if (susfs_is_current_ksu_domain()) {
|
||||
#if defined(CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT)
|
||||
if (susfs_auto_add_sus_bind_mount(old_name, &old_path)) {
|
||||
goto orig_flow;
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT)
|
||||
susfs_auto_add_try_umount_for_bind_mount(path);
|
||||
#endif
|
||||
}
|
||||
#if defined(CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT)
|
||||
orig_flow:
|
||||
#endif
|
||||
#endif // #if defined(CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT) || defined(CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT)
|
||||
|
||||
out2:
|
||||
unlock_mount(mp);
|
||||
out:
|
||||
|
@ -3705,6 +3790,10 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
|
|||
struct mount *old;
|
||||
struct mount *new;
|
||||
int copy_flags;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
bool is_zygote_pid = susfs_is_current_zygote_domain();
|
||||
int last_entry_mnt_id = 0;
|
||||
#endif
|
||||
|
||||
BUG_ON(!ns);
|
||||
|
||||
|
@ -3724,6 +3813,12 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
|
|||
copy_flags = CL_COPY_UNBINDABLE | CL_EXPIRE;
|
||||
if (user_ns != ns->user_ns)
|
||||
copy_flags |= CL_SHARED_TO_SLAVE;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (is_zygote_pid) {
|
||||
// Let clone_mnt() in copy_tree() know we only interested in function called by copy_mnt_ns()
|
||||
copy_flags |= CL_SUSFS_COPY_MNT_NS;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_KDP_NS
|
||||
new = copy_tree(old, ((struct kdp_mount *)old)->mnt->mnt_root, copy_flags);
|
||||
#else
|
||||
|
@ -3785,6 +3880,29 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
|
|||
#endif
|
||||
p = next_mnt(p, old);
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
// current->android_kabi_reserved8 -> to record last valid fake mnt_id to zygote pid
|
||||
// q->mnt.android_kabi_reserved4 -> original mnt_id
|
||||
// q->mnt_id -> will be modified to the fake mnt_id
|
||||
|
||||
// Here We are only interested in processes of which original mnt namespace belongs to zygote
|
||||
// Also we just make use of existing 'q' mount pointer, no need to delcare extra mount pointer
|
||||
if (is_zygote_pid) {
|
||||
last_entry_mnt_id = list_first_entry(&new_ns->list, struct mount, mnt_list)->mnt_id;
|
||||
list_for_each_entry(q, &new_ns->list, mnt_list) {
|
||||
if (unlikely(q->mnt.mnt_root->d_inode->i_state & 33554432)) {
|
||||
continue;
|
||||
}
|
||||
q->mnt.android_kabi_reserved4 = q->mnt_id;
|
||||
q->mnt_id = last_entry_mnt_id++;
|
||||
}
|
||||
}
|
||||
// Assign the 'last_entry_mnt_id' to 'current->android_kabi_reserved8' for later use.
|
||||
// should be fine here assuming zygote is forking/unsharing app in one single thread.
|
||||
// Or should we put a lock here?
|
||||
current->android_kabi_reserved8 = last_entry_mnt_id;
|
||||
#endif
|
||||
|
||||
namespace_unlock();
|
||||
|
||||
if (rootmnt)
|
||||
|
@ -3856,6 +3974,12 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
|
|||
goto out_data;
|
||||
|
||||
ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
||||
// Just for the compatibility of Magic Mount KernelSU
|
||||
if (!ret && susfs_is_current_ksu_domain()) {
|
||||
susfs_auto_add_sus_ksu_default_mount(dir_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
kfree(options);
|
||||
out_data:
|
||||
|
@ -4061,6 +4185,12 @@ out_to:
|
|||
path_put(&to_path);
|
||||
out_from:
|
||||
path_put(&from_path);
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
||||
if (!ret && susfs_is_current_ksu_domain()) {
|
||||
susfs_auto_add_sus_ksu_default_mount(to_pathname);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -4600,3 +4730,24 @@ const struct proc_ns_operations mntns_operations = {
|
|||
.install = mntns_install,
|
||||
.owner = mntns_owner,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
extern void susfs_try_umount_all(uid_t uid);
|
||||
void susfs_run_try_umount_for_current_mnt_ns(void) {
|
||||
struct mount *mnt;
|
||||
struct mnt_namespace *mnt_ns;
|
||||
|
||||
mnt_ns = current->nsproxy->mnt_ns;
|
||||
// Lock the namespace
|
||||
namespace_lock();
|
||||
list_for_each_entry(mnt, &mnt_ns->list, mnt_list) {
|
||||
// Change the sus mount to be private
|
||||
if (mnt->mnt.mnt_root->d_inode->i_state & 33554432) {
|
||||
change_mnt_propagation(mnt, MS_PRIVATE);
|
||||
}
|
||||
}
|
||||
// Unlock the namespace
|
||||
namespace_unlock();
|
||||
susfs_try_umount_all(current_uid().val);
|
||||
}
|
||||
#endif
|
12
fs/open.c
12
fs/open.c
|
@ -395,6 +395,12 @@ static const struct cred *access_override_creds(void)
|
|||
return old_cred;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
extern bool susfs_is_sus_su_hooks_enabled __read_mostly;
|
||||
extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
int *flags);
|
||||
#endif
|
||||
|
||||
static long do_faccessat(int dfd, const char __user *filename, int mode, int flags)
|
||||
{
|
||||
struct path path;
|
||||
|
@ -403,6 +409,12 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla
|
|||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
const struct cred *old_cred = NULL;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
if (susfs_is_sus_su_hooks_enabled) {
|
||||
ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
@ -168,6 +168,15 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
|
|||
|
||||
metacopy_blocks = ovl_is_metacopy_dentry(dentry);
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_OVERLAYFS
|
||||
ovl_path_lowerdata(dentry, &realpath);
|
||||
if (likely(realpath.mnt && realpath.dentry)) {
|
||||
old_cred = ovl_override_creds(dentry->d_sb);
|
||||
err = vfs_getattr(&realpath, stat, request_mask, flags);
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
type = ovl_path_real(dentry, &realpath);
|
||||
old_cred = ovl_override_creds(dentry->d_sb);
|
||||
err = vfs_getattr(&realpath, stat, request_mask, flags);
|
||||
|
|
|
@ -930,7 +930,19 @@ static int ovl_dir_open(struct inode *inode, struct file *file)
|
|||
if (!od)
|
||||
return -ENOMEM;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_OVERLAYFS
|
||||
ovl_path_lowerdata(file->f_path.dentry, &realpath);
|
||||
if (likely(realpath.mnt && realpath.dentry)) {
|
||||
// We still use '__OVL_PATH_UPPER' here which should be fine.
|
||||
type = __OVL_PATH_UPPER;
|
||||
goto bypass_orig_flow;
|
||||
}
|
||||
#endif
|
||||
|
||||
type = ovl_path_real(file->f_path.dentry, &realpath);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_OVERLAYFS
|
||||
bypass_orig_flow:
|
||||
#endif
|
||||
realfile = ovl_dir_open_realfile(file, &realpath);
|
||||
if (IS_ERR(realfile)) {
|
||||
kfree(od);
|
||||
|
|
|
@ -327,6 +327,18 @@ static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|||
struct path path;
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_OVERLAYFS
|
||||
ovl_path_lowerdata(root_dentry, &path);
|
||||
if (likely(path.mnt && path.dentry)) {
|
||||
err = vfs_statfs(&path, buf);
|
||||
if (!err) {
|
||||
buf->f_namelen = 255; // 255 for erofs, ext2/4, f2fs
|
||||
buf->f_type = path.dentry->d_sb->s_magic;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
ovl_path_real(root_dentry, &path);
|
||||
|
||||
err = vfs_statfs(&path, buf);
|
||||
|
|
|
@ -12,8 +12,19 @@
|
|||
|
||||
static char *saved_boot_config;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SPOOF_BOOTCONFIG
|
||||
extern int susfs_spoof_bootconfig(struct seq_file *m);
|
||||
#endif
|
||||
|
||||
static int boot_config_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
#ifdef CONFIG_KSU_SUSFS_SPOOF_BOOTCONFIG
|
||||
if (saved_boot_config) {
|
||||
if (!susfs_spoof_bootconfig(m)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (saved_boot_config)
|
||||
seq_puts(m, saved_boot_config);
|
||||
return 0;
|
||||
|
|
|
@ -317,6 +317,10 @@ static void show_vma_header_prefix(struct seq_file *m,
|
|||
seq_putc(m, ' ');
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
extern void susfs_sus_ino_for_show_map_vma(unsigned long ino, dev_t *out_dev, unsigned long *out_ino);
|
||||
#endif
|
||||
|
||||
static void
|
||||
show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
|
||||
{
|
||||
|
@ -331,8 +335,17 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
|
|||
|
||||
if (file) {
|
||||
struct inode *inode = file_inode(vma->vm_file);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
if (unlikely(inode->i_state & 67108864)) {
|
||||
susfs_sus_ino_for_show_map_vma(inode->i_ino, &dev, &ino);
|
||||
goto bypass_orig_flow;
|
||||
}
|
||||
#endif
|
||||
dev = inode->i_sb->s_dev;
|
||||
ino = inode->i_ino;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
bypass_orig_flow:
|
||||
#endif
|
||||
pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
#include "pnode.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
extern bool susfs_is_current_ksu_domain(void);
|
||||
#endif
|
||||
|
||||
static __poll_t mounts_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
|
@ -103,6 +107,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 (unlikely((r->mnt.mnt_root->d_inode->i_state & 33554432) && !susfs_is_current_ksu_domain()))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (sb->s_op->show_devname) {
|
||||
err = sb->s_op->show_devname(m, mnt_path.dentry);
|
||||
if (err)
|
||||
|
@ -137,6 +146,10 @@ 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
|
||||
if (unlikely((r->mnt.mnt_root->d_inode->i_state & 33554432) && !susfs_is_current_ksu_domain()))
|
||||
return 0;
|
||||
#endif
|
||||
seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
|
||||
MAJOR(sb->s_dev), MINOR(sb->s_dev));
|
||||
if (sb->s_op->show_path) {
|
||||
|
@ -199,6 +212,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 (unlikely((r->mnt.mnt_root->d_inode->i_state & 33554432) && !susfs_is_current_ksu_domain()))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* device */
|
||||
if (sb->s_op->show_devname) {
|
||||
seq_puts(m, "device ");
|
||||
|
|
|
@ -307,6 +307,10 @@ struct getdents_callback64 {
|
|||
int error;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
extern int susfs_sus_ino_for_filldir64(unsigned long ino);
|
||||
#endif
|
||||
|
||||
static int filldir64(struct dir_context *ctx, const char *name, int namlen,
|
||||
loff_t offset, u64 ino, unsigned int d_type)
|
||||
{
|
||||
|
@ -317,6 +321,11 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
|
|||
sizeof(u64));
|
||||
int prev_reclen;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (likely(current_cred()->user->android_kabi_reserved2 & 16777216) && susfs_sus_ino_for_filldir64(ino)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
buf->error = verify_dirent_name(name, namlen);
|
||||
if (unlikely(buf->error))
|
||||
return buf->error;
|
||||
|
|
26
fs/stat.c
26
fs/stat.c
|
@ -24,6 +24,10 @@
|
|||
#include "internal.h"
|
||||
#include "mount.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
extern void susfs_sus_ino_for_generic_fillattr(unsigned long ino, struct kstat *stat);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* generic_fillattr - Fill in the basic attributes from the inode struct
|
||||
* @inode: Inode to use as the source
|
||||
|
@ -35,6 +39,16 @@
|
|||
*/
|
||||
void generic_fillattr(struct inode *inode, struct kstat *stat)
|
||||
{
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
if (unlikely(inode->i_state & 67108864)) {
|
||||
susfs_sus_ino_for_generic_fillattr(inode->i_ino, stat);
|
||||
stat->mode = inode->i_mode;
|
||||
stat->rdev = inode->i_rdev;
|
||||
stat->uid = inode->i_uid;
|
||||
stat->gid = inode->i_gid;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
stat->dev = inode->i_sb->s_dev;
|
||||
stat->ino = inode->i_ino;
|
||||
stat->mode = inode->i_mode;
|
||||
|
@ -171,6 +185,12 @@ int vfs_fstat(int fd, struct kstat *stat)
|
|||
*
|
||||
* 0 will be returned on success, and a -ve error code if unsuccessful.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
extern bool susfs_is_sus_su_hooks_enabled __read_mostly;
|
||||
extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
#endif
|
||||
|
||||
static int vfs_statx(int dfd, const char __user *filename, int flags,
|
||||
struct kstat *stat, u32 request_mask)
|
||||
{
|
||||
|
@ -178,6 +198,12 @@ static int vfs_statx(int dfd, const char __user *filename, int flags,
|
|||
unsigned lookup_flags = 0;
|
||||
int error;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
if (susfs_is_sus_su_hooks_enabled) {
|
||||
ksu_handle_stat(&dfd, &filename, &flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
|
||||
AT_STATX_SYNC_TYPE))
|
||||
return -EINVAL;
|
||||
|
|
22
fs/statfs.c
22
fs/statfs.c
|
@ -109,6 +109,22 @@ retry:
|
|||
goto retry;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_OVERLAYFS
|
||||
/* - When mounting overlay, the f_flags are set with 'ro' and 'relatime',
|
||||
* but this is an abnormal status, as when we inspect the output from mountinfo,
|
||||
* we will find that all partitions set with 'ro' will have 'noatime' set as well.
|
||||
* - But what is strange here is that the vfsmnt f_flags of the lowest layer has corrent f_flags set,
|
||||
* and still it is always changed to 'relatime' instead of 'noatime' for the final result,
|
||||
* I can't think of any other reason to explain about this, maybe the f_flags is set by its own
|
||||
* filesystem implementation but not the one from overlayfs.
|
||||
* - Anyway we just cannot use the retrieved f_flags from ovl_getattr() of overlayfs,
|
||||
* we need to run one more check for user_statfs() and fd_statfs() by ourselves.
|
||||
*/
|
||||
if (unlikely((st->f_flags & ST_RDONLY) && (st->f_flags & ST_RELATIME))) {
|
||||
st->f_flags &= ~ST_RELATIME;
|
||||
st->f_flags |= ST_NOATIME;
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -120,6 +136,12 @@ int fd_statfs(int fd, struct kstatfs *st)
|
|||
error = vfs_statfs(&f.file->f_path, st);
|
||||
fdput(f);
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_OVERLAYFS
|
||||
if (unlikely((st->f_flags & ST_RDONLY) && (st->f_flags & ST_RELATIME))) {
|
||||
st->f_flags &= ~ST_RELATIME;
|
||||
st->f_flags |= ST_NOATIME;
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -763,8 +763,18 @@ static int s_show(struct seq_file *m, void *p)
|
|||
seq_printf(m, "%px %c %s\t[%s]\n", value,
|
||||
type, iter->name, iter->module_name);
|
||||
} else
|
||||
#ifndef CONFIG_KSU_SUSFS_HIDE_KSU_SUSFS_SYMBOLS
|
||||
seq_printf(m, "%px %c %s\n", value,
|
||||
iter->type, iter->name);
|
||||
#else
|
||||
{
|
||||
if (strstr(iter->name, "ksu_") || !strncmp(iter->name, "susfs_", 6) || !strncmp(iter->name, "ksud", 4)) {
|
||||
return 0;
|
||||
}
|
||||
seq_printf(m, "%px %c %s\n", value,
|
||||
iter->type, iter->name);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
10
kernel/sys.c
10
kernel/sys.c
|
@ -1311,13 +1311,23 @@ static int override_version(struct new_utsname __user *name)
|
|||
return 0;
|
||||
#endif
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS_SPOOF_UNAME
|
||||
extern int susfs_spoof_uname(struct new_utsname* tmp);
|
||||
#endif
|
||||
|
||||
SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
|
||||
{
|
||||
struct new_utsname tmp;
|
||||
|
||||
down_read(&uts_sem);
|
||||
#ifdef CONFIG_KSU_SUSFS_SPOOF_UNAME
|
||||
if (likely(!susfs_spoof_uname(&tmp)))
|
||||
goto bypass_orig_flow;
|
||||
#endif
|
||||
memcpy(&tmp, utsname(), sizeof(tmp));
|
||||
#ifdef CONFIG_KSU_SUSFS_SPOOF_UNAME
|
||||
bypass_orig_flow:
|
||||
#endif
|
||||
up_read(&uts_sem);
|
||||
if (copy_to_user(name, &tmp, sizeof(tmp)))
|
||||
return -EFAULT;
|
||||
|
|
Loading…
Reference in a new issue