From d89e00b9b194df7b7b7aca7743325910b4ff699f Mon Sep 17 00:00:00 2001 From: bxySo Date: Fri, 22 Mar 2024 21:44:41 +0800 Subject: [PATCH] patches: Support `path_umount` - https://github.com/xiaoleGun/KernelSU_Action/issues/142 - https://github.com/tiann/KernelSU/commit/b4cfc2f2980b5904d045b04931c67aa7d11a8c80 - https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#how-to-backport-path-umount --- patches/patches.sh | 58 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/patches/patches.sh b/patches/patches.sh index c636e892df..8b02739a97 100644 --- a/patches/patches.sh +++ b/patches/patches.sh @@ -1,15 +1,16 @@ -#!/bin/bash +#!/usr/bin/env bash # Patches author: weishu # Shell authon: xiaoleGun <1592501605@qq.com> # bdqllW # Tested kernel versions: 5.4, 4.19, 4.14, 4.9 -# 20240123 +# 20240601 patch_files=( fs/exec.c fs/open.c fs/read_write.c fs/stat.c + fs/namespace.c drivers/input/input.c ) @@ -23,7 +24,6 @@ for i in "${patch_files[@]}"; do case $i in # fs/ changes - ## exec.c fs/exec.c) sed -i '/static int do_execveat_common/i\#ifdef CONFIG_KSU\nextern bool ksu_execveat_hook __read_mostly;\nextern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv,\n void *envp, int *flags);\nextern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,\n void *argv, void *envp, int *flags);\n#endif' fs/exec.c if grep -q "return __do_execve_file(fd, filename, argv, envp, flags, NULL);" fs/exec.c; then @@ -33,7 +33,6 @@ for i in "${patch_files[@]}"; do fi ;; - ## open.c fs/open.c) if grep -q "long do_faccessat(int dfd, const char __user \*filename, int mode)" fs/open.c; then sed -i '/long do_faccessat(int dfd, const char __user \*filename, int mode)/i\#ifdef CONFIG_KSU\nextern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,\n int *flags);\n#endif' fs/open.c @@ -43,18 +42,16 @@ for i in "${patch_files[@]}"; do sed -i '/if (mode & ~S_IRWXO)/i\ #ifdef CONFIG_KSU\n ksu_handle_faccessat(&dfd, &filename, &mode, NULL);\n #endif\n' fs/open.c ;; - ## read_write.c fs/read_write.c) sed -i '/ssize_t vfs_read(struct file/i\#ifdef CONFIG_KSU\nextern bool ksu_vfs_read_hook __read_mostly;\nextern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,\n size_t *count_ptr, loff_t **pos);\n#endif' fs/read_write.c sed -i '/ssize_t vfs_read(struct file/,/ssize_t ret;/{/ssize_t ret;/a\ - #ifdef CONFIG_KSU\ - if (unlikely(ksu_vfs_read_hook))\ - ksu_handle_vfs_read(&file, &buf, &count, &pos);\ - #endif + #ifdef CONFIG_KSU\ + if (unlikely(ksu_vfs_read_hook))\ + ksu_handle_vfs_read(&file, &buf, &count, &pos);\ + #endif }' fs/read_write.c ;; - ## stat.c fs/stat.c) if grep -q "int vfs_statx(int dfd, const char __user \*filename, int flags," fs/stat.c; then sed -i '/int vfs_statx(int dfd, const char __user \*filename, int flags,/i\#ifdef CONFIG_KSU\nextern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);\n#endif' fs/stat.c @@ -65,8 +62,47 @@ for i in "${patch_files[@]}"; do fi ;; + fs/namespace.c) + sed -i '/int ksys_umount(char __user \*name, int flags)/i \ +#ifdef CONFIG_KSU\ +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) /* Check optimistically */\ + 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);\ +\ + /* we must not call path_put() as that would clear mnt_expiry_mark */\ + dput(path->dentry);\ + mntput_no_expire(mnt);\ + return ret;\ +}\ +#endif\ +' fs/namespace.c + ;; + # drivers/input changes - ## input.c drivers/input/input.c) sed -i '/static void input_handle_event/i\#ifdef CONFIG_KSU\nextern bool ksu_input_hook __read_mostly;\nextern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value);\n#endif\n' drivers/input/input.c sed -i '/int disposition = input_get_disposition(dev, type, code, &value);/a\ #ifdef CONFIG_KSU\n if (unlikely(ksu_input_hook))\n ksu_handle_input_handle_event(&type, &code, &value);\n #endif' drivers/input/input.c