summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
authorMoritz Jodeit <moritz@cvs.openbsd.org>2007-09-17 07:07:24 +0000
committerMoritz Jodeit <moritz@cvs.openbsd.org>2007-09-17 07:07:24 +0000
commit78bd82b79fdb80709642f906507dbf2b169271d9 (patch)
treea44ce4d3fa6dd9758572d4125985c736db06c00c /lib/libc
parentf75700d891f9b74d2f1c29a1ced7415b4916ea8f (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.c16
-rw-r--r--lib/libc/db/hash/hash_page.c11
-rw-r--r--lib/libc/db/hash/ndbm.c7
-rw-r--r--lib/libc/gen/auth_subr.c20
-rw-r--r--lib/libc/gen/authenticate.c25
-rw-r--r--lib/libc/gen/getnetgrent.c14
-rw-r--r--lib/libc/gen/login_cap.c15
-rw-r--r--lib/libc/locale/setlocale.c7
-rw-r--r--lib/libc/locale/setrunelocale.c9
-rw-r--r--lib/libc/net/rcmd.c6
-rw-r--r--lib/libc/time/strftime.c11
-rw-r--r--lib/libc/yp/yp_bind.c9
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