Re: NFS expert, please diagnose this
Hello.
I think I see the problem with regard to setuid programs and nfs.
It's in the kernel.
It's in the file kernel-source-2.0.27/fs/nfs/proc.c.
Alas the same code is repeated in several places, so I'm not sure how to
fix it: there must be a reason for exact this coding.
Does anybody here know what to do? Or know whom I might contact to get a
second opinion?
Thanks,
MartinS
Here follows a snippet from the above mentioned file and an possible scenario
(the one that makes at fail if /var/spool/cron/atjobs is on a nfs mounted
partition) to illustrate the problem:
---- Start of proc.c snippet. ----
[...]
int nfs_proc_lookup(struct nfs_server *server, struct nfs_fh *dir, const char *n
ame,
struct nfs_fh *fhandle, struct nfs_fattr *fattr)
{
int *p, *p0;
int status;
int ruid = 0;
PRINTK("NFS call lookup %s\n", name);
#ifdef NFS_PROC_DEBUG
if (!strcmp(name, "xyzzy"))
proc_debug = 1 - proc_debug;
#endif
if (!(p0 = nfs_rpc_alloc(server->rsize)))
return -EIO;
retry:
p = nfs_rpc_header(p0, NFSPROC_LOOKUP, ruid);
p = xdr_encode_fhandle(p, dir);
p = xdr_encode_string(p, name);
if ((status = nfs_rpc_call(server, p0, p, server->rsize)) < 0) {
nfs_rpc_free(p0);
return status;
}
if (!(p = nfs_rpc_verify(p0)))
status = -errno_NFSERR_IO;
else if ((status = ntohl(*p++)) == NFS_OK) {
p = xdr_decode_fhandle(p, fhandle);
p = xdr_decode_fattr(p, fattr);
PRINTK("NFS reply lookup\n");
/* status = 0; */
}
else {
if (!ruid && current->fsuid == 0 && current->uid != 0) {
ruid = 1;
goto retry;
}
PRINTK("NFS reply lookup failed = %d\n", status);
status = -nfs_stat_to_errno(status);
}
nfs_rpc_free(p0);
return status;
}
[...]
static int *nfs_rpc_header(int *p, int procedure, int ruid)
{
return rpc_header(p, procedure, NFS_PROGRAM, NFS_VERSION,
(ruid ? current->uid : current->fsuid),
current->egid, current->groups);
}
[...]
---- End of proc.c snippet. ----
Now first ruid is initialised to 0. First time around we fail looking up the
file and status (what is supposed to be propagated to errno) is set to 2
(ENOENT), so the statements "ruid = 1;" and "goto retry;" is executed.
Second time around the lookup will be performed as current->uid, which
obviously fail (as the directory is only writeable for root), hence
status (and after that errno) is set to 13 (EACCES).
Comments?
--
TO UNSUBSCRIBE FROM THIS MAILING LIST: e-mail the word "unsubscribe" to
debian-user-request@lists.debian.org .
Trouble? e-mail to templin@bucknell.edu .
Reply to: