Bug 974797 - cvs segfaults when having invalid salt in passwd configuration file
cvs segfaults when having invalid salt in passwd configuration file
Status: CLOSED ERRATA
Product: Fedora
Classification: Fedora
Component: cvs (Show other bugs)
18
i686 Linux
unspecified Severity high
: ---
: ---
Assigned To: Petr Pisar
Fedora Extras Quality Assurance
https://savannah.nongnu.org/bugs/inde...
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2013-06-15 18:26 EDT by Michael Jørgensen
Modified: 2014-01-02 11:23 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2014-01-02 11:23:46 EST
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Michael Jørgensen 2013-06-15 18:26:14 EDT
Description of problem:
I'm trying to setup a CVS server, but when I login (using pserver), I get a segfault, and the login fails.


Version-Release number of selected component (if applicable):
cvs-1.11.23-29.fc18.i686


How reproducible:
Always


Steps to Reproduce:
I can access the local repository quite fine, and I have setup a single user in CVSROOT/passwd. Running cvs -d CVSROOT login works fine - I get prompted for the password, and I can checkout the files from the repository.

But when I test the pserver protocol (because I later want to connect from a remote machine) using the command cvs -d :pserver:cvsuser@localhost:CVSROOT login I get an error message from the client: "end of file from server".


Actual results:
The client reports "end of file from server".

I then check in /var/log/messages, and I find these lines:

Jun 15 22:55:23 granbo-1 xinetd[437]: START: cvspserver pid=17064 from=::1
Jun 15 22:55:23 granbo-1 kernel: [ 1712.522236] cvs[17064]: segfault at 0 ip b755d508 sp bfd80f0c error 4 in libc-2.16.so[b740f000+1b0000]
Jun 15 22:55:23 granbo-1 xinetd[437]: EXIT: cvspserver signal=11 pid=17064 duration=0(sec)



Expected results:
No segfault in /var/log/messages
Being able to acces the cvs repository.


Additional info:

Do you have any idea what is the problem? Clearly, this is a very simple setup and should work for everyone.

Can you suggest anything I can do to help debug the problem? I'm familiar with gdb, but I don't know how to start gdb, when cvs is started from xinetd.

Can you suggest another way to access the repository from a remote machine? I'm using ssh to connect to the machine.
Comment 1 Michael Jørgensen 2013-06-15 19:09:52 EDT
I've managed to run valgrind on the cvs process (by disabling xinetd and starting cvs using netcat. The complete command I used was:

valgrind -v --trace-children=yes --log-file=val.%p nc --exec "/usr/bin/cvs -f --allow-root=/share/CVS-Root pserver" -l 2401

This gave me a stack trace:

==17544== Invalid read of size 1
==17544==    at 0x402B48A: strcmp (mc_replace_strmem.c:730)
==17544==    by 0x809464B: check_password (server.c:5651)
==17544==    by 0x809A5F2: pserver_authenticate_connection (server.c:6076)
==17544==    by 0x804C104: main (main.c:730)
==17544==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==17544==
==17544==
==17544== Process terminating with default action of signal 11 (SIGSEGV)
==17544==  Access not within mapped region at address 0x0
==17544==    at 0x402B48A: strcmp (mc_replace_strmem.c:730)
==17544==    by 0x809464B: check_password (server.c:5651)
==17544==    by 0x809A5F2: pserver_authenticate_connection (server.c:6076)
==17544==    by 0x804C104: main (main.c:730)
==17544==  If you believe this happened as a result of a stack
==17544==  overflow in your program's main thread (unlikely but
==17544==  possible), you can try to increase the size of the
==17544==  main thread stack using the --main-stacksize= flag.
==17544==  The main thread stack size used in this run was 8388608.
Comment 2 Petr Pisar 2013-06-17 03:43:29 EDT
This is the code:

   /* Verify blank passwords directly, otherwise use crypt(). */
    if ((found_password == NULL)
        || ((strcmp (found_password, crypt (password, found_password))
         == 0)))

So (1) found_password is not NULL but it's an invalid pointer, or (2) crypt() returns NULL.

I've applied a patch recently into F19 and F20 because crypt() in glibc >= 2.17 can return NULL. (Especially in FIPS mode.) The patch should fix the second case. Can you try to use F19 sources in your F18 system? There is possibility that glibc maintainers ported the change into F18.

The first case can be verified with inspecting the found_password using gdb in the same way you used valgrind (at least I hope gdb can transit execve()).

I will try to reproduce the issue.

Could you publish your CVSROOT/passwd file (or at least the line with the affected user name)?
Comment 3 Petr Pisar 2013-06-17 04:24:22 EDT
I've just give a try on x86_64 with password `foo' and salt `ba' (passwd line `cvsuser:ba4TuD1iozTxw:petr') and I could not reproduce the problem.
Comment 4 Michael Jørgensen 2013-06-17 11:14:29 EDT
My password file contains just a single line:
cvsuser:$apr1$.QAb5YMY$Sqeo5hrku5XWfFsqWPWrS0:cvsuser

I've managed to create a coredump, and did a backtrace using gdb. The result is below. It seems that both variables password and found_password are as expected.

Are you saying this is a bug in the crypt() function? Or is my password file somehow corrupt? I can't remember how I created it, perhaps using htpasswd.


[root@granbo-1 mike]# gdb /usr/bin/cvs core.24720 
GNU gdb (GDB) Fedora (7.5.1-38.fc18)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/bin/cvs...Reading symbols from /usr/lib/debug/usr/bin/cvs.debug...done.
done.
[New LWP 24720]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `/usr/bin/cvs -f --allow-root=/share/CVS-Root pserver'.
Program terminated with signal 11, Segmentation fault.
#0  __strcmp_ssse3 () at ../sysdeps/i386/i686/multiarch/strcmp-ssse3.S:228
228             movzbl  (%eax), %ecx
(gdb) bt
#0  __strcmp_ssse3 () at ../sysdeps/i386/i686/multiarch/strcmp-ssse3.S:228
#1  0x0809464c in check_repository_password (host_user_ptr=<synthetic pointer>, 
    repository=0x83a10d0 "/share/CVS-Root", password=0x83a14d8 "random_guess", username=0x83a1118 "cvsuser")
    at server.c:5651
#2  check_password (username=0x83a1118 "cvsuser", password=password@entry=0x83a14d8 "random_guess", 
    repository=0x83a10d0 "/share/CVS-Root") at server.c:5727
#3  0x0809a5f3 in pserver_authenticate_connection () at server.c:6076
#4  0x0804c105 in main (argc=1, argv=0xbfaa5120) at main.c:730

(gdb) info locals
No locals.
(gdb) f 1
#1  0x0809464c in check_repository_password (host_user_ptr=<synthetic pointer>, 
    repository=0x83a10d0 "/share/CVS-Root", password=0x83a14d8 "random_guess", username=0x83a1118 "cvsuser")
    at server.c:5651
5651                || ((strcmp (found_password, crypt (password, found_password))
(gdb) info locals
found_password = 0x83a1688 "$apr1$.QAb5YMY$Sqeo5hrku5XWfFsqWPWrS0"
host_user_tmp = 0x83a16ae "cvsuser"
non_cvsuser_portion = <optimized out>
retval = 0
fp = <optimized out>
linebuf = 0x83a1680 "cvsuser:$apr1$.QAb5YMY$Sqeo5hrku5XWfFsqWPWrS0"
linebuf_len = 64
found_it = 1
filename = 0x83a14f0 "/share/CVS-Root/CVSROOT/passwd"
namelen = <optimized out>
(gdb) f 2
#2  check_password (username=0x83a1118 "cvsuser", password=password@entry=0x83a14d8 "random_guess", 
    repository=0x83a10d0 "/share/CVS-Root") at server.c:5727
5727        rc = check_repository_password (username, password, repository,
(gdb) info locals
rc = 0
host_user = 0x0
found_passwd = 0x0
pw = <optimized out>
Comment 5 Michael Jørgensen 2013-06-17 11:26:01 EDT
I'm not inclined to try F19 sources at this time. I've found a workaround, where I use CVS over SSH instead of the pserver protocol.

But I don't mind in assisting to reproduce the problem.
Comment 6 Petr Pisar 2013-06-18 07:25:32 EDT
(In reply to Michael Jørgensen from comment #4)
> My password file contains just a single line:
> cvsuser:$apr1$.QAb5YMY$Sqeo5hrku5XWfFsqWPWrS0:cvsuser
> 
[...]
> Are you saying this is a bug in the crypt() function? Or is my password file
> somehow corrupt? I can't remember how I created it, perhaps using htpasswd.
> 
With this line, I was able to reproduce your problem. It's been already reported to upstream <https://savannah.nongnu.org/bugs/index.php?39040> and the patch is in Fedora 19 and newer.

Your problem is the salted string is not a valid input for glibc's crypt(3). Manual page reads:

> salt is a two-character string chosen from the set [a–zA–Z0–9./].  This
> string is used to perturb the algorithm in one of 4096 different ways.

This is not the case, however there is a notice:

> If  salt is a character string starting with the characters "$id$" fol‐
> lowed by a string terminated by "$":
>
>      $id$salt$encrypted
>
> then instead of using the DES machine,  id  identifies  the  encryption
> method  used  and  this  then  determines  how the rest of the password
> string is interpreted.  The following values of id are supported:
>
>      ID  | Method
>      ─────────────────────────────────────────────────────────
>      1   | MD5
>      2a  | Blowfish (not in mainline glibc; added in some
>          | Linux distributions)
>      5   | SHA-256 (since glibc 2.7)
>      6   | SHA-512 (since glibc 2.7)

Your string is `$apr1$.QAb5YMY$Sqeo5hrku5XWfFsqWPWrS0'. I.e. the ID `apr1' is not known to glibc. Hence the crypt(3) returns NULL and subsequent strcmp() segfaults.

I will apply the patch from Fedora 19, so cvs will not segfault anymore and the authentication will fail.
Comment 7 Fedora Update System 2013-06-18 07:47:04 EDT
cvs-1.11.23-30.fc18 has been submitted as an update for Fedora 18.
https://admin.fedoraproject.org/updates/cvs-1.11.23-30.fc18
Comment 8 Fedora Update System 2013-06-18 07:47:32 EDT
cvs-1.11.23-27.fc17 has been submitted as an update for Fedora 17.
https://admin.fedoraproject.org/updates/cvs-1.11.23-27.fc17
Comment 9 Fedora Update System 2013-06-26 21:54:18 EDT
cvs-1.11.23-27.fc17 has been pushed to the Fedora 17 stable repository.  If problems still persist, please make note of it in this bug report.
Comment 10 Fedora Update System 2013-06-26 21:58:34 EDT
cvs-1.11.23-30.fc18 has been pushed to the Fedora 18 stable repository.  If problems still persist, please make note of it in this bug report.
Comment 11 Fedora End Of Life 2013-12-21 10:47:50 EST
This message is a reminder that Fedora 18 is nearing its end of life.
Approximately 4 (four) weeks from now Fedora will stop maintaining
and issuing updates for Fedora 18. It is Fedora's policy to close all
bug reports from releases that are no longer maintained. At that time
this bug will be closed as WONTFIX if it remains open with a Fedora 
'version' of '18'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version prior to Fedora 18's end of life.

Thank you for reporting this issue and we are sorry that we may not be 
able to fix it before Fedora 18 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior to Fedora 18's end of life.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

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