Coverage Report

Created: 2025-11-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/util-coredump-config.c
Line
Count
Source
1
/* Copyright (C) 2007-2010 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
/**
19
 * \file
20
 *
21
 * \author Eileen Donlon <emdonlo@gmail.com>
22
 *
23
 * Coredump configuration
24
 */
25
26
#include "suricata-common.h"
27
#define _FILE_OFFSET_BITS 64
28
#include "util-coredump-config.h"
29
#include "conf.h"
30
#ifdef HAVE_SYS_RESOURCE_H
31
#include <sys/resource.h>
32
#endif
33
#ifdef HAVE_SYS_PRCTL_H
34
#include <sys/prctl.h>
35
#endif
36
#include "util-debug.h"
37
38
#ifdef OS_WIN32
39
40
void CoredumpEnable(void) {
41
}
42
43
int32_t CoredumpLoadConfig(void) {
44
    /* todo: use the registry to get/set dump configuration */
45
    SCLogInfo("Configuring core dump is not yet supported on Windows.");
46
    return 0;
47
}
48
49
#else
50
51
static bool unlimited = false;
52
static rlim_t max_dump = 0;
53
54
/**
55
 * \brief Enable coredumps on systems where coredumps can and need to
56
 * be enabled.
57
 */
58
void CoredumpEnable(void)
59
0
{
60
0
    if (!unlimited && !max_dump) {
61
0
        return;
62
0
    }
63
0
#if HAVE_SYS_PRCTL_H
64
    /* Linux specific core dump configuration; set dumpable flag if needed */
65
0
    int dumpable = 0;
66
0
    dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
67
0
    if (dumpable == -1) {
68
0
        SCLogNotice("Failed to get dumpable state of process, "
69
0
                    "core dumps may not be enabled: %s",
70
0
                strerror(errno));
71
0
    }
72
0
    else if (unlimited || max_dump > 0) {
73
        /* try to enable core dump for this process */
74
0
        if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
75
0
            SCLogInfo("Unable to make this process dumpable.");
76
0
        } else {
77
0
            SCLogDebug("Process is dumpable.");
78
0
        }
79
0
    }
80
    /* don't clear dumpable flag since this will have other effects;
81
     * just set dump size to 0 below */
82
0
#endif /* HAVE_SYS_PRCTL_H */
83
0
}
84
85
/**
86
 * \brief Configures the core dump size.
87
 *
88
 * \retval Returns 1 on success and 0 on failure.
89
 *
90
 */
91
int32_t CoredumpLoadConfig (void)
92
33
{
93
33
#ifdef HAVE_SYS_RESOURCE_H
94
    /* get core dump configuration settings for suricata */
95
33
    const char *dump_size_config = NULL;
96
33
    size_t rlim_size = sizeof(rlim_t);
97
98
33
    if (ConfGet ("coredump.max-dump", &dump_size_config) == 0) {
99
33
        SCLogDebug ("core dump size not specified");
100
33
        return 1;
101
33
    }
102
0
    if (dump_size_config == NULL) {
103
0
        SCLogError("malformed value for coredump.max-dump: NULL");
104
0
        return 0;
105
0
    }
106
0
    if (strcasecmp (dump_size_config, "unlimited") == 0) {
107
0
        unlimited = true;
108
0
    }
109
0
    else {
110
        /* disallow negative values */
111
0
        if (strchr (dump_size_config, '-') != NULL) {
112
0
            SCLogInfo ("Negative value for core dump size; ignored.");
113
0
            return 0;
114
0
        }
115
        /* the size of rlim_t is platform dependent */
116
0
        if (rlim_size > 8) {
117
0
            SCLogInfo ("Unexpected type for rlim_t");
118
0
            return 0;
119
0
        }
120
0
        errno = 0;
121
0
        if (rlim_size == 8) {
122
0
            max_dump = (rlim_t) strtoull (dump_size_config, NULL, 10);
123
0
        }
124
0
        else if (rlim_size == 4) {
125
0
            max_dump = (rlim_t) strtoul (dump_size_config, NULL, 10);
126
0
        }
127
0
        if ((errno == ERANGE) || (errno != 0 && max_dump == 0)) {
128
0
            SCLogInfo ("Illegal core dump size: %s.", dump_size_config);
129
0
            return 0;
130
0
        }
131
0
        SCLogInfo ("Max dump is %"PRIu64, (uint64_t) max_dump);
132
0
    }
133
134
0
    CoredumpEnable();
135
136
0
    struct rlimit lim;     /*existing limit*/
137
0
    struct rlimit new_lim; /*desired limit*/
138
139
    /* get the current core dump file configuration */
140
0
    if (getrlimit (RLIMIT_CORE, &lim) == -1) {
141
0
       SCLogInfo ("Can't read coredump limit for this process.");
142
0
        return 0;
143
0
    }
144
145
0
    if (unlimited) {
146
        /* we want no limit on coredump size */
147
0
        if (lim.rlim_max == RLIM_INFINITY && lim.rlim_cur == RLIM_INFINITY) {
148
0
            SCLogConfig ("Core dump size is unlimited.");
149
0
            return 1;
150
0
        }
151
0
        else {
152
0
            new_lim.rlim_max = RLIM_INFINITY;
153
0
            new_lim.rlim_cur = RLIM_INFINITY;
154
0
            if (setrlimit (RLIMIT_CORE, &new_lim) == 0) {
155
0
                SCLogConfig ("Core dump size set to unlimited.");
156
0
                return 1;
157
0
            }
158
0
            if (errno == EPERM) {
159
                /* couldn't raise the hard limit to unlimited;
160
                 * try increasing the soft limit to the hard limit instead */
161
0
                if (lim.rlim_cur < lim.rlim_max) {
162
0
                    new_lim.rlim_cur = lim.rlim_max;
163
0
                    if (setrlimit (RLIMIT_CORE, & new_lim) == 0) {
164
0
                        SCLogInfo ("Could not set core dump size to unlimited; core dump size set to the hard limit.");
165
0
                        return 0;
166
0
                    }
167
0
                    else {
168
0
                        SCLogInfo ("Failed to set core dump size to unlimited or to the hard limit.");
169
0
                        return 0;
170
0
                    }
171
0
                }
172
0
                SCLogInfo ("Could not set core dump size to unlimited; it's set to the hard limit.");
173
0
                return 0;
174
0
            }
175
0
        }
176
0
    }
177
0
    else {
178
        /* we want a non-infinite soft limit on coredump size */
179
0
        new_lim.rlim_cur = max_dump;
180
181
        /* check whether the hard limit needs to be adjusted */
182
0
        if (lim.rlim_max == RLIM_INFINITY) {
183
            /* keep the current value (unlimited) for the hard limit */
184
0
            new_lim.rlim_max = lim.rlim_max;
185
0
        }
186
0
#ifdef RLIM_SAVED_MAX
187
0
        else if (lim.rlim_max == RLIM_SAVED_MAX) {
188
            /* keep the current value (unknown) for the hard limit */
189
0
            new_lim.rlim_max = lim.rlim_max;
190
0
        }
191
0
#endif
192
0
        else if (lim.rlim_max <  max_dump) {
193
            /* need to raise the hard coredump size limit */
194
0
            new_lim.rlim_max =  max_dump;
195
0
        }
196
0
        else {
197
            /* hard limit is ample */
198
0
            new_lim.rlim_max = lim.rlim_max;
199
0
        }
200
0
        if (setrlimit (RLIMIT_CORE, &new_lim) == 0) {
201
0
            SCLogInfo ("Core dump setting attempted is %"PRIu64, (uint64_t) new_lim.rlim_cur);
202
0
            struct rlimit actual_lim;
203
0
            if (getrlimit (RLIMIT_CORE, &actual_lim) == 0) {
204
0
                if (actual_lim.rlim_cur == RLIM_INFINITY) {
205
0
                    SCLogConfig ("Core dump size set to unlimited.");
206
0
                }
207
0
#ifdef RLIM_SAVED_CUR
208
0
                else if (actual_lim.rlim_cur == RLIM_SAVED_CUR) {
209
0
                    SCLogInfo ("Core dump size set to soft limit.");
210
0
                }
211
0
#endif
212
0
                else {
213
0
                    SCLogInfo ("Core dump size set to %"PRIu64, (uint64_t) actual_lim.rlim_cur);
214
0
                }
215
0
            }
216
0
            return 1;
217
0
        }
218
219
0
        if (errno == EINVAL || errno == EPERM) {
220
            /* couldn't increase the hard limit, or the soft limit exceeded the hard
221
             * limit; try to raise the soft limit to the hard limit */
222
0
            if ((lim.rlim_cur < max_dump && lim.rlim_cur < lim.rlim_max)
223
0
#ifdef RLIM_SAVED_CUR
224
0
                || (lim.rlim_cur == RLIM_SAVED_CUR)
225
0
#endif
226
0
            ){
227
0
                new_lim.rlim_max = lim.rlim_max;
228
0
                new_lim.rlim_cur = lim.rlim_max;
229
0
                if (setrlimit (RLIMIT_CORE, &new_lim) == 0)  {
230
0
                    SCLogInfo("Core dump size set to the hard limit.");
231
0
                    return 0;
232
0
                }
233
0
            }
234
0
        }
235
0
    }
236
    /* failed to set the coredump limit */
237
0
    SCLogInfo("Couldn't set coredump size to %s.", dump_size_config);
238
0
#endif /* HAVE_SYS_RESOURCE_H */
239
0
    return 0;
240
0
}
241
242
#endif /* OS_WIN32 */