Bug 20042 - "rsh -t" doesn't timeout if rcmd(3) never returns [patch included]
Summary: "rsh -t" doesn't timeout if rcmd(3) never returns [patch included]
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 4.0-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: iedowse
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2000-07-19 19:40 UTC by Keith White
Modified: 2002-08-26 20:51 UTC (History)
0 users

See Also:


Attachments
file.diff (1.01 KB, patch)
2000-07-19 19:40 UTC, Keith White
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Keith White 2000-07-19 19:40:01 UTC
The documentation for rsh(1) leads you to believe that you can use
the "-t" flag to timeout if nothing happens for the specified
number of seconds.  This doesn't always work.

The rcmd(3) call will never return if the target machine is in a hung
state.  The rsh commmand will wait forever, even with the "-t" flag.

Fix: The following patch fixes the problem.  You'll need to add
considerable salt and pepper to taste...

$ ident /usr/src/usr.bin/rsh/rsh.c
/usr/src/usr.bin/rsh/rsh.c:
     $FreeBSD: src/usr.bin/rsh/rsh.c,v 1.21 2000/02/24 21:06:19 markm Exp $

---cut here---
How-To-Repeat: 
Place a machine (server, say) in a hung state.  On another machine
(client, say) execute an rsh -t.  Notice that the rsh never times out.

        client$ rsh -t 60 server
        wait...
Comment 1 iedowse freebsd_committer freebsd_triage 2002-08-10 00:44:37 UTC
State Changed
From-To: open->feedback


It isn't safe to call errx() from a signal handler - would you 
like to suggest a better patch that uses only functions that are 
documented in sigaction(2) as being safe to call? You can also 
remove the #ifdef's from around the new code.
Comment 2 Keith White 2002-08-13 16:53:53 UTC
On Fri, 9 Aug 2002, Ian Dowse wrote:

> Synopsis: "rsh -t" doesn't timeout if rcmd(3) never returns [patch included]
>
> State-Changed-From-To: open->feedback
> State-Changed-By: iedowse
> State-Changed-When: Fri Aug 9 16:44:37 PDT 2002
> State-Changed-Why:
>
> It isn't safe to call errx() from a signal handler - would you
> like to suggest a better patch that uses only functions that are
> documented in sigaction(2) as being safe to call? You can also
> remove the #ifdef's from around the new code.
>
> http://www.freebsd.org/cgi/query-pr.cgi?pr=20042

My initial bug report didn't include an easy way to demonstrate the
problem.  This will.

server# kill -STOP `cat /var/run/inetd.pid`

client$ rsh -t 5 server who
        ...wait, rsh doesn't return after 5 seconds...

after patching rsh
client$ rsh -t 5 server who
        timeout reached before connection completed.

server# kill -CONT `cat /var/run/inetd.pid`

The following patch should fulfill the criteria:

---cut here---
--- rsh.c.orig	Sun Mar  4 04:01:45 2001
+++ rsh.c	Tue Aug 13 09:57:06 2002
@@ -89,6 +89,7 @@

 char   *copyargs __P((char **));
 void	sendsig __P((int));
+void	connect_timeout __P((int));
 void	talk __P((int, long, pid_t, int, int));
 void	usage __P((void));

@@ -283,8 +284,22 @@
 			      &rfd2, family);
 	}
 #else
+
+/*
+ * it is possible that the rcmd() will never return -- perhaps because the
+ * remote machine is hung -- so add an alarm just in case
+ */
+
+	if (timeout) {
+		signal(SIGALRM, connect_timeout);
+		alarm(timeout);
+	}
 	rem = rcmd_af(&host, sp->s_port, pw->pw_name, user, args, &rfd2,
 		      family);
+	if (timeout) {
+		signal(SIGALRM, SIG_DFL);
+		alarm(0);
+	}
 #endif

 	if (rem < 0)
@@ -446,6 +461,19 @@
 				(void)write(1, buf, cc);
 		}
 	} while (FD_ISSET(rfd2, &readfrom) || FD_ISSET(rem, &readfrom));
+}
+
+void
+connect_timeout(sig)
+	int sig;
+{
+	char message[] = "timeout reached before connection completed.\n";
+/*
+ * why not use errx()? -- we're in a signal handler so must restrict ourselves
+ * to those functions listed in sigaction(2)
+ */
+	write(STDERR_FILENO, message, sizeof(message)-1);
+	_exit(1);
 }

 void
---cut here---

...keith
-- 
Keith White, EITI/SITE, University of Ottawa
kwhite@site.uottawa.ca [+1 613 562 5800 x6681] FAX [+1 613 562 5664]
Comment 3 iedowse freebsd_committer freebsd_triage 2002-08-13 17:28:57 UTC
State Changed
From-To: feedback->patched


Committed (with minor adjustments) to -current, awaiting MFC. Thanks! 


Comment 4 iedowse freebsd_committer freebsd_triage 2002-08-13 17:28:57 UTC
Responsible Changed
From-To: freebsd-bugs->iedowse


My MFC reminder.
Comment 5 iedowse freebsd_committer freebsd_triage 2002-08-26 20:51:27 UTC
State Changed
From-To: patched->closed


Now fixed in -STABLE too.