[net.sources.bugs] batch #2 of RFS fixes

toddb@tekcrl.UUCP (Todd Brunhoff) (01/27/86)

Thanks to everyone for contributing time to fix up RFS!

Joe Othmer at Bell Labs found the problems related to the execution of a
remote binary.  The reason that ksh tended to fail on all remote executions
seemed to be a particular sequence of system calls.  The problem was that
if a file was remote, u.u_count was not initialized, but it was used.
Here's the fix for 4.2 /sys/sys/kern_exec.c:

***************
*** 128,133
  	u.u_count = resid;
  #ifdef REMOTEFS
  }
  
  remote_again:
  

--- 128,135 -----
  	u.u_count = resid;
  #ifdef REMOTEFS
  }
+ else
+ 	u.u_count = 0;
  
  remote_again:
  

And Here's the same fix for 4.3 /sys/sys/kern_exec.c (4.3 uses resid
instead of u.u_count):

***************
*** 129,133
  #ifdef REMOTEFS
  }
  
  remote_again:
  

--- 129,135 -----
  #ifdef REMOTEFS
  }
+ else
+ 	resid = 0;
  
  remote_again:
  

The reason that you could execute all remote files, reguardless of their
mode was due to the wrong error being returned in the server.  Joe also
found the fix for this in remote/serversyscall.c in the routine
s_execinfo():  There error returned should be EACCES.
***************
*** 441,447
  	if ((st.st_mode & S_IFMT) != S_IFREG
  	|| ! myaccess(&st, proc->p_ruser->r_user, X_OK))
  	{
! 		err = ENOEXEC;
  		debug12("%s mode=0%o %sreg file, %sexecutable\n",
  			path, st.st_mode,
  			(st.st_mode & S_IFMT) != S_IFREG ? "not " : "",

--- 441,457 -----
  	if ((st.st_mode & S_IFMT) != S_IFREG
  	|| ! myaccess(&st, proc->p_ruser->r_user, X_OK))
  	{
! 		err = EACCES;
  		debug12("%s mode=0%o %sreg file, %sexecutable\n",
  			path, st.st_mode,
  			(st.st_mode & S_IFMT) != S_IFREG ? "not " : "",


Bill Sommerfeld at MIT has found that the server code is not compatible
with the BIND nameserver.  No fix for this... but he said using the
old compatibility routines works fine.

He also found that in later 4.3 beta releases, the names of one of the
structure elements used by the server conflicts with a define in
/usr/include/netdb.h; specifically, h_addr.  The following diffs
show where the changes need to be made to change h_addr to h_iaddr
(for "internet address").  Note that not all of the occurences of
h_addr can be changed.

------ remote/find.c --------
***************
*** 102,108
  
  	debug4("find %s...\n", inet_ntoa(*addr));
  	for(h=hostlist; h; h=h->h_next)
! 		if (bcmp(addr, &h->h_addr, sizeof(struct in_addr)) == 0)
  		{
  			toplist(&hostlist, h);
  			debug4("\tis %s (%s)\n",

--- 102,108 -----
  
  	debug4("find %s...\n", inet_ntoa(*addr));
  	for(h=hostlist; h; h=h->h_next)
! 		if (bcmp(addr, &h->h_iaddr, sizeof(struct in_addr)) == 0)
  		{
  			toplist(&hostlist, h);
  			debug4("\tis %s (%s)\n",
***************
*** 106,112
  		{
  			toplist(&hostlist, h);
  			debug4("\tis %s (%s)\n",
! 				h->h_names[0], inet_ntoa(h->h_addr));
  			return(h);
  		}
  		else

--- 106,112 -----
  		{
  			toplist(&hostlist, h);
  			debug4("\tis %s (%s)\n",
! 				h->h_names[0], inet_ntoa(h->h_iaddr));
  			return(h);
  		}
  		else
***************
*** 111,117
  		}
  		else
  			debug4("\tnot %s (%s)\n",
! 				h->h_names[0], inet_ntoa(h->h_addr));
  	log("no host entry for %s, continuing anyway.\n", inet_ntoa(*addr));
  	/*
  	 * Kludge up a hosts structure for this guy

--- 111,117 -----
  		}
  		else
  			debug4("\tnot %s (%s)\n",
! 				h->h_names[0], inet_ntoa(h->h_iaddr));
  	log("no host entry for %s, continuing anyway.\n", inet_ntoa(*addr));
  	/*
  	 * Kludge up a hosts structure for this guy
***************
*** 118,124
  	 */
  	h = newhost();
  	h->h_names = newname(NULL, BOGUSHOST);
! 	bcopy(addr, &h->h_addr, sizeof(struct in_addr));
  	addlist(&hostlist, h);
  	return(h);
  }

--- 118,124 -----
  	 */
  	h = newhost();
  	h->h_names = newname(NULL, BOGUSHOST);
! 	bcopy(addr, &h->h_iaddr, sizeof(struct in_addr));
  	addlist(&hostlist, h);
  	return(h);
  }



--- remote/info.c ------
***************
*** 320,326
  		sin = &sinbuf;
  		debug6("path %s mapped to host %s\n", path, h->h_names[0]);
  		bzero((char *)sin, sizeof (struct sockaddr_in));
! 		bcopy(&h->h_addr, (char *)&sin->sin_addr,
  			sizeof(struct in_addr));
  		sin->sin_family = AF_INET;
  		sin->sin_port = serviceport;

--- 320,326 -----
  		sin = &sinbuf;
  		debug6("path %s mapped to host %s\n", path, h->h_names[0]);
  		bzero((char *)sin, sizeof (struct sockaddr_in));
! 		bcopy(&h->h_iaddr, (char *)&sin->sin_addr,
  			sizeof(struct in_addr));
  		sin->sin_family = AF_INET;
  		sin->sin_port = serviceport;


--- remote/init.c ------
***************
*** 210,216
  			hst->h_names = newname(hst->h_names,
  					h->h_aliases[ i ]);
  
! 		hst->h_addr = *((struct in_addr *)(h->h_addr));
  		addlist(&hostlist, hst);
  
  		/*

--- 210,216 -----
  			hst->h_names = newname(hst->h_names,
  					h->h_aliases[ i ]);
  
! 		hst->h_iaddr = *((struct in_addr *)(h->h_addr));
  		addlist(&hostlist, hst);
  
  		/*
***************
*** 234,240
  			hst->h_default_user = user;
  			debug2("default user for host %s (%s) is %s\n",
  				hst->h_names[ 0 ],
! 				inet_ntoa(hst->h_addr), user->u_name);
  		}
  		ruser = hst->h_default_ruser = newruser();
  		if (user)

--- 234,240 -----
  			hst->h_default_user = user;
  			debug2("default user for host %s (%s) is %s\n",
  				hst->h_names[ 0 ],
! 				inet_ntoa(hst->h_iaddr), user->u_name);
  		}
  		ruser = hst->h_default_ruser = newruser();
  		if (user)


--- remote/serverio.c
***************
*** 131,137
  	register long	s;
  
  	bzero((char *)&sin, sizeof (sin));
! 	bcopy(&h->h_addr, (char *)&sin.sin_addr, sizeof(struct in_addr));
  	sin.sin_family = AF_INET;
  	sin.sin_port = serviceport;
  	s = socket(AF_INET, SOCK_STREAM, 0);

--- 131,137 -----
  	register long	s;
  
  	bzero((char *)&sin, sizeof (sin));
! 	bcopy(&h->h_iaddr, (char *)&sin.sin_addr, sizeof(struct in_addr));
  	sin.sin_family = AF_INET;
  	sin.sin_port = serviceport;
  	s = socket(AF_INET, SOCK_STREAM, 0);


--- remote/server.h -----
***************
*** 207,213
  	long	h_portnum;	/* port number that we connected on */
  	char	*h_mntpt;	/* mount point for this machine */
  	process	*h_proclist;	/* processes we know about on this host */
! 	struct in_addr	h_addr;	/* network address */
  	union h_bytes {
  		long	hu_mounted; /* non-zero if host has been mounted */
  		u_char	hu_byteorder[4]; /* byte order for this host */

--- 207,213 -----
  	long	h_portnum;	/* port number that we connected on */
  	char	*h_mntpt;	/* mount point for this machine */
  	process	*h_proclist;	/* processes we know about on this host */
! 	struct in_addr	h_iaddr;/* internet address */
  	union h_bytes {
  		long	hu_mounted; /* non-zero if host has been mounted */
  		u_char	hu_byteorder[4]; /* byte order for this host */


"bruce" @ think noticed that new kernel include file, remotefs.h, contained an
interesting octal constant: 08000.  Fortunately pcc interprets this the way
I meant it as 010000.  The following is the context diff for that change.
--- /sys/remote/remotefs.h -----
***************
*** 85,91
  #if vax || magnolia || P4400
  #define		SREMOTE		0x08000000 /* proc.h: activity has occured */
  #define		SNOREMOTE	0x10000000 /* proc.h: disallow remote access */
! #define		FREMOTE		08000	   /* file.h: this is a remote file */
  #endif vax || magnolia || P4400
  
  /*

--- 85,91 -----
  #if vax || magnolia || P4400
  #define		SREMOTE		0x08000000 /* proc.h: activity has occured */
  #define		SNOREMOTE	0x10000000 /* proc.h: disallow remote access */
! #define		FREMOTE		010000	   /* file.h: this is a remote file */
  #endif vax || magnolia || P4400
  
  /*