Bug 27860

Summary: sshd dumps core
Product: Base System Reporter: Yoshihiro Koya <Yoshihiro.Koya>
Component: binAssignee: dwmalone
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 5.0-CURRENT   
Hardware: Any   
OS: Any   

Description Yoshihiro Koya 2001-06-03 21:40:00 UTC
Too long user name causes sshd to dump core.
I tried to make patch. But, I couldn't do it.
The following is the output from the gdb.

current# ls
.cshrc		cdrom		etc		root		tmp
.profile	compat		home		sbin		usr
COPYRIGHT	dev		lost+found	sshd.core	var
bin		dist		mnt		stand
boot		entropy		proc		sys
current# gdb /usr/sbin/sshd sshd.core
GNU gdb 4.18
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-unknown-freebsd"...
(no debugging symbols found)...
Core was generated by `sshd'.
Program terminated with signal 10, Bus error.
Reading symbols from /usr/lib/libopie.so.2...(no debugging symbols found)...
done.
Reading symbols from /usr/lib/libmd.so.2...(no debugging symbols found)...done.
Reading symbols from /usr/lib/libcrypt.so.2...(no debugging symbols found)...done.
Reading symbols from /usr/lib/libcrypto.so.2...(no debugging symbols found)...done.
Reading symbols from /usr/lib/libutil.so.3...(no debugging symbols found)... done.
Reading symbols from /usr/lib/libz.so.2...(no debugging symbols found)...done.
Reading symbols from /usr/lib/libwrap.so.3...(no debugging symbols found)...done.
Reading symbols from /usr/lib/libpam.so.1...(no debugging symbols found)...done.
Reading symbols from /usr/lib/libc.so.5...(no debugging symbols found)...done.
Reading symbols from /usr/libexec/ld-elf.so.1...(no debugging symbols found)...done.
#0  0x28225f32 in __log2 () from /usr/lib/libc.so.5
(gdb) where
#0  0x28225f32 in __log2 () from /usr/lib/libc.so.5
#1  0x28223d1c in __call_hash () from /usr/lib/libc.so.5
#2  0x28223623 in __hash_open () from /usr/lib/libc.so.5
#3  0x282234be in __hash_open () from /usr/lib/libc.so.5
#4  0x281ec203 in endpwent () from /usr/lib/libc.so.5
#5  0x281eb21a in netname2host () from /usr/lib/libc.so.5
#6  0x281ebbdc in netname2host () from /usr/lib/libc.so.5
#7  0x28213f95 in nsdispatch () from /usr/lib/libc.so.5
#8  0x281ebf45 in getpwnam () from /usr/lib/libc.so.5
#9  0x80537b5 in getsockname ()
#10 0x805e74f in getsockname ()
#11 0x80535a2 in getsockname ()
#12 0x804dc23 in getsockname ()
#13 0x804c0f9 in getsockname ()

Fix: 

Unfortunately I don't have much enough time to find what casues this, 
and also don't have good idea to fix it.
But the above __log2 function may be found in 
/usr/src/lib/libc/db/hash/hash_log2.c.
How-To-Repeat: Type

  % slogin localhost -l xxxx<10000 times x's>xxx

For example, use the following small program

/* genx.c */
#include <stdio.h>

int
main(int argc, char *argv[])
{
	int i;

	for (i = 0; i < 10000; i++)
		putchar('x');

	return 0;
}

and type

  % slogin localhost -l `./genx`

Then, you may get something like as follows:

Jun  4 04:54:43 current /boot/kernel/kernel: pid 2479 (sshd), uid 0: exited on signal 10 (core dumped)
Comment 1 dwmalone 2001-06-04 11:28:31 UTC
On Mon, Jun 04, 2001 at 05:30:53AM +0900, Yoshihiro Koya wrote:

> >How-To-Repeat:
> Type
> 
>   % slogin localhost -l xxxx<10000 times x's>xxx

I've reproduced this with a -current machine at home but it doesn't
seem to to be a problem on -stable. The backtraces looks the same
but doesn't seem to make much sense.

	David.
Comment 2 Yoshihiro Koya 2001-06-04 16:30:50 UTC
Hello,

From: David Malone <dwmalone@maths.tcd.ie>
Subject: Re: bin/27860: sshd caught signal 10
Date: Mon, 4 Jun 2001 11:28:31 +0100
Message-ID: <20010604112831.A4410@walton.maths.tcd.ie>

> On Mon, Jun 04, 2001 at 05:30:53AM +0900, Yoshihiro Koya wrote:
> 
> > >How-To-Repeat:
> > Type
> > 
> >   % slogin localhost -l xxxx<10000 times x's>xxx
> 
> I've reproduced this with a -current machine at home but it doesn't
> seem to to be a problem on -stable. The backtraces looks the same
> but doesn't seem to make much sense.

I agree. I couldn't reproduce my 4.3-stable box.
The version of that ssh is

   SSH Version OpenSSH_2.3.0 green@FreeBSD.org 20010321.

But, I could reproduced on -current which was build on 2001/01/12.
And the version of that ssh is OpenSSH_2.3.0.

On the other hand, I had an another sshd.core on my 4.2-stable box
which is:
  4.2-STABLE FreeBSD 4.2-STABLE #0: Thu Mar  1 12:26:02 JST 2001
The following is the backtraces:

---
This GDB was configured as "i386-unknown-freebsd"...
(no debugging symbols found)...
Core was generated by `sshd'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/lib/libopie.so.2...(no debugging symbols found)...
done.
(snip)
Reading symbols from /usr/libexec/ld-elf.so.1...(no debugging symbols found)...
done.
#0  0x281791c8 in login_getpwclass () from /usr/lib/libutil.so.3
(gdb) where
#0  0x281791c8 in login_getpwclass () from /usr/lib/libutil.so.3
#1  0x80532e8 in getsockname ()
#2  0x805a9ef in getsockname ()
#3  0x8052fd0 in getsockname ()
#4  0x804d81d in getsockname ()
#5  0x804be95 in getsockname ()
---
In this case, sshd caught signal 11. But the reason why sshd dumped
core on that box isn't clear to me. I can, however, reproduce it.
In order to get sshd.core, I only have to type

  % slogin that_host -l nonexistent_user_name

The version of ssh is
  SSH Version OpenSSH_2.3.0, protocol versions 1.5/2.0.

koya
Comment 3 dwmalone 2001-06-07 22:58:19 UTC
On Mon, Jun 04, 2001 at 05:30:53AM +0900, Yoshihiro Koya wrote:
> >Description:
> Too long user name causes sshd to dump core.
> I tried to make patch. But, I couldn't do it.

I've found the problem - it looks like a reintroduction of a bug
in getpwent.c. It was originally fixed in versions 1.47 and 1.48
but the bug was brought back in again with the nsswitch stuff.

I'm testing the patch below which seems to fix the problem. If
someone can review it for me I'll commit it tomorrow.

Note - MAXLOGNAME includes space for the trailing \0, which the
key doesn't seem to include - hence the comparison with MAXLOGNAME-1.
I've tested it with a 16 character username and things seem to work
as expected.

	David.


Index: src/lib/libc/gen/getpwent.c
===================================================================
RCS file: /cvs/FreeBSD-CVS/src/lib/libc/gen/getpwent.c,v
retrieving revision 1.59
diff -u -r1.59 getpwent.c
--- src/lib/libc/gen/getpwent.c	2001/01/24 12:59:22	1.59
+++ src/lib/libc/gen/getpwent.c	2001/06/07 21:30:34
@@ -386,7 +386,9 @@
 	case _PW_KEYBYNAME:
 		name = va_arg(ap, const char *);
 		len = strlen(name);
-		memmove(bf + 1, name, (size_t)MIN(len, MAXLOGNAME));
+		if (len > MAXLOGNAME - 1)
+			return NS_NOTFOUND;
+		memmove(bf + 1, name, len);
 		key.size = len + 1;
 		break;
 	case _PW_KEYBYUID:
Comment 4 dwmalone freebsd_committer freebsd_triage 2001-06-07 23:00:30 UTC
Responsible Changed
From-To: freebsd-bugs->dwmalone

I think I've figured this one out.
Comment 5 Yoshihiro Koya 2001-06-08 00:32:21 UTC
Hello,

From: David Malone <dwmalone@maths.tcd.ie>
Subject: Re: bin/27860: sshd caught signal 10
Date: Thu, 7 Jun 2001 22:58:19 +0100
Message-ID: <20010607225819.A34120@walton.maths.tcd.ie>

> On Mon, Jun 04, 2001 at 05:30:53AM +0900, Yoshihiro Koya wrote:
> > >Description:
> > Too long user name causes sshd to dump core.
> > I tried to make patch. But, I couldn't do it.
> 
> I've found the problem - it looks like a reintroduction of a bug
> in getpwent.c. It was originally fixed in versions 1.47 and 1.48
> but the bug was brought back in again with the nsswitch stuff.
> 
> I'm testing the patch below which seems to fix the problem. If
> someone can review it for me I'll commit it tomorrow.

I've also tested your patch.  I typed 
% slogin localhost -l xxxxx(10000 times)xxxx

as before.  But the slogin on my 5-current box didn't cause any
problem. The version of my 5-current running on my box is 
FreeBSD 5.0-CURRENT #0: Wed May 30 00:38:02 JST 2001.
But I don't have much enough time now to test 
it on my another 4.2-STABLE box.

Thank you very much!!

koya
Comment 6 dwmalone 2001-06-08 07:44:22 UTC
> I've also tested your patch.  I typed 
> % slogin localhost -l xxxxx(10000 times)xxxx

> as before.  But the slogin on my 5-current box didn't cause any
> problem. The version of my 5-current running on my box is 
> FreeBSD 5.0-CURRENT #0: Wed May 30 00:38:02 JST 2001.
> But I don't have much enough time now to test 
> it on my another 4.2-STABLE box.

I'm testing a buildworld with the patch at the moment and Jacques
Vidrine is going to read over the patch and look for any other
places where the same thing may have happened. We should have it
fixed in a few days.

	David.
Comment 7 Jacques Vidrine 2001-06-11 13:44:34 UTC
This  is  what was  bothering  me:  the  check  is happening  only  in
_local_pwd.  This  is (currently) the  only place where such  a buffer
overflow could occur (the nis and  hesiod cases don't need to copy the
data).   But I  have this  feeling that  the check  should be  done in
getpwnam().

On the other hand,  there are so many other places  that we could wind
up with  usernames > MAXLOGNAME, that  maybe it is not  worth checking
all cases.

So I  think your  fix should  be committed to  -CURRENT: we  can worry
about other cases some other time.

Oh, by the way, the test should be (len > sizeof(bf) - 1).  We are not
really checking MAXLOGNAME here, but the buffer size -- another reason
that I'm wishy-washy about moving the test up to getpwnam.

Cheers,
-- 
Jacques Vidrine / n@nectar.com / jvidrine@verio.net / nectar@FreeBSD.org

On Thu, Jun 07, 2001 at 10:58:19PM +0100, David Malone wrote:
> On Mon, Jun 04, 2001 at 05:30:53AM +0900, Yoshihiro Koya wrote:
> > >Description:
> > Too long user name causes sshd to dump core.
> > I tried to make patch. But, I couldn't do it.
> 
> I've found the problem - it looks like a reintroduction of a bug
> in getpwent.c. It was originally fixed in versions 1.47 and 1.48
> but the bug was brought back in again with the nsswitch stuff.
> 
> I'm testing the patch below which seems to fix the problem. If
> someone can review it for me I'll commit it tomorrow.
> 
> Note - MAXLOGNAME includes space for the trailing \0, which the
> key doesn't seem to include - hence the comparison with MAXLOGNAME-1.
> I've tested it with a 16 character username and things seem to work
> as expected.
> 
> 	David.
> 
> 
> Index: src/lib/libc/gen/getpwent.c
> ===================================================================
> RCS file: /cvs/FreeBSD-CVS/src/lib/libc/gen/getpwent.c,v
> retrieving revision 1.59
> diff -u -r1.59 getpwent.c
> --- src/lib/libc/gen/getpwent.c	2001/01/24 12:59:22	1.59
> +++ src/lib/libc/gen/getpwent.c	2001/06/07 21:30:34
> @@ -386,7 +386,9 @@
>  	case _PW_KEYBYNAME:
>  		name = va_arg(ap, const char *);
>  		len = strlen(name);
> -		memmove(bf + 1, name, (size_t)MIN(len, MAXLOGNAME));
> +		if (len > MAXLOGNAME - 1)
> +			return NS_NOTFOUND;
> +		memmove(bf + 1, name, len);
>  		key.size = len + 1;
>  		break;
>  	case _PW_KEYBYUID:
>
Comment 8 dwmalone freebsd_committer freebsd_triage 2001-06-18 17:09:35 UTC
State Changed
From-To: open->closed

A version of the patch has been committed to -current. The problem 
doesn't exist in -stable.