]> source.dussan.org Git - rspamd.git/commitdiff
* Fix bad memory leaks and memory corruption in url detecting module
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 6 Mar 2009 14:12:08 +0000 (17:12 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 6 Mar 2009 14:12:08 +0000 (17:12 +0300)
src/plugins/surbl.c
src/url.c
src/util.c

index a58b0ef89166e245e8f62b63ed2a4cb13ba6d51e..46162c57d8295b2b663c26ed3b9d21a207ec2485 100644 (file)
@@ -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;
 }
 
index 31851c3bba1fe7627d6ce259b81d6875d0bba802..4c0281f5e51b5acfe9cfb8e77a16c3bd793cb904 100644 (file)
--- 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);
        }
 }
index 4ca9a437b8c70c939a7b81fdc6ff4a2f073d4c6d..cbe6d9821c17befd8ff0eac886289e418637603a 100644 (file)
@@ -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);
 }