diff options
author | Vsevolod Stakhov <vsevolod@rspamd.com> | 2022-04-13 20:42:54 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rspamd.com> | 2022-04-13 20:42:54 +0100 |
commit | d89c7389ff1f7b7a8147dc658a4117ec0fe6f9cb (patch) | |
tree | a6047e08a934f0938144645c5547844aaee61d11 /src | |
parent | d7b4d913b5695ac580103176db03fcd628901b89 (diff) | |
download | rspamd-d89c7389ff1f7b7a8147dc658a4117ec0fe6f9cb.tar.gz rspamd-d89c7389ff1f7b7a8147dc658a4117ec0fe6f9cb.zip |
[Fix] Ignore directories in RarV5 archives
Issue: #4134
Diffstat (limited to 'src')
-rw-r--r-- | src/libmime/archives.c | 106 |
1 files changed, 57 insertions, 49 deletions
diff --git a/src/libmime/archives.c b/src/libmime/archives.c index 45fca12f2..2cf054035 100644 --- a/src/libmime/archives.c +++ b/src/libmime/archives.c @@ -694,6 +694,7 @@ rspamd_archive_process_rar (struct rspamd_task *task, else { /* We have a file header, go forward */ guint64 fname_len; + bool is_directory = false; /* File header specific flags */ RAR_READ_VINT_SKIP (); @@ -713,68 +714,75 @@ rspamd_archive_process_rar (struct rspamd_task *task, /* Crc32 */ RAR_SKIP_BYTES (sizeof (guint32)); } + if (flags & 0x1) { + /* Ignore directories for sanity purposes */ + is_directory = true; + msg_debug_archive ("skip directory record in a rar archive"); + } - /* Compression */ - RAR_READ_VINT_SKIP (); - /* Host OS */ - RAR_READ_VINT_SKIP (); - /* Filename length (finally!) */ - RAR_READ_VINT_SKIP (); - fname_len = vint; + if (!is_directory) { + /* Compression */ + RAR_READ_VINT_SKIP (); + /* Host OS */ + RAR_READ_VINT_SKIP (); + /* Filename length (finally!) */ + RAR_READ_VINT_SKIP (); + fname_len = vint; - if (fname_len == 0 || fname_len > (gsize)(end - p)) { - msg_debug_archive ("rar archive is invalid (bad filename size)"); + if (fname_len == 0 || fname_len > (gsize) (end - p)) { + msg_debug_archive ("rar archive is invalid (bad filename size)"); - return; - } + return; + } - f = g_malloc0 (sizeof (*f)); - f->uncompressed_size = uncomp_sz; - f->compressed_size = comp_sz; - rspamd_archive_file_try_utf (task, arch, f, p, fname_len); + f = g_malloc0(sizeof(*f)); + f->uncompressed_size = uncomp_sz; + f->compressed_size = comp_sz; + rspamd_archive_file_try_utf(task, arch, f, p, fname_len); - if (f->fname) { - msg_debug_archive ("added rarv5 file: %v", f->fname); - g_ptr_array_add (arch->files, f); - if (f->flags & RSPAMD_ARCHIVE_FILE_OBFUSCATED) { - arch->flags |= RSPAMD_ARCHIVE_HAS_OBFUSCATED_FILES; + if (f->fname) { + msg_debug_archive ("added rarv5 file: %v", f->fname); + g_ptr_array_add(arch->files, f); + if (f->flags & RSPAMD_ARCHIVE_FILE_OBFUSCATED) { + arch->flags |= RSPAMD_ARCHIVE_HAS_OBFUSCATED_FILES; + } + } + else { + g_free(f); + f = NULL; } - } - else { - g_free (f); - f = NULL; - } - if (f && has_extra && extra_sz > 0 && - p + fname_len + extra_sz < end) { - /* Try to find encryption record in extra field */ - const guchar *ex = p + fname_len; + if (f && has_extra && extra_sz > 0 && + p + fname_len + extra_sz < end) { + /* Try to find encryption record in extra field */ + const guchar *ex = p + fname_len; - while (ex < p + extra_sz) { - const guchar *t; - gint64 cur_sz = 0, sec_type = 0; + while (ex < p + extra_sz) { + const guchar *t; + gint64 cur_sz = 0, sec_type = 0; - r = rspamd_archive_rar_read_vint (ex, extra_sz, &cur_sz); - if (r == -1) { - msg_debug_archive ("rar archive is invalid (bad vint)"); - return; - } + r = rspamd_archive_rar_read_vint(ex, extra_sz, &cur_sz); + if (r == -1) { + msg_debug_archive ("rar archive is invalid (bad vint)"); + return; + } - t = ex + r; + t = ex + r; - r = rspamd_archive_rar_read_vint (t, extra_sz - r, &sec_type); - if (r == -1) { - msg_debug_archive ("rar archive is invalid (bad vint)"); - return; - } + r = rspamd_archive_rar_read_vint(t, extra_sz - r, &sec_type); + if (r == -1) { + msg_debug_archive ("rar archive is invalid (bad vint)"); + return; + } - if (sec_type == 0x01) { - f->flags |= RSPAMD_ARCHIVE_FILE_ENCRYPTED; - arch->flags |= RSPAMD_ARCHIVE_ENCRYPTED; - break; - } + if (sec_type == 0x01) { + f->flags |= RSPAMD_ARCHIVE_FILE_ENCRYPTED; + arch->flags |= RSPAMD_ARCHIVE_ENCRYPTED; + break; + } - ex += cur_sz; + ex += cur_sz; + } } } |