From 446140a19a2c229f3b2e2fb708334ad2fbced0f1 Mon Sep 17 00:00:00 2001 From: jouyouyun Date: Mon, 25 Apr 2022 10:52:38 +0800 Subject: [PATCH] hookmanager: add file & bprm example --- kernel/hookmanager/file-bprm/Makefile | 11 ++ kernel/hookmanager/file-bprm/README.org | 82 ++++++++ .../hookmanager/file-bprm/file_operations.c | 181 ++++++++++++++++++ 3 files changed, 274 insertions(+) create mode 100644 kernel/hookmanager/file-bprm/Makefile create mode 100644 kernel/hookmanager/file-bprm/README.org create mode 100644 kernel/hookmanager/file-bprm/file_operations.c diff --git a/kernel/hookmanager/file-bprm/Makefile b/kernel/hookmanager/file-bprm/Makefile new file mode 100644 index 0000000..eced04f --- /dev/null +++ b/kernel/hookmanager/file-bprm/Makefile @@ -0,0 +1,11 @@ +obj-m := file_operations.o +ccflags-y := -std=gnu99 -Wno-declaration-after-statement -O3 +cwd := $(shell pwd) + +kdir := /lib/modules/$(shell uname -r)/build + +all: + make -C ${kdir} M=${cwd} modules + +clean: + make -C ${kdir} M=${cwd} clean diff --git a/kernel/hookmanager/file-bprm/README.org b/kernel/hookmanager/file-bprm/README.org new file mode 100644 index 0000000..d76262b --- /dev/null +++ b/kernel/hookmanager/file-bprm/README.org @@ -0,0 +1,82 @@ +# % Options Settings: https://orgmode.org/manual/Export-Settings.html +#+OPTIONS: timestamp:nil ^:nil <:nil p:t prop:t tags:t tasks:t todo:t +#+LATEX_CLASS: article +#+LaTeX_CLASS_OPTIONS: [a4paper,12pt] +#+LATEX_HEADER: \usepackage{booktabs} +# % to include pdf/eps/png files +#+LATEX_HEADER: \usepackage{indentfirst} +#+LATEX_HEADER: \usepackage{graphicx} +# % useful to add 'todo' markers +#+LaTeX_HEADER: \usepackage{todonotes} +# % hyperrefs +#+LaTeX_HEADER: \usepackage{hyperref} +# % ----------------- Code blocks ---------------- +# % Dependencies: pip install pygments +# % nice source code formatting +#+LaTeX_HEADER: \usepackage[utf8]{inputenc} +#+LaTeX_HEADER: \usepackage{xcolor} +#+LaTeX_HEADER: \definecolor{bg}{rgb}{0.98,0.98,0.98} +#+LaTeX_HEADER: \usepackage{minted} +#+LaTeX_HEADER: \setminted{ +#+LaTeX_HEADER: mathescape, +#+LaTeX_HEADER: linenos, +#+LaTeX_HEADER: numbersep=5pt, +#+LaTeX_HEADER: frame=lines, +#+LaTeX_HEADER: framesep=2mm, +#+LaTeX_HEADER: autogobble, +#+LaTeX_HEADER: style=tango, +#+LaTeX_HEADER: bgcolor=bg +#+LaTeX_HEADER: } +# % ----------------- Code blocks ---------------- +# % change style of section headings +#+LaTeX_HEADER: \usepackage{sectsty} +#+LaTeX_HEADER: \allsectionsfont{\sffamily} +# % only required for orgmode ticked TODO items, can remove +#+LaTeX_HEADER: \usepackage{amssymb} +# % only required for underlining text +#+LaTeX_HEADER: \usepackage[normalem]{ulem} +# % often use this in differential operators: +#+LaTeX_HEADER: \renewcommand{\d}{\ensuremath{\mathrm{d}}} +# % allow more reasonable text width for most documents than LaTeX default +#+LaTeX_HEADER: \setlength{\textheight}{21cm} +#+LaTeX_HEADER: \setlength{\textwidth}{16cm} +# % reduce left and right margins accordingly +#+LaTeX_HEADER: \setlength{\evensidemargin}{-0cm} +#+LaTeX_HEADER: \setlength{\oddsidemargin}{-0cm} +# % reduce top margin +#+LaTeX_HEADER: \setlength{\topmargin}{0cm} +# % Increase default line spacing a little if desired +#+LaTeX_HEADER: %\renewcommand{\baselinestretch}{1.2} +# % tailored float handling +#+LaTeX_HEADER: %\renewcommand{\topfraction}{0.8} +#+LaTeX_HEADER: %\renewcommand{\bottomfraction}{0.6} +#+LaTeX_HEADER: %\renewcommand{\textfraction}{0.2} +# % references formats +#+LaTeX_HEADER: \usepackage[round]{natbib} +# % Chinese supported +#+LATEX_HEADER: \usepackage{xeCJK} +# % references formats +#+LATEX_HEADER: \usepackage[round]{natbib} +#+LATEX_HEADER: \setCJKmainfont{Noto Serif CJK SC} +#+LATEX_HEADER: \setCJKsansfont{Noto Sans CJK SC} +#+LATEX_HEADER: \setCJKmonofont{Noto Sans Mono CJK SC} +# % End of Chinese supported +# % Line & paragraph space +#+LATEX_HEADER: \usepackage{setspace} +#+LATEX_HEADER: \renewcommand{\baselinestretch}{1.5} +#+LATEX_HEADER: \setlength{\parskip}{0.8em} +# % Line & paragraph space end +# % Breaking Page Between Title and Toc +#+LATEX_HEADER: \makeatletter \def\@maketitle{\null \begin{center} {\vskip 5em \Huge \@title} \vskip 30em {\LARGE \@author} \vskip 3em {\LARGE \@date} \end{center} \newpage} \makeatother +# % End of Breaking Page Between Title and Toc +#+LATEX_HEADER: \usepackage{tikz} +#+LATEX_HEADER: \renewcommand\contentsname{目录} +# Generate Tex File: C-c C-e l l; then replace verbatim with minted, and must special the code language +#+LATEX_HEADER: % Generate PDF: xelatex -shell-escape +#+AUTHOR: jouyouyun +#+EMAIL: yanbowen717@gmail.com +#+TITLE: hookmanager 文件操作实例 + +** 背景 + +由于需要知道文件修改与删除的时机,因此写了个 =demo= 来验证猜想,详见: [[./file_operations.c][file_operations]] diff --git a/kernel/hookmanager/file-bprm/file_operations.c b/kernel/hookmanager/file-bprm/file_operations.c new file mode 100644 index 0000000..513fbc9 --- /dev/null +++ b/kernel/hookmanager/file-bprm/file_operations.c @@ -0,0 +1,181 @@ +/** + * Copyright (C) 2021 jouyouyun + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * file_remove.c -- file remove hook examples + * + * Written on 星期一, 4 一月 2021. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MOD_NAME "file_operations" + +struct hook_wrapper { + int id; + struct uos_hook_cb_entry cb; +}; + +static void dump_file(struct file *file, const char *msg) +{ + char *buf = NULL; + char *tmp = NULL; + char *dbuf = NULL, *dtmp = NULL; + unsigned long ino = 0; + + buf = kzalloc(PATH_MAX, GFP_KERNEL); + dbuf = kzalloc(PATH_MAX, GFP_KERNEL); + if (unlikely(buf == NULL) || unlikely(dbuf == NULL)) { + printk("[%s] (%s) failed to alloc", MOD_NAME, msg); + goto out; + } + + // tmp = d_absolute_path((const struct path *)&(file->f_path), buf, PATH_MAX); + tmp = d_path((const struct path *)&(file->f_path), buf, PATH_MAX); + dtmp = dentry_path_raw(file->f_path.dentry, dbuf, PATH_MAX); + if (IS_ERR(tmp) || IS_ERR(dtmp)) { + printk("[%s] (%s) failed to get path", MOD_NAME, msg); + goto free; + } + + if (strstr(tmp, "TEST") != NULL || strstr(dtmp, "TEST") != NULL) { + ino = (file->f_inode) ? file->f_inode->i_ino : 0; + printk("[%s] (%s) , comm(%d-%d:%s), path: %s, dentry: %s, inode: %lu", + MOD_NAME, msg, current->pid, task_ppid_nr(current), + current->comm ? current->comm : "NULL", tmp, dtmp, ino); + } + +free: + kfree(buf); + buf = NULL; + kfree(dbuf); + dbuf = NULL; +out: + return ; +} + +static int hook_file_open(struct file *file) { + dump_file(file, "file_open"); + return 0; +} + +static void dump_bprm(struct linux_binprm *bprm, const char *msg) { + // 5.10 + /* if (bprm->executable) */ + /* retval = dump_file(bprm->executable, msg); */ + /* if (bprm->interpreter) */ + /* retval = dump_file(bprm->interpreter, msg); */ + if (bprm->file) + dump_file(bprm->file, msg); + + if (strstr(bprm->filename,"TEST") != NULL) + printk("\tfilename (%s)", bprm->filename?bprm->filename:"NULL"); + if (strstr(bprm->interp, "TEST") != NULL) + printk("\tinterp(%s)", bprm->interp ? bprm->interp : "NULL"); + // 5.10 + /* printk("\tfilename (%s), \n\tinterp(%s), \n\tfdpath(%s)", */ + /* bprm->filename ? bprm->filename : "NULL", */ + /* bprm->interp ? bprm->interp : "NULL", */ + /* bprm->fdpath ? bprm->fdpath : "NULL"); */ +} + +static int hook_bprm_committed_creds(struct linux_binprm *bprm) { + dump_bprm(bprm, "bprm_committed_creds"); + return 0; +} + +static int hook_bprm_check_security(struct linux_binprm *bprm) { + dump_bprm(bprm, "bprm_check_security"); + return 0; +} + +static struct hook_wrapper entries[] = { + { + .id = UOS_FILE_OPEN, + .cb = + { + .owner = MOD_NAME, + .cb_addr = (unsigned long)hook_file_open, + .ret_type = UOS_HOOK_RET_TY_INT, + .arg_len = 1, + }, + }, + { + .id = UOS_BPRM_COMMITTED_CREDS, + .cb = + { + .owner = MOD_NAME, + .cb_addr = (unsigned long)hook_bprm_committed_creds, + .ret_type = UOS_HOOK_RET_TY_NONE, + .arg_len = 1, + }, + }, + { + .id = UOS_BPRM_CHECK_SECURITY, + .cb = + { + .owner = MOD_NAME, + .cb_addr = (unsigned long)hook_bprm_check_security, + .ret_type = UOS_HOOK_RET_TY_INT, + .arg_len = 1, + }, + }, + { + .id = UOS_HOOK_NONE, + }, +}; + +static void unregister_hook(int idx) { + int i = 0; + int err = 0; + + for (; entries[i].id != UOS_HOOK_NONE; i++) { + if (idx != -1 && i >= idx) + break; + + err = uos_hook_cancel(entries[i].id, entries[i].cb.owner); + if (err) + printk("[%s] failed to cancel hook %d, error: %d", MOD_NAME, + entries[i].id, err); + } +} + +int __init mod_init(void) { + int i = 0; + int err = 0; + + for (; entries[i].id != UOS_HOOK_NONE; i++) { + err = uos_hook_register(entries[i].id, &entries[i].cb); + if (err) { + printk("[%s] failed to register hook: %d, err: %d", MOD_NAME, + entries[i].id, err); + break; + } + } + + if (err) { + unregister_hook(i); + return -1; + } + + return 0; +} + +void __exit mod_exit(void) { unregister_hook(-1); } + +module_init(mod_init); +module_exit(mod_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("jouyouyun"); +MODULE_DESCRIPTION("Test file operation hook");