diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2008-11-10 00:57:36 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2008-11-10 00:57:36 +0000 |
commit | aab0bd7a74764156f16a206e42a73ba781a36a46 (patch) | |
tree | 3e8828d3d465c97d7a72782e13d56c8aed5c4a13 | |
parent | a3eec907fbf8d8ca500077872de89f7efb8b2223 (diff) |
- snprintf() can return -1, make sure every call is checked properly
-rw-r--r-- | usr.sbin/smtpd/aliases.c | 20 | ||||
-rw-r--r-- | usr.sbin/smtpd/parse.y | 22 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue.c | 82 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.c | 57 | ||||
-rw-r--r-- | usr.sbin/smtpd/ssl.c | 13 |
5 files changed, 130 insertions, 64 deletions
diff --git a/usr.sbin/smtpd/aliases.c b/usr.sbin/smtpd/aliases.c index df209deb5ea..f8f7755a8c4 100644 --- a/usr.sbin/smtpd/aliases.c +++ b/usr.sbin/smtpd/aliases.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aliases.c,v 1.2 2008/11/05 12:14:45 sobrado Exp $ */ +/* $OpenBSD: aliases.c,v 1.3 2008/11/10 00:57:35 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -155,6 +155,7 @@ aliases_virtual_exist(struct smtpd *env, struct path *path) DB *aliasesdb; struct map *map; char strkey[STRLEN]; + int spret; map = map_findbyname(env, "virtual"); if (map == NULL) @@ -169,8 +170,8 @@ aliases_virtual_exist(struct smtpd *env, struct path *path) if (aliasesdb == NULL) return 0; - if (snprintf(strkey, STRLEN, "%s@%s", path->user, path->domain) - >= STRLEN) { + spret = snprintf(strkey, STRLEN, "%s@%s", path->user, path->domain); + if (spret == -1 || spret >= STRLEN) { aliasesdb->close(aliasesdb); return 0; } @@ -180,8 +181,8 @@ aliases_virtual_exist(struct smtpd *env, struct path *path) if ((ret = aliasesdb->get(aliasesdb, &key, &val, 0)) != 0) { - if (snprintf(strkey, STRLEN, "@%s", path->domain) - >= STRLEN) { + spret = snprintf(strkey, STRLEN, "@%s", path->domain); + if (spret == -1 || spret >= STRLEN) { aliasesdb->close(aliasesdb); return 0; } @@ -213,6 +214,7 @@ aliases_virtual_get(struct smtpd *env, struct aliaseslist *aliases, struct alias *nextalias; struct map *map; char strkey[STRLEN]; + int spret; map = map_findbyname(env, "virtual"); if (map == NULL) @@ -227,8 +229,8 @@ aliases_virtual_get(struct smtpd *env, struct aliaseslist *aliases, if (aliasesdb == NULL) return 0; - if (snprintf(strkey, STRLEN, "%s@%s", path->user, path->domain) - >= STRLEN) { + spret = snprintf(strkey, STRLEN, "%s@%s", path->user, path->domain); + if (spret == -1 || spret >= STRLEN) { aliasesdb->close(aliasesdb); return 0; } @@ -238,8 +240,8 @@ aliases_virtual_get(struct smtpd *env, struct aliaseslist *aliases, if ((ret = aliasesdb->get(aliasesdb, &key, &val, 0)) != 0) { - if (snprintf(strkey, STRLEN, "@%s", path->domain) - >= STRLEN) { + spret = snprintf(strkey, STRLEN, "@%s", path->domain); + if (spret == -1 || spret >= STRLEN) { aliasesdb->close(aliasesdb); return 0; } diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y index 4d928c26b13..670f305bc1a 100644 --- a/usr.sbin/smtpd/parse.y +++ b/usr.sbin/smtpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.4 2008/11/10 00:29:33 gilles Exp $ */ +/* $OpenBSD: parse.y,v 1.5 2008/11/10 00:57:35 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -444,6 +444,7 @@ mapref : STRING { int bits; struct sockaddr_in ssin; struct sockaddr_in6 ssin6; + int spret; if ((m = calloc(1, sizeof(*m))) == NULL) fatal("out of memory"); @@ -453,7 +454,9 @@ mapref : STRING { free(m); YYERROR; } - snprintf(m->m_name, STRLEN, "<dynamic(%u)>", m->m_id); + spret = snprintf(m->m_name, STRLEN, "<dynamic(%u)>", m->m_id); + if (spret == -1 || spret >= STRLEN) + fatal("snprintf"); m->m_flags |= F_DYNAMIC|F_USED; m->m_type = T_SINGLE; @@ -515,6 +518,7 @@ mapref : STRING { } | '(' { struct map *m; + int spret; if ((m = calloc(1, sizeof(*m))) == NULL) fatal("out of memory"); @@ -525,7 +529,9 @@ mapref : STRING { free(m); YYERROR; } - snprintf(m->m_name, STRLEN, "<dynamic(%u)>", m->m_id); + spret = snprintf(m->m_name, STRLEN, "<dynamic(%u)>", m->m_id); + if (spret == -1 || spret >= STRLEN) + fatal("snprintf"); m->m_flags |= F_DYNAMIC|F_USED; m->m_type = T_LIST; @@ -539,6 +545,7 @@ mapref : STRING { } | '{' { struct map *m; + int spret; if ((m = calloc(1, sizeof(*m))) == NULL) fatal("out of memory"); @@ -549,7 +556,9 @@ mapref : STRING { free(m); YYERROR; } - snprintf(m->m_name, STRLEN, "<dynamic(%u)>", m->m_id); + spret = snprintf(m->m_name, STRLEN, "<dynamic(%u)>", m->m_id); + if (spret == -1 || spret >= STRLEN) + fatal("snprintf"); m->m_flags |= F_DYNAMIC|F_USED; m->m_type = T_HASH; @@ -664,6 +673,7 @@ from : FROM mapref { struct mapel *me; struct sockaddr_in *ssin; struct sockaddr_in6 *ssin6; + int spret; if ((m = calloc(1, sizeof(*m))) == NULL) fatal("out of memory"); @@ -673,7 +683,9 @@ from : FROM mapref { free(m); YYERROR; } - snprintf(m->m_name, STRLEN, "<dynamic(%u)>", m->m_id); + spret = snprintf(m->m_name, STRLEN, "<dynamic(%u)>", m->m_id); + if (spret == -1 || spret >= STRLEN) + fatal("snprintf"); m->m_flags |= F_DYNAMIC|F_USED; m->m_type = T_SINGLE; diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c index 6efca7caa04..6d39045dea5 100644 --- a/usr.sbin/smtpd/queue.c +++ b/usr.sbin/smtpd/queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue.c,v 1.2 2008/11/05 12:14:45 sobrado Exp $ */ +/* $OpenBSD: queue.c,v 1.3 2008/11/10 00:57:35 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -631,9 +631,10 @@ queue_message_from_id(char *message_id, struct message *message) char pathname[MAXPATHLEN]; int fd; int ret; + int spret; - if (snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_ENVELOPES, message_id) - >= MAXPATHLEN) { + spret = snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_ENVELOPES, message_id); + if (spret == -1 || spret >= MAXPATHLEN) { warnx("queue_load_submissions: filename too long."); return 0; } @@ -749,9 +750,11 @@ queue_create_message_file(char *message_id) { int fd; char pathname[MAXPATHLEN]; + int spret; - if (snprintf(pathname, MAXPATHLEN, "%s/%d.XXXXXXXXXXXXXXXX", - PATH_MESSAGES, time(NULL)) >= MAXPATHLEN) + spret = snprintf(pathname, MAXPATHLEN, "%s/%d.XXXXXXXXXXXXXXXX", + PATH_MESSAGES, time(NULL)); + if (spret == -1 || spret >= MAXPATHLEN) return -1; fd = mkstemp(pathname); @@ -770,9 +773,10 @@ void queue_delete_message_file(char *message_id) { char pathname[MAXPATHLEN]; + int spret; - if (snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_MESSAGES, message_id) - >= MAXPATHLEN) + spret = snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_MESSAGES, message_id); + if (spret == -1 || spret >= MAXPATHLEN) fatal("queue_delete_message_file: message id too long"); if (unlink(pathname) == -1) @@ -790,6 +794,7 @@ queue_record_submission(struct message *message) size_t spoolsz; int fd; int mode = O_CREAT|O_TRUNC|O_WRONLY|O_EXCL|O_SYNC|O_EXLOCK; + int spret; if (message->type & T_DAEMON_MESSAGE) { spool = PATH_DAEMON; @@ -807,14 +812,16 @@ queue_record_submission(struct message *message) } spoolsz = strlen(spool); - if (snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_MESSAGES, - message->message_id) >= MAXPATHLEN) + + spret = snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_MESSAGES, + message->message_id); + if (spret == -1 || spret >= MAXPATHLEN) fatal("queue_record_submission: message id too long"); for (;;) { - if (snprintf(linkname, MAXPATHLEN, "%s/%s.%qu", spool, - message->message_id, (u_int64_t)arc4random()) - >= MAXPATHLEN) + spret = snprintf(linkname, MAXPATHLEN, "%s/%s.%qu", spool, + message->message_id, (u_int64_t)arc4random()); + if (spret == -1 || spret >= MAXPATHLEN) fatal("queue_record_submission: message uid too long"); (void)strlcpy(message_uid, linkname + spoolsz + 1, MAXPATHLEN); @@ -825,8 +832,9 @@ queue_record_submission(struct message *message) err(1, "link: %s , %s", pathname, linkname); } - if (snprintf(dbname, MAXPATHLEN, "%s/%s", PATH_ENVELOPES, - message_uid) >= MAXPATHLEN) + spret = snprintf(dbname, MAXPATHLEN, "%s/%s", PATH_ENVELOPES, + message_uid); + if (spret == -1 || spret >= MAXPATHLEN) fatal("queue_record_submission: database uid too long"); fd = open(dbname, mode, 0600); @@ -915,6 +923,7 @@ queue_remove_submission(struct message *message) char dbname[MAXPATHLEN]; char *spool; struct stat sb; + int spret; if (message->type & T_DAEMON_MESSAGE) { spool = PATH_DAEMON; @@ -931,16 +940,19 @@ queue_remove_submission(struct message *message) } } - if (snprintf(dbname, MAXPATHLEN, "%s/%s", PATH_ENVELOPES, - message->message_uid) >= MAXPATHLEN) + spret = snprintf(dbname, MAXPATHLEN, "%s/%s", PATH_ENVELOPES, + message->message_uid); + if (spret == -1 || spret >= MAXPATHLEN) fatal("queue_remove_submission: database uid too long"); - if (snprintf(linkname, MAXPATHLEN, "%s/%s", spool, - message->message_uid) >= MAXPATHLEN) + spret = snprintf(linkname, MAXPATHLEN, "%s/%s", spool, + message->message_uid); + if (spret == -1 || spret >= MAXPATHLEN) fatal("queue_remove_submission: message uid too long"); - if (snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_MESSAGES, - message->message_id) >= MAXPATHLEN) + spret = snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_MESSAGES, + message->message_id); + if (spret == -1 || spret >= MAXPATHLEN) fatal("queue_remove_submission: message id too long"); if (unlink(dbname) == -1) { @@ -1050,9 +1062,11 @@ queue_open_message_file(struct batch *batch) { int fd; char pathname[MAXPATHLEN]; + int spret; - if (snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_MESSAGES, - batch->message_id) >= MAXPATHLEN) + spret = snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_MESSAGES, + batch->message_id); + if (spret == -1 || spret >= MAXPATHLEN) fatal("queue_open_message_file: message id too long"); fd = open(pathname, O_RDONLY); @@ -1068,6 +1082,7 @@ queue_update_database(struct message *message) int fd; char *spool; char pathname[MAXPATHLEN]; + int spret; if (message->type & T_DAEMON_MESSAGE) { spool = PATH_DAEMON; @@ -1084,8 +1099,9 @@ queue_update_database(struct message *message) } } - if (snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_ENVELOPES, - message->message_uid) >= MAXPATHLEN) + spret = snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_ENVELOPES, + message->message_uid); + if (spret == -1 || spret >= MAXPATHLEN) fatal("queue_update_database: pathname too long"); if ((fd = open(pathname, O_RDWR|O_EXLOCK)) == -1) @@ -1110,16 +1126,24 @@ queue_record_daemon(struct message *message) size_t spoolsz; int fd; int mode = O_CREAT|O_TRUNC|O_WRONLY|O_EXCL|O_SYNC|O_EXLOCK; + int spret; - (void)snprintf(pathname, MAXPATHLEN, "%s/%s", + spret = snprintf(pathname, MAXPATHLEN, "%s/%s", PATH_MESSAGES, message->message_id); + if (spret == -1 || spret >= MAXPATHLEN) + return 0; spoolsz = strlen(PATH_DAEMON); for (;;) { - (void)snprintf(linkname, MAXPATHLEN, "%s/%s.%qu", + spret = snprintf(linkname, MAXPATHLEN, "%s/%s.%qu", PATH_DAEMON, message->message_id, (u_int64_t)arc4random()); - (void)strlcpy(message_uid, linkname + spoolsz + 1, MAXPATHLEN); + if (spret == -1 || spret >= MAXPATHLEN) + return 0; + + if (strlcpy(message_uid, linkname + spoolsz + 1, MAXPATHLEN) + >= MAXPATHLEN) + return 0; if (link(pathname, linkname) == -1) { if (errno == EEXIST) @@ -1127,8 +1151,10 @@ queue_record_daemon(struct message *message) err(1, "link"); } - (void)snprintf(dbname, MAXPATHLEN, "%s/%s", + spret = snprintf(dbname, MAXPATHLEN, "%s/%s", PATH_ENVELOPES, message_uid); + if (spret == -1 || spret >= MAXPATHLEN) + return 0; fd = open(dbname, mode, 0600); if (fd == -1) diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index e3aa8cc1e31..826d91b76ee 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.3 2008/11/05 12:14:45 sobrado Exp $ */ +/* $OpenBSD: smtpd.c,v 1.4 2008/11/10 00:57:35 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -630,8 +630,10 @@ setup_spool(uid_t uid, gid_t gid) char pathname[MAXPATHLEN]; struct stat sb; int ret; + int spret; - if (snprintf(pathname, MAXPATHLEN, "%s", PATH_SPOOL) >= MAXPATHLEN) + spret = snprintf(pathname, MAXPATHLEN, "%s", PATH_SPOOL); + if (spret == -1 || spret >= MAXPATHLEN) fatal("snprintf"); if (stat(pathname, &sb) == -1) { @@ -676,8 +678,9 @@ setup_spool(uid_t uid, gid_t gid) ret = 1; for (n = 0; n < sizeof(paths)/sizeof(paths[0]); n++) { - if (snprintf(pathname, MAXPATHLEN, "%s%s", PATH_SPOOL, - paths[n]) >= MAXPATHLEN) + spret = snprintf(pathname, MAXPATHLEN, "%s%s", PATH_SPOOL, + paths[n]); + if (spret == -1 || spret >= MAXPATHLEN) fatal("snprintf"); if (stat(pathname, &sb) == -1) { @@ -750,10 +753,11 @@ parent_open_message_file(struct batch *batchp) { int fd; char pathname[MAXPATHLEN]; + int spret; - if (snprintf(pathname, MAXPATHLEN, "%s%s/%s", - PATH_SPOOL, PATH_MESSAGES, batchp->message_id) - >= MAXPATHLEN) { + spret = snprintf(pathname, MAXPATHLEN, "%s%s/%s", + PATH_SPOOL, PATH_MESSAGES, batchp->message_id); + if (spret == -1 || spret >= MAXPATHLEN) { batchp->message.status |= S_MESSAGE_PERMFAILURE; return -1; } @@ -768,6 +772,7 @@ parent_open_mailbox(struct batch *batchp, struct path *path) int fd; struct passwd *pw; char pathname[MAXPATHLEN]; + int spret; pw = getpwnam(path->pw_name); if (pw == NULL) { @@ -775,7 +780,9 @@ parent_open_mailbox(struct batch *batchp, struct path *path) return -1; } - (void)snprintf(pathname, MAXPATHLEN, "%s", path->rule.r_value.path); + spret = snprintf(pathname, MAXPATHLEN, "%s", path->rule.r_value.path); + if (spret == -1 || spret >= MAXPATHLEN) + return -1; fd = open(pathname, O_CREAT|O_APPEND|O_RDWR|O_EXLOCK|O_SYNC|O_NONBLOCK, 0600); if (fd == -1) { @@ -813,6 +820,7 @@ parent_open_maildir(struct batch *batchp, struct path *path) int fd; struct passwd *pw; char pathname[MAXPATHLEN]; + int spret; pw = getpwnam(path->pw_name); if (pw == NULL) { @@ -820,15 +828,19 @@ parent_open_maildir(struct batch *batchp, struct path *path) return -1; } - snprintf(pathname, MAXPATHLEN, "%s", path->rule.r_value.path); - log_debug("PATH: %s", pathname); + spret = snprintf(pathname, MAXPATHLEN, "%s", path->rule.r_value.path); + if (spret == -1 || spret >= MAXPATHLEN) + return -1; + if (! parent_maildir_init(pw, pathname)) { batchp->message.status |= S_MESSAGE_TEMPFAILURE; return -1; } - if (snprintf(pathname, MAXPATHLEN, "%s/tmp/%s", - pathname, batchp->message.message_uid) >= MAXPATHLEN) { + spret = snprintf(pathname, MAXPATHLEN, "%s/tmp/%s", + pathname, batchp->message.message_uid); + + if (spret == -1 || spret >= MAXPATHLEN) { batchp->message.status |= S_MESSAGE_TEMPFAILURE; return -1; } @@ -850,10 +862,11 @@ parent_maildir_init(struct passwd *pw, char *root) u_int8_t i; char pathname[MAXPATHLEN]; char *subdir[] = { "/", "/tmp", "/cur", "/new" }; + int spret; for (i = 0; i < sizeof (subdir) / sizeof (char *); ++i) { - if (snprintf(pathname, MAXPATHLEN, "%s%s", root, subdir[i]) - >= MAXPATHLEN) + spret = snprintf(pathname, MAXPATHLEN, "%s%s", root, subdir[i]); + if (spret == -1 || spret >= MAXPATHLEN) return 0; if (mkdir(pathname, 0700) == -1) if (errno != EEXIST) @@ -871,6 +884,7 @@ parent_rename_mailfile(struct batch *batchp) char srcpath[MAXPATHLEN]; char dstpath[MAXPATHLEN]; struct path *path; + int spret; if (batchp->type & T_DAEMON_BATCH) { path = &batchp->message.sender; @@ -885,10 +899,15 @@ parent_rename_mailfile(struct batch *batchp) return 0; } - (void)snprintf(srcpath, MAXPATHLEN, "%s/tmp/%s", + spret = snprintf(srcpath, MAXPATHLEN, "%s/tmp/%s", path->rule.r_value.path, batchp->message.message_uid); - (void)snprintf(dstpath, MAXPATHLEN, "%s/new/%s", + if (spret == -1 || spret >= MAXPATHLEN) + return 0; + + spret = snprintf(dstpath, MAXPATHLEN, "%s/new/%s", path->rule.r_value.path, batchp->message.message_uid); + if (spret == -1 || spret >= MAXPATHLEN) + return 0; if (rename(srcpath, dstpath) == -1) { batchp->message.status |= S_MESSAGE_TEMPFAILURE; @@ -964,8 +983,12 @@ parent_open_filename(struct batch *batchp, struct path *path) { int fd; char pathname[MAXPATHLEN]; + int spret; + + spret = snprintf(pathname, MAXPATHLEN, "%s", path->u.filename); + if (spret == -1 || spret >= MAXPATHLEN) + return -1; - (void)snprintf(pathname, MAXPATHLEN, "%s", path->u.filename); fd = open(pathname, O_CREAT|O_APPEND|O_RDWR|O_EXLOCK|O_SYNC|O_NONBLOCK, 0600); if (fd == -1) { /* XXX - this needs to be discussed ... */ diff --git a/usr.sbin/smtpd/ssl.c b/usr.sbin/smtpd/ssl.c index 73e1fcc1043..b70bab95713 100644 --- a/usr.sbin/smtpd/ssl.c +++ b/usr.sbin/smtpd/ssl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl.c,v 1.2 2008/11/05 12:14:45 sobrado Exp $ */ +/* $OpenBSD: ssl.c,v 1.3 2008/11/10 00:57:35 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -285,6 +285,7 @@ ssl_load_certfile(struct smtpd *env, const char *name) struct ssl *s; struct ssl key; char certfile[PATH_MAX]; + int spret; if (strlcpy(key.ssl_name, name, sizeof(key.ssl_name)) >= sizeof(key.ssl_name)) { @@ -301,8 +302,9 @@ ssl_load_certfile(struct smtpd *env, const char *name) (void)strlcpy(s->ssl_name, key.ssl_name, sizeof(s->ssl_name)); - if (snprintf(certfile, sizeof(certfile), - "/etc/mail/certs/%s.crt", name) == -1) { + spret = snprintf(certfile, sizeof(certfile), + "/etc/mail/certs/%s.crt", name); + if (spret == -1 || spret >= (int)sizeof(certfile)) { free(s); return (-1); } @@ -312,8 +314,9 @@ ssl_load_certfile(struct smtpd *env, const char *name) return (-1); } - if (snprintf(certfile, sizeof(certfile), - "/etc/mail/certs/%s.key", name) == -1) { + spret = snprintf(certfile, sizeof(certfile), + "/etc/mail/certs/%s.key", name); + if (spret == -1 || spret >= (int)sizeof(certfile)) { free(s->ssl_cert); free(s); return -1; |