Skip to content

Commit

Permalink
Ticket #3621: fix segfault when enter in some cpio archives.
Browse files Browse the repository at this point in the history
(cpio_create_entry): fix NULL dereference (i. e. in case of stale link).

Signed-off-by: Andrew Borodin <[email protected]>
  • Loading branch information
aborodin committed Mar 28, 2016
1 parent 990f6f1 commit a056be3
Showing 1 changed file with 36 additions and 23 deletions.
59 changes: 36 additions & 23 deletions src/vfs/cpio/cpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,44 +469,57 @@ cpio_create_entry (struct vfs_class *me, struct vfs_s_super *super, struct stat
}
else
{ /* !entry */
if (inode == NULL)
/* root == NULL can be in the following case:
* a/b/c -> d
* where 'a/b' is the stale link and therefore root of 'c' cannot be found in the archive
*/
if (root != NULL)
{
inode = vfs_s_new_inode (me, super, st);
if ((st->st_nlink > 0) && ((arch->type == CPIO_NEWC) || (arch->type == CPIO_CRC)))
if (inode == NULL)
{
/* For case of hardlinked files */
defer_inode *i;

i = g_new (defer_inode, 1);
i->inumber = st->st_ino;
i->device = st->st_dev;
i->inode = inode;

arch->deferred = g_slist_prepend (arch->deferred, i);
inode = vfs_s_new_inode (me, super, st);
if ((st->st_nlink > 0) && ((arch->type == CPIO_NEWC) || (arch->type == CPIO_CRC)))
{
/* For case of hardlinked files */
defer_inode *i;

i = g_new (defer_inode, 1);
i->inumber = st->st_ino;
i->device = st->st_dev;
i->inode = inode;

arch->deferred = g_slist_prepend (arch->deferred, i);
}
}
}

if (st->st_size != 0)
inode->data_offset = CPIO_POS (super);
if (st->st_size != 0)
inode->data_offset = CPIO_POS (super);

entry = vfs_s_new_entry (me, tn, inode);
vfs_s_insert_entry (me, root, entry);
entry = vfs_s_new_entry (me, tn, inode);
vfs_s_insert_entry (me, root, entry);
}

g_free (name);

if (!S_ISLNK (st->st_mode))
CPIO_SEEK_CUR (super, st->st_size);
else
{
inode->linkname = g_malloc (st->st_size + 1);

if (mc_read (arch->fd, inode->linkname, st->st_size) < st->st_size)
if (inode != NULL)
{
inode->linkname[0] = '\0';
return STATUS_EOF;
/* FIXME: do we must read from arch->fd in case of inode != NULL only or in any case? */

inode->linkname = g_malloc (st->st_size + 1);

if (mc_read (arch->fd, inode->linkname, st->st_size) < st->st_size)
{
inode->linkname[0] = '\0';
return STATUS_EOF;
}

inode->linkname[st->st_size] = '\0'; /* Linkname stored without terminating \0 !!! */
}

inode->linkname[st->st_size] = '\0'; /* Linkname stored without terminating \0 !!! */
CPIO_POS (super) += st->st_size;
cpio_skip_padding (super);
}
Expand Down

0 comments on commit a056be3

Please sign in to comment.