Coverage Report

Created: 2026-09-06 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata8/src/detect-entropy.c
Line
Count
Source
1
/* Copyright (C) 2025 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
#include "suricata-common.h"
19
20
#include "detect.h"
21
#include "detect-parse.h"
22
#include "detect-engine.h"
23
#include "detect-engine-buffer.h"
24
25
#include "detect-entropy.h"
26
#include "util-var-name.h"
27
#include "flow-var.h"
28
29
#include "rust.h"
30
31
static int DetectEntropySetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
32
2.80k
{
33
2.80k
    DetectEntropyData *ded = SCDetectEntropyParse(arg);
34
2.80k
    if (ded == NULL) {
35
430
        goto error;
36
430
    }
37
38
2.37k
    int sm_list = DETECT_SM_LIST_PMATCH;
39
2.37k
    if (s->init_data->list != DETECT_SM_LIST_NOTSET) {
40
        /* sticky buffer */
41
1.12k
        if (DetectBufferGetActiveList(de_ctx, s) == -1)
42
0
            goto error;
43
44
1.12k
        sm_list = s->init_data->list;
45
1.12k
        const char *name;
46
1.12k
        if (sm_list == DETECT_SM_LIST_BASE64_DATA) {
47
88
            name = "base64_data";
48
1.03k
        } else {
49
1.03k
            name = DetectEngineBufferTypeGetNameById(de_ctx, sm_list);
50
1.03k
            if (name == NULL) {
51
0
                DEBUG_VALIDATE_BUG_ON(1);
52
0
                name = "unknown";
53
0
            }
54
1.03k
        }
55
1.12k
        ded->fv_idx = VarNameStoreRegister(name, VAR_TYPE_FLOW_FLOAT);
56
1.24k
    } else {
57
1.24k
        ded->fv_idx = VarNameStoreRegister("content", VAR_TYPE_FLOW_FLOAT);
58
1.24k
    }
59
2.37k
    if (ded->fv_idx == 0) {
60
0
        goto error;
61
0
    }
62
63
2.37k
    if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_ENTROPY, (SigMatchCtx *)ded, sm_list) != NULL) {
64
2.37k
        SCReturnInt(0);
65
2.37k
    }
66
67
    /* fall through */
68
69
430
error:
70
430
    SCLogDebug("error during entropy setup");
71
430
    if (ded != NULL) {
72
0
        SCDetectEntropyFree(ded);
73
0
    }
74
430
    SCReturnInt(-1);
75
2.37k
}
76
77
static void DetectEntropyFree(DetectEngineCtx *de_ctx, void *ptr)
78
2.37k
{
79
2.37k
    if (ptr) {
80
2.37k
        DetectEntropyData *ded = (DetectEntropyData *)ptr;
81
2.37k
        VarNameStoreUnregister(ded->fv_idx, VAR_TYPE_FLOW_FLOAT);
82
2.37k
        SCDetectEntropyFree(ptr);
83
2.37k
    }
84
2.37k
}
85
86
bool DetectEntropyDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s,
87
        const SigMatchCtx *ctx, Flow *flow, const uint8_t *buffer, const uint32_t buffer_len)
88
8.41k
{
89
8.41k
    double entropy = -1.0;
90
8.41k
    bool rc = SCDetectEntropyMatch(buffer, buffer_len, (const DetectEntropyData *)ctx, &entropy);
91
92
8.41k
    if (flow && entropy != -1.0) {
93
8.40k
        DetectEntropyData *ded = (DetectEntropyData *)ctx;
94
8.40k
        FlowVarAddFloat(flow, ded->fv_idx, entropy);
95
8.40k
    }
96
97
8.41k
    return rc;
98
8.41k
}
99
100
void DetectEntropyRegister(void)
101
79
{
102
79
    sigmatch_table[DETECT_ENTROPY].name = "entropy";
103
79
    sigmatch_table[DETECT_ENTROPY].desc = "calculate entropy";
104
79
    sigmatch_table[DETECT_ENTROPY].url = "/rules/payload-keywords.html#entropy";
105
79
    sigmatch_table[DETECT_ENTROPY].Free = DetectEntropyFree;
106
79
    sigmatch_table[DETECT_ENTROPY].Setup = DetectEntropySetup;
107
79
}