在open、read、write的参数中,mode的接口提供的比较方便,通过对fs/namei.c中vfs_create()中添加判断,解除对高位的事后修改就能传入到文件的i_mode。然而i_mode各个位基本已被使用完毕,使用新的组合的mode可能会将这一类文件变为“古怪的文件”,虽然能用open()、read()、write()进行操作,但是不能用vi等工具打开,原因可能是没有针对这种mode添加进一步的其他操作,用起来并不像S_IFREG这种普通文件这么方便。
经指点和启发,使用这三个函数的flag位进行扩充是可行的,以下是实现方法。本文以2.6.13的内核为例。
/include/asm-i386/fcntl.h中添加一个新的flag,为open()进行i_node的flag的填充提供判断依据,如#define O_SECRET 04。
/include/linux/fs.h中Inode flags添加一个新的flag,这个是inode中保存的flag,为read和write提供判断的依据,如#define S_SECRET 1024。
这里需要说明一下,创建inode时使用了i_op->create。之前读到这里时感觉线索已经断了,这个create的定义在哪里呢?一篇文章对其进行了解释,文件系统的挂载会自动用相应的操作替换这个i_op。点击访问原文
重新梳理一下flag的传递过程。open() --> sys_open() --> filp_open() --> open_namei() (此时填充到nd中) --> vfs_create() --> i_op->create (对应namei.c中ext3_create()),在这里对新定义的flag进行处理。判断逻辑:if ((nd->intent.open.flags & 1024) == 1024) ...; 此时要将namei.c中添加#include <linux/namei.h>。
之后对sys_write()进行扩充。
if (file) { loff_t pos = file_pos_read(file); if ((file->f_dentry->d_inode->i_flags) & 1024) //新增异或加密功能 { //printk("I'm in write...\n"); test4_secret(buf,count); //printk("%s\n",buf); ret = vfs_write(file, buf, count, &pos); } else ret = vfs_write(file, buf, count, &pos); file_pos_write(file, pos); fput_light(file, fput_needed);
加密函数如下,有一些bug没有修正,可能造成缓冲区溢出:
int test4_secret(const char *buf, size_t count) { char key ='a'; char *ptr; ptr = buf; while (count) { *ptr = *ptr ^ key; ptr ++; count --; } return 0; }
sys_read()可以做类似处理,但这会造成整个写——读“透明”,无法判断是否成功加密。如果仅作验证,只修改sys_write()就行了。
本文转自五岳博客园博客,原文链接:www.cnblogs.com/wuyuegb2312/archive/2012/06/04/2530249.html,如需转载请自行联系原作者