- pull up latest revision of patch to reduce lockups in rsh/rshd

This commit is contained in:
Nalin Dahyabhai 2006-07-25 15:52:36 +00:00
parent ece8aeb4c7
commit 30f6a9b1cb
2 changed files with 257 additions and 3 deletions

251
krb5-1.5-io.patch Normal file
View File

@ -0,0 +1,251 @@
We can get stuck if a write is going to block because both ends are writing and
neither end is reading. This is a port of a patch which aims to solve that
problem, but for now it's incomplete because we don't handle partial writes. A
proper non-blocking implementation would require a bit more work.
diff -ur krb5-1.5/src/appl/bsd/defines.h krb5-1.5/src/appl/bsd/defines.h
--- krb5-1.5/src/appl/bsd/defines.h 2003-01-01 05:13:20.000000000 -0500
+++ krb5-1.5/src/appl/bsd/defines.h 2006-07-21 15:11:44.000000000 -0400
@@ -34,6 +34,7 @@
enum kcmd_proto *protonum /* input and output */
);
+extern int rcmd_stream_has_unsent_data (void);
extern int rcmd_stream_read (int fd, char *buf, size_t len, int secondary);
extern int rcmd_stream_write (int fd, char *buf, size_t len, int secondary);
extern int getport (int * /* portnum */, int * /* addrfamily */);
diff -ur krb5-1.5/src/appl/bsd/kcmd.c krb5-1.5/src/appl/bsd/kcmd.c
--- krb5-1.5/src/appl/bsd/kcmd.c 2004-10-01 18:08:14.000000000 -0400
+++ krb5-1.5/src/appl/bsd/kcmd.c 2006-07-21 15:11:44.000000000 -0400
@@ -839,6 +839,11 @@
output = twrite;
}
+int rcmd_stream_has_unsent_data (void)
+{
+ return (nstored > 0);
+}
+
void rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck, am_client,
protonum)
krb5_keyblock *in_keyblock;
@@ -1019,7 +1024,8 @@
cc = krb5_net_read(bsd_context, fd, &c, 1);
/* we should check for non-blocking here, but we'd have
to make it save partial reads as well. */
- if (cc <= 0) return cc; /* read error */
+ if (cc == 0) return nreturned; /* EOF */
+ if (cc < 0) return cc; /* read error */
if (cc == 1) {
if (c == 0 || !do_lencheck) break;
}
diff -ur krb5-1.5/src/appl/bsd/krsh.c krb5-1.5/src/appl/bsd/krsh.c
--- krb5-1.5/src/appl/bsd/krsh.c 2006-07-21 16:05:57.000000000 -0400
+++ krb5-1.5/src/appl/bsd/krsh.c 2006-07-21 15:19:05.000000000 -0400
@@ -128,10 +128,11 @@
char **argv0;
{
int rem, pid = 0;
- char *host=0, *cp, **ap, buf[RCMD_BUFSIZ], *args, **argv = argv0, *user = 0;
+ char *host=0, *cp, **ap, buf[PIPE_BUF], *args, **argv = argv0, *user = 0;
register int cc;
struct passwd *pwd;
fd_set readfrom, ready;
+ fd_set writeto, ready_wr;
int one = 1;
struct servent *sp;
struct servent defaultservent;
@@ -548,9 +549,14 @@
FD_ZERO(&readfrom);
FD_SET(rfd2, &readfrom);
FD_SET(rem, &readfrom);
+ FD_ZERO(&writeto);
do {
+ int max_fd;
+ max_fd = (rfd2 > rem) ? rfd2 : rem;
+ max_fd = (max_fd > 2) ? max_fd : 2;
ready = readfrom;
- if (select(((rfd2 > rem) ? rfd2 : rem) + 1, &ready, 0, 0, 0) < 0) {
+ ready_wr = writeto;
+ if (select(max_fd + 1, &ready, &ready_wr, 0, 0) < 0) {
if (errno != EINTR) {
perror("select");
exit(1);
@@ -558,22 +564,38 @@
continue;
}
if (FD_ISSET(rfd2, &ready)) {
- errno = 0;
- cc = rcmd_stream_read(rfd2, buf, sizeof buf, 1);
- if (cc <= 0) {
- if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
- FD_CLR(rfd2, &readfrom);
- } else
- (void) write(2, buf, (unsigned) cc);
+ FD_SET(2, &writeto);
+ }
+ if (FD_ISSET(2, &ready_wr)) {
+ do {
+ errno = 0;
+ cc = rcmd_stream_read(rfd2, buf, sizeof buf, 1);
+ if (cc <= 0) {
+ if ((errno != EWOULDBLOCK) && (errno != EAGAIN)) {
+ FD_CLR(rfd2, &readfrom);
+ break;
+ }
+ } else
+ (void) write(2, buf, (unsigned) cc);
+ } while (rcmd_stream_has_unsent_data());
+ FD_CLR(2, &writeto);
}
if (FD_ISSET(rem, &ready)) {
- errno = 0;
- cc = rcmd_stream_read(rem, buf, sizeof buf, 0);
- if (cc <= 0) {
- if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
- FD_CLR(rem, &readfrom);
- } else
- (void) write(1, buf, (unsigned) cc);
+ FD_SET(1, &writeto);
+ }
+ if (FD_ISSET(1, &ready_wr)) {
+ do {
+ errno = 0;
+ cc = rcmd_stream_read(rem, buf, sizeof buf, 0);
+ if (cc <= 0) {
+ if ((errno != EWOULDBLOCK) && (errno != EAGAIN)) {
+ FD_CLR(rem, &readfrom);
+ break;
+ }
+ } else
+ (void) write(1, buf, (unsigned) cc);
+ } while (rcmd_stream_has_unsent_data());
+ FD_CLR(1, &writeto);
}
} while (FD_ISSET(rem, &readfrom) || FD_ISSET(rfd2, &readfrom));
if (nflag == 0)
diff -ur krb5-1.5/src/appl/bsd/krshd.c krb5-1.5/src/appl/bsd/krshd.c
--- krb5-1.5/src/appl/bsd/krshd.c 2006-06-20 00:06:52.000000000 -0400
+++ krb5-1.5/src/appl/bsd/krshd.c 2006-07-21 16:02:12.000000000 -0400
@@ -633,7 +633,8 @@
short port;
int pv[2], pw[2], px[2], cc;
fd_set ready, readfrom;
- char buf[RCMD_BUFSIZ], sig;
+ fd_set ready_wr, writeto;
+ char buf[PIPE_BUF], sig;
struct sockaddr_storage localaddr;
#ifdef POSIX_SIGNALS
struct sigaction sa;
@@ -1261,6 +1262,10 @@
if (pw[0] > maxfd)
maxfd = pw[0];
+ if (px[1] > maxfd)
+ maxfd = px[1];
+ FD_ZERO(&writeto);
+
/* read from f, write to px[1] -- child stdin */
/* read from s, signal child */
/* read from pv[0], write to s -- child stderr */
@@ -1268,36 +1273,47 @@
do {
ready = readfrom;
- if (select(maxfd + 1, &ready, (fd_set *)0,
+ ready_wr = writeto;
+ if (select(maxfd + 1, &ready, &ready_wr,
(fd_set *)0, (struct timeval *)0) < 0) {
if (errno == EINTR) {
continue;
} else {
break;
- }
+ }
}
if (port&&FD_ISSET(pv[0], &ready)) {
+ FD_SET(s, &writeto);
+ FD_CLR(pv[0], &readfrom);
+ }
+ if (port&&FD_ISSET(s, &ready_wr)) {
/* read from the child stderr, write to the net */
errno = 0;
cc = read(pv[0], buf, sizeof (buf));
- if (cc <= 0) {
+ if ((cc <= 0) ||
+ (rcmd_stream_write(s, buf, (unsigned) cc, 1) != cc)) {
shutdown(s, 1+1);
- FD_CLR(pv[0], &readfrom);
} else {
- (void) rcmd_stream_write(s, buf, (unsigned) cc, 1);
+ FD_SET(pv[0], &readfrom);
}
+ FD_CLR(s, &writeto);
}
if (FD_ISSET(pw[0], &ready)) {
+ FD_SET(f, &writeto);
+ FD_CLR(pw[0], &readfrom);
+ }
+ if (FD_ISSET(f, &ready_wr)) {
/* read from the child stdout, write to the net */
errno = 0;
cc = read(pw[0], buf, sizeof (buf));
- if (cc <= 0) {
+ if ((cc <= 0) ||
+ (rcmd_stream_write(f, buf, (unsigned) cc, 0) != cc)) {
shutdown(f, 1+1);
- FD_CLR(pw[0], &readfrom);
} else {
- (void) rcmd_stream_write(f, buf, (unsigned) cc, 0);
+ FD_SET(pw[0], &readfrom);
}
+ FD_CLR(f, &writeto);
}
if (port&&FD_ISSET(s, &ready)) {
/* read from the alternate channel, signal the child */
@@ -1315,12 +1331,15 @@
}
}
if (FD_ISSET(f, &ready)) {
+ FD_SET(px[1], &writeto);
+ FD_CLR(f, &readfrom);
+ }
+ if (FD_ISSET(px[1], &ready_wr)) {
/* read from the net, write to child stdin */
errno = 0;
cc = rcmd_stream_read(f, buf, sizeof(buf), 0);
if (cc <= 0) {
(void) close(px[1]);
- FD_CLR(f, &readfrom);
} else {
int wcc;
wcc = write(px[1], buf, (unsigned) cc);
@@ -1328,17 +1347,22 @@
/* pipe closed, don't read any more */
/* might check for EPIPE */
(void) close(px[1]);
- FD_CLR(f, &readfrom);
- } else if (wcc != cc) {
- syslog(LOG_INFO, "only wrote %d/%d to child",
- wcc, cc);
+ } else {
+ if (wcc != cc)
+ syslog(LOG_INFO, "only wrote %d/%d to child",
+ wcc, cc);
+ FD_SET(f, &readfrom);
}
}
+ FD_CLR(px[1], &writeto);
}
} while ((port&&FD_ISSET(s, &readfrom)) ||
FD_ISSET(f, &readfrom) ||
(port&&FD_ISSET(pv[0], &readfrom) )||
- FD_ISSET(pw[0], &readfrom));
+ FD_ISSET(pw[0], &readfrom) ||
+ (port&&FD_ISSET(s, &writeto)) ||
+ FD_ISSET(f, &writeto) ||
+ FD_ISSET(px[1], &writeto));
ignore_signals();
#ifdef KERBEROS
syslog(LOG_INFO ,

View File

@ -10,7 +10,7 @@
Summary: The Kerberos network authentication system.
Name: krb5
Version: 1.5
Release: 1.2
Release: 2
# Maybe we should explode from the now-available-to-everybody tarball instead?
# http://web.mit.edu/kerberos/dist/krb5/1.5/krb5-1.5-signed.tar
Source0: krb5-%{version}.tar.gz
@ -58,7 +58,7 @@ Patch27: krb5-1.3.3-rcp-sendlarge.patch
Patch29: krb5-1.3.5-kprop-mktemp.patch
Patch30: krb5-1.3.4-send-pr-tempfile.patch
Patch32: krb5-1.4-ncurses.patch
Patch33: krb5-1.5-rsh-deadlock.patch
Patch33: krb5-1.5-io.patch
Patch35: krb5-1.5-fclose.patch
Patch36: krb5-1.3.3-rcp-markus.patch
Patch39: krb5-1.4.1-api.patch
@ -130,6 +130,9 @@ network uses Kerberos, this package should be installed on every
workstation.
%changelog
* Fri Jul 21 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-2
- pull up latest revision of patch to reduce lockups in rsh/rshd
* Mon Jul 17 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-1.2
- rebuild
@ -917,7 +920,7 @@ workstation.
%patch29 -p1 -b .kprop-mktemp
%patch30 -p1 -b .send-pr-tempfile
%patch32 -p1 -b .ncurses
%patch33 -p1 -b .rsh-deadlock
%patch33 -p1 -b .io
%patch35 -p1 -b .fclose
%patch36 -p1 -b .rcp-markus
%patch39 -p1 -b .api