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