Subject: Re: Bug in current sdr implementation ?

From: Bill Fenner <[email-masked]>
Date: Fri, 27 Jun 1997 14:31:08 PDT

As far as I can tell, all of the bad advertisements are coming from
ferao.jungle.bt.co.uk, both the proxy-reannouncements and the "v=0"
announcement that crashes sdr.  I see ferao.jungle.bt.co.uk
announcing the following sessions:

s=#unix
s=Brazil Test
s=CANARIE AGM - CAnet II Launch
s=FreeBSD Lounge
s=IMJ -- Channel 1
s=MPoll Test: Alpha 4 required
s=PIM
s=Places all over the world
s=UO Presents KWAX Classical Radio
s=UO Presents KWVA Campus Radio
s=USC-CS dgroup VR conference room (private)

And, of course, the truncated session that is causing sdr's to
crash all over the place.

The fix to make sdr not crash is as follows:

cvs diff: Diffing .
===================================================================
RCS file: /tilde/fenner/cvs/sdr/src/sd_listen.c,v
retrieving revision 1.1.1.8
diff -u -r1.1.1.8 sd_listen.c
--- 1.1.1.8	1996/11/12 17:25:33
+++ sd_listen.c	1997/06/27 20:53:17
@@ -790,7 +790,7 @@
 
     i = 0;
     mediactr=0;  tctr=0;  pctr=0;  ectr=0;  bctr=0;  kctr=0;
-    uctr=0; chan[0]=NULL; timemax=0;
+    uctr=0; chan[0]=NULL; chan[1]=NULL; timemax=0;
     vars[0][0]='\0';
     while (length > 0) 
       {

  Bill

---

From: Oliver Brand <[email-masked]>
Date: Sat, 28 Jun 1997 00:20:16 +0200 (MET DST)

> The fix to make sdr not crash is as follows:

The session re-announcements are exactly the same that I saw in the
last hours. Is anyone in the UK going to tell those guys at the
"jungle site" what's wrong with their installation ?

The patch is correct (as far as I can tell), but only works if the broken
advertisements have no channel identifier (c=). I've seen some announcements
with a valid c= field, but without any session identifier (s=) or
description (i=). For these cases, the following patch should be helpful:

--- /usr/home/brand/tmp/sdr-2.3a1/src/sd_listen.c	Fri Nov  1 10:59:25 1996
+++ sd_listen.c	Fri Jun 27 18:12:29 1997
@@ -789,8 +792,9 @@
     strncpy(origsrc, (char *)inet_ntoa(source), 16);
 
     i = 0;
+    session = orig = desc = NULL;
     mediactr=0;  tctr=0;  pctr=0;  ectr=0;  bctr=0;  kctr=0;
-    uctr=0; chan[0]=NULL; timemax=0;
+    uctr=0; chan[0] = chan[1] = NULL; timemax=0;
     vars[0][0]='\0';
     while (length > 0) 
       {
@@ -1100,18 +1108,22 @@
       }
     Tcl_SetVar(interp, "trust", trust, TCL_GLOBAL_ONLY);
     Tcl_SetVar(interp, "recvkey", recvkey, TCL_GLOBAL_ONLY);
-    splat_tcl_special_chars(session);
-    Tcl_SetVar(interp, "session", session, TCL_GLOBAL_ONLY);
-    splat_tcl_special_chars(desc);
-    Tcl_SetVar(interp, "desc", desc, TCL_GLOBAL_ONLY);
+    if (session != NULL)
+    {
+      splat_tcl_special_chars(session);
+      Tcl_SetVar(interp, "session", session, TCL_GLOBAL_ONLY);
+    }
+    if (desc != NULL)
+    {
+      splat_tcl_special_chars(desc);
+      Tcl_SetVar(interp, "desc", desc, TCL_GLOBAL_ONLY);
+    }
     if (chan[0]==NULL) chan[0]=chan[1];
     if (chan[0]==NULL) {
-      if (debug1==TRUE)
 	fprintf(stderr, "No channel field received!\n");
       return((unsigned long)-1);
     }
     if(strlen(chan[0])>TMPSTRLEN) {
-      if (debug1==TRUE)
 	fprintf(stderr, "Unacceptably long channel field received\n");
       chan[0][TMPSTRLEN-1]='\0';
     }
@@ -1208,14 +1220,17 @@
     Tcl_SetVar(interp, "multicast", tmpstr, TCL_GLOBAL_ONLY);
 
     /*Originator field*/
-    splat_tcl_special_chars(orig);
-    if (strlen(orig)>TMPSTRLEN) {
-      if (debug1==TRUE)
-	fprintf(stderr, "Unacceptably long originator field received\n");
-      orig[TMPSTRLEN-1]='\0';
-    };
-    sscanf(orig, "%s %s %s %s %s %s", creator, createtime, modtime, in, ip, 
-	   createaddr);
+    if (orig != NULL)
+    {
+      splat_tcl_special_chars(orig);
+      if (strlen(orig)>TMPSTRLEN) {
+        if (debug1==TRUE)
+	  fprintf(stderr, "Unacceptably long originator field received\n");
+        orig[TMPSTRLEN-1]='\0';
+      };
+      sscanf(orig, "%s %s %s %s %s %s", creator, createtime, modtime, in, ip, 
+	     createaddr);
+    }
     if (check_net_type(in,ip)<0) return (unsigned long)-1;
     Tcl_SetVar(interp, "creator", creator, TCL_GLOBAL_ONLY);
     Tcl_SetVar(interp, "modtime", modtime, TCL_GLOBAL_ONLY);

Oliver

---

From: John Hawkinson <[email-masked]>
Date: Fri, 27 Jun 1997 20:39:22 -0400 (EDT)

> description (i=). For these cases, the following patch should be helpful:

Thanks.

For those who don't have a convenient sdr build environment, you can:

	1.	Move sdr to sdr.orig

	2.	Save the following as "sdr.gdb":
---cut
set height 0
break parse_entry
run
cont
set $foo=malloc(4)
set $bar=malloc(4)
call strcpy($foo,"foo")
call strcpy($bar,"bar")
commands 1
silent
set chan[1]=0
set session=$foo
set desc=$bar
cont
end
detach
quit
---cut

	3.	Save the following as "sdr" and make it executable,
		replacing /path/to/ with the right paths:
---cut
#!/bin/sh
gdb --nx --command=/path/to/sdr.gdb /path/to/sdr.orig
---cut

And that should be sufficient until Mark releases a new version. At least,
it works under SunOS.

It doesn't do all the bounds checking Oliver's patch does, nor should it
substitute for a well-written and commented gdb script released by
sdr's maintainer.

--jhawk

ps: yes, this could have been written more easly using gdb's
if() construct, but that only appeared in gdb 4.16, which I
didn't have handy and some people might not have.

---

From: John Hawkinson <[email-masked]>
Date: Fri, 27 Jun 1997 20:49:50 -0400 (EDT)

Sigh. Take Two.

It appears the reliability of breakpoints after detaching in gdb is
somewhat weird. It seemed to work in my test program, but not for
sdr. :-(

So please use this version of sdr.gdb instead:

---cut
set height 0
break parse_entry
run
cont
set $foo=malloc(4)
set $bar=malloc(4)
call strcpy($foo,"foo")
call strcpy($bar,"bar")
commands 1
silent
set chan[1]=0
set session=$foo
set desc=$bar
cont
end
cont
quit
---cut

--jhawk