I'm using smtpd as a smtp relay for around 50+ systems.  It will run for a
few days and eat up memory before crashing.  The patch provided is by Jared
Yanovich.  After a good amount of testing, we discovered the memory leak.

Index: asr.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/asr.c,v
retrieving revision 1.2
diff -u -p -r1.2 asr.c
--- asr.c       3 Dec 2010 23:29:08 -0000       1.2
+++ asr.c       19 Mar 2011 19:48:33 -0000
@@ -774,8 +774,7 @@ asr_ctx_query(struct asr_ctx *ac, int ty
 void
 asr_done(struct asr *asr)
 {
-       if (asr_ctx_unref(asr->a_ctx))
-               return;
+       asr_ctx_unref(asr->a_ctx);
        if (asr->a_path)
                free(asr->a_path);
        free(asr);
Index: client.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/client.c,v
retrieving revision 1.33
diff -u -p -r1.33 client.c
--- client.c    28 Nov 2010 13:56:43 -0000      1.33
+++ client.c    19 Mar 2011 19:48:33 -0000
@@ -573,6 +573,7 @@ client_close(struct smtp_client *sp)
                SSL_free(sp->ssl);
 #endif
        close(sp->w.fd);
+       fclose(sp->body);
        free(sp);
 }

@@ -690,6 +691,7 @@ client_getln(struct smtp_client *sp, int

                if (ln[3] == ' ')
                        break;
+               free(ln);
        }

        /* validate reply code */
Index: queue_shared.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/queue_shared.c,v
retrieving revision 1.35
diff -u -p -r1.35 queue_shared.c
--- queue_shared.c      28 Nov 2010 14:35:58 -0000      1.35
+++ queue_shared.c      19 Mar 2011 19:48:33 -0000
@@ -124,6 +124,8 @@ queue_record_layout_envelope(char *queue
        FILE *fp;
        int fd;

+       fp = NULL;
+
 again:
        if (! bsnprintf(evpname, sizeof(evpname), "%s/%s%s/%s.%qu",
queuepath,
                message->message_id, PATH_ENVELOPES, message->message_id,
@@ -154,14 +156,20 @@ again:
                fatal("queue_record_incoming_envelope: write");
        }

-       if (! safe_fclose(fp))
+       if (! safe_fclose(fp)) {
+               fp = NULL;
+               fd = -1;
                goto tempfail;
+       }

        return 1;

 tempfail:
        unlink(evpname);
-       close(fd);
+       if (fp)
+               fclose(fp);
+       else if (fd != -1)
+               close(fd);
        message->creation = 0;
        message->message_uid[0] = '\0';

Reply via email to