Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ecbb903c authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker
Browse files

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: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent bd8b2441
Loading
Loading
Loading
Loading
+17 −8
Original line number Original line Diff line number Diff line
@@ -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)) {
		if ((access_result & NFS_DIR_MAY_WRITE) == NFS_DIR_MAY_WRITE)
			mask |= MAY_WRITE;
			mask |= MAY_WRITE;
	if (access_result & NFS_MAY_LOOKUP)
		if ((access_result & NFS_MAY_LOOKUP) == NFS_MAY_LOOKUP)
			mask |= MAY_EXEC;
			mask |= MAY_EXEC;
	if (access_result & NFS_MAY_EXECUTE)
	} 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;
			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: