diff --git a/src/critical_partition_protect/critical_partition_protect.c b/src/critical_partition_protect/critical_partition_protect.c index 583c663..aa589f6 100644 --- a/src/critical_partition_protect/critical_partition_protect.c +++ b/src/critical_partition_protect/critical_partition_protect.c @@ -15,6 +15,7 @@ #include #include +#include "file.h" KPM_NAME("Anti Format Critical Partition"); KPM_VERSION(ANTI_FORMAT_VERSION); @@ -22,32 +23,37 @@ KPM_LICENSE("GPL v2"); KPM_AUTHOR("1f2003d5"); KPM_DESCRIPTION("通过拦截内核调用对关键分区进行保护,防止被恶意格机"); -struct open_flags { - int open_flag; - umode_t mode; - int acc_mode; - int intent; - int lookup_flags; -}; +char *skfunc_def(d_path)(const struct path *path, char *buf, int buflen) = NULL; +void skfunc_def(fput)(struct file *file) = NULL; hook_func_def(do_filp_open, struct file *, int dfd, struct filename *pathname, const struct open_flags *o); hook_func_no_info(do_filp_open); static struct file *hook_replace(do_filp_open)(int dfd, struct filename *pathname, const struct open_flags *o) { - const char *currFN = pathname->name; - if (unlikely(strstr(currFN, "/dev") != NULL) && unlikely(strstr(currFN, "/block") != NULL)) { - // Check write mode - if ((o->open_flag & (O_WRONLY | O_RDWR | O_CREAT | O_TRUNC)) != 0) { - if (unlikely(strstr(currFN, "/sd") != NULL) || unlikely(strstr(currFN, "/loop") != NULL) || unlikely(strstr(currFN, "/mapper") != NULL) || unlikely(strstr(currFN, "/dm-") != NULL) || unlikely(strstr(currFN, "/by-name") != NULL) || unlikely(strstr(currFN, "/bootdevice") != NULL)) { + struct file *filp = hook_call_backup(do_filp_open, dfd, pathname, o); + if (!IS_ERR(filp)) { + char tmp[100] = { 0 }; + char *currFN = skfunc(d_path)(&filp->f_path, tmp, 100); #ifdef DEBUG - pr_info("[AntiFormatDevice] %s, open_flag: %d, mode: %d", currFN, o->open_flag, o->mode); + pr_info("[AntiFormatDevice] %s", currFN); #endif - pr_err("[AntiFormatDevice] Evil operation, disallowed!"); - return ERR_PTR(-EACCES); + if (currFN) { + if (unlikely(strstr(currFN, "/dev") != NULL) && unlikely(strstr(currFN, "/block") != NULL)) { + // Check write mode + if ((o->open_flag & (O_WRONLY | O_RDWR | O_CREAT | O_TRUNC)) != 0) { + if (unlikely(strstr(currFN, "/sd") != NULL) || unlikely(strstr(currFN, "/loop") != NULL) || unlikely(strstr(currFN, "/mapper") != NULL) || unlikely(strstr(currFN, "/dm-") != NULL) || unlikely(strstr(currFN, "/by-name") != NULL) || unlikely(strstr(currFN, "/bootdevice") != NULL)) { +#ifdef DEBUG + pr_info("[AntiFormatDevice] %s, open_flag: %d, mode: %d", currFN, o->open_flag, o->mode); +#endif + pr_err("[AntiFormatDevice] Evil operation, disallowed!"); + skfunc(fput)(filp); + return ERR_PTR(-EACCES); + } + } } } } - return hook_call_backup(do_filp_open, dfd, pathname, o); + return filp; } static inline bool installHook() { @@ -91,6 +97,18 @@ static long anti_format_device_init(const char *args, const char *event, void *_ pr_info("[AntiFormatDevice] Kernel Patch Version: %x\n", kpver); pr_info("[AntiFormatDevice] Initializing...\n"); + skfunc_match(d_path, NULL, NULL); + if (!skfunc(d_path)) { + pr_info("[AntiFormatDevice] kernel func: 'd_path' does not exist!\n"); + goto exit; + } + + skfunc_match(fput, NULL, NULL); + if (!skfunc(fput)) { + pr_info("[AntiFormatDevice] kernel func: 'fput' does not exist!\n"); + goto exit; + } + if (anti_format_device_control_internal(true)) { pr_info("[AntiFormatDevice] Module initializing completed.\n"); goto exit; diff --git a/src/critical_partition_protect/file.h b/src/critical_partition_protect/file.h new file mode 100644 index 0000000..651be55 --- /dev/null +++ b/src/critical_partition_protect/file.h @@ -0,0 +1,32 @@ +#ifndef _KPM_FILE_H +#define _KPM_FILE_H + +#include +#include + +struct vfsmount; +struct dentry; + +struct path { + struct vfsmount *mnt; + struct dentry *dentry; +}; + +struct file { + union { + struct llist_node fu_llist; + struct rcu_head fu_rcuhead; + } f_u; + struct path f_path; + struct inode *f_inode; +}; + +struct open_flags { + int open_flag; + umode_t mode; + int acc_mode; + int intent; + int lookup_flags; +}; + +#endif //_KPM_FILE_H