我的目标是修改进程的打开文件描述符的访问权限。例如,有一个PID已知的进程,它有2个文件描述符,与标准3分开。一个以只读权限打开,另一个以只写权限打开。我想将文件描述符权限从只读修改为读写。之后,文件描述符可用于编写用它创建的对象。
我编写了一个内核模块,可以访问由PID识别的进程的文件描述符。我搜索了标题和论坛,以了解linux数据结构如何处理文件描述符,但我仍然感到困惑。我发现,每个进程都有自己的 task_struct ,其中包含所有打开文件的成员,其中包含一个打开文件描述符数组。我不知道它是如何从这里链接到inode。
我发现有一个struct文件的成员,称为 f_mode ,它为我们提供了权限,但我找不到调用它的方法。当我直接访问它时,它给了我一个unsigned int但我不知道什么值映射到什么?另外,我不确定这是否是存储访问权限的数据成员。如果我修改它会改变文件描述符的访问权限吗?
代码如下:
static int __init mainInit(void){
int pid=13433;
struct task_struct * task;
struct files_struct * files;
struct fdtable * filestable;
struct path files_path;
//Get Task structure from PID
task = pid_task(find_vpid(pid), PIDTYPE_PID );
//Get open FIles from the task tstructure
files = task->files;
filestable=files_fdtable(files);
int i=0;
char *cwd;
char *buf = (char *)kmalloc(GFP_KERNEL,100*sizeof(char));
while(filestable->fd[i] != NULL){
files_path = filestable->fd[i]->f_path;
cwd=d_path(&files_path,buf, 100*sizeof(char));
printk(KERN_INFO "Open FD with %d with name %s with access %x\n", i, cwd,filestable->fd[i]->f_mode);
//printk(KERN_INFO "FMode read:%x Fmodewrite:%x\n",FMODE_READ,FMODE_WRITE);
//Check access mode
if(filestable->fd[i]->f_mode==FMODE_READ){
printk(KERN_INFO "File has access FMODE_READ\n");
}else if(filestable->fd[i]->f_mode==FMODE_WRITE){
printk(KERN_INFO "File has access FMODE_WRTIE\n");
}
i++;
}
return 0;
}
static void __exit mainExit(void){
printk(KERN_INFO "Goodbye Kernel!. Returning to normal useless world!\n");
}
module_init(mainInit);
module_exit(mainExit);
答案 0 :(得分:0)
这个想法错了,代码错了。实际目标是什么?为什么文件不能开始写入?如果程序显式打开它进行读取,程序如何突然开始写入文件?这并没有加起来。
你不能只是将标志打开以使文件打开以进行写入。您必须在开放路径中重新执行所有检查。
static int __init mainInit(void){
在大多数情况下,内核不使用camelCase。
int pid=13433;
'='周围缺少空格。
struct task_struct * task;
'*'和'task'之间的虚假空间。
struct files_struct * files;
struct fdtable * filestable;
iditom将它命名为'fdt'。
struct path files_path;
//Get Task structure from PID
task = pid_task(find_vpid(pid), PIDTYPE_PID );
既没有rcu也没有任务列表,因此这是不安全的。
//Get open FIles from the task tstructure
files = task->files;
任务锁定未被保留,因此缺失是不安全的。
filestable=files_fdtable(files);
如果启用了调试,内核本身会告诉你这行是错误的。
int i=0;
char *cwd;
char *buf = (char *)kmalloc(GFP_KERNEL,100*sizeof(char));
为什么要施放,为什么包含100和为什么包含sizeof(char)?这里硬编码100也是错误的,因为它会导致错误的重复数字。
while(filestable->fd[i] != NULL){
不仅没有fd表锁,因此遍历是不安全的,它不会按照你想要的方式工作。一个进程可以在使用过的fds之间使用未使用的fds。
files_path = filestable->fd[i]->f_path;
cwd=d_path(&files_path,buf, 100*sizeof(char));
邀请容易出错的重复数字100.首先,您认为d_path的安全性是什么?
printk(KERN_INFO "Open FD with %d with name %s with access %x\n", i, cwd,filestable->fd[i]->f_mode);
//printk(KERN_INFO "FMode read:%x Fmodewrite:%x\n",FMODE_READ,FMODE_WRITE);
//Check access mode
if(filestable->fd[i]->f_mode==FMODE_READ){
printk(KERN_INFO "File has access FMODE_READ\n");
}else if(filestable->fd[i]->f_mode==FMODE_WRITE){
printk(KERN_INFO "File has access FMODE_WRTIE\n");
}
i++;
}
return 0;
}
static void __exit mainExit(void){
printk(KERN_INFO "Goodbye Kernel!. Returning to normal useless world!\n");
}