Potential memory leak in linux kernel?

While doing static analysis of the linux kernel for memory leaks, I came across an interesting scenario where I cannot find a variable allocation. The allocation takes place in the following function (using the kmalloc call) as shown below:

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

}

      

I expect the allocated memory to be fixed:

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

      

But it looks like this function is accessing the allocated variable in order to free some of its internal elements, but not the variable 'p' itself. So where is this variable memory freed? If it is supposed to be released in the mounts_release function, it is a potential memory leak.

+3


source to share


1 answer


If you look at 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;
}

      

Effectively makes kfree(file->private_data)

Now file->private_data

configured in mounts_open_common as

file->private_data = &p->m;

      



This p

is the one kmalloc'd

in your question. The element is m

not a pointer, so it cannot be freed. However, it is the 1st memberstruct proc_mounts

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

      

So seq_release()

does kfree () on the member address m

, the same address that was obtained withp = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL);

I think this is not very convenient for a static analyzer. But there is no memory leak.

+6


source







All Articles