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:
Andrew Borodin 2011-10-19 12:45:28 +04:00
parent 50574c687a
commit 664b3efcda
4 changed files with 42 additions and 20 deletions

View File

@ -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)

View File

@ -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,

View File

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

View File

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