Skip to content

Commit

Permalink
hookmanager: add file & bprm example
Browse files Browse the repository at this point in the history
  • Loading branch information
jouyouyun committed Apr 25, 2022
1 parent 143b684 commit 446140a
Show file tree
Hide file tree
Showing 3 changed files with 274 additions and 0 deletions.
11 changes: 11 additions & 0 deletions kernel/hookmanager/file-bprm/Makefile
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
82 changes: 82 additions & 0 deletions kernel/hookmanager/file-bprm/README.org
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]]
181 changes: 181 additions & 0 deletions kernel/hookmanager/file-bprm/file_operations.c
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");

0 comments on commit 446140a

Please sign in to comment.