Skip to content

seg fault when sending more than one email #30

@daniel-ames

Description

@daniel-ames

If I try to send an email more than once in the same process, it crashes in smtp_start_session(). The last event I see from the attempt is SMTP_EV_CONNECT before it fails. The first attempt works great. Any attempts after that fail.

(I was able to reproduce this in the example mail-file.c as well.)

First, here is my function that I'm calling to send an email:

int send_email(char *subject) {
  smtp_session_t session = smtp_create_session();
  smtp_message_t message = smtp_add_message(session);
  smtp_recipient_t recipient;
  const smtp_status_t *status;
  enum notify_flags notify = Notify_NOTSET;

  int res = smtp_starttls_enable(session, Starttls_REQUIRED);
  auth_context_t authctx = auth_create_context ();
  auth_set_mechanism_flags (authctx, AUTH_PLUGIN_PLAIN, 0);
  auth_set_interact_cb (authctx, authinteract, NULL);
  
  smtp_set_eventcb(session, event_cb, NULL);
  smtp_auth_set_context (session, authctx);

  smtp_set_header(message, "From", "House Controller", "<REDACTED>");
  smtp_set_header(message, "To", NULL, "<REDACTED>");
  smtp_set_header(message, "Subject", subject);
  smtp_set_server(session, "smtp.gmail.com:587");

  FILE* fd = fopen("test-mail", "r");  // this is the same test-mail file the came with the example code. The behavior persists with my own files too
  
  smtp_set_message_fp(message, fd);

  recipient = smtp_add_recipient(message, "<REDACTED>");
  notify = Notify_SUCCESS | Notify_FAILURE | Notify_DELAY;
  smtp_dsn_set_notify (recipient, notify);

  if (!smtp_start_session(session)) {
    printf("failed to start session\n");
    smtp_destroy_session(session);
    auth_destroy_context (authctx);
    fclose(fd);
    auth_client_exit();
    return 1;
  }

  smtp_destroy_session(session);
  auth_destroy_context (authctx);
  fclose(fd);
  auth_client_exit();  
  return 0;
}

I can call the above function ONCE in my program, per process instance. Another call will crash. I can call it once, close the program, then call it again no problem. Just never more than once per process instance.

I also reproduced the issue with the example code. The following modifications to the mail-file.c example reproduces the crash:

...
...
  /* Free resources consumed by the program.
   */
  smtp_destroy_session (session);
  auth_destroy_context (authctx);
  fclose (fp);
  auth_client_exit ();

  
  // <my additions>

  // now do it again
  printf("waiting 10 seconds...\n");
  sleep(10);
  

  auth_client_init ();
  session = smtp_create_session ();
  message = smtp_add_message (session);
  smtp_starttls_enable (session, Starttls_REQUIRED);
  smtp_set_server (session, host ? host : "localhost:25");

  authctx = auth_create_context ();
  auth_set_mechanism_flags (authctx, AUTH_PLUGIN_PLAIN, 0);
  auth_set_interact_cb (authctx, authinteract, NULL);

  smtp_set_eventcb(session, event_cb, NULL);

  smtp_set_reverse_path (message, from);
  smtp_set_header (message, "To", NULL, NULL);

  fp = fopen (file, "r");
  smtp_set_message_fp (message, fp);
  recipient = smtp_add_recipient (message, "<REDACTED>");
  smtp_dsn_set_notify (recipient, notify);

  if (!smtp_start_session (session))
    {
      char buf[128];

      fprintf (stderr, "SMTP server problem %s\n",
	       smtp_strerror (smtp_errno (), buf, sizeof buf));
    }
  else
    {
      /* Report on the success or otherwise of the mail transfer.
       */
      status = smtp_message_transfer_status (message);
      printf ("%d %s", status->code,
              (status->text != NULL) ? status->text : "\n");
      smtp_enumerate_recipients (message, print_recipient_status, NULL);
    }

  /* Free resources consumed by the program.
   */
  smtp_destroy_session (session);
  auth_destroy_context (authctx);
  fclose (fp);
  auth_client_exit ();

  // </my additions>

  exit (0);
}

The above experiment also crashes in the second call to smtp_start_session().
Can reproduce in ubuntu 22.04 and Arch.

Before I start diving too much deeper, has anyone seen this before? Perhaps I'm not tearing down the session correctly?

Thanks for reading all that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions