近来学习了下systemtap,忽然想了个问题,怎么在linux下面监控一个用户对那些文件进行操作?准备用它来学习一下内核。
文件操作主要是open,read、write,是不是监控这3个系统调用就可以了?说干就干,上代码。
下面是程序filemon.stp
%{
#include <linux/file.h>
#include <linux/dcache.h>
#include <linux/mount.h>
#include <linux/fs.h>
#include <linux/fdtable.h>
#include <linux/err.h>
%}
probe kernel.function("sys_open"){
if(uid()==$1) /*监控特定用户,$1为命令行传入的参数,数字型格式*/
printf("(%d)execname:(%s)-----openfile:(%s)\n",pid(),execname(),user_string($filename))
}
function fd_to_name:string(fd:long)
%{
struct file *file;
struct files_struct *files;
struct inode *inode;
struct task_struct *task;
const unsigned char *name = NULL;
char *buffer;
buffer = (char*) kmalloc(PATH_MAX,GFP_KERNEL);
if(!buffer)
return ;
task_lock(current);
files = current->files;
if (files)
atomic_inc(&files->count);
task_unlock(current);
if (!files)
return ;
spin_lock(&files->file_lock);
file = fcheck_files(files, (int)STAP_ARG_fd); /*STAP_ARG_fd为systemtap传给嵌入c的参数*/
if (!file)
goto out_unlock;
name = d_path(&(file->f_path), buffer,PATH_MAX);
if (IS_ERR(name)) {
goto out_unlock;
printk("d_path did not work!\n");
}
strlcpy (THIS->__retvalue, name, PATH_MAX);
kfree(buffer);
out_unlock:
spin_unlock(&files->file_lock);
atomic_dec(&files->count);
%}
probe kernel.function("sys_read"){
if(uid()==$1) /*监控特定用户*/
printf("(%d)readfile:%s\n",pid(),fd_to_name($fd));
}
probe kernel.function("sys_write"){
if(uid()==$1)
printf("(%d)writefile:%s\n",pid(),fd_to_name($fd));
}
简单说明:上面这一段嵌入c的代码主要是用d_path将文件描述符fd转换为路径名
用stap -g --vp filemon.stp 501 运行一下,结果如下图
总结一下:要想用好systemtap,得对内核非常熟悉。