Bug 9968 - ypserv-1.3.7 has infinite loop due to improper use of ndbm
Summary: ypserv-1.3.7 has infinite loop due to improper use of ndbm
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: ypserv
Version: 6.1
Hardware: i386
OS: Linux
medium
high
Target Milestone: ---
Assignee: Cristian Gafton
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2000-03-05 03:17 UTC by khp
Modified: 2008-05-01 15:37 UTC (History)
1 user (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2000-05-19 11:11:17 UTC
Embargoed:


Attachments (Terms of Use)

Description khp 2000-03-05 03:17:32 UTC
ypserv-1.3.7 uses the ndbm functions improperly in the functions,
ypproc_all_2_svc() and ypdb_nextkey(). Depending on the keys in the NIS map
being accessed through the database functions, this causes the forked
ypserv child process to loop endlessly. On the client side, the ypcat
eventually times out with an error. E.G.:

healey root> ypcat -k auto.home
ypcat -k auto.home
yp_all: clnt_call: RPC: Timed out
No such map auto.home. Reason: Internal NIS error

The problem is that ndbm library considers the memory pointed to by the
dptr field of the datum structure as static and asserts that this memory
may be (and is!) changed by subsequent calls into the ndbm functions.
Here's a quote from the ndbm(3b) man page on an IRIX64 6.5 machine (I
couldn't find any Linux documentation on ndbm, only gdbm):

Dptr pointers returned by these subroutines point into static storage
     that is changed by subsequent calls.

I also verified that ndbm operates this way by looking at the gdbm source
code when it operates in ndbm compatibility mode.

As dbm_firstkey() and dbm_nextkey() get called repeatedly in
ypdb_nextkey(), they overwrite the contents of the key passed in as a
parameter to the ypdb_nextkey() routine with the key value of the key
returned by dbm_nextkey(). Not good.

I'm new at Linux patches, but here's my attempt at providing a patch that
fixes the problem in the proper format:

--- server.c    Sat Mar  4 21:22:55 2000
+++ fixed.server.c      Sat Mar  4 20:58:21 2000
@@ -1079,6 +1079,13 @@
        {
           datum dkey = ypdb_firstkey (data->dbm);

+#if defined(HAVE_NDBM)
+         /* XXX Replace strncmp */
+         while (dkey.dptr != NULL && strncmp (dkey.dptr, "YP_", 3) == 0)
+         {
+             dkey = dbm_nextkey (data->dbm);
+         }
+#else
          /* XXX Replace strncmp */
          while (dkey.dptr != NULL && strncmp (dkey.dptr, "YP_", 3) == 0)
            {
@@ -1086,6 +1093,7 @@
              dkey = ypdb_nextkey (data->dbm, tkey);
              ypdb_free (tkey.dptr);
            }
+#endif

           if (dkey.dptr != NULL)
             {

Since I #ifdefed this code appropriately, I hope it is fairly safe for
compatibility with other database facilities that ypserv might use.
Still, I'd be interested in communicating with the maintainer (Thorsten
Kukuk?).

Here is the auto.home file I used to cause the problem (other of my NIS
maps caused it as well - netgroup, passwd):

khp		-fstype=nfs		edsel:/home/khp

I don't know the hashing scheme used by ndbm, but it may help in
reproducing the bug to have the map be small, e.g. one entry only as above.

I didn't dig into the ndbm code in glibc so I can't say how easily this bug
will reproduce on other systems. It might depend on how the dbm* routines
actually handle the static storage into which point these dptr fields. On
my machine, the problem is eminently reproducible. BTW, other weird bugs
may occur due to the fact that the ypproc_all_2_svc() routine frees the
memory pointed to by tkey.dptr, memory that ndbm thinks it owns. I don't
know what sort of database corruption this might cause if any. A quick grep
of the ypserv code did show a lot of other calls to ypdb_free() but I
didn't check other places in the code to see if there are similar bugs
elsewhere.


Note You need to log in before you can comment on or make changes to this bug.