Coverage Report

Created: 2026-05-16 07:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/util-file-swf-decompression.c
Line
Count
Source
1
/* Copyright (C) 2017 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17
18
/** \file
19
 *
20
 * \author Giuseppe Longo <giuseppe@glongo.it>
21
 *
22
 */
23
24
25
#include "suricata.h"
26
#include "suricata-common.h"
27
28
#include "app-layer-htp.h"
29
30
#include "util-file-decompression.h"
31
#include "util-file-swf-decompression.h"
32
#include "util-misc.h"
33
#include "util-print.h"
34
#include "util-validate.h"
35
36
#include "rust.h"
37
38
#include <zlib.h>
39
40
0
#define MAX_SWF_DECOMPRESSED_LEN 50000000
41
/*
42
 * Return uncompressed file length
43
 * in little-endian order
44
 */
45
uint32_t FileGetSwfDecompressedLen(const uint8_t *buffer,
46
                                   const uint32_t buffer_len)
47
1
{
48
1
    if (buffer_len < 8) {
49
0
        return 0;
50
0
    }
51
52
1
    uint32_t a = buffer[4];
53
1
    uint32_t b = buffer[5];
54
1
    uint32_t c = buffer[6];
55
1
    uint32_t d = buffer[7];
56
57
1
    uint32_t value = (((a & 0xff) << 24UL) |
58
1
                      ((b & 0xff) << 16UL) |
59
1
                      ((c & 0xff) << 8UL) |
60
1
                       (d & 0xff));
61
62
1
    uint32_t len = (((value >> 24) & 0x000000FFUL) |
63
1
                    ((value >> 8)  & 0x0000FF00UL) |
64
1
                    ((value << 8)  & 0x00FF0000UL) |
65
1
                    ((value << 24) & 0xFF000000UL));
66
67
1
    return MIN(MAX_SWF_DECOMPRESSED_LEN, len);
68
1
}
69
70
uint8_t FileGetSwfVersion(const uint8_t *buffer, const uint32_t buffer_len)
71
1
{
72
1
    if (buffer_len > 3)
73
1
        return buffer[3];
74
75
0
    return 0;
76
1
}
77
78
/* CWS format */
79
/*
80
 * | 4 bytes         | 4 bytes    | n bytes         |
81
 * | 'CWS' + version | script len | compressed data |
82
 */
83
int FileSwfZlibDecompression(DetectEngineThreadCtx *det_ctx,
84
                             uint8_t *compressed_data, uint32_t compressed_data_len,
85
                             uint8_t *decompressed_data, uint32_t decompressed_data_len)
86
1
{
87
1
    int ret = 1;
88
1
    z_stream infstream;
89
1
    memset(&infstream, 0, sizeof(infstream));
90
1
    infstream.zalloc = Z_NULL;
91
1
    infstream.zfree = Z_NULL;
92
1
    infstream.opaque = Z_NULL;
93
94
1
    infstream.avail_in = (uInt)compressed_data_len;
95
1
    infstream.next_in = (Bytef *)compressed_data;
96
1
    infstream.avail_out = (uInt)decompressed_data_len;
97
1
    infstream.next_out = (Bytef *)decompressed_data;
98
99
1
    int result = inflateInit(&infstream);
100
1
    if (result != Z_OK) {
101
0
        DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_Z_UNKNOWN_ERROR);
102
0
        return 0;
103
0
    }
104
105
1
    result = inflate(&infstream, Z_NO_FLUSH);
106
1
    switch(result) {
107
0
        case Z_STREAM_END:
108
0
            break;
109
0
        case Z_OK:
110
0
            break;
111
1
        case Z_DATA_ERROR:
112
1
            DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_Z_DATA_ERROR);
113
1
            ret = 0;
114
1
            break;
115
0
        case Z_STREAM_ERROR:
116
0
            DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_Z_STREAM_ERROR);
117
0
            ret = 0;
118
0
            break;
119
0
        case Z_BUF_ERROR:
120
0
            DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_Z_BUF_ERROR);
121
0
            ret = 0;
122
0
            break;
123
0
        default:
124
0
            DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_Z_UNKNOWN_ERROR);
125
0
            ret = 0;
126
0
            break;
127
1
    }
128
1
    inflateEnd(&infstream);
129
130
1
    return ret;
131
1
}
132
133
/* ZWS format */
134
/*
135
 * | 4 bytes         | 4 bytes    | 4 bytes        | 5 bytes    | n bytes   | 6 bytes         |
136
 * | 'ZWS' + version | script len | compressed len | LZMA props | LZMA data | LZMA end marker |
137
 */
138
int FileSwfLzmaDecompression(DetectEngineThreadCtx *det_ctx,
139
                             uint8_t *compressed_data, uint32_t compressed_data_len,
140
                             uint8_t *decompressed_data, uint32_t decompressed_data_len)
141
0
{
142
0
    int ret = 0;
143
144
0
    size_t inprocessed = compressed_data_len;
145
0
    size_t outprocessed = decompressed_data_len;
146
147
0
    ret = lzma_decompress(compressed_data, &inprocessed, decompressed_data, &outprocessed,
148
0
            MAX_SWF_DECOMPRESSED_LEN);
149
150
0
    switch(ret) {
151
0
        case LzmaOk:
152
0
            ret = 1;
153
0
            break;
154
0
        case LzmaIoError:
155
0
            DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_LZMA_IO_ERROR);
156
0
            ret = 0;
157
0
            break;
158
0
        case LzmaHeaderTooShortError:
159
0
            DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_LZMA_HEADER_TOO_SHORT_ERROR);
160
0
            ret = 0;
161
0
            break;
162
0
        case LzmaError:
163
0
            DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_LZMA_DECODER_ERROR);
164
0
            ret = 0;
165
0
            break;
166
0
        case LzmaMemoryError:
167
0
            DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_LZMA_MEMLIMIT_ERROR);
168
0
            ret = 0;
169
0
            break;
170
0
        case LzmaXzError:
171
            /* We should not see XZ compressed SWF files */
172
0
            DEBUG_VALIDATE_BUG_ON(ret == LzmaXzError);
173
0
            DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_LZMA_XZ_ERROR);
174
0
            ret = 0;
175
0
            break;
176
0
        default:
177
0
            DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_LZMA_UNKNOWN_ERROR);
178
0
            ret = 0;
179
0
            break;
180
0
    }
181
182
0
    return ret;
183
0
}