aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c151
1 files changed, 75 insertions, 76 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 941441d3e386..30709589e0c9 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -5282,9 +5282,10 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
5282 int rc = 0; 5282 int rc = 0;
5283 int bytes_returned; 5283 int bytes_returned;
5284 int name_len; 5284 int name_len;
5285 struct fealist *ea_response_data;
5285 struct fea *temp_fea; 5286 struct fea *temp_fea;
5286 char *temp_ptr; 5287 char *temp_ptr;
5287 __u16 params, byte_count; 5288 __u16 params, byte_count, data_offset;
5288 5289
5289 cFYI(1, ("In Query All EAs path %s", searchName)); 5290 cFYI(1, ("In Query All EAs path %s", searchName));
5290QAllEAsRetry: 5291QAllEAsRetry:
@@ -5334,85 +5335,83 @@ QAllEAsRetry:
5334 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5335 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5335 if (rc) { 5336 if (rc) {
5336 cFYI(1, ("Send error in QueryAllEAs = %d", rc)); 5337 cFYI(1, ("Send error in QueryAllEAs = %d", rc));
5337 } else { /* decode response */ 5338 goto QAllEAsOut;
5338 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5339 }
5339 5340
5340 /* BB also check enough total bytes returned */
5341 /* BB we need to improve the validity checking
5342 of these trans2 responses */
5343 if (rc || (pSMBr->ByteCount < 4))
5344 rc = -EIO; /* bad smb */
5345 /* else if (pFindData){
5346 memcpy((char *) pFindData,
5347 (char *) &pSMBr->hdr.Protocol +
5348 data_offset, kl);
5349 }*/ else {
5350 /* check that length of list is not more than bcc */
5351 /* check that each entry does not go beyond length
5352 of list */
5353 /* check that each element of each entry does not
5354 go beyond end of list */
5355 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5356 struct fealist *ea_response_data;
5357 rc = 0;
5358 /* validate_trans2_offsets() */
5359 /* BB check if start of smb + data_offset > &bcc+ bcc */
5360 ea_response_data = (struct fealist *)
5361 (((char *) &pSMBr->hdr.Protocol) +
5362 data_offset);
5363 name_len = le32_to_cpu(ea_response_data->list_len);
5364 cFYI(1, ("ea length %d", name_len));
5365 if (name_len <= 8) {
5366 /* returned EA size zeroed at top of function */
5367 cFYI(1, ("empty EA list returned from server"));
5368 } else {
5369 /* account for ea list len */
5370 name_len -= 4;
5371 temp_fea = ea_response_data->list;
5372 temp_ptr = (char *)temp_fea;
5373 while (name_len > 0) {
5374 __u16 value_len;
5375 name_len -= 4;
5376 temp_ptr += 4;
5377 rc += temp_fea->name_len;
5378 /* account for prefix user. and trailing null */
5379 rc = rc + 5 + 1;
5380 if (rc < (int)buf_size) {
5381 memcpy(EAData, "user.", 5);
5382 EAData += 5;
5383 memcpy(EAData, temp_ptr,
5384 temp_fea->name_len);
5385 EAData += temp_fea->name_len;
5386 /* null terminate name */
5387 *EAData = 0;
5388 EAData = EAData + 1;
5389 } else if (buf_size == 0) {
5390 /* skip copy - calc size only */
5391 } else {
5392 /* stop before overrun buffer */
5393 rc = -ERANGE;
5394 break;
5395 }
5396 name_len -= temp_fea->name_len;
5397 temp_ptr += temp_fea->name_len;
5398 /* account for trailing null */
5399 name_len--;
5400 temp_ptr++;
5401 value_len =
5402 le16_to_cpu(temp_fea->value_len);
5403 name_len -= value_len;
5404 temp_ptr += value_len;
5405 /* BB check that temp_ptr is still
5406 within the SMB BB*/
5407 5341
5408 /* no trailing null to account for 5342 /* BB also check enough total bytes returned */
5409 in value len */ 5343 /* BB we need to improve the validity checking
5410 /* go on to next EA */ 5344 of these trans2 responses */
5411 temp_fea = (struct fea *)temp_ptr; 5345
5412 } 5346 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5413 } 5347 if (rc || (pSMBr->ByteCount < 4)) {
5348 rc = -EIO; /* bad smb */
5349 goto QAllEAsOut;
5350 }
5351
5352 /* check that length of list is not more than bcc */
5353 /* check that each entry does not go beyond length
5354 of list */
5355 /* check that each element of each entry does not
5356 go beyond end of list */
5357 /* validate_trans2_offsets() */
5358 /* BB check if start of smb + data_offset > &bcc+ bcc */
5359
5360 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5361 ea_response_data = (struct fealist *)
5362 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5363
5364 name_len = le32_to_cpu(ea_response_data->list_len);
5365 cFYI(1, ("ea length %d", name_len));
5366 if (name_len <= 8) {
5367 cFYI(1, ("empty EA list returned from server"));
5368 goto QAllEAsOut;
5369 }
5370
5371 /* account for ea list len */
5372 name_len -= 4;
5373 temp_fea = ea_response_data->list;
5374 temp_ptr = (char *)temp_fea;
5375 while (name_len > 0) {
5376 __u16 value_len;
5377 name_len -= 4;
5378 temp_ptr += 4;
5379 rc += temp_fea->name_len;
5380 /* account for prefix user. and trailing null */
5381 rc = rc + 5 + 1;
5382 if (rc < (int) buf_size) {
5383 memcpy(EAData, "user.", 5);
5384 EAData += 5;
5385 memcpy(EAData, temp_ptr, temp_fea->name_len);
5386 EAData += temp_fea->name_len;
5387 /* null terminate name */
5388 *EAData = 0;
5389 EAData = EAData + 1;
5390 } else if (buf_size == 0) {
5391 /* skip copy - calc size only */
5392 } else {
5393 /* stop before overrun buffer */
5394 rc = -ERANGE;
5395 break;
5414 } 5396 }
5397 name_len -= temp_fea->name_len;
5398 temp_ptr += temp_fea->name_len;
5399 /* account for trailing null */
5400 name_len--;
5401 temp_ptr++;
5402 value_len = le16_to_cpu(temp_fea->value_len);
5403 name_len -= value_len;
5404 temp_ptr += value_len;
5405 /* BB check that temp_ptr is still
5406 within the SMB BB*/
5407
5408 /* no trailing null to account for
5409 in value len */
5410 /* go on to next EA */
5411 temp_fea = (struct fea *)temp_ptr;
5415 } 5412 }
5413
5414QAllEAsOut:
5416 cifs_buf_release(pSMB); 5415 cifs_buf_release(pSMB);
5417 if (rc == -EAGAIN) 5416 if (rc == -EAGAIN)
5418 goto QAllEAsRetry; 5417 goto QAllEAsRetry;