diff options
author | Moritz Jodeit <moritz@cvs.openbsd.org> | 2007-09-17 07:07:24 +0000 |
---|---|---|
committer | Moritz Jodeit <moritz@cvs.openbsd.org> | 2007-09-17 07:07:24 +0000 |
commit | 78bd82b79fdb80709642f906507dbf2b169271d9 (patch) | |
tree | a44ce4d3fa6dd9758572d4125985c736db06c00c /lib/libc | |
parent | f75700d891f9b74d2f1c29a1ced7415b4916ea8f (diff) |
Check snprintf(3) return value for error or truncation.
Mostly path construction, where truncation could be bad.
ok and input from deraadt@ millert@ ray@
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/db/btree/bt_open.c | 16 | ||||
-rw-r--r-- | lib/libc/db/hash/hash_page.c | 11 | ||||
-rw-r--r-- | lib/libc/db/hash/ndbm.c | 7 | ||||
-rw-r--r-- | lib/libc/gen/auth_subr.c | 20 | ||||
-rw-r--r-- | lib/libc/gen/authenticate.c | 25 | ||||
-rw-r--r-- | lib/libc/gen/getnetgrent.c | 14 | ||||
-rw-r--r-- | lib/libc/gen/login_cap.c | 15 | ||||
-rw-r--r-- | lib/libc/locale/setlocale.c | 7 | ||||
-rw-r--r-- | lib/libc/locale/setrunelocale.c | 9 | ||||
-rw-r--r-- | lib/libc/net/rcmd.c | 6 | ||||
-rw-r--r-- | lib/libc/time/strftime.c | 11 | ||||
-rw-r--r-- | lib/libc/yp/yp_bind.c | 9 |
12 files changed, 112 insertions, 38 deletions
diff --git a/lib/libc/db/btree/bt_open.c b/lib/libc/db/btree/bt_open.c index cdc439cba22..d837df88ae2 100644 --- a/lib/libc/db/btree/bt_open.c +++ b/lib/libc/db/btree/bt_open.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bt_open.c,v 1.13 2005/08/05 13:02:59 espie Exp $ */ +/* $OpenBSD: bt_open.c,v 1.14 2007/09/17 07:07:23 moritz Exp $ */ /*- * Copyright (c) 1990, 1993, 1994 @@ -91,7 +91,7 @@ __bt_open(const char *fname, int flags, int mode, const BTREEINFO *openinfo, DB *dbp; pgno_t ncache; ssize_t nr; - int machine_lorder; + int machine_lorder, saved_errno; t = NULL; @@ -322,13 +322,15 @@ einval: errno = EINVAL; eftype: errno = EFTYPE; goto err; -err: if (t) { +err: saved_errno = errno; + if (t) { if (t->bt_dbp) free(t->bt_dbp); if (t->bt_fd != -1) (void)close(t->bt_fd); free(t); } + errno = saved_errno; return (NULL); } @@ -385,14 +387,18 @@ static int tmp(void) { sigset_t set, oset; - int fd; + int fd, len; char *envtmp = NULL; char path[MAXPATHLEN]; if (issetugid() == 0) envtmp = getenv("TMPDIR"); - (void)snprintf(path, + len = snprintf(path, sizeof(path), "%s/bt.XXXXXX", envtmp ? envtmp : "/tmp"); + if (len < 0 || len >= sizeof(path)) { + errno = ENAMETOOLONG; + return(-1); + } (void)sigfillset(&set); (void)sigprocmask(SIG_BLOCK, &set, &oset); diff --git a/lib/libc/db/hash/hash_page.c b/lib/libc/db/hash/hash_page.c index c32e2820069..a744e689b41 100644 --- a/lib/libc/db/hash/hash_page.c +++ b/lib/libc/db/hash/hash_page.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hash_page.c,v 1.17 2005/08/05 13:03:00 espie Exp $ */ +/* $OpenBSD: hash_page.c,v 1.18 2007/09/17 07:07:23 moritz Exp $ */ /*- * Copyright (c) 1990, 1993, 1994 @@ -832,13 +832,18 @@ static int open_temp(HTAB *hashp) { sigset_t set, oset; + int len; char *envtmp = NULL; char path[MAXPATHLEN]; - + if (issetugid() == 0) envtmp = getenv("TMPDIR"); - (void)snprintf(path, + len = snprintf(path, sizeof(path), "%s/_hash.XXXXXX", envtmp ? envtmp : "/tmp"); + if (len < 0 || len >= sizeof(path)) { + errno = ENAMETOOLONG; + return (-1); + } /* Block signals; make sure file goes away at process exit. */ (void)sigfillset(&set); diff --git a/lib/libc/db/hash/ndbm.c b/lib/libc/db/hash/ndbm.c index 58f2cf040a8..5e4c3655dc8 100644 --- a/lib/libc/db/hash/ndbm.c +++ b/lib/libc/db/hash/ndbm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ndbm.c,v 1.21 2005/08/08 08:05:33 espie Exp $ */ +/* $OpenBSD: ndbm.c,v 1.22 2007/09/17 07:07:23 moritz Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -189,8 +189,10 @@ _dbm_open(file, suff, flags, mode) { HASHINFO info; char path[MAXPATHLEN]; + int len; - if (strlen(file) + strlen(suff) > sizeof(path) - 1) { + len = snprintf(path, sizeof path, "%s%s", file, suff); + if (len < 0 || len >= sizeof path) { errno = ENAMETOOLONG; return (NULL); } @@ -205,7 +207,6 @@ _dbm_open(file, suff, flags, mode) info.cachesize = 0; info.hash = NULL; info.lorder = 0; - snprintf(path, sizeof path, "%s%s", file, suff); return ((DBM *)__hash_open(path, flags, mode, &info, 0)); } diff --git a/lib/libc/gen/auth_subr.c b/lib/libc/gen/auth_subr.c index ae34c02c078..4b3efa798e9 100644 --- a/lib/libc/gen/auth_subr.c +++ b/lib/libc/gen/auth_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth_subr.c,v 1.30 2004/12/02 20:38:36 millert Exp $ */ +/* $OpenBSD: auth_subr.c,v 1.31 2007/09/17 07:07:23 moritz Exp $ */ /* * Copyright (c) 2000-2002,2004 Todd C. Miller <Todd.Miller@courtesan.com> @@ -305,10 +305,15 @@ char * auth_challenge(auth_session_t *as) { char path[MAXPATHLEN]; + int len; if (as == NULL || as->style == NULL || as->name == NULL) return (NULL); + len = snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", as->style); + if (len < 0 || len >= sizeof(path)) + return (NULL); + as->state = 0; if (as->challenge) { @@ -316,7 +321,6 @@ auth_challenge(auth_session_t *as) as->challenge = NULL; } - snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", as->style); auth_call(as, path, as->style, "-s", "challenge", as->name, as->class, (char *)NULL); if (as->state & AUTH_CHALLENGE) @@ -518,14 +522,20 @@ int auth_setoption(auth_session_t *as, char *n, char *v) { struct authopts *opt; - int i = strlen(n) + strlen(v) + 2; + size_t len = strlen(n) + strlen(v) + 2; + int ret; - if ((opt = malloc(sizeof(*opt) + i)) == NULL) + if ((opt = malloc(sizeof(*opt) + len)) == NULL) return (-1); opt->opt = (char *)(opt + 1); - snprintf(opt->opt, i, "%s=%s", n, v); + ret = snprintf(opt->opt, len, "%s=%s", n, v); + if (ret < 0 || ret >= len) { + free(opt); + errno = ENAMETOOLONG; + return (-1); + } opt->next = as->optlist; as->optlist = opt; return(0); diff --git a/lib/libc/gen/authenticate.c b/lib/libc/gen/authenticate.c index a4f7aea2bd8..1ef26b683b9 100644 --- a/lib/libc/gen/authenticate.c +++ b/lib/libc/gen/authenticate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authenticate.c,v 1.15 2005/12/19 17:07:43 millert Exp $ */ +/* $OpenBSD: authenticate.c,v 1.16 2007/09/17 07:07:23 moritz Exp $ */ /*- * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. @@ -172,7 +172,7 @@ auth_cat(char *file) int auth_approval(auth_session_t *as, login_cap_t *lc, char *name, char *type) { - int close_on_exit, close_lc_on_exit; + int close_on_exit, close_lc_on_exit, len; struct passwd *pwd; char *approve, *s, path[MAXPATHLEN]; @@ -227,7 +227,15 @@ auth_approval(auth_session_t *as, login_cap_t *lc, char *name, char *type) if (strncmp(type, "approve-", 8) == 0) type += 8; - snprintf(path, sizeof(path), "approve-%s", type); + len = snprintf(path, sizeof(path), "approve-%s", type); + if (len < 0 || len >= sizeof(path)) { + if (close_lc_on_exit) + login_close(lc); + syslog(LOG_ERR, "approval path too long %.*s...", + MAXPATHLEN, type); + _warnx("approval script path too long"); + return (0); + } } if ((approve = login_getcapstr(lc, s = path, NULL, NULL)) == NULL) @@ -415,6 +423,7 @@ auth_userresponse(auth_session_t *as, char *response, int more) { char path[MAXPATHLEN]; char *style, *name, *challenge, *class; + int len; if (as == NULL) return (0); @@ -427,6 +436,14 @@ auth_userresponse(auth_session_t *as, char *response, int more) return (auth_close(as)); return(0); } + + len = snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", style); + if (len < 0 || len >= sizeof(path)) { + if (more == 0) + return (auth_close(as)); + return (0); + } + challenge = auth_getitem(as, AUTHV_CHALLENGE); class = auth_getitem(as, AUTHV_CLASS); @@ -439,8 +456,6 @@ auth_userresponse(auth_session_t *as, char *response, int more) else auth_setdata(as, "", 1); - snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", style); - auth_call(as, path, style, "-s", "response", name, class, (char *)NULL); /* diff --git a/lib/libc/gen/getnetgrent.c b/lib/libc/gen/getnetgrent.c index c6556d95879..7c0b0b795ec 100644 --- a/lib/libc/gen/getnetgrent.c +++ b/lib/libc/gen/getnetgrent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getnetgrent.c,v 1.20 2007/09/05 08:12:15 moritz Exp $ */ +/* $OpenBSD: getnetgrent.c,v 1.21 2007/09/17 07:07:23 moritz Exp $ */ /* * Copyright (c) 1994 Christos Zoulas @@ -505,8 +505,16 @@ char * _ng_makekey(const char *s1, const char *s2, size_t len) { char *buf = malloc(len); - if (buf != NULL) - (void) snprintf(buf, len, "%s.%s", _NG_STAR(s1), _NG_STAR(s2)); + int ret; + + if (buf == NULL) + return NULL; + ret = snprintf(buf, len, "%s.%s", _NG_STAR(s1), _NG_STAR(s2)); + if (ret < 0 || ret >= len) { + free(buf); + return NULL; + } + return buf; } diff --git a/lib/libc/gen/login_cap.c b/lib/libc/gen/login_cap.c index fb6a7e0df8b..81aaa24afef 100644 --- a/lib/libc/gen/login_cap.c +++ b/lib/libc/gen/login_cap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: login_cap.c,v 1.27 2007/09/02 15:19:16 deraadt Exp $ */ +/* $OpenBSD: login_cap.c,v 1.28 2007/09/17 07:07:23 moritz Exp $ */ /* * Copyright (c) 2000-2004 Todd C. Miller <Todd.Miller@courtesan.com> @@ -509,6 +509,7 @@ gsetrl(login_cap_t *lc, int what, char *name, int type) char name_cur[32]; char name_max[32]; char *v; + int len; /* * If we have no capabilities then there is nothing to do and @@ -517,8 +518,16 @@ gsetrl(login_cap_t *lc, int what, char *name, int type) if (lc->lc_cap == NULL) return (0); - snprintf(name_cur, sizeof name_cur, "%s-cur", name); - snprintf(name_max, sizeof name_max, "%s-max", name); + len = snprintf(name_cur, sizeof name_cur, "%s-cur", name); + if (len < 0 || len >= sizeof name_cur) { + syslog(LOG_ERR, "current resource limit name too large"); + return (-1); + } + len = snprintf(name_max, sizeof name_max, "%s-max", name); + if (len < 0 || len >= sizeof name_max) { + syslog(LOG_ERR, "max resource limit name too large"); + return (-1); + } if (getrlimit(what, &r)) { syslog(LOG_ERR, "getting resource limit: %m"); diff --git a/lib/libc/locale/setlocale.c b/lib/libc/locale/setlocale.c index 1463ed4184a..7217445a3ae 100644 --- a/lib/libc/locale/setlocale.c +++ b/lib/libc/locale/setlocale.c @@ -1,4 +1,4 @@ -/* $OpenBSD: setlocale.c,v 1.15 2007/09/06 08:26:12 moritz Exp $ */ +/* $OpenBSD: setlocale.c,v 1.16 2007/09/17 07:07:23 moritz Exp $ */ /* * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -226,6 +226,7 @@ static int load_locale_sub(int category, const char *locname, int isspecial) { char name[PATH_MAX]; + int len; /* check for the default locales */ if (!strcmp(new_categories[category], "C") || @@ -238,8 +239,10 @@ load_locale_sub(int category, const char *locname, int isspecial) if (strchr(locname, '/') != NULL) return -1; - (void)snprintf(name, sizeof(name), "%s/%s/%s", + len = snprintf(name, sizeof(name), "%s/%s/%s", _PathLocale, locname, categories[category]); + if (len < 0 || len >= sizeof(name)) + return -1; switch (category) { case LC_CTYPE: diff --git a/lib/libc/locale/setrunelocale.c b/lib/libc/locale/setrunelocale.c index 47a47b9042d..e4166aee8b3 100644 --- a/lib/libc/locale/setrunelocale.c +++ b/lib/libc/locale/setrunelocale.c @@ -1,4 +1,4 @@ -/* $OpenBSD: setrunelocale.c,v 1.2 2005/10/20 09:09:49 otto Exp $ */ +/* $OpenBSD: setrunelocale.c,v 1.3 2007/09/17 07:07:23 moritz Exp $ */ /* $NetBSD: setrunelocale.c,v 1.14 2003/08/07 16:43:07 agc Exp $ */ /*- @@ -181,14 +181,17 @@ _xpg4_setrunelocale(const char *encoding) { char path[PATH_MAX]; _RuneLocale *rl; - int error; + int error, len; if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX")) { rl = &_DefaultRuneLocale; goto found; } - snprintf(path, sizeof(path), "%s/%s/LC_CTYPE", _PathLocale, encoding); + len = snprintf(path, sizeof(path), + "%s/%s/LC_CTYPE", _PathLocale, encoding); + if (len < 0 || len >= sizeof(path)) + return ENAMETOOLONG; error = _newrunelocale(path); if (error) diff --git a/lib/libc/net/rcmd.c b/lib/libc/net/rcmd.c index e2b91994920..30ca6710c4f 100644 --- a/lib/libc/net/rcmd.c +++ b/lib/libc/net/rcmd.c @@ -382,10 +382,14 @@ again: (void)fclose(hostf); } if (first == 1 && (__check_rhosts_file || superuser)) { + int len; + first = 0; if ((pwd = getpwnam(luser)) == NULL) return (-1); - snprintf(pbuf, sizeof pbuf, "%s/.rhosts", pwd->pw_dir); + len = snprintf(pbuf, sizeof pbuf, "%s/.rhosts", pwd->pw_dir); + if (len < 0 || len >= sizeof pbuf) + return (-1); /* * Change effective uid while opening .rhosts. If root and diff --git a/lib/libc/time/strftime.c b/lib/libc/time/strftime.c index 58bde890b91..578e8f7cc0c 100644 --- a/lib/libc/time/strftime.c +++ b/lib/libc/time/strftime.c @@ -1,4 +1,4 @@ -/* $OpenBSD: strftime.c,v 1.16 2005/08/08 08:05:38 espie Exp $ */ +/* $OpenBSD: strftime.c,v 1.17 2007/09/17 07:07:23 moritz Exp $ */ #include "private.h" /* @@ -660,6 +660,7 @@ _loc P((void)) int fd; int oldsun; /* "...ain't got nothin' to do..." */ + int len; char * lbuf; char * nlbuf; char * name; @@ -699,16 +700,20 @@ _loc P((void)) ((sizeof locale_home) + namesize + (sizeof lc_time))) goto no_locale; oldsun = 0; - (void) snprintf(filename, sizeof filename, "%s/%s/%s", locale_home, + len = snprintf(filename, sizeof filename, "%s/%s/%s", locale_home, name, lc_time); + if (len < 0 || len >= sizeof filename) + goto no_locale; fd = open(filename, O_RDONLY); if (fd < 0) { /* ** Old Sun systems have a different naming and data convention. */ oldsun = 1; - (void) snprintf(filename, sizeof filename, "%s/%s/%s", + len = snprintf(filename, sizeof filename, "%s/%s/%s", locale_home, lc_time, name); + if (len < 0 || len >= sizeof filename) + goto no_locale; fd = open(filename, O_RDONLY); if (fd < 0) goto no_locale; diff --git a/lib/libc/yp/yp_bind.c b/lib/libc/yp/yp_bind.c index e1ef44433e4..fa8fa63531d 100644 --- a/lib/libc/yp/yp_bind.c +++ b/lib/libc/yp/yp_bind.c @@ -1,4 +1,4 @@ -/* $OpenBSD: yp_bind.c,v 1.15 2005/08/05 13:02:16 espie Exp $ */ +/* $OpenBSD: yp_bind.c,v 1.16 2007/09/17 07:07:23 moritz Exp $ */ /* * Copyright (c) 1992, 1993, 1996 Theo de Raadt <deraadt@theos.com> * All rights reserved. @@ -106,8 +106,13 @@ _yp_dobind(const char *dom, struct dom_binding **ypdb) } again: if (ysd->dom_vers == 0) { - (void) snprintf(path, sizeof(path), "%s/%s.%d", + r = snprintf(path, sizeof(path), "%s/%s.%d", BINDINGDIR, dom, 2); + if (r < 0 || r >= sizeof(path)) { + if (new) + free(ysd); + return YPERR_BADARGS; + } if ((fd = open(path, O_RDONLY)) == -1) { /* * no binding file, YP is dead, or not yet fully |