SOURCES: rwho-debian-0.17-8.diff (NEW) - gcc4 and security patch

areq areq at pld-linux.org
Fri Jun 17 23:37:00 CEST 2005


Author: areq                         Date: Fri Jun 17 21:37:00 2005 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- gcc4 and security patch

---- Files affected:
SOURCES:
   rwho-debian-0.17-8.diff (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/rwho-debian-0.17-8.diff
diff -u /dev/null SOURCES/rwho-debian-0.17-8.diff:1.1
--- /dev/null	Fri Jun 17 23:37:00 2005
+++ SOURCES/rwho-debian-0.17-8.diff	Fri Jun 17 23:36:55 2005
@@ -0,0 +1,878 @@
+--- netkit-rwho-0.17.orig/rwho/Makefile
++++ netkit-rwho-0.17/rwho/Makefile
+@@ -3,8 +3,6 @@
+ include ../MCONFIG
+ include ../MRULES
+ 
+-CFLAGS += -I../include
+-
+ rwho: rwho.o
+ 	$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
+ 
+--- netkit-rwho-0.17.orig/ruptime/ruptime.c
++++ netkit-rwho-0.17/ruptime/ruptime.c
+@@ -212,7 +212,7 @@
+ 	static char resbuf[32];
+ 	int days, hours, minutes;
+ 
+-	if (tval < 0 || tval > 999*24*60*60) {
++	if (tval < 0) {
+ 		(void)snprintf(resbuf, sizeof(resbuf), "%s     ??:??", updown);
+ 		return(resbuf);
+ 	}
+@@ -220,10 +220,10 @@
+ 	hours = minutes / 60; minutes %= 60;
+ 	days = hours / 24; hours %= 24;
+ 	if (days)
+-		(void)snprintf(resbuf, sizeof(resbuf), "%s %3d+%02d:%02d",
++		(void)snprintf(resbuf, sizeof(resbuf), "%s %4d+%02d:%02d",
+ 		    updown, days, hours, minutes);
+ 	else
+-		(void)snprintf(resbuf, sizeof(resbuf), "%s     %2d:%02d",
++		(void)snprintf(resbuf, sizeof(resbuf), "%s      %2d:%02d",
+ 		    updown, hours, minutes);
+ 	return(resbuf);
+ }
+--- netkit-rwho-0.17.orig/rwhod/Makefile
++++ netkit-rwho-0.17/rwhod/Makefile
+@@ -3,8 +3,11 @@
+ include ../MCONFIG
+ include ../MRULES
+ 
+-CFLAGS += -I../include
+-OBJS = rwhod.o daemon.o
++ifneq ($(USE_GLIBC),1)
++CFLAGS += -D_GNU_SOURCE
++endif
++
++OBJS = rwhod.o
+ 
+ rwhod: $(OBJS)
+ 	$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
+--- netkit-rwho-0.17.orig/rwhod/rwhod.8
++++ netkit-rwho-0.17/rwhod/rwhod.8
+@@ -32,7 +32,10 @@
+ .\"     from: @(#)rwhod.8	6.5 (Berkeley) 3/16/91
+ .\"	$Id$
+ .\"
+-.Dd May 13, 1997
++.\" Modified by Philippe Troin <phil at fifi.org>: added interface
++.\" options and forwarding.
++
++.Dd March 10, 1999
+ .Dt RWHOD 8
+ .Os "Linux NetKit (0.17)"
+ .Sh NAME
+@@ -40,7 +43,8 @@
+ .Nd system status server
+ .Sh SYNOPSIS
+ .Nm rwhod
+-.Op Fl bpa
++.Op Fl bpaf
++.Op -i <if>...
+ .Op Fl u Ar user
+ .Sh DESCRIPTION
+ .Nm Rwhod
+@@ -67,22 +71,6 @@
+ in the ``rwho'' service specification; see 
+ .Xr services 5 . 
+ .Pp
+-If the
+-.Fl b
+-flag is supplied, only broadcast interfaces, such as ethernets, will
+-be used.  
+-If the
+-.Fl p
+-flag is supplied, only point-to-point interfaces will be used. If the
+-.Fl a
+-flag is supplied, or no flags are supplied, all interfaces will be
+-used.
+-.Pp
+-If the
+-.Fl u
+-flag is supplied, rwhod will run as the specified user instead of as
+-root.
+-.Pp
+ The messages sent and received, are of the form:
+ .Bd -literal -offset indent
+ struct	outmp {
+@@ -145,16 +133,78 @@
+ .Nm Rwhod
+ recomputes the system boot time every 30 minutes because on
+ some (non-Linux) systems it is not a totally reliable process.
++.Sh FLAGS
++If the
++.Fl b
++flag is supplied, only broadcast interfaces, such as ethernets, will
++be used.  
++If the
++.Fl p
++flag is supplied, only point-to-point interfaces will be used. If the
++.Fl a
++flag is supplied, or no flags are supplied, all interfaces will be
++used.
++.Pp
++Alternately, you may specify interfaces by name by providing one or
++more
++.Fl i
++options followed by the interface name.
++.Pp
++If the
++.Fl u
++flag is supplied, rwhod will run as the specified user instead of as
++root.
++.Pp
++.Nm Rwhod
++can also forward packets between interfaces if started with
++.Fl f.
++Please read the
++.Xr CAVEATS
++section before enabling
++.Xr rwhod
++forwarding.
++.Sh CAVEATS
++While 
++.Xr rwhod
++listens on any interface present on the host, it will only send (or
++forward) to the interfaces determined by the 
++.Fl a b p i
++flags.
++.Pp
++When operating in forwarding mode (with
++.Fl f
++), 
++.Xr rwhod
++forwards all correct rwhod packets received on an interface to all the
++other interfaces. You can create a broadcast storm if there is a
++loop in your network and all the routers in the loop run in forwarding
++mode. To prevent this from happenning,
++.Xr rwhod
++will shut down forwarding (and log the event to the syslog) if more
++than one 
++.Xr rwhod
++packet is forwarded per second on average over the last three
++minutes. If this happens, you must break the loop of forwarding routers.
+ .Sh SEE ALSO
+ .Xr rwho 1 ,
+ .Xr ruptime 1
+ .Sh BUGS
+-There should be a way to relay status information between networks. 
++Some kind of proxying feature might be useful if your router doesn't
++run
++.Xr rwhod.
++.Pp
+ People often interpret the server dying
+-or network communtication failures
++or network communication failures
+ as a machine going down.
++.Pp
++.Xr Rwhod
++doesn't refresh its interface list, which might be useful when using
++.Fl a b p.
+ .Sh HISTORY
+ The
+ .Nm
+ command appeared in
+ .Bx 4.2 .
++.Pp
++Philippe Troin <phil at fifi.org> implemented forwarding and interface
++selection flags.
+--- netkit-rwho-0.17.orig/rwhod/rwhod.c
++++ netkit-rwho-0.17/rwhod/rwhod.c
+@@ -29,6 +29,10 @@
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
++
++ * Modified by Philippe Troin <phil at fifi.org> (added options & implemented 
++ * them.
++
+  */
+ 
+ char copyright[] =
+@@ -47,6 +51,7 @@
+ #include <signal.h>
+ #include <sys/ioctl.h>
+ #include <sys/file.h>
++#include <sys/types.h>
+ 
+ #include <net/if.h>
+ #include <netinet/in.h>
+@@ -69,11 +74,13 @@
+ #include <arpa/inet.h>
+ #include <pwd.h>
+ #include <grp.h>
+-
+-#include "daemon.h"
++#include <time.h>
++#include <stdint.h>
+ 
+ #include "../version.h"
+ 
++typedef struct sockaddr_in SA;
++
+ #define ENDIAN	LITTLE_ENDIAN
+ 
+ /*
+@@ -95,7 +102,16 @@
+ static void	broadcaster(void);
+ static int	configure(int s);
+ static int	verify(const char *name);
++#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2)
+ static int	getloadavg(double ptr[3], int n);
++#endif
++
++/* This is the list of interface we want to listen on */
++struct wanted_neigh {
++	struct wanted_neigh *w_next;
++  	char                *w_ifname;
++  	enum { W_USED_NOT, W_USED_ONCE, W_USED_MULTI } w_used;
++};
+ 
+ /*
+  * We communicate with each neighbor in
+@@ -103,21 +119,30 @@
+  * started up.  Neighbors are currently
+  * directly connected via a hardware interface.
+  */
+-struct	neighbor {
++struct neighbor {
+ 	struct	neighbor *n_next;
+ 	char	*n_name;		/* interface name */
+-	char	*n_addr;		/* who to send to */
++	SA	*n_myaddr;              /* My address on this i/f */
++  	SA	*n_mask;                /* Netmask on this i/f */
++	SA	*n_dstaddr;		/* who to send to */
+ 	int	n_addrlen;		/* size of address */
+ 	int	n_flags;		/* should forward?, interface flags */
+ };
+ 
++static struct wanted_neigh *wanted_neigh;
+ static struct neighbor *neighbors;
+ static struct servent *sp;
+ static int sk;
+-static int use_pointopoint = 0;
+-static int use_broadcast = 0;
++static int use_pointopoint;
++static int use_broadcast;
+ static int need_init = 1;
+-static int child_pid = 0;
++static int child_pid;
++static int use_forwarding;
++static int forwarded_packets;
++
++/* Max number of packets to forward between each alarm() tick.
++   If this number is exceeded, then the forwarding is switched off. */
++#define MAX_FWD_PACKETS (AL_INTERVAL)
+ 
+ #define WHDRSIZE	(((caddr_t) &((struct whod *) 0)->wd_we) \
+ 			- ((caddr_t) 0))
+@@ -126,24 +151,48 @@
+ static void termhandler(int);
+ static void sendpacket(struct whod *);
+ static void getboottime(struct whod *);
++static void forward(const SA *, const struct whod *, int cc);
++static void usage(void);
+ 
+ int
+ main(int argc, char *argv[])
+ {
++  	struct wanted_neigh *wn;
++	int wn_dup;
+ 	struct sockaddr_in from;
+-	struct passwd *pw = 0;
++	struct passwd *pw;
+ 	struct stat st;
+ 	char path[64];
+-	char *user = NULL;
++	char *user = "rwhod";
+ 	int on = 1;
+ 	int opt;
++	time_t before;
+ 
+ 	if (getuid()) {
+ 		fprintf(stderr, "rwhod: not super user\n");
++	}
++	openlog("rwhod", LOG_PID, LOG_DAEMON);
++	sp = getservbyname("who", "udp");
++	if (sp == 0) {
++		fprintf(stderr, "rwhod: udp/who: unknown service\n");
++		exit(1);
++	}
++	if ((sk = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
++		syslog(LOG_ERR, "socket: %m");
++		exit(1);
++	}
++	if (setsockopt(sk, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
++		syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
++		exit(1);
++	}
++	sine.sin_family = AF_INET;
++	sine.sin_port = sp->s_port;
++	if (bind(sk, (struct sockaddr *)&sine, sizeof(sine)) < 0) {
++		syslog(LOG_ERR, "bind: %m");
+ 		exit(1);
+ 	}
+ 
+-	while ((opt = getopt(argc, argv, "bpau:")) != EOF) {
++	while ((opt = getopt(argc, argv, "bpai:fu:")) != EOF) {
+ 	    switch (opt) {
+ 	      case 'b':
+ 		  use_broadcast = 1;
+@@ -155,31 +204,60 @@
+ 		  use_broadcast = 1;
+ 		  use_pointopoint = 1;
+ 		  break;
++	      case 'f':
++		  use_forwarding = 1;
++		  break;
++	      case 'i':
++		  wn_dup = 0;
++		  for (wn = wanted_neigh; wn; wn = wn->w_next) {
++			if (strcmp(wn->w_ifname, optarg)== 0) {
++				wn_dup = 1;
++				break;
++			}
++		  }
++		  if (wn_dup) {
++			fprintf(stderr, "rwhod: warning: "
++				"duplicate interface %s in arguments\n",
++				optarg);
++		  } else {
++			wn = malloc(sizeof(struct wanted_neigh));
++			if (wn == NULL) {
++				fprintf(stderr, "rwhod: out of memory\n");
++				exit(2);
++			}
++			wn->w_next = wanted_neigh;
++			wn->w_ifname = malloc(strlen(optarg)+1);
++			wn->w_used = W_USED_NOT;
++			if (wn->w_ifname == NULL) {
++				fprintf(stderr, "rwhod: out of memory\n");
++				exit(2);
++			}
++			strcpy(wn->w_ifname, optarg);
++			wanted_neigh = wn;
++		  }
++		  break;
+ 	      case 'u':
+ 	      	  user = optarg;
+ 		  break;
+ 	      case '?':
+ 	      default:
+-		  fprintf(stderr, "usage: rwhod [-bpa] [-u user]\n");
+-		  exit(1);
+-		  break;
++		  usage();
+ 	    }
+ 	}
+ 	if (optind<argc) {
+-	    fprintf(stderr, "usage: rwhod [-bpa] [-u user]\n");
+-	    exit(1);
++		usage();
+ 	}
+-	if (!use_pointopoint && !use_broadcast) {
++	if (!use_pointopoint && !use_broadcast && !wanted_neigh) {
+ 		/* use none is nonsensical; default to all */
+ 		use_pointopoint = 1;
+ 		use_broadcast = 1;
+ 	}
+-	
+-	sp = getservbyname("who", "udp");
+-	if (sp == 0) {
+-		fprintf(stderr, "rwhod: udp/who: unknown service\n");
++	if ((use_pointopoint || use_broadcast) && wanted_neigh) {
++		fprintf(stderr, "rwhod: cannot specify both -i and one of -b "
++			"-p -a\n");
+ 		exit(1);
+ 	}
++
+ #ifndef DEBUG
+ 	daemon(1, 0);
+ #endif
+@@ -189,53 +267,20 @@
+ 		exit(1);
+ 	}
+ 	(void) signal(SIGHUP, huphandler);
+-	openlog("rwhod", LOG_PID, LOG_DAEMON);
+-
+-	if ((sk = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+-		syslog(LOG_ERR, "socket: %m");
+-		exit(1);
+-	}
+-	if (setsockopt(sk, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
+-		syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
+-		exit(1);
+-	}
+-	sine.sin_family = AF_INET;
+-	sine.sin_port = sp->s_port;
+-	if (bind(sk, (struct sockaddr *)&sine, sizeof(sine)) < 0) {
+-		syslog(LOG_ERR, "bind: %m");
+-		exit(1);
+-	}
+ 
+ 	(void) umask(022);
+ 
+ 	signal(SIGTERM, termhandler);
+-	child_pid = fork();
+-	if (child_pid < 0) {
+-		syslog(LOG_ERR, "fork: %m");
+-		exit(1);
+-	}
+-	if (child_pid == 0) {
+-		broadcaster();
+-		exit(0);
+-	}
+ 
+ 	/* We have to drop privs in two steps--first get the
+ 	 * account info, then drop privs after chroot */
+-	if (user && (pw = getpwnam(user)) == NULL) {
++	if ((pw = getpwnam(user)) == NULL) {
+ 		syslog(LOG_ERR, "unknown user: %s", user);
+ 		exit(1);
+ 	}
+ 
+-	/* Chroot to the spool directory
+-	 * (note this is already our $cwd) */
+-	if (chroot(_PATH_RWHODIR) < 0) {
+-		syslog(LOG_ERR, "chroot(%s): %m", _PATH_RWHODIR);
+-		kill(child_pid, SIGTERM);
+-		exit(1);
+-	}
+-
+ 	/* Now drop privs */
+-	if (pw) {
++	if (pw->pw_uid) {
+ 		if (setgroups(1, &pw->pw_gid) < 0
+ 		 || setgid(pw->pw_gid) < 0
+ 		 || setuid(pw->pw_uid) < 0) {
+@@ -244,10 +289,28 @@
+ 		}
+ 	}
+ 
++	if (!configure(sk))
++		exit(1);
++
++	child_pid = fork();
++	if (child_pid < 0) {
++		syslog(LOG_ERR, "fork: %m");
++		exit(1);
++	}
++	if (child_pid == 0) {
++		broadcaster();
++		exit(0);
++	}
++
++	before = 0;
+ 	for (;;) {
+ 		struct whod wd;
+ 		int cc, whod;
++#ifdef __GLIBC__
++		socklen_t len = sizeof(from);
++#else
+ 		size_t len = sizeof(from);
++#endif
+ 
+ 		memset(&wd, 0, sizeof(wd));
+ 		cc = recvfrom(sk, (char *)&wd, sizeof(struct whod), 0,
+@@ -257,6 +320,8 @@
+ 				syslog(LOG_WARNING, "recv: %m");
+ 			continue;
+ 		}
++		if (cc < WHDRSIZE)
++			continue;
+ 		if (from.sin_port != sp->s_port) {
+ 			syslog(LOG_WARNING, "%d: bad from port",
+ 				ntohs(from.sin_port));
+@@ -266,14 +331,24 @@
+ 			continue;
+ 		if (wd.wd_type != WHODTYPE_STATUS)
+ 			continue;
++
++		if (use_forwarding) {
++			time_t now = time(NULL);
++			if ((uintmax_t) (now - before) >= AL_INTERVAL) {
++				before = now;
++				forwarded_packets = 0;
++			}
++			forward(&from, &wd, cc);
++		}
++
+ 		/* 
+ 		 * Ensure null termination of the name within the packet.
+ 		 * Otherwise we might overflow or read past the end.
+ 		 */
+ 		wd.wd_hostname[sizeof(wd.wd_hostname)-1] = 0;
+ 		if (!verify(wd.wd_hostname)) {
+-			syslog(LOG_WARNING, "malformed host name from %x",
+-				from.sin_addr);
++			syslog(LOG_WARNING, "malformed host name from %s",
++				inet_ntoa(from.sin_addr));
+ 			continue;
+ 		}
+ 		snprintf(path, sizeof(path), "whod.%s", wd.wd_hostname);
+@@ -306,7 +381,7 @@
+ 		}
+ #endif
+ 		wd.wd_recvtime = time(NULL);
+-		write(whod, (char *)&wd, cc);
++		write(whod, &wd, cc);
+ 		if (fstat(whod, &st) < 0 || st.st_size > cc)
+ 			ftruncate(whod, cc);
+ 		(void) close(whod);
+@@ -345,9 +420,6 @@
+ 	size_t		mynamelen;
+ 	struct whod	mywd;
+ 
+-	if (!configure(sk))
+-		exit(1);
+-
+ 	/*
+ 	 * Establish host name as returned by system.
+ 	 */
+@@ -357,7 +429,7 @@
+ 	}
+ 	if ((cp = index(myname, '.')) != NULL)
+ 		*cp = '\0';
+-	mynamelen = strlen(myname);
++	mynamelen = strlen(myname) + 1;
+ 	if (mynamelen > sizeof(mywd.wd_hostname)) 
+ 		mynamelen = sizeof(mywd.wd_hostname);
+ 	strncpy(mywd.wd_hostname, myname, mynamelen);
+@@ -448,7 +520,9 @@
+ 	}
+ 	we = wd->wd_we;
+ 	for (i = 0; i < nutmps; i++) {
+-		if (stat(we->we_utmp.out_line, &stb) >= 0)
++		const char *p = we->we_utmp.out_line;
++
++		if (!strchr(p, ':') && stat(p, &stb) >= 0)
+ 			we->we_idle = htonl(now - stb.st_atime);
+ 		we++;
+ 	}
+@@ -460,10 +534,10 @@
+ 	wd->wd_vers = WHODVERSION;
+ 	wd->wd_type = WHODTYPE_STATUS;
+ 	for (np = neighbors; np != NULL; np = np->n_next) {
+-		if (sendto(sk, (char *)wd, cc, 0,
+-			   (struct sockaddr *) np->n_addr, np->n_addrlen) < 0) 
++		if (sendto(sk, wd, cc, 0,
++			   (struct sockaddr *) np->n_dstaddr, np->n_addrlen) < 0) 
+ 		  syslog(LOG_ERR, "sendto(%s): %m",
+-			 inet_ntoa(((struct sockaddr_in *)np->n_addr)->sin_addr));
++			 inet_ntoa(np->n_dstaddr->sin_addr));
+ 	}
+ 
+ 	if (nutmps && chdir(_PATH_RWHODIR)) {
+@@ -472,6 +546,7 @@
+ 	}
+ }
+ 
++#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2)
+ /*
+  * Taken from:
+  *
+@@ -518,6 +593,7 @@
+ 	fclose(fp);
+ 	return 0;
+ }
++#endif	/* __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) */
+ 
+ 
+ void
+@@ -566,7 +642,7 @@
+ 		exit(1);
+ 	}
+ 	(void) lseek(kmemf, (long)nl[NL_BOOTTIME].n_value, L_SET);
+-	(void) read(kmemf, (char *)&wd->wd_boottime,
++	(void) read(kmemf, &wd->wd_boottime,
+ 	    sizeof (wd->wd_boottime));
+ 	wd->wd_boottime = htonl(wd->wd_boottime);
+ #endif
<<Diff was trimmed, longer than 597 lines>>



More information about the pld-cvs-commit mailing list