From nobody@FreeBSD.org  Tue May 19 01:07:15 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id DBD0E106566C
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 19 May 2009 01:07:15 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id AF0E08FC08
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 19 May 2009 01:07:15 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id n4J17Fwn068771
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 19 May 2009 01:07:15 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id n4J17Fx6068770;
	Tue, 19 May 2009 01:07:15 GMT
	(envelope-from nobody)
Message-Id: <200905190107.n4J17Fx6068770@www.freebsd.org>
Date: Tue, 19 May 2009 01:07:15 GMT
From: Glen Barber <glen.j.barber@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: sshd(8) gives false-positive when unable to obtain socket
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         134694
>Category:       bin
>Synopsis:       sshd(8) gives false-positive when unable to obtain socket
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 19 01:10:01 UTC 2009
>Closed-Date:    Sun May 31 11:47:37 UTC 2009
>Last-Modified:  Sun May 31 11:47:37 UTC 2009
>Originator:     Glen Barber
>Release:        7.2-STABLE
>Organization:
>Environment:
FreeBSD phoenix 7.2-STABLE FreeBSD 7.2-STABLE #0 r192129M: Thu May 14 22:53:56 UTC 2009     root@phoenix:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
sshd(8) does not error when unable to acquire a socket.  
>How-To-Repeat:
- Configure sshd to listen on the same socket as another service.  
- Restart the other service, then restart sshd.
- '/etc/rc.d/sshd status' will show:
sshd is not running.
>Fix:


>Release-Note:
>Audit-Trail:

From: Eygene Ryabinkin <rea-fbsd@codelabs.ru>
To: Glen Barber <glen.j.barber@gmail.com>
Cc: hackers@freebsd.org, bug-followup@freebsd.org
Subject: Re: bin/134694: gives false-positive when unable to obtain socket
	[WAS: sshd(8) - alert user when fails to execute from rc.d]
Date: Wed, 20 May 2009 14:19:22 +0400

 Glen, good day.
 
 Mon, May 18, 2009 at 10:49:52PM -0400, Glen Barber wrote:
 > Earlier this evening, I submitted a PR about sshd(8) giving a
 > false-positive when starting on an already occupied socket[1].  I
 > would like to enable some form of console output when the rc.d script
 > is called if the service cannot properly bind to the socket, but I
 > want to make sure I do it "the right way."
 
 Reading through the PR, I can't figure out what do you mean.
 You're saying that
  1. you spawn the other service on a port N;
  2. then you're spawning SSH on the same port via rc.d script;
  3. after this '/etc/rc.d/sshd status' gives you 'sshd is not running'.
 
 But this is completely right: after step 2 there will be no SSH daemon
 listening, because it fails to bind to the port.  And the 'status'
 command of an rc.d script is perfectly correct -- no SSH daemon is
 running, really.
 
 > I was digging through src/crypto/openssh/sshd.c hoping to submit a
 > patch to enable this, but I'm not certain that is the right place to
 > be looking.  After digging through erc/etc/rc.d/sshd, I am failing to
 > understand how the service would check the listening port, so now I
 > feel like I am hitting a wall.
 
 You seem to mix two things: binding to the port and the output from rc.d
 'status' command.  Binding to the port is done by SSH by the bind(2)
 system call and if something is already listening on the given address,
 the socket won't be bound, so SSH daemon terminates.
 
 'status' (for the case of /etc/rc.d/sshd) deduces the status of the
 service from it's pid file (variable pidfile) with the subroutine
 check_pidfile.  Look at /etc/rc.subr: 'status' is handled via
 "run_rc_command status" that evaluates _pidcmd that sets $rc_pid.  And
 then $rc_pid it checked for being non-empty, and if emptiness found,
 command
 -----
                                 echo "${name} is not running."
 -----
 is executed.  It produces the result you're seeing.
 
 So, I would say that the PR in question is somewhat false positive.
 -- 
 Eygene
  _                ___       _.--.   #
  \`.|\..----...-'`   `-._.-'_.-'`   #  Remember that it is hard
  /  ' `         ,       __.--'      #  to read the on-line manual
  )/' _/     \   `-_,   /            #  while single-stepping the kernel.
  `-'" `"\_  ,_.-;_.-\_ ',  fsc/as   #
      _.-'_./   {_.'   ; /           #    -- FreeBSD Developers handbook
     {_.-``-'         {_/            #

From: Dimitry Andric <dimitry@andric.com>
To: rea-fbsd@codelabs.ru
Cc: Glen Barber <glen.j.barber@gmail.com>, hackers@freebsd.org, 
 bug-followup@freebsd.org
Subject: Re: bin/134694: gives false-positive when unable to obtain socket
 [WAS: sshd(8) - alert user when fails to execute from rc.d]
Date: Wed, 20 May 2009 12:54:56 +0200

 On 2009-05-20 12:19, Eygene Ryabinkin wrote:
 > You seem to mix two things: binding to the port and the output from rc.d
 > 'status' command.  Binding to the port is done by SSH by the bind(2)
 > system call and if something is already listening on the given address,
 > the socket won't be bound, so SSH daemon terminates.
 
 I think what might be confusing, is the fact that sshd dies due to
 bind() failing, and it should; but you will only see this in the syslog,
 NOT on the command line.
 
 E.g. the /etc/rc.d/sshd script will NOT give an error, because the
 /usr/bin/sshd it calls will fork, and as soon as the fork is okay, the
 original instance with exit with 0.  The forked instance is what will
 die on bind(), so you will not see any failures from it.

From: Dimitry Andric <dimitry@andric.com>
To: Tobias Fendin <tobias.fendin@glocalnet.net>
Cc: rea-fbsd@codelabs.ru, hackers@freebsd.org, 
 Glen Barber <glen.j.barber@gmail.com>,
 bug-followup@freebsd.org
Subject: Re: bin/134694: gives false-positive when unable to obtain socket
 [WAS: sshd(8) - alert user when fails to execute from rc.d]
Date: Wed, 20 May 2009 13:27:02 +0200

 On 2009-05-20 13:18, Tobias Fendin wrote:
 > Does the child really die? I did a little test:
 > 
 > # /etc/rc.d/sshd status
 > sshd is not running.
 > # nc -l 22 >/tmp/ssh_test &
 > [1] 1733
 > # /etc/rc.d/sshd start
 > Starting sshd.
 > # /etc/rc.d/sshd status
 > sshd is running as pid 1740.
 
 This is because sshd binds to both IPv4 and IPv6 ports.  The IPv4 bind
 fails, as you will see in syslog, while the IPv6 bind succeeds.  Thus
 sshd keeps on running.
 
 If you start two nc's (I don't know any way to do this with one
 instance), e.g.:
 
 nc -4 -l 22 > /tmp/ssh_test4 &
 nc -6 -l 22 > /tmp/ssh_test6 &
 
 and then try starting sshd, you should see it quit.

From: Tobias Fendin <tobias.fendin@glocalnet.net>
To: Dimitry Andric <dimitry@andric.com>
Cc: rea-fbsd@codelabs.ru, hackers@freebsd.org, 
 Glen Barber <glen.j.barber@gmail.com>,
 bug-followup@freebsd.org
Subject: Re: bin/134694: gives false-positive when unable to obtain socket
 [WAS: sshd(8) - alert user when fails to execute from rc.d]
Date: Wed, 20 May 2009 13:18:15 +0200

 Dimitry Andric wrote:
 > On 2009-05-20 12:19, Eygene Ryabinkin wrote:
 >   
 >> You seem to mix two things: binding to the port and the output from rc.d
 >> 'status' command.  Binding to the port is done by SSH by the bind(2)
 >> system call and if something is already listening on the given address,
 >> the socket won't be bound, so SSH daemon terminates.
 >>     
 >
 > I think what might be confusing, is the fact that sshd dies due to
 > bind() failing, and it should; but you will only see this in the syslog,
 > NOT on the command line.
 >
 > E.g. the /etc/rc.d/sshd script will NOT give an error, because the
 > /usr/bin/sshd it calls will fork, and as soon as the fork is okay, the
 > original instance with exit with 0.  The forked instance is what will
 > die on bind(), so you will not see any failures from it.
 > _______________________________________________
 > freebsd-hackers@freebsd.org mailing list
 > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
 > To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"
 >
 >   
 Does the child really die? I did a little test:
 
 # /etc/rc.d/sshd status
 sshd is not running.
 # nc -l 22 >/tmp/ssh_test &
 [1] 1733
 # /etc/rc.d/sshd start
 Starting sshd.
 # /etc/rc.d/sshd status
 sshd is running as pid 1740.
 # ssh someuser@localhost                          // This didn't timeout 
 or anything, just didn't give any output. I killed it after a couple of 
 minutes.
 ^C
 [1]+  Done                    nc -l 22 > /tmp/ssh_test
 # ssh someuser@localhost
 The authenticity of host 'localhost (::1)' can't be established.
 DSA key fingerprint is 9f:fa:ee:f5:39:c5:de:c4:8f:b9:c5:43:d8:9d:85:23.
 Are you sure you want to continue connecting (yes/no)? ^C
 # uname -a
 FreeBSD asator 7.0-RELEASE-p2 FreeBSD 7.0-RELEASE-p2 #0: Thu Mar  5 
 03:16:15 CET 2009     root@asator:/usr/obj/usr/src/sys/A_KERNEL  i386
 
 As you can see, the first execution of ssh connects to nc (which 
 terminated when I killed the ssh client). And the second execution it 
 gets through to sshd (thus, sshd never failed at it's startup).
 I don't know if this is the expected behavior, or if it has changed on 
 -CURRENT.

From: Dimitry Andric <dimitry@andric.com>
To: Glen Barber <glen.j.barber@gmail.com>
Cc: hackers@freebsd.org, bug-followup@freebsd.org
Subject: Re: bin/134694: gives false-positive when unable to obtain socket
 	[WAS: sshd(8) - alert user when fails to execute from rc.d]
Date: Wed, 20 May 2009 16:46:11 +0200

 On 2009-05-20 16:40, Glen Barber wrote:
 > sshd was listening on :25, both IPv4 and IPv6
 > sendmail was listening on :25 (because I had forgotten to disable it)
 > 
 > The system boots, and sendmail starts before sshd.  When sshd starts
 > (or tries to) there is no console output that it had failed.  The only
 > way you realize it is not running, is when you cannot remotely log in.
 
 Yes, this is unfortunate, but normal, as I explained in an earlier post.
 
 The sshd process does not return any error (and thus the /etc/rc.d
 script doesn't either), because it has no way to know that its forked
 copy died.
 
 The solution to this PR is "don't run stuff on conflicting ports". :)

From: Glen Barber <glen.j.barber@gmail.com>
To: Tobias Fendin <tobias.fendin@glocalnet.net>
Cc: hackers@freebsd.org, bug-followup@freebsd.org
Subject: Re: bin/134694: gives false-positive when unable to obtain socket 
	[WAS: sshd(8) - alert user when fails to execute from rc.d]
Date: Wed, 20 May 2009 10:42:58 -0400

 Hi, Tobias
 
 On Wed, May 20, 2009 at 7:18 AM, Tobias Fendin
 <tobias.fendin@glocalnet.net> wrote:
 >
 > Does the child really die? I did a little test:
 >
 > # /etc/rc.d/sshd status
 > sshd is not running.
 > # nc -l 22 >/tmp/ssh_test &
 > [1] 1733
 > # /etc/rc.d/sshd start
 > Starting sshd.
 > # /etc/rc.d/sshd status
 > sshd is running as pid 1740.
 > # ssh someuser@localhost =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
 =A0// This didn't timeout or
 > anything, just didn't give any output. I killed it after a couple of
 > minutes.
 > ^C
 > [1]+ =A0Done =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0nc -l 22 > /tmp/ssh_t=
 est
 > # ssh someuser@localhost
 > The authenticity of host 'localhost (::1)' can't be established.
 > DSA key fingerprint is 9f:fa:ee:f5:39:c5:de:c4:8f:b9:c5:43:d8:9d:85:23.
 > Are you sure you want to continue connecting (yes/no)? ^C
 > # uname -a
 > FreeBSD asator 7.0-RELEASE-p2 FreeBSD 7.0-RELEASE-p2 #0: Thu Mar =A05 03:=
 16:15
 > CET 2009 =A0 =A0 root@asator:/usr/obj/usr/src/sys/A_KERNEL =A0i386
 >
 > As you can see, the first execution of ssh connects to nc (which terminat=
 ed
 > when I killed the ssh client). And the second execution it gets through t=
 o
 > sshd (thus, sshd never failed at it's startup).
 > I don't know if this is the expected behavior, or if it has changed on
 > -CURRENT.
 >
 
 Perhaps sshd is checking for forked processes of itself, but not other
 daemons listening on that socket?
 
 --=20
 Glen Barber

From: Glen Barber <glen.j.barber@gmail.com>
To: rea-fbsd@codelabs.ru
Cc: hackers@freebsd.org, bug-followup@freebsd.org
Subject: Re: bin/134694: gives false-positive when unable to obtain socket 
	[WAS: sshd(8) - alert user when fails to execute from rc.d]
Date: Wed, 20 May 2009 10:38:18 -0400

 Hi, Eygene
 
 On Wed, May 20, 2009 at 6:19 AM, Eygene Ryabinkin <rea-fbsd@codelabs.ru> wr=
 ote:
 > Glen, good day.
 >
 > Mon, May 18, 2009 at 10:49:52PM -0400, Glen Barber wrote:
 >> Earlier this evening, I submitted a PR about sshd(8) giving a
 >> false-positive when starting on an already occupied socket[1]. =A0I
 >> would like to enable some form of console output when the rc.d script
 >> is called if the service cannot properly bind to the socket, but I
 >> want to make sure I do it "the right way."
 >
 > Reading through the PR, I can't figure out what do you mean.
 > You're saying that
 > =A01. you spawn the other service on a port N;
 > =A02. then you're spawning SSH on the same port via rc.d script;
 > =A03. after this '/etc/rc.d/sshd status' gives you 'sshd is not running'.
 >
 > But this is completely right: after step 2 there will be no SSH daemon
 > listening, because it fails to bind to the port. =A0And the 'status'
 > command of an rc.d script is perfectly correct -- no SSH daemon is
 > running, really.
 >
 
 That is correct.  There is no daemon running, but there is no output
 on the console that starting sshd failed -- it is only listed in
 messages.  (And if you don't know it failed, you may never look in
 messages to realize this.)
 
 >> I was digging through src/crypto/openssh/sshd.c hoping to submit a
 >> patch to enable this, but I'm not certain that is the right place to
 >> be looking. =A0After digging through erc/etc/rc.d/sshd, I am failing to
 >> understand how the service would check the listening port, so now I
 >> feel like I am hitting a wall.
 >
 > You seem to mix two things: binding to the port and the output from rc.d
 > 'status' command. =A0Binding to the port is done by SSH by the bind(2)
 > system call and if something is already listening on the given address,
 > the socket won't be bound, so SSH daemon terminates.
 >
 > 'status' (for the case of /etc/rc.d/sshd) deduces the status of the
 > service from it's pid file (variable pidfile) with the subroutine
 > check_pidfile. =A0Look at /etc/rc.subr: 'status' is handled via
 > "run_rc_command status" that evaluates _pidcmd that sets $rc_pid. =A0And
 > then $rc_pid it checked for being non-empty, and if emptiness found,
 > command
 > -----
 > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0echo "${na=
 me} is not running."
 > -----
 > is executed. =A0It produces the result you're seeing.
 >
 > So, I would say that the PR in question is somewhat false positive.
 > --
 > Eygene
 > =A0_ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0___ =A0 =A0 =A0 _.--. =A0 #
 > =A0\`.|\..----...-'` =A0 `-._.-'_.-'` =A0 # =A0Remember that it is hard
 > =A0/ =A0' ` =A0 =A0 =A0 =A0 , =A0 =A0 =A0 __.--' =A0 =A0 =A0# =A0to read =
 the on-line manual
 > =A0)/' _/ =A0 =A0 \ =A0 `-_, =A0 / =A0 =A0 =A0 =A0 =A0 =A0# =A0while sing=
 le-stepping the kernel.
 > =A0`-'" `"\_ =A0,_.-;_.-\_ ', =A0fsc/as =A0 #
 > =A0 =A0 _.-'_./ =A0 {_.' =A0 ; / =A0 =A0 =A0 =A0 =A0 # =A0 =A0-- FreeBSD =
 Developers handbook
 > =A0 =A0{_.-``-' =A0 =A0 =A0 =A0 {_/ =A0 =A0 =A0 =A0 =A0 =A0#
 >
 
 
 
 --=20
 Glen Barber

From: Glen Barber <glen.j.barber@gmail.com>
To: Dimitry Andric <dimitry@andric.com>
Cc: hackers@freebsd.org, bug-followup@freebsd.org
Subject: Re: bin/134694: gives false-positive when unable to obtain socket 
	[WAS: sshd(8) - alert user when fails to execute from rc.d]
Date: Wed, 20 May 2009 10:40:59 -0400

 Hi, Dimitry
 
 On Wed, May 20, 2009 at 7:27 AM, Dimitry Andric <dimitry@andric.com> wrote:
 > On 2009-05-20 13:18, Tobias Fendin wrote:
 >> Does the child really die? I did a little test:
 >>
 >> # /etc/rc.d/sshd status
 >> sshd is not running.
 >> # nc -l 22 >/tmp/ssh_test &
 >> [1] 1733
 >> # /etc/rc.d/sshd start
 >> Starting sshd.
 >> # /etc/rc.d/sshd status
 >> sshd is running as pid 1740.
 >
 > This is because sshd binds to both IPv4 and IPv6 ports. =A0The IPv4 bind
 > fails, as you will see in syslog, while the IPv6 bind succeeds. =A0Thus
 > sshd keeps on running.
 >
 > If you start two nc's (I don't know any way to do this with one
 > instance), e.g.:
 >
 > nc -4 -l 22 > /tmp/ssh_test4 &
 > nc -6 -l 22 > /tmp/ssh_test6 &
 >
 > and then try starting sshd, you should see it quit.
 >
 
 It's not an IPv4 versus IPv6 problem.  How I tested this, as I had
 this problem in the past (which was a non-standard setup, but still a
 problem):
 
 sshd was listening on :25, both IPv4 and IPv6
 sendmail was listening on :25 (because I had forgotten to disable it)
 
 The system boots, and sendmail starts before sshd.  When sshd starts
 (or tries to) there is no console output that it had failed.  The only
 way you realize it is not running, is when you cannot remotely log in.
 
 --=20
 Glen Barber

From: Glen Barber <glen.j.barber@gmail.com>
To: Dimitry Andric <dimitry@andric.com>
Cc: hackers@freebsd.org, bug-followup@freebsd.org
Subject: Re: bin/134694: gives false-positive when unable to obtain socket 
	[WAS: sshd(8) - alert user when fails to execute from rc.d]
Date: Wed, 20 May 2009 13:39:28 -0400

 Hi, Dimitry
 
 On Wed, May 20, 2009 at 10:46 AM, Dimitry Andric <dimitry@andric.com> wrote=
 :
 > On 2009-05-20 16:40, Glen Barber wrote:
 >> sshd was listening on :25, both IPv4 and IPv6
 >> sendmail was listening on :25 (because I had forgotten to disable it)
 >>
 >> The system boots, and sendmail starts before sshd. =A0When sshd starts
 >> (or tries to) there is no console output that it had failed. =A0The only
 >> way you realize it is not running, is when you cannot remotely log in.
 >
 > Yes, this is unfortunate, but normal, as I explained in an earlier post.
 >
 > The sshd process does not return any error (and thus the /etc/rc.d
 > script doesn't either), because it has no way to know that its forked
 > copy died.
 >
 > The solution to this PR is "don't run stuff on conflicting ports". :)
 >
 
 I absolutely agree about not running sshd on conflicting ports.  After
 a bit more testing, I found that "most" other services will complain
 when they cannot obtain the requested socket, and you will see a
 failure notice via the rc.d script.
 
 My concern is when someone has a "definite need" to run sshd on a
 non-standard port less than, say 1024 for example.  This is the real
 reason I initially created the PR and posted to hackers@ about this --
 I'd like to fix it.  But, I want to fix it the right way, and not hack
 a crude solution.
 
 Regards,
 
 --=20
 Glen Barber

From: Glen Barber <glen.j.barber@gmail.com>
To: freebsd-gnats-submit@freebsd.org, bug-followup@freebsd.org
Cc:  
Subject: Re: misc/134694: sshd(8) gives false-positive when unable to obtain 
	socket
Date: Sun, 31 May 2009 06:27:41 -0400

 This PR can be closed.
 
 -- 
 Glen Barber

From: Glen Barber <glen.j.barber@gmail.com>
To: freebsd-gnats-submit@freebsd.org, bug-followup@freebsd.org
Cc:  
Subject: Re: misc/134694: sshd(8) gives false-positive when unable to obtain 
	socket
Date: Sun, 31 May 2009 06:27:41 -0400

 This PR can be closed.
 
 -- 
 Glen Barber
State-Changed-From-To: open->closed  
State-Changed-By: brucec 
State-Changed-When: Sun May 31 11:43:48 UTC 2009 
State-Changed-Why:  
Closed at submitter's request 

http://www.freebsd.org/cgi/query-pr.cgi?pr=134694 
>Unformatted:
