Code

1373b4ef9b3d92400c2e2d2dec63f3f17fc24fe4
[pkg-collectd.git] / debian / patches / bts595756-notify_email-segfault.dpatch
1 #! /bin/sh /usr/share/dpatch/dpatch-run
2 ## bts595756-notify_email-segfault.dpatch
3 ## by Florian Forster <octo@verplant.org>
4 ##
5 ## DP: notify_email plugin: Serialize all accesses to libesmtp using a mutex.
6 ## DP:
7 ## DP: libesmtp is not thread-safe. This fixes segfaults when accessing the
8 ## DP: plugin in parallel.
10 @DPATCH@
12 diff a/src/notify_email.c b/src/notify_email.c
13 --- a/src/notify_email.c
14 +++ b/src/notify_email.c
15 @@ -1,6 +1,7 @@
16  /**
17   * collectd - src/notify_email.c
18   * Copyright (C) 2008  Oleg King
19 + * Copyright (C) 2010  Florian Forster
20   *
21   * This program is free software; you can redistribute it and/or modify it
22   * under the terms of the GNU General Public License as published by the
23 @@ -18,6 +19,7 @@
24   *
25   * Authors:
26   *   Oleg King <king2 at kaluga.ru>
27 + *   Florian Forster <octo at collectd.org>
28   **/
29  
30  #include "collectd.h"
31 @@ -26,6 +28,7 @@
32  
33  #include <auth-client.h>
34  #include <libesmtp.h>
35 +#include <pthread.h>
36  
37  #define MAXSTRING               256
38  
39 @@ -45,6 +48,7 @@ static char **recipients;
40  static int recipients_len = 0;
41  
42  static smtp_session_t session;
43 +static pthread_mutex_t session_lock = PTHREAD_MUTEX_INITIALIZER;
44  static smtp_message_t message;
45  static auth_context_t authctx = NULL;
46  
47 @@ -113,17 +117,23 @@ static int notify_email_init (void)
48  {
49    char server[MAXSTRING];
50  
51 +  ssnprintf(server, sizeof (server), "%s:%i",
52 +      (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host,
53 +      smtp_port);
54 +
55 +  pthread_mutex_lock (&session_lock);
56 +
57    auth_client_init();
58 -  if (!(session = smtp_create_session ())) {
59 +
60 +  session = smtp_create_session ();
61 +  if (session == NULL) {
62 +    pthread_mutex_unlock (&session_lock);
63      ERROR ("notify_email plugin: cannot create SMTP session");
64      return (-1);
65    }
66  
67    smtp_set_monitorcb (session, monitor_cb, NULL, 1);
68    smtp_set_hostname (session, hostname_g);
69 -  ssnprintf(server, sizeof (server), "%s:%i",
70 -      (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host,
71 -      smtp_port);
72    smtp_set_server (session, server);
73  
74    if (smtp_user && smtp_password) {
75 @@ -133,18 +143,30 @@ static int notify_email_init (void)
76    }
77  
78    if ( !smtp_auth_set_context (session, authctx)) {
79 +    pthread_mutex_unlock (&session_lock);
80      ERROR ("notify_email plugin: cannot set SMTP auth context");
81      return (-1);   
82    }
83  
84 +  pthread_mutex_unlock (&session_lock);
85    return (0);
86  } /* int notify_email_init */
87  
88  static int notify_email_shutdown (void)
89  {
90 -  smtp_destroy_session (session);
91 -  auth_destroy_context (authctx);
92 +  pthread_mutex_lock (&session_lock);
93 +
94 +  if (session != NULL)
95 +    smtp_destroy_session (session);
96 +  session = NULL;
97 +
98 +  if (authctx != NULL)
99 +    auth_destroy_context (authctx);
100 +  authctx = NULL;
102    auth_client_exit();
104 +  pthread_mutex_unlock (&session_lock);
105    return (0);
106  } /* int notify_email_shutdown */
107  
108 @@ -248,7 +270,16 @@ static int notify_email_notification (const notification_t *n,
109        n->host,
110        n->message);
111  
112 +  pthread_mutex_lock (&session_lock);
114 +  if (session == NULL) {
115 +    /* Initialization failed or we're in the process of shutting down. */
116 +    pthread_mutex_unlock (&session_lock);
117 +    return (-1);
118 +  }
120    if (!(message = smtp_add_message (session))) {
121 +    pthread_mutex_unlock (&session_lock);
122      ERROR ("notify_email plugin: cannot set SMTP message");
123      return (-1);   
124    }
125 @@ -264,6 +295,7 @@ static int notify_email_notification (const notification_t *n,
126      char buf[MAXSTRING];
127      ERROR ("notify_email plugin: SMTP server problem: %s",
128          smtp_strerror (smtp_errno (), buf, sizeof buf));
129 +    pthread_mutex_unlock (&session_lock);
130      return (-1);
131    } else {
132      const smtp_status_t *status;
133 @@ -274,6 +306,7 @@ static int notify_email_notification (const notification_t *n,
134      smtp_enumerate_recipients (message, print_recipient_status, NULL);
135    }
136  
137 +  pthread_mutex_unlock (&session_lock);
138    return (0);
139  } /* int notify_email_notification */
140