NFS: Be more careful about mapping file permissions
When mapping a directory, we want the MAY_WRITE permissions to reflect whether or not we have permission to modify, add and delete the directory entries. MAY_EXEC must map to lookup permissions. On the other hand, for files, we want MAY_WRITE to reflect a permission to modify and extend the file. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
bd8b244174
commit
ecbb903c56
25
fs/nfs/dir.c
25
fs/nfs/dir.c
|
@ -2379,21 +2379,30 @@ EXPORT_SYMBOL_GPL(nfs_access_add_cache);
|
||||||
#define NFS_MAY_WRITE (NFS4_ACCESS_MODIFY | \
|
#define NFS_MAY_WRITE (NFS4_ACCESS_MODIFY | \
|
||||||
NFS4_ACCESS_EXTEND | \
|
NFS4_ACCESS_EXTEND | \
|
||||||
NFS4_ACCESS_DELETE)
|
NFS4_ACCESS_DELETE)
|
||||||
|
#define NFS_FILE_MAY_WRITE (NFS4_ACCESS_MODIFY | \
|
||||||
|
NFS4_ACCESS_EXTEND)
|
||||||
|
#define NFS_DIR_MAY_WRITE NFS_MAY_WRITE
|
||||||
#define NFS_MAY_LOOKUP (NFS4_ACCESS_LOOKUP)
|
#define NFS_MAY_LOOKUP (NFS4_ACCESS_LOOKUP)
|
||||||
#define NFS_MAY_EXECUTE (NFS4_ACCESS_EXECUTE)
|
#define NFS_MAY_EXECUTE (NFS4_ACCESS_EXECUTE)
|
||||||
static int
|
static int
|
||||||
nfs_access_calc_mask(u32 access_result)
|
nfs_access_calc_mask(u32 access_result, umode_t umode)
|
||||||
{
|
{
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
|
|
||||||
if (access_result & NFS_MAY_READ)
|
if (access_result & NFS_MAY_READ)
|
||||||
mask |= MAY_READ;
|
mask |= MAY_READ;
|
||||||
if (access_result & NFS_MAY_WRITE)
|
if (S_ISDIR(umode)) {
|
||||||
mask |= MAY_WRITE;
|
if ((access_result & NFS_DIR_MAY_WRITE) == NFS_DIR_MAY_WRITE)
|
||||||
if (access_result & NFS_MAY_LOOKUP)
|
mask |= MAY_WRITE;
|
||||||
mask |= MAY_EXEC;
|
if ((access_result & NFS_MAY_LOOKUP) == NFS_MAY_LOOKUP)
|
||||||
if (access_result & NFS_MAY_EXECUTE)
|
mask |= MAY_EXEC;
|
||||||
mask |= MAY_EXEC;
|
} else if (S_ISREG(umode)) {
|
||||||
|
if ((access_result & NFS_FILE_MAY_WRITE) == NFS_FILE_MAY_WRITE)
|
||||||
|
mask |= MAY_WRITE;
|
||||||
|
if ((access_result & NFS_MAY_EXECUTE) == NFS_MAY_EXECUTE)
|
||||||
|
mask |= MAY_EXEC;
|
||||||
|
} else if (access_result & NFS_MAY_WRITE)
|
||||||
|
mask |= MAY_WRITE;
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2438,7 +2447,7 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
|
||||||
}
|
}
|
||||||
nfs_access_add_cache(inode, &cache);
|
nfs_access_add_cache(inode, &cache);
|
||||||
out_cached:
|
out_cached:
|
||||||
cache_mask = nfs_access_calc_mask(cache.mask);
|
cache_mask = nfs_access_calc_mask(cache.mask, inode->i_mode);
|
||||||
if ((mask & ~cache_mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
|
if ((mask & ~cache_mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
|
||||||
status = -EACCES;
|
status = -EACCES;
|
||||||
out:
|
out:
|
||||||
|
|
Loading…
Reference in New Issue