There are a few places where untrusted information could cause problems. There's a bug in the configuration file parser that might result in an LHS= modifying the rhs setting. The case-insensitive comparison routine is probably called safely (with the second argument at least as long as the first), but it looks weird. --- hesiod-3.0.2/hesiod.c Wed Oct 3 15:16:17 2001 +++ hesiod-3.0.2/hesiod.c Wed Oct 3 15:33:41 2001 @@ -138,7 +138,8 @@ const char *rhs; int len; - strcpy(bindname, name); + strncpy(bindname, name, sizeof(bindname) - 1); + bindname[sizeof(bindname) - 1] = 0; /* Find the right right hand side to use, possibly truncating bindname. */ p = strchr(bindname, '@'); @@ -288,7 +289,7 @@ if (cistrcmp(key, "lhs") == 0 || cistrcmp(key, "rhs") == 0) { - which = (strcmp(key, "lhs") == 0) ? &ctx->lhs : &ctx->rhs; + which = (cistrcmp(key, "lhs") == 0) ? &ctx->lhs : &ctx->rhs; *which = malloc(strlen(data) + 1); if (!*which) { @@ -462,7 +463,7 @@ static int cistrcmp(const char *s1, const char *s2) { - while (*s1 && tolower(*s1) == tolower(*s2)) + while (*s1 && *s2 && tolower(*s1) == tolower(*s2)) { s1++; s2++; --- hesiod-3.0.2/hespwnam.c Wed Oct 3 15:29:40 2001 +++ hesiod-3.0.2/hespwnam.c Wed Oct 3 15:29:43 2001 @@ -39,9 +39,16 @@ struct passwd *hesiod_getpwuid(void *context, uid_t uid) { - char uidstr[16]; + char uidstr[32]; - sprintf(uidstr, "%d", uid); - return getpwcommon(context, uidstr, 1); + if (snprintf(uidstr, sizeof(uidstr), "%ld", (long)uid) < sizeof(uidstr)) + { + return getpwcommon(context, uidstr, 1); + } + else + { + errno = ERANGE; + return NULL; + } } --- hesiod-3.0.2/hesservbyname.c Wed Oct 3 15:33:25 2001 +++ hesiod-3.0.2/hesservbyname.c Wed Oct 3 15:33:22 2001 @@ -188,7 +188,7 @@ static int cistrcmp(const char *s1, const char *s2) { - while (*s1 && tolower(*s1) == tolower(*s2)) + while (*s1 && *s2 && tolower(*s1) == tolower(*s2)) { s1++; s2++;