Skip to content

Commit 141f131

Browse files
mtwebsterclefebvre
authored andcommitted
epub: Prevent path traversal when extracting files [CVE-2023-44451]
Test each file's resolved path against the temporary directory before extracting. Fixes: CVE-2023-44451 - Linux Mint Xreader EPUB File Parsing Directory Traversal Remote Code Execution Vulnerability. This vulnerability was discovered by: Febin Mon Saji working with Trend Micro Zero Day Initiative
1 parent 4902eae commit 141f131

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

Diff for: backend/epub/epub-document.c

+21-3
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ check_mime_type(const gchar* uri,GError** error)
665665
}
666666

667667
static gboolean
668-
extract_one_file(EpubDocument* epub_document,GError ** error)
668+
extract_one_file(EpubDocument* epub_document, GFile *tmp_gfile, GError ** error)
669669
{
670670
GFile * outfile ;
671671
gsize writesize = 0;
@@ -696,6 +696,21 @@ extract_one_file(EpubDocument* epub_document,GError ** error)
696696
if (g_strrstr(currentfilename, ".html") != NULL)
697697
g_string_insert_c (gfilepath, gfilepath->len-4, 'x');
698698

699+
outfile = g_file_new_for_path (gfilepath->str);
700+
g_autofree gchar *rpath = g_file_get_relative_path (tmp_gfile, outfile);
701+
702+
if (rpath == NULL)
703+
{
704+
g_set_error_literal (error,
705+
EV_DOCUMENT_ERROR,
706+
EV_DOCUMENT_ERROR_INVALID,
707+
_("epub file is invalid or corrupt"));
708+
g_critical ("Invalid filename in Epub container - '%s'", (gchar *) currentfilename);
709+
g_object_unref (outfile);
710+
result = FALSE;
711+
goto out;
712+
}
713+
699714
/*if we encounter a directory, make a directory inside our temporary folder.*/
700715
if (directory != NULL && *directory == '\0')
701716
{
@@ -723,7 +738,6 @@ extract_one_file(EpubDocument* epub_document,GError ** error)
723738
g_string_free(dir_create,TRUE);
724739
}
725740

726-
outfile = g_file_new_for_path(gfilepath->str);
727741
outstream = g_file_create(outfile,G_FILE_CREATE_PRIVATE,NULL,error);
728742
gpointer buffer = g_malloc0(512);
729743
while ( (writesize = unzReadCurrentFile(epub_document->epubDocument,buffer,512) ) != 0 )
@@ -751,6 +765,7 @@ extract_epub_from_container (const gchar* uri,
751765
EpubDocument *epub_document,
752766
GError ** error)
753767
{
768+
GFile *tmp_gfile = NULL;
754769
GError *err = NULL;
755770
epub_document->archivename = g_filename_from_uri(uri,NULL,error);
756771

@@ -812,9 +827,11 @@ extract_epub_from_container (const gchar* uri,
812827
goto out;
813828
}
814829

830+
tmp_gfile = g_file_new_for_path (epub_document->tmp_archive_dir);
831+
815832
while ( TRUE )
816833
{
817-
if ( extract_one_file(epub_document,&err) == FALSE )
834+
if ( extract_one_file(epub_document, tmp_gfile, &err) == FALSE )
818835
{
819836
if (err) {
820837
g_propagate_error (error, err);
@@ -835,6 +852,7 @@ extract_epub_from_container (const gchar* uri,
835852
}
836853

837854
out:
855+
g_clear_object (&tmp_gfile);
838856
unzClose(epub_document->epubDocument);
839857
return result;
840858
}

0 commit comments

Comments
 (0)