本文所涉及的代码均为linux kernel v2.6.31
在分析csaw 2010 pwn

创建proc文件

linux利用create_proc_entry()函数实现proc文件的创建,函数包含三个参数:
函数原型*create_proc_entry(const char *name, mode_t mode,struct proc_dir_entry *parent);

  • name :表示文件的名字
  • mode :文件的一些属性,默认是0755
  • parent:表示文件的父目录,没有的话就是null

create_proc_entry函数的返回值

create_proc_entry函数的返回值是一个结构体

struct proc_dir_entry {
    unsigned int low_ino;
    unsigned short namelen;
    const char *name;
    mode_t mode;
    nlink_t nlink;
    uid_t uid;
    gid_t gid;
    loff_t size;
    const struct inode_operations *proc_iops;
    /*
     * NULL ->proc_fops means "PDE is going away RSN" or
     * "PDE is just created". In either case, e.g. ->read_proc won't be
     * called because it's too late or too early, respectively.
     *
     * If you're allocating ->proc_fops dynamically, save a pointer
     * somewhere.
     */
    const struct file_operations *proc_fops;
    struct proc_dir_entry *next, *parent, *subdir;
    void *data;
    read_proc_t *read_proc;
    write_proc_t *write_proc;
    atomic_t count;        /* use count */
    int pde_users;    /* number of callers into module in progress */
    spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
    struct completion *pde_unload_completion;
    struct list_head pde_openers;    /* who did ->open, but not ->release */
};

里面包含了对这个文件进行读写所需要的函数:read_proc_t read_proc;write_proc_t write_proc;
这两个函数也是用户空间与内核空间进行数据交换的重点

read_proc

函数原型

typedef    int (read_proc_t)(char *page, char **start, off_t off,
              int count, int *eof, void *data);

参数分析

  • page: 在对proc文件进行读操作时,内核首先会分配一个页大小的缓冲区。
  • start : 当start参数没设置时:off参数起作用,表示文件指针偏移;当设置start以后,off参数不再起作用
  • off : 表示一段偏移,它可以通过lseek函数更改
  • count : 读取的个数
  • eof : 当eof=1时,随时可以在page中取出数据;当eof=0时,只有page填满数据时才能取出。

write_proc

typedef    int (write_proc_t)(struct file *file, const char __user *buffer,
               unsigned long count, void *data);

preView