2014-09-26 3 views
3

Выполняя статический анализ ядра linux для утечек памяти, я столкнулся с интересным сценарием, когда я не могу найти выделение переменной. Распределение происходит в следующей функции (с помощью kmalloc вызова), как показано ниже:Потенциальная утечка памяти в ядре linux?

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, то это потенциальная утечка памяти.

+0

что seq_release (inode, файл); вызов делает? –

+0

Функция mounts_release() должна освобождать память, связанную с установленным устройством, насколько я знаю! – dsingh

ответ

6

Если посмотреть на 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; 
} 

Это effectivly делает kfree(file->private_data)

Теперь file->private_data устанавливается в mounts_open_common в

file->private_data = &p->m; 

Это p который kmalloc'd в вашем вопросе , Элемент m не является указателем, поэтому его нельзя освобождать. Тем не менее, это 1. член struct 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; 
}; 

Так seq_release() выполняет kfree() по адресу m члена, что это тот же адрес был получен с p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL);

Я предполагаю, что это не очень дружественные статический анализатор. Но утечки памяти нет.

+0

В функции seq_release() ясно указано, что m является указателем типа seq_file, поэтому kfree (m) освободит память, выделенную этим указателем (который, я думаю, был бы выделен в функции seq_open(), вызванный нашим оригинальным mounts_open_common()), а не родительскую структуру proc_point, указанную переменной p. – dsingh

+0

Также linux использует container_of macro для извлечения родительского указателя из дочернего элемента. вы можете проверить это в функциях generic_create_cred()/generic_free_cred ............. – dsingh

+0

Вы не можете использовать переменную типа, которая имеет тип 1-го элемента структуры и которая указывает на адрес первого члена структуры для освобождения всей родительской структуры. – dsingh

Смежные вопросы