mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
Ticket #2623: vfs: use data after free.
(vfs_s_close): vfs-specific data of file handler vfs_file_handler_t::data is freed in vfs_s_subclass::fh_close method and then can be used in vfs_s_subclass::file_store_one. Bug is related to ftp and fish VFSes. Added new vfs_s_subclass::fh_free_data method to free vfs-specific data of file handler vfs_file_handler_t::data. Use it in ftp and vfs VFSes. Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
50574c687a
commit
664b3efcda
@ -730,6 +730,8 @@ vfs_s_close (void *fh)
|
||||
close (FH->handle);
|
||||
|
||||
vfs_s_free_inode (me, FH->ino);
|
||||
if (MEDATA->fh_free_data != NULL)
|
||||
MEDATA->fh_free_data (fh);
|
||||
g_free (fh);
|
||||
return res;
|
||||
}
|
||||
@ -1264,11 +1266,18 @@ vfs_s_open (const vfs_path_t * vpath, int flags, mode_t mode)
|
||||
fh->linear = LS_LINEAR_PREOPEN;
|
||||
}
|
||||
}
|
||||
else if ((VFSDATA (path_element)->fh_open != NULL)
|
||||
&& (VFSDATA (path_element)->fh_open (path_element->class, fh, flags, mode) != 0))
|
||||
else
|
||||
{
|
||||
g_free (fh);
|
||||
return NULL;
|
||||
struct vfs_s_subclass *s;
|
||||
|
||||
s = VFSDATA (path_element);
|
||||
if (s->fh_open != NULL && s->fh_open (path_element->class, fh, flags, mode) != 0)
|
||||
{
|
||||
if (s->fh_free_data != NULL)
|
||||
s->fh_free_data (fh);
|
||||
g_free (fh);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (fh->ino->localname)
|
||||
|
@ -133,6 +133,7 @@ struct vfs_s_subclass
|
||||
|
||||
int (*fh_open) (struct vfs_class * me, vfs_file_handler_t * fh, int flags, mode_t mode);
|
||||
int (*fh_close) (struct vfs_class * me, vfs_file_handler_t * fh);
|
||||
void (*fh_free_data) (vfs_file_handler_t * fh);
|
||||
|
||||
struct vfs_s_entry *(*find_entry) (struct vfs_class * me,
|
||||
struct vfs_s_inode * root,
|
||||
|
@ -1445,6 +1445,18 @@ fish_rmdir (const vfs_path_t * vpath)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
fish_fh_free_data (vfs_file_handler_t * fh)
|
||||
{
|
||||
if (fh != NULL)
|
||||
{
|
||||
g_free (fh->data);
|
||||
fh->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
fish_fh_open (struct vfs_class *me, vfs_file_handler_t * fh, int flags, mode_t mode)
|
||||
{
|
||||
@ -1476,23 +1488,12 @@ fish_fh_open (struct vfs_class *me, vfs_file_handler_t * fh, int flags, mode_t m
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
g_free (fh->data);
|
||||
fish_fh_free_data (fh);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
fish_fh_close (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
{
|
||||
(void) me;
|
||||
|
||||
g_free (fh->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
fish_fill_names (struct vfs_class *me, fill_names_f func)
|
||||
{
|
||||
@ -1561,7 +1562,7 @@ init_fish (void)
|
||||
fish_subclass.open_archive = fish_open_archive;
|
||||
fish_subclass.free_archive = fish_free_archive;
|
||||
fish_subclass.fh_open = fish_fh_open;
|
||||
fish_subclass.fh_close = fish_fh_close;
|
||||
fish_subclass.fh_free_data = fish_fh_free_data;
|
||||
fish_subclass.dir_load = fish_dir_load;
|
||||
fish_subclass.file_store = fish_file_store;
|
||||
fish_subclass.linear_start = fish_linear_start;
|
||||
|
@ -2102,6 +2102,18 @@ ftpfs_rmdir (const vfs_path_t * vpath)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
ftpfs_fh_free_data (vfs_file_handler_t *fh)
|
||||
{
|
||||
if (fh != NULL)
|
||||
{
|
||||
g_free (fh->data);
|
||||
fh->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
ftpfs_fh_open (struct vfs_class *me, vfs_file_handler_t * fh, int flags, mode_t mode)
|
||||
{
|
||||
@ -2170,7 +2182,7 @@ ftpfs_fh_open (struct vfs_class *me, vfs_file_handler_t * fh, int flags, mode_t
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
g_free (fh->data);
|
||||
ftpfs_fh_free_data (fh);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2194,8 +2206,6 @@ ftpfs_fh_close (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
vfs_s_invalidate (me, FH_SUPER);
|
||||
}
|
||||
|
||||
g_free (fh->data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2556,6 +2566,7 @@ init_ftpfs (void)
|
||||
ftpfs_subclass.free_archive = ftpfs_free_archive;
|
||||
ftpfs_subclass.fh_open = ftpfs_fh_open;
|
||||
ftpfs_subclass.fh_close = ftpfs_fh_close;
|
||||
ftpfs_subclass.fh_free_data = ftpfs_fh_free_data;
|
||||
ftpfs_subclass.dir_load = ftpfs_dir_load;
|
||||
ftpfs_subclass.file_store = ftpfs_file_store;
|
||||
ftpfs_subclass.linear_start = ftpfs_linear_start;
|
||||
|
Loading…
Reference in New Issue
Block a user