From f562af7ee53faba5c6aef59a4a985f4ca7f5ec87 Mon Sep 17 00:00:00 2001 From: Tommy Wu Date: Mon, 25 Sep 2023 12:06:11 +0800 Subject: fix kernelsu for 4.4 --- arch/arm64/configs/clover_defconfig | 3 ++- drivers/input/input.c | 6 ++++++ fs/exec.c | 11 +++++++++++ fs/open.c | 4 ++++ fs/read_write.c | 7 +++++++ fs/stat.c | 4 ++++ security/selinux/hooks.c | 19 +++++++++++++++++-- 7 files changed, 51 insertions(+), 3 deletions(-) diff --git a/arch/arm64/configs/clover_defconfig b/arch/arm64/configs/clover_defconfig index d91f5031ade6..35d9985eb326 100644 --- a/arch/arm64/configs/clover_defconfig +++ b/arch/arm64/configs/clover_defconfig @@ -42,7 +42,8 @@ CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y -CONFIG_KPROBES=y +CONFIG_KPROBES=n +CONFIG_OVERLAY_FS=y CONFIG_JUMP_LABEL=y CONFIG_CC_STACKPROTECTOR_STRONG=y CONFIG_ARCH_MMAP_RND_BITS=24 diff --git a/drivers/input/input.c b/drivers/input/input.c index 6d9f58a446fa..a33a00d2b452 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -368,6 +368,9 @@ static int input_get_disposition(struct input_dev *dev, return disposition; } +extern bool ksu_input_hook __read_mostly; +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); + static void input_handle_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { @@ -375,6 +378,9 @@ static void input_handle_event(struct input_dev *dev, disposition = input_get_disposition(dev, type, code, &value); + if (unlikely(ksu_input_hook)) + ksu_handle_input_handle_event(&type, &code, &value); + if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) dev->event(dev, type, code, value); diff --git a/fs/exec.c b/fs/exec.c index 341b872d758f..e1e69fdc8f3e 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1527,6 +1527,12 @@ static int exec_binprm(struct linux_binprm *bprm) return ret; } +extern bool ksu_execveat_hook __read_mostly; +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, + void *envp, int *flags); +extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, + void *argv, void *envp, int *flags); + /* * sys_execve() executes a new program. */ @@ -1541,6 +1547,11 @@ static int do_execveat_common(int fd, struct filename *filename, struct files_struct *displaced; int retval; + if (unlikely(ksu_execveat_hook)) + ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); + else + ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags); + if (IS_ERR(filename)) return PTR_ERR(filename); diff --git a/fs/open.c b/fs/open.c index b7e2889a710c..a7a74ec7df13 100644 --- a/fs/open.c +++ b/fs/open.c @@ -338,6 +338,9 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) return error; } +extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, + int *flags); + /* * access() needs to use the real uid/gid, not the effective uid/gid. * We do this by temporarily clearing all FS-related capabilities and @@ -353,6 +356,7 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) int res; unsigned int lookup_flags = LOOKUP_FOLLOW; + ksu_handle_faccessat(&dfd, &filename, &mode, NULL); if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; diff --git a/fs/read_write.c b/fs/read_write.c index 27023e8f531e..6ca1aa4a7a35 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -436,10 +436,17 @@ ssize_t __vfs_read(struct file *file, char __user *buf, size_t count, } EXPORT_SYMBOL(__vfs_read); +extern bool ksu_vfs_read_hook __read_mostly; +extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, + size_t *count_ptr, loff_t **pos); + ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { ssize_t ret; + if (unlikely(ksu_vfs_read_hook)) + ksu_handle_vfs_read(&file, &buf, &count, &pos); + if (!(file->f_mode & FMODE_READ)) return -EBADF; if (!(file->f_mode & FMODE_CAN_READ)) diff --git a/fs/stat.c b/fs/stat.c index 004dd77c3b93..aef47035309d 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -87,6 +87,8 @@ int vfs_fstat(unsigned int fd, struct kstat *stat) } EXPORT_SYMBOL(vfs_fstat); +extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); + int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, int flag) { @@ -94,6 +96,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, int error = -EINVAL; unsigned int lookup_flags = 0; + ksu_handle_stat(&dfd, &filename, &flag); + if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH)) != 0) goto out; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 3bac79428c9b..c58f766b9cef 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -214,7 +214,7 @@ static inline u32 task_sid(const struct task_struct *task) /* * get the subjective security ID of the current task */ -static inline u32 current_sid(void) +u32 current_sid(void) { const struct task_security_struct *tsec = current_security(); @@ -2266,9 +2266,12 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, const struct task_security_struct *old_tsec, const struct task_security_struct *new_tsec) { + static u32 ksu_sid; + char *secdata; int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); int nosuid = (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID); - int rc; + int rc,error; + u32 seclen; if (!nnp && !nosuid) return 0; /* neither NNP nor nosuid */ @@ -2276,6 +2279,18 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, if (new_tsec->sid == old_tsec->sid) return 0; /* No change in credentials */ + + if(!ksu_sid){ + security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid); + } + error = security_secid_to_secctx(old_tsec->sid, &secdata, &seclen); + if (!error) { + rc = strcmp("u:r:init:s0",secdata); + security_release_secctx(secdata, seclen); + if(rc == 0 && new_tsec->sid == ksu_sid){ + return 0; + } + } /* * The only transitions we permit under NNP or nosuid * are transitions to bounded SIDs, i.e. SIDs that are -- cgit v1.2.3