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';