diff options
author | Moritz Jodeit <moritz@cvs.openbsd.org> | 2007-03-26 18:13:09 +0000 |
---|---|---|
committer | Moritz Jodeit <moritz@cvs.openbsd.org> | 2007-03-26 18:13:09 +0000 |
commit | 8664bb9d6aff5046b748d8bb833913083b09c424 (patch) | |
tree | d6887e8414eed00b5a3b346e5415f261439fee85 /usr.bin/sendbug/sendbug.c | |
parent | b7b431926c81f40cfdfd7e008faf2e41d1d22a22 (diff) |
Simplify gecos parsing code and prevent buffer overflow
when gecos field contains multiple '&' characters with
other characters inbetween.
With and OK ray@
Diffstat (limited to 'usr.bin/sendbug/sendbug.c')
-rw-r--r-- | usr.bin/sendbug/sendbug.c | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/usr.bin/sendbug/sendbug.c b/usr.bin/sendbug/sendbug.c index caf6923d6e7..44cab8efae1 100644 --- a/usr.bin/sendbug/sendbug.c +++ b/usr.bin/sendbug/sendbug.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sendbug.c,v 1.30 2007/03/26 07:16:11 ray Exp $ */ +/* $OpenBSD: sendbug.c,v 1.31 2007/03/26 18:13:08 moritz Exp $ */ /* * Written by Ray Lai <ray@cyth.net>. @@ -285,7 +285,7 @@ sendmail(const char *tmppath) void init(void) { - size_t len = 0, namelen; + size_t amp, len, namelen; const char *src; int sysname[2]; char *dst, *cp; @@ -294,16 +294,12 @@ init(void) err(1, "getpwuid"); namelen = strlen(pw->pw_name); - /* Add length of expanded '&', minus existing '&'. */ - src = pw->pw_gecos; - src += strcspn(src, ",&"); - while (*src == '&') { - len += namelen - 1; - /* Look for next '&', skipping the one we just found. */ - src += 1 + strcspn(src, ",&"); - } - /* Add full name length, including all those '&' we skipped. */ - len += src - pw->pw_gecos; + /* Count number of '&'. */ + for (amp = 0, src = pw->pw_gecos; *src && *src != ','; ++src) + if (*src == '&') + ++amp; + /* Expanded str = orig str - '&' chars + concatenated logins. */ + len = (src - pw->pw_gecos) - amp + (amp * namelen); if ((fullname = malloc(len + 1)) == NULL) err(1, "malloc"); |