suricata
app-layer-htp-mem.c
Go to the documentation of this file.
1 /* Copyright (C) 2013 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  * \ingroup httplayer
20  *
21  * @{
22  */
23 
24 /**
25  * \file
26  *
27  * \author Eric Leblond <eric@regit.org>
28  *
29  * This file provides a memory handling for the HTTP protocol support.
30  */
31 
32 #include "suricata-common.h"
33 #include "app-layer-htp-mem.h"
34 
35 #include "conf.h"
36 #include "util-misc.h"
37 #include "util-debug.h"
38 
39 SC_ATOMIC_DECLARE(uint64_t, htp_config_memcap);
40 SC_ATOMIC_DECLARE(uint64_t, htp_memuse);
41 SC_ATOMIC_DECLARE(uint64_t, htp_memcap);
42 
43 void HTPParseMemcap(void)
44 {
45  const char *conf_val;
46 
47  SC_ATOMIC_INIT(htp_config_memcap);
48 
49  /** set config values for memcap, prealloc and hash_size */
50  uint64_t memcap;
51  if ((ConfGet("app-layer.protocols.http.memcap", &conf_val)) == 1)
52  {
53  if (ParseSizeStringU64(conf_val, &memcap) < 0) {
54  SCLogError("Error parsing http.memcap "
55  "from conf file - %s. Killing engine",
56  conf_val);
57  exit(EXIT_FAILURE);
58  } else {
59  SC_ATOMIC_SET(htp_config_memcap, memcap);
60  }
61  SCLogInfo("HTTP memcap: %"PRIu64, SC_ATOMIC_GET(htp_config_memcap));
62  } else {
63  /* default to unlimited */
64  SC_ATOMIC_SET(htp_config_memcap, 0);
65  }
66 
67  SC_ATOMIC_INIT(htp_memuse);
68  SC_ATOMIC_INIT(htp_memcap);
69 }
70 
71 static void HTPIncrMemuse(uint64_t size)
72 {
73  (void) SC_ATOMIC_ADD(htp_memuse, size);
74  return;
75 }
76 
77 static void HTPDecrMemuse(uint64_t size)
78 {
79  (void) SC_ATOMIC_SUB(htp_memuse, size);
80  return;
81 }
82 
83 uint64_t HTPMemuseGlobalCounter(void)
84 {
85  uint64_t tmpval = SC_ATOMIC_GET(htp_memuse);
86  return tmpval;
87 }
88 
89 uint64_t HTPMemcapGlobalCounter(void)
90 {
91  uint64_t tmpval = SC_ATOMIC_GET(htp_memcap);
92  return tmpval;
93 }
94 
95 /**
96  * \brief Check if alloc'ing "size" would mean we're over memcap
97  *
98  * \retval 1 if in bounds
99  * \retval 0 if not in bounds
100  */
101 static int HTPCheckMemcap(uint64_t size)
102 {
103  uint64_t memcapcopy = SC_ATOMIC_GET(htp_config_memcap);
104  if (memcapcopy == 0 || size + SC_ATOMIC_GET(htp_memuse) <= memcapcopy)
105  return 1;
106  (void) SC_ATOMIC_ADD(htp_memcap, 1);
107  return 0;
108 }
109 
110 /**
111  * \brief Update memcap value
112  *
113  * \param size new memcap value
114  */
115 int HTPSetMemcap(uint64_t size)
116 {
117  if (size == 0 || (uint64_t)SC_ATOMIC_GET(htp_memuse) < size) {
118  SC_ATOMIC_SET(htp_config_memcap, size);
119  return 1;
120  }
121  return 0;
122 }
123 
124 /**
125  * \brief Update memcap value
126  *
127  * \retval memcap value
128  */
129 uint64_t HTPGetMemcap(void)
130 {
131  uint64_t memcapcopy = SC_ATOMIC_GET(htp_config_memcap);
132  return memcapcopy;
133 }
134 
135 void *HTPMalloc(size_t size)
136 {
137  void *ptr = NULL;
138 
139  if (HTPCheckMemcap((uint32_t)size) == 0)
140  return NULL;
141 
142  ptr = SCMalloc(size);
143 
144  if (unlikely(ptr == NULL))
145  return NULL;
146 
147  HTPIncrMemuse((uint64_t)size);
148 
149  return ptr;
150 }
151 
152 void *HTPCalloc(size_t n, size_t size)
153 {
154  void *ptr = NULL;
155 
156  if (HTPCheckMemcap((uint32_t)(n * size)) == 0)
157  return NULL;
158 
159  ptr = SCCalloc(n, size);
160 
161  if (unlikely(ptr == NULL))
162  return NULL;
163 
164  HTPIncrMemuse((uint64_t)(n * size));
165 
166  return ptr;
167 }
168 
169 void *HTPRealloc(void *ptr, size_t orig_size, size_t size)
170 {
171  if (size > orig_size) {
172  if (HTPCheckMemcap((uint32_t)(size - orig_size)) == 0)
173  return NULL;
174  }
175 
176  void *rptr = SCRealloc(ptr, size);
177  if (rptr == NULL)
178  return NULL;
179 
180  if (size > orig_size) {
181  HTPIncrMemuse((uint64_t)(size - orig_size));
182  } else {
183  HTPDecrMemuse((uint64_t)(orig_size - size));
184  }
185 
186  return rptr;
187 }
188 
189 void HTPFree(void *ptr, size_t size)
190 {
191  SCFree(ptr);
192 
193  HTPDecrMemuse((uint64_t)size);
194 }
195 
196 /**
197  * @}
198  */
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:314
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:386
ParseSizeStringU64
int ParseSizeStringU64(const char *size, uint64_t *res)
Definition: util-misc.c:198
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:332
HTPRealloc
void * HTPRealloc(void *ptr, size_t orig_size, size_t size)
Definition: app-layer-htp-mem.c:169
HTPMemuseGlobalCounter
uint64_t HTPMemuseGlobalCounter(void)
Definition: app-layer-htp-mem.c:83
SC_ATOMIC_DECLARE
SC_ATOMIC_DECLARE(uint64_t, htp_config_memcap)
HTPParseMemcap
void HTPParseMemcap(void)
Definition: app-layer-htp-mem.c:43
HTPSetMemcap
int HTPSetMemcap(uint64_t size)
Update memcap value.
Definition: app-layer-htp-mem.c:115
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:335
util-debug.h
HTPGetMemcap
uint64_t HTPGetMemcap(void)
Update memcap value.
Definition: app-layer-htp-mem.c:129
HTPCalloc
void * HTPCalloc(size_t n, size_t size)
Definition: app-layer-htp-mem.c:152
SC_ATOMIC_SUB
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
Definition: util-atomic.h:341
conf.h
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
SCRealloc
#define SCRealloc(ptr, sz)
Definition: util-mem.h:50
suricata-common.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
HTPMemcapGlobalCounter
uint64_t HTPMemcapGlobalCounter(void)
Definition: app-layer-htp-mem.c:89
app-layer-htp-mem.h
HTPMalloc
void * HTPMalloc(size_t size)
Definition: app-layer-htp-mem.c:135
HTPFree
void HTPFree(void *ptr, size_t size)
Definition: app-layer-htp-mem.c:189
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:375
util-misc.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53