batch #2 of RFS fixes (includes remote exec fix)
Todd Brunhoff
toddb at tekcrl.UUCP
Tue Jan 28 06:34:58 AEST 1986
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
/*
More information about the Comp.unix.wizards
mailing list