summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2009-03-06 17:12:08 +0300
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2009-03-06 17:12:08 +0300
commit6e382e5e70667dea4044645b57a2e8e3ccbc3254 (patch)
tree6d3b5def243aca1574d74dd7f3dd2fd4ed9591a0
parent514d83c13d1f22263c9662154e7459cdbff51c97 (diff)
downloadrspamd-6e382e5e70667dea4044645b57a2e8e3ccbc3254.tar.gz
rspamd-6e382e5e70667dea4044645b57a2e8e3ccbc3254.zip
* Fix bad memory leaks and memory corruption in url detecting module
-rw-r--r--src/plugins/surbl.c7
-rw-r--r--src/url.c61
-rw-r--r--src/util.c2
3 files changed, 58 insertions, 12 deletions
diff --git a/src/plugins/surbl.c b/src/plugins/surbl.c
index a58b0ef89..46162c57d 100644
--- a/src/plugins/surbl.c
+++ b/src/plugins/surbl.c
@@ -247,7 +247,6 @@ format_surbl_request (memory_pool_t *pool, f_str_t *hostname, struct suffix_item
octet2 = g_match_info_fetch (info, 2);
octet3 = g_match_info_fetch (info, 3);
octet4 = g_match_info_fetch (info, 4);
- g_match_info_free (info);
result = memory_pool_alloc (pool, len);
msg_debug ("format_surbl_request: got numeric host for check: %s.%s.%s.%s", octet1, octet2, octet3, octet4);
snprintf (result, len, "%s.%s.%s.%s.%s", octet4, octet3, octet2, octet1, suffix->suffix);
@@ -255,6 +254,7 @@ format_surbl_request (memory_pool_t *pool, f_str_t *hostname, struct suffix_item
g_free (octet2);
g_free (octet3);
g_free (octet4);
+ g_match_info_free (info);
return result;
}
g_match_info_free (info);
@@ -270,19 +270,21 @@ format_surbl_request (memory_pool_t *pool, f_str_t *hostname, struct suffix_item
/* Match additional part for hosters */
g_free (part1);
g_free (part2);
+ g_match_info_free (info);
if (g_regex_match_full (extract_hoster_regexp, hostname->begin, hostname->len, 0, 0, &info, NULL) == TRUE) {
gchar *hpart1, *hpart2, *hpart3;
hpart1 = g_match_info_fetch (info, 1);
hpart2 = g_match_info_fetch (info, 2);
hpart3 = g_match_info_fetch (info, 3);
- g_match_info_free (info);
msg_debug ("format_surbl_request: got hoster 3-d level domain %s.%s.%s", hpart1, hpart2, hpart3);
snprintf (result, len, "%s.%s.%s.%s", hpart1, hpart2, hpart3, suffix->suffix);
g_free (hpart1);
g_free (hpart2);
g_free (hpart3);
+ g_match_info_free (info);
return result;
}
+ g_match_info_free (info);
return NULL;
}
snprintf (result, len, "%s.%s.%s", part1, part2, suffix->suffix);
@@ -291,6 +293,7 @@ format_surbl_request (memory_pool_t *pool, f_str_t *hostname, struct suffix_item
return result;
}
+ g_match_info_free (info);
return NULL;
}
diff --git a/src/url.c b/src/url.c
index 31851c3bb..4c0281f5e 100644
--- a/src/url.c
+++ b/src/url.c
@@ -177,6 +177,37 @@ static const unsigned char urlchr_table[256] =
#undef U
#undef RU
+static const char *
+url_strerror (enum uri_errno err)
+{
+ switch (err) {
+ case URI_ERRNO_OK:
+ return "Parsing went well";
+ case URI_ERRNO_EMPTY:
+ return "The URI string was empty";
+ case URI_ERRNO_INVALID_PROTOCOL:
+ return "No protocol was found";
+ case URI_ERRNO_NO_SLASHES:
+ return "Slashes after protocol missing";
+ case URI_ERRNO_TOO_MANY_SLASHES:
+ return "Too many slashes after protocol";
+ case URI_ERRNO_TRAILING_DOTS:
+ return "'.' after host";
+ case URI_ERRNO_NO_HOST:
+ return "Host part is missing";
+ case URI_ERRNO_NO_PORT_COLON:
+ return "':' after host without port";
+ case URI_ERRNO_NO_HOST_SLASH:
+ return "Slash after host missing";
+ case URI_ERRNO_IPV6_SECURITY:
+ return "IPv6 security bug detected";
+ case URI_ERRNO_INVALID_PORT:
+ return "Port number is bad";
+ case URI_ERRNO_INVALID_PORT_RANGE:
+ return "Port number is not within 0-65535";
+ }
+}
+
static inline int
end_of_dir(unsigned char c)
{
@@ -825,7 +856,7 @@ url_parse_text (struct worker_task *task, GByteArray *content)
GMatchInfo *info;
GError *err = NULL;
int pos = 0, start;
- gboolean rc;
+ int rc;
char *url_str = NULL;
struct uri *new;
@@ -840,13 +871,17 @@ url_parse_text (struct worker_task *task, GByteArray *content)
if (url_str != NULL) {
new = memory_pool_alloc (task->task_pool, sizeof (struct uri));
if (new != NULL) {
- parse_uri (new, url_str, task->task_pool);
- TAILQ_INSERT_TAIL (&task->urls, new, next);
+ rc = parse_uri (new, url_str, task->task_pool);
+ if (rc != URI_ERRNO_OK) {
+ msg_info ("url_parse_html: error while parsing url %s: %s", url_str, url_strerror (rc));
+ }
+ else {
+ TAILQ_INSERT_TAIL (&task->urls, new, next);
+ }
}
}
- g_free (url_str);
+ memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_free, url_str);
}
- g_match_info_free (info);
}
else if (err != NULL) {
msg_debug ("url_parse_text: error matching regexp: %s", err->message);
@@ -855,6 +890,7 @@ url_parse_text (struct worker_task *task, GByteArray *content)
else {
msg_debug ("url_parse_text: cannot find url pattern in given string");
}
+ g_match_info_free (info);
} while (rc);
}
}
@@ -865,7 +901,7 @@ url_parse_html (struct worker_task *task, GByteArray *content)
GMatchInfo *info;
GError *err = NULL;
int pos = 0, start;
- gboolean rc;
+ int rc;
char *url_str = NULL;
struct uri *new;
@@ -880,13 +916,17 @@ url_parse_html (struct worker_task *task, GByteArray *content)
if (url_str != NULL) {
new = memory_pool_alloc (task->task_pool, sizeof (struct uri));
if (new != NULL) {
- parse_uri (new, url_str, task->task_pool);
- TAILQ_INSERT_TAIL (&task->urls, new, next);
+ rc = parse_uri (new, url_str, task->task_pool);
+ if (rc != URI_ERRNO_OK) {
+ msg_info ("url_parse_html: error while parsing url %s: %s", url_str, url_strerror (rc));
+ }
+ else {
+ TAILQ_INSERT_TAIL (&task->urls, new, next);
+ }
}
}
- g_free (url_str);
+ memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_free, url_str);
}
- g_match_info_free (info);
}
else if (err) {
msg_debug ("url_parse_html: error matching regexp: %s", err->message);
@@ -895,6 +935,7 @@ url_parse_html (struct worker_task *task, GByteArray *content)
else {
msg_debug ("url_parse_html: cannot find url pattern in given string");
}
+ g_match_info_free (info);
} while (rc);
}
}
diff --git a/src/util.c b/src/util.c
index 4ca9a437b..cbe6d9821 100644
--- a/src/util.c
+++ b/src/util.c
@@ -236,6 +236,7 @@ init_signals (struct sigaction *signals, sig_t sig_handler)
signals->sa_handler = sig_handler;
+ signals->sa_flags = 0;
sigaction (SIGTERM, signals, NULL);
sigaction (SIGINT, signals, NULL);
sigaction (SIGHUP, signals, NULL);
@@ -248,6 +249,7 @@ init_signals (struct sigaction *signals, sig_t sig_handler)
sigemptyset (&sigpipe_act.sa_mask);
sigaddset (&sigpipe_act.sa_mask, SIGPIPE);
sigpipe_act.sa_handler = SIG_IGN;
+ sigpipe_act.sa_flags = 0;
sigaction (SIGPIPE, &sigpipe_act, NULL);
}