diff options
author | Jacek Masiulaniec <jacekm@cvs.openbsd.org> | 2009-05-19 11:24:25 +0000 |
---|---|---|
committer | Jacek Masiulaniec <jacekm@cvs.openbsd.org> | 2009-05-19 11:24:25 +0000 |
commit | 6605dde7b156889e10a66d8abc8d4a5e55e400db (patch) | |
tree | c91b52ce8d846c48669652cb12baa147db0dd42d /usr.sbin/smtpd | |
parent | 2d92391cf0aa52d8ad4386b2574fe64618d2178d (diff) |
Verify the amount of IMSG payload is exactly as expected; ok gilles@
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r-- | usr.sbin/smtpd/control.c | 44 | ||||
-rw-r--r-- | usr.sbin/smtpd/lka.c | 34 | ||||
-rw-r--r-- | usr.sbin/smtpd/mda.c | 35 | ||||
-rw-r--r-- | usr.sbin/smtpd/mfa.c | 32 | ||||
-rw-r--r-- | usr.sbin/smtpd/mta.c | 32 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue.c | 43 | ||||
-rw-r--r-- | usr.sbin/smtpd/runner.c | 17 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtp.c | 17 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.c | 31 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 8 |
10 files changed, 196 insertions, 97 deletions
diff --git a/usr.sbin/smtpd/control.c b/usr.sbin/smtpd/control.c index af8dde4339d..8085c8a13e8 100644 --- a/usr.sbin/smtpd/control.c +++ b/usr.sbin/smtpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.25 2009/05/14 15:05:12 eric Exp $ */ +/* $OpenBSD: control.c,v 1.26 2009/05/19 11:24:24 jacekm Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -333,21 +333,23 @@ control_dispatch_ext(int fd, short event, void *arg) break; } case IMSG_RUNNER_SCHEDULE: { - struct sched s; + struct sched *s = imsg.data; if (euid) goto badcred; + + if (IMSG_DATA_SIZE(&imsg) != sizeof(*s)) + goto badcred; - s = *(struct sched *)imsg.data; - s.fd = fd; + s->fd = fd; - if (! valid_message_id(s.mid) && ! valid_message_uid(s.mid)) { + if (! valid_message_id(s->mid) && ! valid_message_uid(s->mid)) { imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } - imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_RUNNER_SCHEDULE, 0, 0, -1, &s, sizeof(s)); + imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_RUNNER_SCHEDULE, 0, 0, -1, s, sizeof(*s)); break; } case IMSG_CTL_SHUTDOWN: @@ -502,10 +504,11 @@ control_dispatch_parent(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_STATS: { - struct stats *s; + struct stats *s = imsg.data; struct ctl_conn *c; - s = imsg.data; + IMSG_SIZE_CHECK(s); + if ((c = control_connbyfd(s->fd)) == NULL) { log_warn("control_dispatch_parent: fd %d not found", s->fd); return; @@ -655,10 +658,11 @@ control_dispatch_queue(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_STATS: { - struct stats *s; + struct stats *s = imsg.data; struct ctl_conn *c; - s = imsg.data; + IMSG_SIZE_CHECK(s); + if ((c = control_connbyfd(s->fd)) == NULL) { log_warn("control_dispatch_queue: fd %d not found", s->fd); imsg_free(&imsg); @@ -717,10 +721,11 @@ control_dispatch_runner(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_STATS: { - struct stats *s; + struct stats *s = imsg.data; struct ctl_conn *c; - s = imsg.data; + IMSG_SIZE_CHECK(s); + if ((c = control_connbyfd(s->fd)) == NULL) { log_warn("control_dispatch_runner: fd %d not found", s->fd); imsg_free(&imsg); @@ -733,10 +738,11 @@ control_dispatch_runner(int sig, short event, void *p) break; } case IMSG_RUNNER_SCHEDULE: { - struct sched *s; + struct sched *s = imsg.data; struct ctl_conn *c; - s = imsg.data; + IMSG_SIZE_CHECK(s); + if ((c = control_connbyfd(s->fd)) == NULL) { log_warn("control_dispatch_runner: fd %d not found", s->fd); imsg_free(&imsg); @@ -796,10 +802,11 @@ control_dispatch_smtp(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_STATS: { - struct stats *s; + struct stats *s = imsg.data; struct ctl_conn *c; - s = imsg.data; + IMSG_SIZE_CHECK(s); + if ((c = control_connbyfd(s->fd)) == NULL) { log_warn("control_dispatch_queue: fd %d not found", s->fd); imsg_free(&imsg); @@ -812,10 +819,13 @@ control_dispatch_smtp(int sig, short event, void *p) break; } case IMSG_SMTP_ENQUEUE: { + int *fd = imsg.data; struct ctl_conn *c; int client_fd; - client_fd = *(int *)imsg.data; + IMSG_SIZE_CHECK(fd); + + client_fd = *fd; if ((c = control_connbyfd(client_fd)) == NULL) { log_warn("control_dispatch_smtp: fd %d not found", client_fd); diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c index 10e65eaaed9..2a0ea909437 100644 --- a/usr.sbin/smtpd/lka.c +++ b/usr.sbin/smtpd/lka.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka.c,v 1.46 2009/05/14 15:05:12 eric Exp $ */ +/* $OpenBSD: lka.c,v 1.47 2009/05/19 11:24:24 jacekm Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -131,11 +131,11 @@ lka_dispatch_parent(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_PARENT_FORWARD_OPEN: { int fd; - struct forward_req *fwreq; + struct forward_req *fwreq = imsg.data; struct lkasession key; struct lkasession *lkasession; - fwreq = imsg.data; + IMSG_SIZE_CHECK(fwreq); key.id = fwreq->id; lkasession = SPLAY_FIND(lkatree, &env->lka_sessions, &key); @@ -232,9 +232,10 @@ lka_dispatch_mfa(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_LKA_MAIL: { - struct submit_status *ss; + struct submit_status *ss = imsg.data; + + IMSG_SIZE_CHECK(ss); - ss = imsg.data; ss->code = 530; if (ss->u.path.user[0] == '\0' && ss->u.path.domain[0] == '\0') @@ -249,13 +250,14 @@ lka_dispatch_mfa(int sig, short event, void *p) break; } case IMSG_LKA_RCPT: { - struct submit_status *ss; + struct submit_status *ss = imsg.data; struct message message; struct lkasession *lkasession; struct forward_req fwreq; int ret; - ss = imsg.data; + IMSG_SIZE_CHECK(ss); + ss->code = 530; if (IS_RELAY(ss->u.path.rule.r_action)) { @@ -371,6 +373,8 @@ lka_dispatch_mta(int sig, short event, void *p) struct secret *query = imsg.data; char *secret = NULL; + IMSG_SIZE_CHECK(query); + secret = map_dblookup(env, "secrets", query->host); log_debug("secret for %s %s", query->host, @@ -388,9 +392,13 @@ lka_dispatch_mta(int sig, short event, void *p) } case IMSG_DNS_A: - case IMSG_DNS_MX: - dns_async(env, ibuf, imsg.hdr.type, imsg.data); + case IMSG_DNS_MX: { + struct dns *query = imsg.data; + + IMSG_SIZE_CHECK(query); + dns_async(env, ibuf, imsg.hdr.type, query); break; + } default: log_warnx("lka_dispatch_mta: got imsg %d", @@ -438,9 +446,13 @@ lka_dispatch_smtp(int sig, short event, void *p) break; switch (imsg.hdr.type) { - case IMSG_DNS_PTR: - dns_async(env, ibuf, IMSG_DNS_PTR, imsg.data); + case IMSG_DNS_PTR: { + struct dns *query = imsg.data; + + IMSG_SIZE_CHECK(query); + dns_async(env, ibuf, IMSG_DNS_PTR, query); break; + } default: log_warnx("lka_dispatch_smtp: got imsg %d", imsg.hdr.type); diff --git a/usr.sbin/smtpd/mda.c b/usr.sbin/smtpd/mda.c index b1fb9bf42af..e81c2e0e106 100644 --- a/usr.sbin/smtpd/mda.c +++ b/usr.sbin/smtpd/mda.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mda.c,v 1.16 2009/05/14 15:05:12 eric Exp $ */ +/* $OpenBSD: mda.c,v 1.17 2009/05/19 11:24:24 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -92,12 +92,13 @@ mda_dispatch_parent(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_MDA_MAILBOX_FILE: { + struct batch *batchp = imsg.data; struct session *s; - struct batch *batchp; struct message *messagep; enum message_status status; - batchp = (struct batch *)imsg.data; + IMSG_SIZE_CHECK(batchp); + messagep = &batchp->message; status = messagep->status; @@ -125,13 +126,14 @@ mda_dispatch_parent(int sig, short event, void *p) } case IMSG_MDA_MESSAGE_FILE: { + struct batch *batchp = imsg.data; struct session *s; - struct batch *batchp; struct message *messagep; enum message_status status; int (*store)(struct batch *, struct message *) = store_write_message; - batchp = (struct batch *)imsg.data; + IMSG_SIZE_CHECK(batchp); + messagep = &batchp->message; status = messagep->status; @@ -266,8 +268,11 @@ mda_dispatch_runner(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_BATCH_CREATE: { - struct session *s; + struct batch *request = imsg.data; struct batch *batchp; + struct session *s; + + IMSG_SIZE_CHECK(request); /* create a client session */ if ((s = calloc(1, sizeof(*s))) == NULL) @@ -282,7 +287,7 @@ mda_dispatch_runner(int sig, short event, void *p) if (batchp == NULL) fatal("mda_dispatch_runner: calloc"); - *batchp = *(struct batch *)imsg.data; + *batchp = *request; batchp->session_id = s->s_id; batchp->env = env; batchp->flags = 0; @@ -296,14 +301,17 @@ mda_dispatch_runner(int sig, short event, void *p) } case IMSG_BATCH_APPEND: { - struct batch *batchp; + struct message *append = imsg.data; struct message *messagep; + struct batch *batchp; + + IMSG_SIZE_CHECK(append); messagep = calloc(1, sizeof (struct message)); if (messagep == NULL) fatal("mda_dispatch_runner: calloc"); - *messagep = *(struct message *)imsg.data; + *messagep = *append; batchp = batch_by_id(env, messagep->batch_id); if (batchp == NULL) @@ -321,12 +329,13 @@ mda_dispatch_runner(int sig, short event, void *p) } case IMSG_BATCH_CLOSE: { - struct batch *batchp; - struct session *s; - struct batch lookup; + struct batch *batchp = imsg.data; + struct session *s; + struct batch lookup; struct message *messagep; - batchp = (struct batch *)imsg.data; + IMSG_SIZE_CHECK(batchp); + batchp = batch_by_id(env, batchp->id); if (batchp == NULL) fatalx("mda_dispatch_runner: internal inconsistency."); diff --git a/usr.sbin/smtpd/mfa.c b/usr.sbin/smtpd/mfa.c index 8095394af91..8114619dbd9 100644 --- a/usr.sbin/smtpd/mfa.c +++ b/usr.sbin/smtpd/mfa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfa.c,v 1.25 2009/05/14 15:05:12 eric Exp $ */ +/* $OpenBSD: mfa.c,v 1.26 2009/05/19 11:24:24 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -149,12 +149,24 @@ mfa_dispatch_smtp(int sig, short event, void *p) break; switch (imsg.hdr.type) { - case IMSG_MFA_MAIL: - mfa_test_mail(env, imsg.data); + case IMSG_MFA_MAIL: { + struct message *m = imsg.data; + + IMSG_SIZE_CHECK(m); + + mfa_test_mail(env, m); break; - case IMSG_MFA_RCPT: - mfa_test_rcpt(env, imsg.data); + } + + case IMSG_MFA_RCPT: { + struct message *m = imsg.data; + + IMSG_SIZE_CHECK(m); + + mfa_test_rcpt(env, m); break; + } + default: log_warnx("mfa_dispatch_smtp: got imsg %d", imsg.hdr.type); @@ -202,17 +214,19 @@ mfa_dispatch_lka(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_LKA_MAIL: { - struct submit_status *ss; + struct submit_status *ss = imsg.data; + + IMSG_SIZE_CHECK(ss); - ss = imsg.data; imsg_compose(env->sc_ibufs[PROC_SMTP], IMSG_MFA_MAIL, 0, 0, -1, ss, sizeof(*ss)); break; } case IMSG_LKA_RCPT: { - struct submit_status *ss; + struct submit_status *ss = imsg.data; + + IMSG_SIZE_CHECK(ss); - ss = imsg.data; imsg_compose(env->sc_ibufs[PROC_SMTP], IMSG_MFA_RCPT, 0, 0, -1, ss, sizeof(*ss)); break; diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c index cf39a9ca47d..c538636d3fc 100644 --- a/usr.sbin/smtpd/mta.c +++ b/usr.sbin/smtpd/mta.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mta.c,v 1.47 2009/05/14 15:05:12 eric Exp $ */ +/* $OpenBSD: mta.c,v 1.48 2009/05/19 11:24:24 jacekm Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -158,6 +158,8 @@ mta_dispatch_lka(int sig, short event, void *p) struct session *s; struct mxhost *mxhost; + IMSG_SIZE_CHECK(reply); + key.s_id = reply->id; s = SPLAY_FIND(sessiontree, &env->sc_sessions, &key); @@ -181,6 +183,8 @@ mta_dispatch_lka(int sig, short event, void *p) struct session *s; int ret; + IMSG_SIZE_CHECK(reply); + key.s_id = reply->id; s = SPLAY_FIND(sessiontree, &env->sc_sessions, &key); @@ -205,6 +209,8 @@ mta_dispatch_lka(int sig, short event, void *p) struct secret *reply = imsg.data; struct session key, *s; + IMSG_SIZE_CHECK(reply); + key.s_id = reply->id; s = SPLAY_FIND(sessiontree, &env->sc_sessions, &key); @@ -266,16 +272,17 @@ mta_dispatch_queue(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_QUEUE_MESSAGE_FD: { - struct batch *batchp; + struct batch *batchp = imsg.data; struct session *sessionp; int fd; + IMSG_SIZE_CHECK(batchp); + if ((fd = imsg_get_fd(ibuf, &imsg)) == -1) { /* NEEDS_FIX - unsure yet how it must be handled */ fatalx("mta_dispatch_queue: imsg_get_fd"); } - batchp = (struct batch *)imsg.data; batchp = batch_by_id(env, batchp->id); sessionp = batchp->sessionp; @@ -333,8 +340,11 @@ mta_dispatch_runner(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_BATCH_CREATE: { - struct session *s; + struct batch *request = imsg.data; struct batch *batchp; + struct session *s; + + IMSG_SIZE_CHECK(request); /* create a client session */ if ((s = calloc(1, sizeof(*s))) == NULL) @@ -350,7 +360,7 @@ mta_dispatch_runner(int sig, short event, void *p) if (batchp == NULL) fatal("mta_dispatch_runner: calloc"); - *batchp = *(struct batch *)imsg.data; + *batchp = *request; batchp->session_id = s->s_id; batchp->env = env; batchp->flags = 0; @@ -364,14 +374,17 @@ mta_dispatch_runner(int sig, short event, void *p) break; } case IMSG_BATCH_APPEND: { - struct batch *batchp; + struct message *append = imsg.data; struct message *messagep; + struct batch *batchp; + + IMSG_SIZE_CHECK(append); messagep = calloc(1, sizeof (struct message)); if (messagep == NULL) fatal("mta_dispatch_runner: calloc"); - *messagep = *(struct message *)imsg.data; + *messagep = *append; batchp = batch_by_id(env, messagep->batch_id); if (batchp == NULL) @@ -388,10 +401,11 @@ mta_dispatch_runner(int sig, short event, void *p) break; } case IMSG_BATCH_CLOSE: { - struct batch *batchp; + struct batch *batchp = imsg.data; struct session *s; - batchp = (struct batch *)imsg.data; + IMSG_SIZE_CHECK(batchp); + batchp = batch_by_id(env, batchp->id); if (batchp == NULL) fatalx("mta_dispatch_runner: internal inconsistency."); diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c index fd0ef84eef6..64c1e53c362 100644 --- a/usr.sbin/smtpd/queue.c +++ b/usr.sbin/smtpd/queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue.c,v 1.62 2009/05/14 15:05:12 eric Exp $ */ +/* $OpenBSD: queue.c,v 1.63 2009/05/19 11:24:24 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -108,9 +108,10 @@ queue_dispatch_control(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_STATS: { - struct stats *s; + struct stats *s = imsg.data; + + IMSG_SIZE_CHECK(s); - s = imsg.data; s->u.queue = s_queue; imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, s, sizeof(*s)); break; @@ -162,12 +163,14 @@ queue_dispatch_smtp(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_QUEUE_CREATE_MESSAGE: { - struct message *messagep; + struct message *messagep = imsg.data; struct submit_status ss; int (*f)(char *); log_debug("queue_dispatch_smtp: creating message file"); - messagep = imsg.data; + + IMSG_SIZE_CHECK(messagep); + ss.id = messagep->session_id; ss.code = 250; bzero(ss.u.msgid, MAX_ID_SIZE); @@ -185,10 +188,11 @@ queue_dispatch_smtp(int sig, short event, void *p) break; } case IMSG_QUEUE_REMOVE_MESSAGE: { - struct message *messagep; + struct message *messagep = imsg.data; void (*f)(char *); - messagep = imsg.data; + IMSG_SIZE_CHECK(messagep); + if (messagep->flags & F_MESSAGE_ENQUEUED) f = enqueue_delete_message; else @@ -199,12 +203,13 @@ queue_dispatch_smtp(int sig, short event, void *p) break; } case IMSG_QUEUE_COMMIT_MESSAGE: { - struct message *messagep; + struct message *messagep = imsg.data; struct submit_status ss; size_t *counter; int (*f)(struct message *); - messagep = imsg.data; + IMSG_SIZE_CHECK(messagep); + ss.id = messagep->session_id; if (messagep->flags & F_MESSAGE_ENQUEUED) { @@ -226,12 +231,13 @@ queue_dispatch_smtp(int sig, short event, void *p) break; } case IMSG_QUEUE_MESSAGE_FILE: { - struct message *messagep; + struct message *messagep = imsg.data; struct submit_status ss; int fd; int (*f)(struct message *); - messagep = imsg.data; + IMSG_SIZE_CHECK(messagep); + ss.id = messagep->session_id; if (messagep->flags & F_MESSAGE_ENQUEUED) @@ -347,10 +353,11 @@ queue_dispatch_mta(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_QUEUE_MESSAGE_FD: { + struct batch *batchp = imsg.data; int fd; - struct batch *batchp; - batchp = imsg.data; + IMSG_SIZE_CHECK(batchp); + fd = queue_open_message_file(batchp->message_id); imsg_compose(ibuf, IMSG_QUEUE_MESSAGE_FD, 0, 0, fd, batchp, sizeof(*batchp)); @@ -410,11 +417,12 @@ queue_dispatch_lka(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_QUEUE_SUBMIT_ENVELOPE: { - struct message *messagep; + struct message *messagep = imsg.data; struct submit_status ss; int (*f)(struct message *); - messagep = imsg.data; + IMSG_SIZE_CHECK(messagep); + messagep->id = queue_generate_id(); ss.id = messagep->session_id; @@ -441,10 +449,11 @@ queue_dispatch_lka(int sig, short event, void *p) } case IMSG_QUEUE_COMMIT_ENVELOPES: { - struct message *messagep; + struct message *messagep = imsg.data; struct submit_status ss; - messagep = imsg.data; + IMSG_SIZE_CHECK(messagep); + ss.id = messagep->session_id; ss.code = 250; diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c index f64560a9a7f..8394f0a4928 100644 --- a/usr.sbin/smtpd/runner.c +++ b/usr.sbin/smtpd/runner.c @@ -1,4 +1,4 @@ -/* $OpenBSD: runner.c,v 1.45 2009/05/14 15:05:12 eric Exp $ */ +/* $OpenBSD: runner.c,v 1.46 2009/05/19 11:24:24 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -195,17 +195,18 @@ runner_dispatch_control(int sig, short event, void *p) env->sc_opts &= ~SMTPD_MTA_PAUSED; break; case IMSG_STATS: { - struct stats *s; + struct stats *s = imsg.data; + + IMSG_SIZE_CHECK(s); - s = imsg.data; s->u.runner = s_runner; imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, s, sizeof(*s)); break; } case IMSG_RUNNER_SCHEDULE: { - struct sched *s; + struct sched *s = imsg.data; - s = imsg.data; + IMSG_SIZE_CHECK(s); s->ret = 0; if (valid_message_uid(s->mid)) @@ -263,8 +264,12 @@ runner_dispatch_queue(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_RUNNER_UPDATE_ENVELOPE: { + struct message *m = imsg.data; + + IMSG_SIZE_CHECK(m); + s_runner.active--; - queue_message_update(imsg.data); + queue_message_update(m); break; } default: diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c index 852322156d9..15232e8fd85 100644 --- a/usr.sbin/smtpd/smtp.c +++ b/usr.sbin/smtpd/smtp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtp.c,v 1.46 2009/05/18 20:23:35 jacekm Exp $ */ +/* $OpenBSD: smtp.c,v 1.47 2009/05/19 11:24:24 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -169,6 +169,8 @@ smtp_dispatch_parent(int sig, short event, void *p) log_debug("smtp_dispatch_parent: parent handled authentication"); + IMSG_SIZE_CHECK(reply); + if ((s = session_lookup(env, reply->session_id)) == NULL) break; @@ -232,6 +234,8 @@ smtp_dispatch_mfa(int sig, short event, void *p) log_debug("smtp_dispatch_mfa: mfa handled return path"); + IMSG_SIZE_CHECK(ss); + if ((s = session_lookup(env, ss->id)) == NULL) break; @@ -289,6 +293,8 @@ smtp_dispatch_lka(int sig, short event, void *p) struct session *s; struct session key; + IMSG_SIZE_CHECK(reply); + key.s_id = reply->id; s = SPLAY_FIND(sessiontree, &env->sc_sessions, &key); @@ -358,6 +364,8 @@ smtp_dispatch_queue(int sig, short event, void *p) log_debug("smtp_dispatch_queue: queue handled message creation"); + IMSG_SIZE_CHECK(ss); + if ((s = session_lookup(env, ss->id)) == NULL) break; @@ -373,6 +381,8 @@ smtp_dispatch_queue(int sig, short event, void *p) log_debug("smtp_dispatch_queue: queue handled message creation"); + IMSG_SIZE_CHECK(ss); + fd = imsg_get_fd(ibuf, &imsg); if ((s = session_lookup(env, ss->id)) == NULL) { @@ -397,6 +407,8 @@ smtp_dispatch_queue(int sig, short event, void *p) log_debug("smtp_dispatch_queue: tempfail in queue"); + IMSG_SIZE_CHECK(ss); + key.s_id = ss->id; s = SPLAY_FIND(sessiontree, &env->sc_sessions, &key); if (s == NULL) @@ -419,6 +431,8 @@ smtp_dispatch_queue(int sig, short event, void *p) log_debug("smtp_dispatch_queue: queue acknowledged message submission"); + IMSG_SIZE_CHECK(ss); + if ((s = session_lookup(env, ss->id)) == NULL) break; @@ -536,6 +550,7 @@ smtp_dispatch_control(int sig, short event, void *p) struct stats *s; s = imsg.data; + IMSG_SIZE_CHECK(s); s->u.smtp = s_smtp; imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, s, sizeof(*s)); break; diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index 7dd4a469bbb..a65a3b7eeca 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.58 2009/05/14 15:05:12 eric Exp $ */ +/* $OpenBSD: smtpd.c,v 1.59 2009/05/19 11:24:24 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -199,10 +199,11 @@ parent_dispatch_lka(int fd, short event, void *p) switch (imsg.hdr.type) { case IMSG_PARENT_FORWARD_OPEN: { + struct forward_req *fwreq = imsg.data; int ret; - struct forward_req *fwreq; - fwreq = imsg.data; + IMSG_SIZE_CHECK(fwreq); + ret = parent_forward_open(fwreq->pw_name); fwreq->status = 0; if (ret == -1) { @@ -305,7 +306,7 @@ parent_dispatch_mda(int fd, short event, void *p) switch (imsg.hdr.type) { case IMSG_PARENT_MAILBOX_OPEN: { - struct batch *batchp; + struct batch *batchp = imsg.data; struct path *path; struct passwd *pw; char *pw_name; @@ -322,7 +323,8 @@ parent_dispatch_mda(int fd, short event, void *p) { A_FILENAME, parent_filename_open } }; - batchp = imsg.data; + IMSG_SIZE_CHECK(batchp); + path = &batchp->message.recipient; if (batchp->type & T_DAEMON_BATCH) { path = &batchp->message.sender; @@ -366,10 +368,11 @@ parent_dispatch_mda(int fd, short event, void *p) break; } case IMSG_PARENT_MESSAGE_OPEN: { - struct batch *batchp; + struct batch *batchp = imsg.data; int desc; - batchp = imsg.data; + IMSG_SIZE_CHECK(batchp); + desc = parent_open_message_file(batchp); imsg_compose(ibuf, IMSG_MDA_MESSAGE_FILE, 0, 0, @@ -378,11 +381,12 @@ parent_dispatch_mda(int fd, short event, void *p) break; } case IMSG_PARENT_MAILBOX_RENAME: { - struct batch *batchp; + struct batch *batchp = imsg.data; struct path *path; struct passwd *pw; - batchp = imsg.data; + IMSG_SIZE_CHECK(batchp); + path = &batchp->message.recipient; if (batchp->type & T_DAEMON_BATCH) { path = &batchp->message.sender; @@ -453,14 +457,14 @@ parent_dispatch_smtp(int fd, short event, void *p) break; } case IMSG_PARENT_AUTHENTICATE: { - struct session_auth_req *req; + struct session_auth_req *req = imsg.data; struct session_auth_reply reply; char buf[1024]; char *user; char *pass; int len; - req = (struct session_auth_req *)imsg.data; + IMSG_SIZE_CHECK(req); reply.session_id = req->session_id; reply.value = 0; @@ -592,9 +596,10 @@ parent_dispatch_control(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_STATS: { - struct stats *s; + struct stats *s = imsg.data; + + IMSG_SIZE_CHECK(s); - s = imsg.data; s->u.parent = s_parent; imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, s, sizeof(*s)); break; diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index 2d464a3db45..34fb604ea73 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.108 2009/05/18 20:23:35 jacekm Exp $ */ +/* $OpenBSD: smtpd.h,v 1.109 2009/05/19 11:24:24 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -225,8 +225,14 @@ enum imsg_type { }; #define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) +#define IMSG_DATA_SIZE(imsg) ((imsg)->hdr.len - IMSG_HEADER_SIZE) #define MAX_IMSGSIZE 16384 +#define IMSG_SIZE_CHECK(p) do { \ + if (IMSG_DATA_SIZE(&imsg) != sizeof(*p)) \ + fatalx("bad length imsg received"); \ +} while (0) + enum blockmodes { BM_NORMAL, BM_NONBLOCK |