Vulnerability Development mailing list archives

Re: Hesiod security


From: KF <dotslash () snosoft com>
Date: Thu, 06 Jun 2002 22:09:32 -0400

Well RedHat and Debian seem to be on top of things. Here is the patch included with the RPM package:

"Hesiod libraries and sample programs.RedHat-7.3 Sourceshesiod-3.0.2-18.src.rpm"

hesiod_3.0.2-12_i386.deb also seems to also have the problem fixed.

-KF


Matt Power wrote:


In the version of Hesiod used internally at MIT, this was fixed in
September 1997. See http://diswww.mit.edu/menelaus/bugs/15502

I'm aware that the latest distribution of Hesiod in the directory
ftp://athena-dist.mit.edu/pub/ATHENA/hesiod/ does not contain a fix
for this problem. There may also be other buffer overflows, or other
implementation problems, in Hesiod that were fixed at MIT or elsewhere
and are not incorporated in the athena-dist.mit.edu distribution. (And
there may be other such problems in Hesiod that no one has fixed.) The
"strcpy(bindname, name)" problem was also noted by other persons, and
some other distributions of Hesiod (for example, ones that are part of
a libc) have made different code changes in response to this problem.


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++;

Current thread: