[patch] User-space nfsd and quotas

Jan Kasprzak (kas@informatics.muni.cz)
Wed, 03 Mar 1999 11:25:30 +0100


Hello,

it seems that the user-space NFS-daemon does not honour
disk quotas, because quotas are checked against current->euid
instead of current->fsuid in include/linux/quotaops.h. The quota
system works for knfsd, because of the following (IMHO dirty)
hack in fs/nfsd/vfs.c:

#ifdef CONFIG_QUOTA
/* This is for disk quota. */
saved_euid = current->euid;
current->euid = current->fsuid;
err = file.f_op->write(&file, buf, cnt, &file.f_pos);
current->euid = saved_euid;
#else
err = file.f_op->write(&file, buf, cnt, &file.f_pos);
#endif

I think not only this is ugly but this allows knfsd to be
killed by an ordinary user for some amount of time (the file.f_op->write
can block, IIRC). The attached patch removes all the CONFIG_QUOTA stuff
from fs/nfsd/vfs.c and modifies include/linux/quotaops.h to check
quotas against current->fsuid instead of current->euid.

Am I right there, or there is a better solution of the
quota versus user-space nfsd problem on 2.2+ kernels? Please Cc: me
in any reply - I may miss the reply otherwise.

-Yenya

--- linux/include/linux/quotaops.h.orig Wed Feb 24 09:39:02 1999
+++ linux/include/linux/quotaops.h Wed Mar 3 11:04:04 1999
@@ -55,7 +55,7 @@
{
if (sb->dq_op) {
if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize),
- current->euid, 0) == NO_QUOTA)
+ current->fsuid, 0) == NO_QUOTA)
return 1;
}
return 0;
@@ -65,7 +65,7 @@
{
if (sb->dq_op) {
if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize),
- current->euid, 1) == NO_QUOTA)
+ current->fsuid, 1) == NO_QUOTA)
return 1;
}
return 0;
@@ -75,7 +75,7 @@
{
if (sb->dq_op) {
sb->dq_op->initialize (inode, -1);
- if (sb->dq_op->alloc_inode (inode, 1, current->euid))
+ if (sb->dq_op->alloc_inode (inode, 1, current->fsuid))
return 1;
}
inode->i_flags |= S_QUOTA;
@@ -101,11 +101,11 @@
if (dentry->d_inode->i_sb->dq_op) {
if (IS_QUOTAINIT(dentry->d_inode) == 0)
dentry->d_inode->i_sb->dq_op->initialize(dentry->d_inode, -1);
- if (dentry->d_inode->i_sb->dq_op->transfer(dentry->d_inode, iattr, 0, current->euid))
+ if (dentry->d_inode->i_sb->dq_op->transfer(dentry->d_inode, iattr, 0, current->fsuid))
goto out;
error = notify_change(dentry, iattr);
if (error)
- dentry->d_inode->i_sb->dq_op->transfer(dentry->d_inode, iattr, 1, current->euid);
+ dentry->d_inode->i_sb->dq_op->transfer(dentry->d_inode, iattr, 1, current->fsuid);
} else {
error = notify_change(dentry, iattr);
}
--- linux/fs/nfsd/vfs.c.orig Wed Mar 3 11:13:18 1999
+++ linux/fs/nfsd/vfs.c Wed Mar 3 11:13:43 1999
@@ -508,9 +508,6 @@
struct inode *inode;
mm_segment_t oldfs;
int err = 0;
-#ifdef CONFIG_QUOTA
- uid_t saved_euid;
-#endif

if (!cnt)
goto out;
@@ -540,15 +537,7 @@

/* Write the data. */
oldfs = get_fs(); set_fs(KERNEL_DS);
-#ifdef CONFIG_QUOTA
- /* This is for disk quota. */
- saved_euid = current->euid;
- current->euid = current->fsuid;
err = file.f_op->write(&file, buf, cnt, &file.f_pos);
- current->euid = saved_euid;
-#else
- err = file.f_op->write(&file, buf, cnt, &file.f_pos);
-#endif
set_fs(oldfs);

/* clear setuid/setgid flag after write */

--
\ Jan "Yenya" Kasprzak <kas at fi.muni.cz>       http://www.fi.muni.cz/~kas/
\\ PGP: finger kas at aisa.fi.muni.cz   0D99A7FB206605D7 8B35FCDE05B18A5E //
\\\             Czech Linux Homepage:  http://www.linux.cz/              ///
///    Can you say "ignored email" three times quickly while chewing     \\\
//     on an apple?                                 --Linus Torvalds      \\

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/