Loading fs/cifs/cifssmb.c +31 −18 Original line number Original line Diff line number Diff line Loading @@ -5285,6 +5285,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, struct fealist *ea_response_data; struct fealist *ea_response_data; struct fea *temp_fea; struct fea *temp_fea; char *temp_ptr; char *temp_ptr; char *end_of_smb; __u16 params, byte_count, data_offset; __u16 params, byte_count, data_offset; cFYI(1, ("In Query All EAs path %s", searchName)); cFYI(1, ("In Query All EAs path %s", searchName)); Loading Loading @@ -5368,22 +5369,47 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, goto QAllEAsOut; goto QAllEAsOut; } } /* make sure list_len doesn't go past end of SMB */ end_of_smb = (char *)pByteArea(&pSMBr->hdr) + BCC(&pSMBr->hdr); if ((char *)ea_response_data + list_len > end_of_smb) { cFYI(1, ("EA list appears to go beyond SMB")); rc = -EIO; goto QAllEAsOut; } /* account for ea list len */ /* account for ea list len */ list_len -= 4; list_len -= 4; temp_fea = ea_response_data->list; temp_fea = ea_response_data->list; temp_ptr = (char *)temp_fea; temp_ptr = (char *)temp_fea; while (list_len > 0) { while (list_len > 0) { __u8 name_len; __u16 value_len; __u16 value_len; list_len -= 4; list_len -= 4; temp_ptr += 4; temp_ptr += 4; rc += temp_fea->name_len; /* make sure we can read name_len and value_len */ if (list_len < 0) { cFYI(1, ("EA entry goes beyond length of list")); rc = -EIO; goto QAllEAsOut; } name_len = temp_fea->name_len; value_len = le16_to_cpu(temp_fea->value_len); list_len -= name_len + 1 + value_len; if (list_len < 0) { cFYI(1, ("EA entry goes beyond length of list")); rc = -EIO; goto QAllEAsOut; } /* account for prefix user. and trailing null */ /* account for prefix user. and trailing null */ rc = rc + 5 + 1; rc += (5 + 1 + name_len); if (rc < (int) buf_size) { if (rc < (int) buf_size) { memcpy(EAData, "user.", 5); memcpy(EAData, "user.", 5); EAData += 5; EAData += 5; memcpy(EAData, temp_ptr, temp_fea->name_len); memcpy(EAData, temp_ptr, name_len); EAData += temp_fea->name_len; EAData += name_len; /* null terminate name */ /* null terminate name */ *EAData = 0; *EAData = 0; ++EAData; ++EAData; Loading @@ -5394,20 +5420,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, rc = -ERANGE; rc = -ERANGE; break; break; } } list_len -= temp_fea->name_len; temp_ptr += name_len + 1 + value_len; temp_ptr += temp_fea->name_len; /* account for trailing null */ list_len--; temp_ptr++; value_len = le16_to_cpu(temp_fea->value_len); list_len -= value_len; temp_ptr += value_len; /* BB check that temp_ptr is still within the SMB BB*/ /* no trailing null to account for in value len */ /* go on to next EA */ temp_fea = (struct fea *)temp_ptr; temp_fea = (struct fea *)temp_ptr; } } Loading Loading
fs/cifs/cifssmb.c +31 −18 Original line number Original line Diff line number Diff line Loading @@ -5285,6 +5285,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, struct fealist *ea_response_data; struct fealist *ea_response_data; struct fea *temp_fea; struct fea *temp_fea; char *temp_ptr; char *temp_ptr; char *end_of_smb; __u16 params, byte_count, data_offset; __u16 params, byte_count, data_offset; cFYI(1, ("In Query All EAs path %s", searchName)); cFYI(1, ("In Query All EAs path %s", searchName)); Loading Loading @@ -5368,22 +5369,47 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, goto QAllEAsOut; goto QAllEAsOut; } } /* make sure list_len doesn't go past end of SMB */ end_of_smb = (char *)pByteArea(&pSMBr->hdr) + BCC(&pSMBr->hdr); if ((char *)ea_response_data + list_len > end_of_smb) { cFYI(1, ("EA list appears to go beyond SMB")); rc = -EIO; goto QAllEAsOut; } /* account for ea list len */ /* account for ea list len */ list_len -= 4; list_len -= 4; temp_fea = ea_response_data->list; temp_fea = ea_response_data->list; temp_ptr = (char *)temp_fea; temp_ptr = (char *)temp_fea; while (list_len > 0) { while (list_len > 0) { __u8 name_len; __u16 value_len; __u16 value_len; list_len -= 4; list_len -= 4; temp_ptr += 4; temp_ptr += 4; rc += temp_fea->name_len; /* make sure we can read name_len and value_len */ if (list_len < 0) { cFYI(1, ("EA entry goes beyond length of list")); rc = -EIO; goto QAllEAsOut; } name_len = temp_fea->name_len; value_len = le16_to_cpu(temp_fea->value_len); list_len -= name_len + 1 + value_len; if (list_len < 0) { cFYI(1, ("EA entry goes beyond length of list")); rc = -EIO; goto QAllEAsOut; } /* account for prefix user. and trailing null */ /* account for prefix user. and trailing null */ rc = rc + 5 + 1; rc += (5 + 1 + name_len); if (rc < (int) buf_size) { if (rc < (int) buf_size) { memcpy(EAData, "user.", 5); memcpy(EAData, "user.", 5); EAData += 5; EAData += 5; memcpy(EAData, temp_ptr, temp_fea->name_len); memcpy(EAData, temp_ptr, name_len); EAData += temp_fea->name_len; EAData += name_len; /* null terminate name */ /* null terminate name */ *EAData = 0; *EAData = 0; ++EAData; ++EAData; Loading @@ -5394,20 +5420,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, rc = -ERANGE; rc = -ERANGE; break; break; } } list_len -= temp_fea->name_len; temp_ptr += name_len + 1 + value_len; temp_ptr += temp_fea->name_len; /* account for trailing null */ list_len--; temp_ptr++; value_len = le16_to_cpu(temp_fea->value_len); list_len -= value_len; temp_ptr += value_len; /* BB check that temp_ptr is still within the SMB BB*/ /* no trailing null to account for in value len */ /* go on to next EA */ temp_fea = (struct fea *)temp_ptr; temp_fea = (struct fea *)temp_ptr; } } Loading