2016-11-09 72 views
0

我的目标是修改进程的打开文件描述符的访问权限。例如,有一个PID已知的进程,其中有两个文件描述符与标准3打开。一个以只读权限打开,另一个以只写权限打开。我想修改文件描述符的权限,从只读到读写。之后,文件描述符可用于写入其创建的对象。了解用于处理文件描述符的linux内核数据结构

我已经编写了一个内核模块,使我可以访问由其PID标识的进程的文件描述符。我搜索了头文件和论坛,以了解linux数据结构如何处理文件描述符,但我仍然感到困惑。我发现,每个进程都有自己的task_struct,其中包含所有打开文件的成员,其中包含一个打开文件描述符的数组。我不知道它是如何与inode链接的。

我发现有结构文件的成员,被称为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

的想法是错误的,该代码是错误的。什么是实际目标?为什么该文件未开始写入?如果程序明确打开它以便阅读,程序如何突然开始写入文件?这不加上任何东西。

你不能只是放置标志来让文件打开。您将不得不重新开放路径中的所有支票。

static int __init mainInit(void){ 

大部分内核不使用camelCase。

int pid=13433; 

'='周围缺少空格。 '*' 和 '任务' 之间

struct task_struct * 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。

 files_path = filestable->fd[i]->f_path; 
     cwd=d_path(&files_path,buf, 100*sizeof(char)); 
是什么让你觉得它是安全的,这里d_path摆在首位数100

邀请容易出错的重复?

 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"); 
}