Commit 61f98b0fca802d7e0191072606519e2230a6226d

Authored by Linus Torvalds

Merge branch 'for-3.11' of git://linux-nfs.org/~bfields/linux

Pull nfsd bugfixes from Bruce Fields:
 "Just three minor bugfixes"

* 'for-3.11' of git://linux-nfs.org/~bfields/linux:
  svcrdma: underflow issue in decode_write_list()
  nfsd4: fix minorversion support interface
  lockd: protect nlm_blocked access in nlmsvc_retry_blocked

Showing 5 changed files Side-by-side Diff

... ... @@ -951,6 +951,7 @@
951 951 unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
952 952 struct nlm_block *block;
953 953  
  954 + spin_lock(&nlm_blocked_lock);
954 955 while (!list_empty(&nlm_blocked) && !kthread_should_stop()) {
955 956 block = list_entry(nlm_blocked.next, struct nlm_block, b_list);
956 957  
... ... @@ -960,6 +961,7 @@
960 961 timeout = block->b_when - jiffies;
961 962 break;
962 963 }
  964 + spin_unlock(&nlm_blocked_lock);
963 965  
964 966 dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
965 967 block, block->b_when);
966 968  
... ... @@ -969,7 +971,9 @@
969 971 retry_deferred_block(block);
970 972 } else
971 973 nlmsvc_grant_blocked(block);
  974 + spin_lock(&nlm_blocked_lock);
972 975 }
  976 + spin_unlock(&nlm_blocked_lock);
973 977  
974 978 return timeout;
975 979 }
... ... @@ -1293,7 +1293,7 @@
1293 1293 * According to RFC3010, this takes precedence over all other errors.
1294 1294 */
1295 1295 status = nfserr_minor_vers_mismatch;
1296   - if (args->minorversion > nfsd_supported_minorversion)
  1296 + if (nfsd_minorversion(args->minorversion, NFSD_TEST) <= 0)
1297 1297 goto out;
1298 1298  
1299 1299 status = nfs41_check_op_ordering(args);
... ... @@ -53,7 +53,6 @@
53 53 extern struct svc_program nfsd_program;
54 54 extern struct svc_version nfsd_version2, nfsd_version3,
55 55 nfsd_version4;
56   -extern u32 nfsd_supported_minorversion;
57 56 extern struct mutex nfsd_mutex;
58 57 extern spinlock_t nfsd_drc_lock;
59 58 extern unsigned long nfsd_drc_max_mem;
... ... @@ -116,7 +116,10 @@
116 116  
117 117 };
118 118  
119   -u32 nfsd_supported_minorversion = 1;
  119 +static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = {
  120 + [0] = 1,
  121 + [1] = 1,
  122 +};
120 123  
121 124 int nfsd_vers(int vers, enum vers_op change)
122 125 {
123 126  
124 127  
... ... @@ -151,15 +154,13 @@
151 154 return -1;
152 155 switch(change) {
153 156 case NFSD_SET:
154   - nfsd_supported_minorversion = minorversion;
  157 + nfsd_supported_minorversions[minorversion] = true;
155 158 break;
156 159 case NFSD_CLEAR:
157   - if (minorversion == 0)
158   - return -1;
159   - nfsd_supported_minorversion = minorversion - 1;
  160 + nfsd_supported_minorversions[minorversion] = false;
160 161 break;
161 162 case NFSD_TEST:
162   - return minorversion <= nfsd_supported_minorversion;
  163 + return nfsd_supported_minorversions[minorversion];
163 164 case NFSD_AVAIL:
164 165 return minorversion <= NFSD_SUPPORTED_MINOR_VERSION;
165 166 }
net/sunrpc/xprtrdma/svc_rdma_marshal.c
... ... @@ -98,6 +98,7 @@
98 98 */
99 99 static u32 *decode_write_list(u32 *va, u32 *vaend)
100 100 {
  101 + unsigned long start, end;
101 102 int nchunks;
102 103  
103 104 struct rpcrdma_write_array *ary =
... ... @@ -113,9 +114,12 @@
113 114 return NULL;
114 115 }
115 116 nchunks = ntohl(ary->wc_nchunks);
116   - if (((unsigned long)&ary->wc_array[0] +
117   - (sizeof(struct rpcrdma_write_chunk) * nchunks)) >
118   - (unsigned long)vaend) {
  117 +
  118 + start = (unsigned long)&ary->wc_array[0];
  119 + end = (unsigned long)vaend;
  120 + if (nchunks < 0 ||
  121 + nchunks > (SIZE_MAX - start) / sizeof(struct rpcrdma_write_chunk) ||
  122 + (start + (sizeof(struct rpcrdma_write_chunk) * nchunks)) > end) {
119 123 dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
120 124 ary, nchunks, vaend);
121 125 return NULL;
... ... @@ -129,6 +133,7 @@
129 133  
130 134 static u32 *decode_reply_array(u32 *va, u32 *vaend)
131 135 {
  136 + unsigned long start, end;
132 137 int nchunks;
133 138 struct rpcrdma_write_array *ary =
134 139 (struct rpcrdma_write_array *)va;
... ... @@ -143,9 +148,12 @@
143 148 return NULL;
144 149 }
145 150 nchunks = ntohl(ary->wc_nchunks);
146   - if (((unsigned long)&ary->wc_array[0] +
147   - (sizeof(struct rpcrdma_write_chunk) * nchunks)) >
148   - (unsigned long)vaend) {
  151 +
  152 + start = (unsigned long)&ary->wc_array[0];
  153 + end = (unsigned long)vaend;
  154 + if (nchunks < 0 ||
  155 + nchunks > (SIZE_MAX - start) / sizeof(struct rpcrdma_write_chunk) ||
  156 + (start + (sizeof(struct rpcrdma_write_chunk) * nchunks)) > end) {
149 157 dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
150 158 ary, nchunks, vaend);
151 159 return NULL;