【问题标题】:Potential memory leak in linux kernel?Linux内核中潜在的内存泄漏?
【发布时间】:2014-09-26 18:56:32
【问题描述】:

在对 linux 内核进行内存泄漏的静态分析时,我遇到了一个有趣的场景,我无法找到变量的解除分配。 分配发生在以下函数中(使用 kmalloc 调用),如下所示:

static int mounts_open_common(struct inode *inode, struct file *file,
              int (*show)(struct seq_file *, struct vfsmount *)){
  struct proc_mounts *p;

  //some code//
  *p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL);**
  file->private_data = &p->m;//the allocated variable is escaped to file structure
  //some code

}

我希望这个分配的内存固定在:

static int mounts_release(struct inode *inode, struct file *file)
{
    struct proc_mounts *p = proc_mounts(file->private_data);
    path_put(&p->root);
    put_mnt_ns(p->ns);
    return seq_release(inode, file);
}

但似乎这个函数正在访问分配的变量以释放它的一些内部成员,而不是变量“p”本身。 那么这个变量的内存在哪里被释放呢?如果它应该在 mounts_release 函数中释放,那么它可能存在内存泄漏。

【问题讨论】:

  • 什么seq_release(inode, file);打电话吗?
  • 据我所知,mounts_release() 函数应该释放与已安装设备相关的内存!

标签: c linux memory-leaks linux-kernel


【解决方案1】:

如果你查看 seq_release:

int seq_release(struct inode *inode, struct file *file)
{
        struct seq_file *m = file->private_data;
        kvfree(m->buf);
        kfree(m);
        return 0;
}

它有效地做kfree(file->private_data)

现在,file->private_datamounts_open_common 中设置为

file->private_data = &p->m;

这就是您问题中的p,即kmalloc'dm 成员不是指针,因此不应被释放。但是,它是struct proc_mounts的1.成员

struct proc_mounts {
        struct seq_file m;
        struct mnt_namespace *ns;
        struct path root;
        int (*show)(struct seq_file *, struct vfsmount *);
        void *cached_mount;
        u64 cached_event;
        loff_t cached_index;
};

所以seq_release()m 成员的地址执行kfree(),这与p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL); 获得的地址相同

我想这对静态分析器不是很友好。但是没有内存泄漏。

【讨论】:

  • 在 seq_release() 函数中明确指出 m 是 seq_file 类型的指针,因此 kfree(m) 将释放由该指针分配的内存(我认为应该在 seq_open()由我们原来的 mounts_open_common() 函数调用的函数),而不是变量 p 指向的父结构 proc_point。
  • Linux 也使用 container_of 宏从其子成员中提取父指针。您可以在 generic_create_cred()/generic_free_cred 函数中检查......
  • 你不能使用类型为结构的第一个成员的变量并且指向结构的第一个成员的地址来释放整个父结构。
  • PurofHy 不,它没有按照您的建议在 seq_open() 中分配,请查看 1. struct proc_mounts 的成员,它不是指针。查看分配 proc_mounts 的line 257。查看line 261 设置file->private_data 的位置,这就是线索。查看seq_open() 并查看当file->private_data 不为NULL(它不分配任何东西)时它做了什么。注意 file->private_data 是如何在 seq_release() 中被释放的。
  • @PurofHy 所以最后file->private 是传递给kfree() 的地址,这与在提到的第257 行获得的地址相同。还要注意,C 保证第一个成员结构将具有与结构本身相同的地址。 (即它的偏移量始终为 0)。此处的代码中未使用 container_of 宏,因为无需提取任何包含结构。这仅适用于struct seq_file mstruct proc_mounts 的1. 成员,因此kfree(p)kfree(&p->m) 相同
猜你喜欢
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多