-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
hookmanager: add file & bprm example
- Loading branch information
Showing
3 changed files
with
274 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <tex file> | ||
#+AUTHOR: jouyouyun | ||
#+EMAIL: [email protected] | ||
#+TITLE: hookmanager 文件操作实例 | ||
|
||
** 背景 | ||
|
||
由于需要知道文件修改与删除的时机,因此写了个 =demo= 来验证猜想,详见: [[./file_operations.c][file_operations]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/** | ||
* Copyright (C) 2021 jouyouyun <[email protected]> | ||
* | ||
* 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 <linux/binfmts.h> | ||
#include <linux/dcache.h> | ||
#include <linux/fs.h> | ||
#include <linux/init.h> | ||
#include <linux/kernel.h> | ||
#include <linux/lsm_uos_hook_manager.h> | ||
#include <linux/module.h> | ||
#include <linux/slab.h> | ||
|
||
#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"); |