diff options
author | Jacek Masiulaniec <jacekm@cvs.openbsd.org> | 2009-11-11 15:36:11 +0000 |
---|---|---|
committer | Jacek Masiulaniec <jacekm@cvs.openbsd.org> | 2009-11-11 15:36:11 +0000 |
commit | eca89ecce3fcb8427ea554e977d2e1f5f67a8717 (patch) | |
tree | 903b9f18b4c53dcb99fef447540c26eed5cbe192 /usr.sbin | |
parent | 0ae0bc9735bfce4e564bd3d306772e3cbd4c26f7 (diff) |
Check if the receive buffer has any unused space before reading from socket in
buf_read (and in ssl_buf_read).
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/smtpd/client.c | 29 | ||||
-rw-r--r-- | usr.sbin/smtpd/ssl.c | 11 |
2 files changed, 25 insertions, 15 deletions
diff --git a/usr.sbin/smtpd/client.c b/usr.sbin/smtpd/client.c index 411351a4c44..3759b918031 100644 --- a/usr.sbin/smtpd/client.c +++ b/usr.sbin/smtpd/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.15 2009/11/11 11:41:05 jacekm Exp $ */ +/* $OpenBSD: client.c,v 1.16 2009/11/11 15:36:10 jacekm Exp $ */ /* * Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net> @@ -437,9 +437,14 @@ client_read(struct smtp_client *sp) if (0) { #endif } else { + errno = 0; if (buf_read(sp->w.fd, &sp->r) == -1) { - strlcpy(sp->ebuf, "130 buf_read error", - sizeof(sp->ebuf)); + if (errno) + snprintf(sp->ebuf, sizeof(sp->ebuf), + "130 buf_read: %s", strerror(errno)); + else + snprintf(sp->ebuf, sizeof(sp->ebuf), + "130 buf_read: connection closed"); return (CLIENT_ERROR); } } @@ -879,8 +884,6 @@ client_getln(struct smtp_client *sp) if ((ln = buf_getln(&sp->r)) == NULL) { if (errno) cause = "150 buf_getln error"; - else if (sp->r.wpos >= sizeof(sp->r.buf)) - cause = "150 reply too big"; else rv = 0; goto done; @@ -1066,19 +1069,21 @@ buf_getln(struct buf_read *r) int buf_read(int fd, struct buf_read *r) { + char *buf = r->buf + r->wpos; + size_t bufsz = sizeof(r->buf) - r->wpos; ssize_t n; - n = read(fd, r->buf + r->wpos, sizeof(r->buf) - r->wpos); - if (n == -1) { - if (errno == EAGAIN || errno == EINTR) - return (-2); + if (bufsz == 0) { + errno = EMSGSIZE; return (-1); } - if (n == 0) { - errno = 0; + if ((n = read(fd, buf, bufsz)) == -1) { + if (errno == EAGAIN || errno == EINTR) + return (-2); + return (-1); + } else if (n == 0) return (-1); - } r->wpos += n; diff --git a/usr.sbin/smtpd/ssl.c b/usr.sbin/smtpd/ssl.c index 02c35430268..0c5f9258580 100644 --- a/usr.sbin/smtpd/ssl.c +++ b/usr.sbin/smtpd/ssl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl.c,v 1.22 2009/10/03 07:59:55 jacekm Exp $ */ +/* $OpenBSD: ssl.c,v 1.23 2009/11/11 15:36:10 jacekm Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -656,11 +656,16 @@ ssl_session_destroy(struct session *s) int ssl_buf_read(SSL *s, struct buf_read *r) { + char *buf = r->buf + r->wpos; + ssize_t bufsz = sizeof(r->buf) - r->wpos; int ret; - ret = SSL_read(s, r->buf + r->wpos, sizeof(r->buf) - r->wpos); + if (bufsz == 0) { + errno = EMSGSIZE; + return (SSL_ERROR_SYSCALL); + } - if (ret > 0) + if ((ret = SSL_read(s, buf, bufsz)) > 0) r->wpos += ret; return SSL_get_error(s, ret); |