>Submitter-Id:   net
>Originator:     John Heidemann
>Organization:
net
>Confidential:  no
>Synopsis:      cvs pserver segfaults on systems where crypt doesn't handle null 
>pointers
>Severity:      serious
>Priority:      medium
>Category:      cvs
>Class:         sw-bug
>Release:       cvs-1.10.7
>Environment:
        <machine, os, target, libraries (multiple lines)>
System: Linux vir.isi.edu 2.2.14-5.0 #1 Tue Mar 7 21:07:39 EST 2000 i686 unknow\
n
Architecture: i686
redhat-6.2 linux with RH-supplied upgrades

>Description:

Cvs pserver segfaults when given an account with no password.
On some systems like redhat 6.2, crypt(3) doesn't like being given
NULL string values and segfaults.  This causes anon cvs access to fail
if the account has no password.


>How-To-Repeat:

set up a cvs server with a passwd file containing only "anoncvs:".
Run "cvs -f --allow-root=/path/to/CVSROOT pserver"
and type this as standard input:

BEGIN VERIFICATION REQUEST
/path/to/CVSROOT
anoncvs
A
END VERIFICATION REQUEST

The following crash occurs:
        Program received signal SIGSEGV, Segmentation fault.
        strncmp (s1=0x4001fc00 "$1$", s2=0x0, n=3) at ../sysdeps/generic/strncmp.c:65
        65      ../sysdeps/generic/strncmp.c: No such file or directory.
        (gdb) bt
        #0  strncmp (s1=0x4001fc00 "$1$", s2=0x0, n=3)
            at ../sysdeps/generic/strncmp.c:65
        #1  0x4001d15b in crypt (key=0x80cf640 "", salt=0x0)
            at ../crypt/sysdeps/unix/crypt-entry.c:127
        #2  0x808898a in strcpy () at ../sysdeps/generic/strcpy.c:30
        #3  0x8088a15 in strcpy () at ../sysdeps/generic/strcpy.c:30
        #4  0x8088d03 in strcpy () at ../sysdeps/generic/strcpy.c:30
        #5  0x806c478 in strcpy () at ../sysdeps/generic/strcpy.c:30
        #6  0x4010a9cb in __libc_start_main (main=0x806bee0 <strcpy+136076>, argc=4, 
            argv=0xbffffb54, init=0x804a134, fini=0x80ab0ac <fstat+88>, 
            rtld_fini=0x4000ae60 <_dl_fini>, stack_end=0xbffffb4c)
            at ../sysdeps/generic/libc-start.c:92

(apparently cvs was stripped so this is only the traceback in glibc).

>Fix:


The following patch fixes the problem by explicitly checking for null
passwords:

--- server.c-   Wed Sep 13 15:02:44 2000
+++ server.c    Wed Sep 13 15:51:13 2000
@@ -5229,6 +5229,7 @@
     if (fclose (fp) < 0)
        error (0, errno, "cannot close %s", filename);
 
+    *host_user_ptr = NULL;
     /* If found_it != 0, then linebuf contains the information we need. */
     if (found_it)
     {
@@ -5240,23 +5241,20 @@
        if (host_user_tmp == NULL)
             host_user_tmp = username;
 
-       if (strcmp (found_password, crypt (password, found_password)) == 0)
-        {
-            /* Give host_user_ptr permanent storage. */
-            *host_user_ptr = xstrdup (host_user_tmp);
+       /* if both are empty, match (avoid passing NULLs to crypt)
+          if only one is empty, fail,
+          otherwise try to match. */
+       if ((!password || strlen(password) == 0) && (!found_password || 
+strlen(found_password) == 0))
+               retval = 1;
+        else if (!password || strlen(password) == 0 || !found_password || 
+strlen(found_password) == 0)
+           retval = 2;
+       else if (strcmp (found_password, crypt (password, found_password)) == 0)
            retval = 1;
-        }
-       else
-        {
-            *host_user_ptr = NULL;
-           retval         = 2;
-        }
-    }
-    else
-    {
-       *host_user_ptr = NULL;
-       retval = 0;
+       else retval = 2;
+        if (retval == 1) /* Give host_user_ptr permanent storage. */
+           *host_user_ptr = xstrdup(host_user_tmp);
     }
+    else retval = 0;
 
     free (filename);
     if (linebuf)



Reply via email to