Skip to content

Commit ecbb903

Browse files
trondmypdamschuma-ntap
authored andcommitted
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 <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent bd8b244 commit ecbb903

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

fs/nfs/dir.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2379,21 +2379,30 @@ EXPORT_SYMBOL_GPL(nfs_access_add_cache);
23792379
#define NFS_MAY_WRITE (NFS4_ACCESS_MODIFY | \
23802380
NFS4_ACCESS_EXTEND | \
23812381
NFS4_ACCESS_DELETE)
2382+
#define NFS_FILE_MAY_WRITE (NFS4_ACCESS_MODIFY | \
2383+
NFS4_ACCESS_EXTEND)
2384+
#define NFS_DIR_MAY_WRITE NFS_MAY_WRITE
23822385
#define NFS_MAY_LOOKUP (NFS4_ACCESS_LOOKUP)
23832386
#define NFS_MAY_EXECUTE (NFS4_ACCESS_EXECUTE)
23842387
static int
2385-
nfs_access_calc_mask(u32 access_result)
2388+
nfs_access_calc_mask(u32 access_result, umode_t umode)
23862389
{
23872390
int mask = 0;
23882391

23892392
if (access_result & NFS_MAY_READ)
23902393
mask |= MAY_READ;
2391-
if (access_result & NFS_MAY_WRITE)
2392-
mask |= MAY_WRITE;
2393-
if (access_result & NFS_MAY_LOOKUP)
2394-
mask |= MAY_EXEC;
2395-
if (access_result & NFS_MAY_EXECUTE)
2396-
mask |= MAY_EXEC;
2394+
if (S_ISDIR(umode)) {
2395+
if ((access_result & NFS_DIR_MAY_WRITE) == NFS_DIR_MAY_WRITE)
2396+
mask |= MAY_WRITE;
2397+
if ((access_result & NFS_MAY_LOOKUP) == NFS_MAY_LOOKUP)
2398+
mask |= MAY_EXEC;
2399+
} else if (S_ISREG(umode)) {
2400+
if ((access_result & NFS_FILE_MAY_WRITE) == NFS_FILE_MAY_WRITE)
2401+
mask |= MAY_WRITE;
2402+
if ((access_result & NFS_MAY_EXECUTE) == NFS_MAY_EXECUTE)
2403+
mask |= MAY_EXEC;
2404+
} else if (access_result & NFS_MAY_WRITE)
2405+
mask |= MAY_WRITE;
23972406
return mask;
23982407
}
23992408

@@ -2438,7 +2447,7 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
24382447
}
24392448
nfs_access_add_cache(inode, &cache);
24402449
out_cached:
2441-
cache_mask = nfs_access_calc_mask(cache.mask);
2450+
cache_mask = nfs_access_calc_mask(cache.mask, inode->i_mode);
24422451
if ((mask & ~cache_mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
24432452
status = -EACCES;
24442453
out:

0 commit comments

Comments
 (0)