Bug 29867

Summary: 4.3 timed master can't sync Red Hat Linux 6.0 box
Product: Base System Reporter: Steve Whiteley <stevew>
Component: miscAssignee: Kris Kennaway <kris>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description Steve Whiteley 2001-08-19 09:00:08 UTC
Running timed as master, to synchronize a Red Hat Linux 6.0 box.  This
worked with FBSD3.5, after upgrading to 4.3, got console error
"short packet (xx/xx bytes) from keats"
(The real message included the byte counts.)
There appeared to be no clock sync.

Fix: 

The problem is that the sizeof(struct tsp) differs on the two systems.
Made the following change in readmsg.c near line 215, which seems to have fixed the problem.
----------------------------------------------------------------------
        length = sizeof(from);
        if ((n = recvfrom(sock, (char *)&msgin, sizeof(struct tsp), 0,
                 (struct sockaddr*)&from, &length)) < 0) {
            syslog(LOG_ERR, "recvfrom: %m");
            exit(1);
        }
/* SRW */
/* Here is a bug: the sizeof(struct tsp) is OS dependent, depending on the
 * length of the tsp_name field (MAXHOSTNAMELEN) which is, e.g., 256 for
 * FreeBSD 4.3 and 64 for RH Linux 6.0.  Keep this as a sanity check,
 * but assume that the name field is 64 or larger
 */  
        if (n < (ssize_t)sizeof(struct tsp) - MAXHOSTNAMELEN + 64) {
/*
        if (n < (ssize_t)sizeof(struct tsp)) {
*/
            syslog(LOG_NOTICE,
                "short packet (%u/%u bytes) from %s",
                  n, sizeof(struct tsp),
                  inet_ntoa(from.sin_addr));
            continue;  
        }
How-To-Repeat: boot and run
Comment 1 Kris Kennaway 2001-08-19 10:18:52 UTC
> The problem is that the sizeof(struct tsp) differs on the two systems.
> Made the following change in readmsg.c near line 215, which seems to have fixed the problem.
> ----------------------------------------------------------------------
>         length = sizeof(from);
>         if ((n = recvfrom(sock, (char *)&msgin, sizeof(struct tsp), 0,
>                  (struct sockaddr*)&from, &length)) < 0) {
>             syslog(LOG_ERR, "recvfrom: %m");
>             exit(1);
>         }
> /* SRW */
> /* Here is a bug: the sizeof(struct tsp) is OS dependent, depending on the
>  * length of the tsp_name field (MAXHOSTNAMELEN) which is, e.g., 256 for
>  * FreeBSD 4.3 and 64 for RH Linux 6.0.  Keep this as a sanity check,
>  * but assume that the name field is 64 or larger
>  */  
>         if (n < (ssize_t)sizeof(struct tsp) - MAXHOSTNAMELEN + 64) {
> /*
>         if (n < (ssize_t)sizeof(struct tsp)) {
> */
>             syslog(LOG_NOTICE,
>                 "short packet (%u/%u bytes) from %s",
>                   n, sizeof(struct tsp),
>                   inet_ntoa(from.sin_addr));
>             continue;  
>         }


I think this is a more complete fix.  According to

  http://sunsite.berkeley.edu/Dienst/UI/2.0/Describe/ncstrl.ucb/CSD-85-250

the original 4.3BSD code had sizeof(tsp.tsp_name) == 32, so that's
probably a safe minimum packet size to use.  Can you please test?

Kris

Index: timed/readmsg.c
===================================================================
RCS file: /mnt/ncvs/src/usr.sbin/timed/timed/readmsg.c,v
retrieving revision 1.7
diff -u -r1.7 readmsg.c
--- timed/readmsg.c	2001/01/01 18:43:21	1.7
+++ timed/readmsg.c	2001/08/19 09:14:07
@@ -212,10 +212,15 @@
 			syslog(LOG_ERR, "recvfrom: %m");
 			exit(1);
 		}
-		if (n < (ssize_t)sizeof(struct tsp)) {
+		/*
+		 * The 4.3BSD protocol spec had a 32-byte tsp_name field, and
+		 * this is still OS-dependent.  Demand that the packet is at
+		 * least long enough to hold a 4.3BSD packet.
+		 */
+		if (n < (ssize_t)(sizeof(struct tsp) - MAXHOSTNAMELEN + 32)) {
 			syslog(LOG_NOTICE,
 			    "short packet (%u/%u bytes) from %s",
-			      n, sizeof(struct tsp),
+			      n, sizeof(struct tsp) - MAXHOSTNAMELEN + 32,
 			      inet_ntoa(from.sin_addr));
 			continue;
 		}
Index: timedc/cmds.c
===================================================================
RCS file: /mnt/ncvs/src/usr.sbin/timed/timedc/cmds.c,v
retrieving revision 1.7
diff -u -r1.7 cmds.c
--- timedc/cmds.c	2001/05/09 08:37:18	1.7
+++ timedc/cmds.c	2001/08/19 09:17:16
@@ -332,10 +332,15 @@
 				warn("recvfrom");
 				continue;
 			}
-			if (cc < sizeof(struct tsp)) {
+			/*
+			 * The 4.3BSD protocol spec had a 32-byte tsp_name field, and
+			 * this is still OS-dependent.  Demand that the packet is at
+			 * least long enough to hold a 4.3BSD packet.
+			 */
+			if (cc < (sizeof(struct tsp) - MAXHOSTNAMELEN + 32)) {
 				fprintf(stderr, 
 				   "short packet (%u/%u bytes) from %s\n",
-				   cc, sizeof(struct tsp),
+				   cc, sizeof(struct tsp) - MAXHOSTNAMELEN + 32,
 				   inet_ntoa(from.sin_addr));
 				continue;
 			}
@@ -484,9 +489,15 @@
 			warn("recvfrom");
 			return;
 		}
-		if (cc < sizeof(struct tsp)) {
-			fprintf(stderr, "short pack (%u/%u bytes) from %s\n",
-			   cc, sizeof(struct tsp), inet_ntoa(from.sin_addr));
+		/*
+		 * The 4.3BSD protocol spec had a 32-byte tsp_name field, and
+		 * this is still OS-dependent.  Demand that the packet is at
+		 * least long enough to hold a 4.3BSD packet.
+		 */
+		if (cc < (sizeof(struct tsp) - MAXHOSTNAMELEN + 32)) {
+			fprintf(stderr, "short packet (%u/%u bytes) from %s\n",
+			    cc, sizeof(struct tsp) - MAXHOSTNAMELEN + 32,
+			    inet_ntoa(from.sin_addr));
 			return;
 		}
 		bytehostorder(&msg);
Comment 2 Kris Kennaway freebsd_committer freebsd_triage 2001-08-19 10:20:08 UTC
State Changed
From-To: open->analyzed

I've developed a patch to correct this. 


Comment 3 Kris Kennaway freebsd_committer freebsd_triage 2001-08-19 10:20:08 UTC
Responsible Changed
From-To: freebsd-bugs->kris
Comment 4 Kris Kennaway freebsd_committer freebsd_triage 2001-08-20 07:16:42 UTC
State Changed
From-To: analyzed->closed

Patch committed.  I'll consult the release engineer about 
merging this into 4.4.