diff options
| -rw-r--r-- | fs/nfs/nfs4proc.c | 25 | ||||
| -rw-r--r-- | include/linux/nfs4.h | 8 |
2 files changed, 27 insertions, 6 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f2b92f6a7efb..9d992b0346e3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -4519,6 +4519,25 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, | |||
| 4519 | 4519 | ||
| 4520 | #ifdef CONFIG_NFS_V4_1 | 4520 | #ifdef CONFIG_NFS_V4_1 |
| 4521 | /* | 4521 | /* |
| 4522 | * Check the exchange flags returned by the server for invalid flags, having | ||
| 4523 | * both PNFS and NON_PNFS flags set, and not having one of NON_PNFS, PNFS, or | ||
| 4524 | * DS flags set. | ||
| 4525 | */ | ||
| 4526 | static int nfs4_check_cl_exchange_flags(u32 flags) | ||
| 4527 | { | ||
| 4528 | if (flags & ~EXCHGID4_FLAG_MASK_R) | ||
| 4529 | goto out_inval; | ||
| 4530 | if ((flags & EXCHGID4_FLAG_USE_PNFS_MDS) && | ||
| 4531 | (flags & EXCHGID4_FLAG_USE_NON_PNFS)) | ||
| 4532 | goto out_inval; | ||
| 4533 | if (!(flags & (EXCHGID4_FLAG_MASK_PNFS))) | ||
| 4534 | goto out_inval; | ||
| 4535 | return NFS_OK; | ||
| 4536 | out_inval: | ||
| 4537 | return -NFS4ERR_INVAL; | ||
| 4538 | } | ||
| 4539 | |||
| 4540 | /* | ||
| 4522 | * nfs4_proc_exchange_id() | 4541 | * nfs4_proc_exchange_id() |
| 4523 | * | 4542 | * |
| 4524 | * Since the clientid has expired, all compounds using sessions | 4543 | * Since the clientid has expired, all compounds using sessions |
| @@ -4531,7 +4550,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) | |||
| 4531 | nfs4_verifier verifier; | 4550 | nfs4_verifier verifier; |
| 4532 | struct nfs41_exchange_id_args args = { | 4551 | struct nfs41_exchange_id_args args = { |
| 4533 | .client = clp, | 4552 | .client = clp, |
| 4534 | .flags = clp->cl_exchange_flags, | 4553 | .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER, |
| 4535 | }; | 4554 | }; |
| 4536 | struct nfs41_exchange_id_res res = { | 4555 | struct nfs41_exchange_id_res res = { |
| 4537 | .client = clp, | 4556 | .client = clp, |
| @@ -4548,9 +4567,6 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) | |||
| 4548 | dprintk("--> %s\n", __func__); | 4567 | dprintk("--> %s\n", __func__); |
| 4549 | BUG_ON(clp == NULL); | 4568 | BUG_ON(clp == NULL); |
| 4550 | 4569 | ||
| 4551 | /* Remove server-only flags */ | ||
| 4552 | args.flags &= ~EXCHGID4_FLAG_CONFIRMED_R; | ||
| 4553 | |||
| 4554 | p = (u32 *)verifier.data; | 4570 | p = (u32 *)verifier.data; |
| 4555 | *p++ = htonl((u32)clp->cl_boot_time.tv_sec); | 4571 | *p++ = htonl((u32)clp->cl_boot_time.tv_sec); |
| 4556 | *p = htonl((u32)clp->cl_boot_time.tv_nsec); | 4572 | *p = htonl((u32)clp->cl_boot_time.tv_nsec); |
| @@ -4576,6 +4592,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) | |||
| 4576 | break; | 4592 | break; |
| 4577 | } | 4593 | } |
| 4578 | 4594 | ||
| 4595 | status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); | ||
| 4579 | dprintk("<-- %s status= %d\n", __func__, status); | 4596 | dprintk("<-- %s status= %d\n", __func__, status); |
| 4580 | return status; | 4597 | return status; |
| 4581 | } | 4598 | } |
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 4925b22219d2..9b46300b4305 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h | |||
| @@ -111,9 +111,13 @@ | |||
| 111 | 111 | ||
| 112 | #define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001 | 112 | #define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001 |
| 113 | #define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002 | 113 | #define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002 |
| 114 | #define EXCHGID4_FLAG_BIND_PRINC_STATEID 0x00000100 | ||
| 115 | |||
| 114 | #define EXCHGID4_FLAG_USE_NON_PNFS 0x00010000 | 116 | #define EXCHGID4_FLAG_USE_NON_PNFS 0x00010000 |
| 115 | #define EXCHGID4_FLAG_USE_PNFS_MDS 0x00020000 | 117 | #define EXCHGID4_FLAG_USE_PNFS_MDS 0x00020000 |
| 116 | #define EXCHGID4_FLAG_USE_PNFS_DS 0x00040000 | 118 | #define EXCHGID4_FLAG_USE_PNFS_DS 0x00040000 |
| 119 | #define EXCHGID4_FLAG_MASK_PNFS 0x00070000 | ||
| 120 | |||
| 117 | #define EXCHGID4_FLAG_UPD_CONFIRMED_REC_A 0x40000000 | 121 | #define EXCHGID4_FLAG_UPD_CONFIRMED_REC_A 0x40000000 |
| 118 | #define EXCHGID4_FLAG_CONFIRMED_R 0x80000000 | 122 | #define EXCHGID4_FLAG_CONFIRMED_R 0x80000000 |
| 119 | /* | 123 | /* |
| @@ -121,8 +125,8 @@ | |||
| 121 | * they're set in the argument or response, have separate | 125 | * they're set in the argument or response, have separate |
| 122 | * invalid flag masks for arg (_A) and resp (_R). | 126 | * invalid flag masks for arg (_A) and resp (_R). |
| 123 | */ | 127 | */ |
| 124 | #define EXCHGID4_FLAG_MASK_A 0x40070003 | 128 | #define EXCHGID4_FLAG_MASK_A 0x40070103 |
| 125 | #define EXCHGID4_FLAG_MASK_R 0x80070003 | 129 | #define EXCHGID4_FLAG_MASK_R 0x80070103 |
| 126 | 130 | ||
| 127 | #define SEQ4_STATUS_CB_PATH_DOWN 0x00000001 | 131 | #define SEQ4_STATUS_CB_PATH_DOWN 0x00000001 |
| 128 | #define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002 | 132 | #define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002 |
