@@ -113,8 +113,7 @@ nfsd4_block_encode_getdeviceinfo(struct xdr_stream *xdr,
113113
114114/**
115115 * nfsd4_block_decode_layoutupdate - decode the block layout extent array
116- * @p: pointer to the xdr data
117- * @len: number of bytes to decode
116+ * @xdr: subbuf set to the encoded array
118117 * @iomapp: pointer to store the decoded extent array
119118 * @nr_iomapsp: pointer to store the number of extents
120119 * @block_size: alignment of extent offset and length
@@ -127,25 +126,24 @@ nfsd4_block_encode_getdeviceinfo(struct xdr_stream *xdr,
127126 *
128127 * Return values:
129128 * %nfs_ok: Successful decoding, @iomapp and @nr_iomapsp are valid
130- * %nfserr_bad_xdr: The encoded array in @p is invalid
129+ * %nfserr_bad_xdr: The encoded array in @xdr is invalid
131130 * %nfserr_inval: An unaligned extent found
132131 * %nfserr_delay: Failed to allocate memory for @iomapp
133132 */
134133__be32
135- nfsd4_block_decode_layoutupdate (__be32 * p , u32 len , struct iomap * * iomapp ,
134+ nfsd4_block_decode_layoutupdate (struct xdr_stream * xdr , struct iomap * * iomapp ,
136135 int * nr_iomapsp , u32 block_size )
137136{
138137 struct iomap * iomaps ;
139- u32 nr_iomaps , i ;
138+ u32 nr_iomaps , expected , len , i ;
139+ __be32 nfserr ;
140140
141- if (len < sizeof (u32 ))
142- return nfserr_bad_xdr ;
143- len -= sizeof (u32 );
144- if (len % PNFS_BLOCK_EXTENT_SIZE )
141+ if (xdr_stream_decode_u32 (xdr , & nr_iomaps ))
145142 return nfserr_bad_xdr ;
146143
147- nr_iomaps = be32_to_cpup (p ++ );
148- if (nr_iomaps != len / PNFS_BLOCK_EXTENT_SIZE )
144+ len = sizeof (__be32 ) + xdr_stream_remaining (xdr );
145+ expected = sizeof (__be32 ) + nr_iomaps * PNFS_BLOCK_EXTENT_SIZE ;
146+ if (len != expected )
149147 return nfserr_bad_xdr ;
150148
151149 iomaps = kcalloc (nr_iomaps , sizeof (* iomaps ), GFP_KERNEL );
@@ -155,21 +153,44 @@ nfsd4_block_decode_layoutupdate(__be32 *p, u32 len, struct iomap **iomapp,
155153 for (i = 0 ; i < nr_iomaps ; i ++ ) {
156154 struct pnfs_block_extent bex ;
157155
158- p = svcxdr_decode_deviceid4 (p , & bex .vol_id );
159- p = xdr_decode_hyper (p , & bex .foff );
156+ if (nfsd4_decode_deviceid4 (xdr , & bex .vol_id )) {
157+ nfserr = nfserr_bad_xdr ;
158+ goto fail ;
159+ }
160+
161+ if (xdr_stream_decode_u64 (xdr , & bex .foff )) {
162+ nfserr = nfserr_bad_xdr ;
163+ goto fail ;
164+ }
160165 if (bex .foff & (block_size - 1 )) {
166+ nfserr = nfserr_inval ;
167+ goto fail ;
168+ }
169+
170+ if (xdr_stream_decode_u64 (xdr , & bex .len )) {
171+ nfserr = nfserr_bad_xdr ;
161172 goto fail ;
162173 }
163- p = xdr_decode_hyper (p , & bex .len );
164174 if (bex .len & (block_size - 1 )) {
175+ nfserr = nfserr_inval ;
176+ goto fail ;
177+ }
178+
179+ if (xdr_stream_decode_u64 (xdr , & bex .soff )) {
180+ nfserr = nfserr_bad_xdr ;
165181 goto fail ;
166182 }
167- p = xdr_decode_hyper (p , & bex .soff );
168183 if (bex .soff & (block_size - 1 )) {
184+ nfserr = nfserr_inval ;
185+ goto fail ;
186+ }
187+
188+ if (xdr_stream_decode_u32 (xdr , & bex .es )) {
189+ nfserr = nfserr_bad_xdr ;
169190 goto fail ;
170191 }
171- bex .es = be32_to_cpup (p ++ );
172192 if (bex .es != PNFS_BLOCK_READWRITE_DATA ) {
193+ nfserr = nfserr_inval ;
173194 goto fail ;
174195 }
175196
@@ -182,13 +203,12 @@ nfsd4_block_decode_layoutupdate(__be32 *p, u32 len, struct iomap **iomapp,
182203 return nfs_ok ;
183204fail :
184205 kfree (iomaps );
185- return nfserr_inval ;
206+ return nfserr ;
186207}
187208
188209/**
189210 * nfsd4_scsi_decode_layoutupdate - decode the scsi layout extent array
190- * @p: pointer to the xdr data
191- * @len: number of bytes to decode
211+ * @xdr: subbuf set to the encoded array
192212 * @iomapp: pointer to store the decoded extent array
193213 * @nr_iomapsp: pointer to store the number of extents
194214 * @block_size: alignment of extent offset and length
@@ -200,21 +220,22 @@ nfsd4_block_decode_layoutupdate(__be32 *p, u32 len, struct iomap **iomapp,
200220 *
201221 * Return values:
202222 * %nfs_ok: Successful decoding, @iomapp and @nr_iomapsp are valid
203- * %nfserr_bad_xdr: The encoded array in @p is invalid
223+ * %nfserr_bad_xdr: The encoded array in @xdr is invalid
204224 * %nfserr_inval: An unaligned extent found
205225 * %nfserr_delay: Failed to allocate memory for @iomapp
206226 */
207227__be32
208- nfsd4_scsi_decode_layoutupdate (__be32 * p , u32 len , struct iomap * * iomapp ,
228+ nfsd4_scsi_decode_layoutupdate (struct xdr_stream * xdr , struct iomap * * iomapp ,
209229 int * nr_iomapsp , u32 block_size )
210230{
211231 struct iomap * iomaps ;
212- u32 nr_iomaps , expected , i ;
232+ u32 nr_iomaps , expected , len , i ;
233+ __be32 nfserr ;
213234
214- if (len < sizeof ( u32 ))
235+ if (xdr_stream_decode_u32 ( xdr , & nr_iomaps ))
215236 return nfserr_bad_xdr ;
216237
217- nr_iomaps = be32_to_cpup ( p ++ );
238+ len = sizeof ( __be32 ) + xdr_stream_remaining ( xdr );
218239 expected = sizeof (__be32 ) + nr_iomaps * PNFS_SCSI_RANGE_SIZE ;
219240 if (len != expected )
220241 return nfserr_bad_xdr ;
@@ -226,14 +247,22 @@ nfsd4_scsi_decode_layoutupdate(__be32 *p, u32 len, struct iomap **iomapp,
226247 for (i = 0 ; i < nr_iomaps ; i ++ ) {
227248 u64 val ;
228249
229- p = xdr_decode_hyper (p , & val );
250+ if (xdr_stream_decode_u64 (xdr , & val )) {
251+ nfserr = nfserr_bad_xdr ;
252+ goto fail ;
253+ }
230254 if (val & (block_size - 1 )) {
255+ nfserr = nfserr_inval ;
231256 goto fail ;
232257 }
233258 iomaps [i ].offset = val ;
234259
235- p = xdr_decode_hyper (p , & val );
260+ if (xdr_stream_decode_u64 (xdr , & val )) {
261+ nfserr = nfserr_bad_xdr ;
262+ goto fail ;
263+ }
236264 if (val & (block_size - 1 )) {
265+ nfserr = nfserr_inval ;
237266 goto fail ;
238267 }
239268 iomaps [i ].length = val ;
@@ -244,5 +273,5 @@ nfsd4_scsi_decode_layoutupdate(__be32 *p, u32 len, struct iomap **iomapp,
244273 return nfs_ok ;
245274fail :
246275 kfree (iomaps );
247- return nfserr_inval ;
276+ return nfserr ;
248277}
0 commit comments