NFSv4: Sanity check the server reply in _nfs4_server_capabilities
We don't want to be setting capabilities and/or requesting attributes that are not appropriate for the NFSv4 minor version. - Ensure that we clear the NFS_CAP_SECURITY_LABEL capability when appropriate - Ensure that we limit the attribute bitmasks to the mounted_on_fileid attribute and less for NFSv4.0 - Ensure that we limit the attribute bitmasks to suppattr_exclcreat and less for NFSv4.1 - Ensure that we limit it to change_sec_label or less for NFSv4.2 Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
d204c5d2b8
commit
b944dba31d
@ -2706,6 +2706,10 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
|
|||||||
nfs4_close_state(ctx->state, ctx->mode);
|
nfs4_close_state(ctx->state, ctx->mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)
|
||||||
|
#define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL)
|
||||||
|
#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_CHANGE_SECURITY_LABEL - 1UL)
|
||||||
|
|
||||||
static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
|
static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
|
||||||
{
|
{
|
||||||
struct nfs4_server_caps_arg args = {
|
struct nfs4_server_caps_arg args = {
|
||||||
@ -2721,12 +2725,25 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
|
|||||||
|
|
||||||
status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
|
status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
|
/* Sanity check the server answers */
|
||||||
|
switch (server->nfs_client->cl_minorversion) {
|
||||||
|
case 0:
|
||||||
|
res.attr_bitmask[1] &= FATTR4_WORD1_NFS40_MASK;
|
||||||
|
res.attr_bitmask[2] = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
res.attr_bitmask[2] &= FATTR4_WORD2_NFS41_MASK;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK;
|
||||||
|
}
|
||||||
memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
|
memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
|
||||||
server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS|
|
server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS|
|
||||||
NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
|
NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
|
||||||
NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|
|
NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|
|
||||||
NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME|
|
NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME|
|
||||||
NFS_CAP_CTIME|NFS_CAP_MTIME);
|
NFS_CAP_CTIME|NFS_CAP_MTIME|
|
||||||
|
NFS_CAP_SECURITY_LABEL);
|
||||||
if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)
|
if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)
|
||||||
server->caps |= NFS_CAP_ACLS;
|
server->caps |= NFS_CAP_ACLS;
|
||||||
if (res.has_links != 0)
|
if (res.has_links != 0)
|
||||||
@ -2755,14 +2772,12 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
|
|||||||
#endif
|
#endif
|
||||||
memcpy(server->attr_bitmask_nl, res.attr_bitmask,
|
memcpy(server->attr_bitmask_nl, res.attr_bitmask,
|
||||||
sizeof(server->attr_bitmask));
|
sizeof(server->attr_bitmask));
|
||||||
|
server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
|
||||||
|
|
||||||
if (server->caps & NFS_CAP_SECURITY_LABEL) {
|
|
||||||
server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
|
|
||||||
res.attr_bitmask[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
|
|
||||||
}
|
|
||||||
memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask));
|
memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask));
|
||||||
server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE;
|
server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE;
|
||||||
server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
|
server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
|
||||||
|
server->cache_consistency_bitmask[2] = 0;
|
||||||
server->acl_bitmask = res.acl_bitmask;
|
server->acl_bitmask = res.acl_bitmask;
|
||||||
server->fh_expire_type = res.fh_expire_type;
|
server->fh_expire_type = res.fh_expire_type;
|
||||||
}
|
}
|
||||||
|
@ -396,6 +396,8 @@ enum lock_type4 {
|
|||||||
#define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1)
|
#define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1)
|
||||||
#define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4)
|
#define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4)
|
||||||
#define FATTR4_WORD2_SECURITY_LABEL (1UL << 16)
|
#define FATTR4_WORD2_SECURITY_LABEL (1UL << 16)
|
||||||
|
#define FATTR4_WORD2_CHANGE_SECURITY_LABEL \
|
||||||
|
(1UL << 17)
|
||||||
|
|
||||||
/* MDS threshold bitmap bits */
|
/* MDS threshold bitmap bits */
|
||||||
#define THRESHOLD_RD (1UL << 0)
|
#define THRESHOLD_RD (1UL << 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user