mirror of
https://github.com/torvalds/linux.git
synced 2025-11-30 23:16:01 +07:00
NFS: Fix LTP test failures when timestamps are delegated
The utimes01 and utime06 tests fail when delegated timestamps are
enabled, specifically in subtests that modify the atime and mtime
fields using the 'nobody' user ID.
The problem can be reproduced as follow:
# echo "/media *(rw,no_root_squash,sync)" >> /etc/exports
# export -ra
# mount -o rw,nfsvers=4.2 127.0.0.1:/media /tmpdir
# cd /opt/ltp
# ./runltp -d /tmpdir -s utimes01
# ./runltp -d /tmpdir -s utime06
This issue occurs because nfs_setattr does not verify the inode's
UID against the caller's fsuid when delegated timestamps are
permitted for the inode.
This patch adds the UID check and if it does not match then the
request is sent to the server for permission checking.
Fixes: e12912d941 ("NFSv4: Add support for delegated atime and mtime attributes")
Signed-off-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
This commit is contained in:
@@ -718,6 +718,8 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct nfs_fattr *fattr;
|
||||
loff_t oldsize = i_size_read(inode);
|
||||
int error = 0;
|
||||
kuid_t task_uid = current_fsuid();
|
||||
kuid_t owner_uid = inode->i_uid;
|
||||
|
||||
nfs_inc_stats(inode, NFSIOS_VFSSETATTR);
|
||||
|
||||
@@ -739,9 +741,11 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
if (nfs_have_delegated_mtime(inode) && attr->ia_valid & ATTR_MTIME) {
|
||||
spin_lock(&inode->i_lock);
|
||||
if (attr->ia_valid & ATTR_MTIME_SET) {
|
||||
nfs_set_timestamps_to_ts(inode, attr);
|
||||
attr->ia_valid &= ~(ATTR_MTIME|ATTR_MTIME_SET|
|
||||
if (uid_eq(task_uid, owner_uid)) {
|
||||
nfs_set_timestamps_to_ts(inode, attr);
|
||||
attr->ia_valid &= ~(ATTR_MTIME|ATTR_MTIME_SET|
|
||||
ATTR_ATIME|ATTR_ATIME_SET);
|
||||
}
|
||||
} else {
|
||||
nfs_update_timestamps(inode, attr->ia_valid);
|
||||
attr->ia_valid &= ~(ATTR_MTIME|ATTR_ATIME);
|
||||
@@ -751,10 +755,12 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
attr->ia_valid & ATTR_ATIME &&
|
||||
!(attr->ia_valid & ATTR_MTIME)) {
|
||||
if (attr->ia_valid & ATTR_ATIME_SET) {
|
||||
spin_lock(&inode->i_lock);
|
||||
nfs_set_timestamps_to_ts(inode, attr);
|
||||
spin_unlock(&inode->i_lock);
|
||||
attr->ia_valid &= ~(ATTR_ATIME|ATTR_ATIME_SET);
|
||||
if (uid_eq(task_uid, owner_uid)) {
|
||||
spin_lock(&inode->i_lock);
|
||||
nfs_set_timestamps_to_ts(inode, attr);
|
||||
spin_unlock(&inode->i_lock);
|
||||
attr->ia_valid &= ~(ATTR_ATIME|ATTR_ATIME_SET);
|
||||
}
|
||||
} else {
|
||||
nfs_update_delegated_atime(inode);
|
||||
attr->ia_valid &= ~ATTR_ATIME;
|
||||
|
||||
Reference in New Issue
Block a user