mirror of https://github.com/akuker/RASCSI.git
Improve buffer overflow checking in scsi_command_util::ModeSelect
Signed-off-by: Klaus Kämpf <kkaempf@gmail.com>
This commit is contained in:
parent
73917bce17
commit
73080d3a53
|
@ -33,9 +33,17 @@ string scsi_command_util::ModeSelect(scsi_command cmd, cdb_t cdb, span<const uin
|
||||||
// Skip block descriptors
|
// Skip block descriptors
|
||||||
int offset;
|
int offset;
|
||||||
if (cmd == scsi_command::eCmdModeSelect10) {
|
if (cmd == scsi_command::eCmdModeSelect10) {
|
||||||
|
if (length < 7) {
|
||||||
|
spdlog::warn("Incomplete Mode parameter header(10)");
|
||||||
|
throw scsi_exception(sense_key::illegal_request, asc::invalid_field_in_parameter_list);
|
||||||
|
}
|
||||||
offset = 8 + GetInt16(buf, 6);
|
offset = 8 + GetInt16(buf, 6);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (length < 4) {
|
||||||
|
spdlog::warn("Incomplete Mode parameter header(6)");
|
||||||
|
throw scsi_exception(sense_key::illegal_request, asc::invalid_field_in_parameter_list);
|
||||||
|
}
|
||||||
offset = 4 + buf[3];
|
offset = 4 + buf[3];
|
||||||
}
|
}
|
||||||
length -= offset;
|
length -= offset;
|
||||||
|
@ -44,8 +52,7 @@ string scsi_command_util::ModeSelect(scsi_command cmd, cdb_t cdb, span<const uin
|
||||||
bool has_valid_page_code = (length == 0);
|
bool has_valid_page_code = (length == 0);
|
||||||
|
|
||||||
// Parse the pages
|
// Parse the pages
|
||||||
// expect (remaining) length > 1 because we access buf[offset+1] below
|
while (length > 0) {
|
||||||
while (length > 1) {
|
|
||||||
// Format device page
|
// Format device page
|
||||||
if (const int page = buf[offset]; page == 0x03) {
|
if (const int page = buf[offset]; page == 0x03) {
|
||||||
if (length < 14) {
|
if (length < 14) {
|
||||||
|
@ -68,12 +75,20 @@ string scsi_command_util::ModeSelect(scsi_command cmd, cdb_t cdb, span<const uin
|
||||||
// OpenVMS Alpha 7.3 uses this
|
// OpenVMS Alpha 7.3 uses this
|
||||||
has_valid_page_code = true;
|
has_valid_page_code = true;
|
||||||
}
|
}
|
||||||
|
else if ((page == 0x00) && (length == 1)) {
|
||||||
|
has_valid_page_code = true;
|
||||||
|
break; // page 0 is valid if last in list, might have no size byte following
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
stringstream s;
|
stringstream s;
|
||||||
s << "Unknown MODE SELECT page code: $" << setfill('0') << setw(2) << hex << page;
|
s << "Unknown MODE SELECT page code: $" << setfill('0') << setw(2) << hex << page;
|
||||||
result = s.str();
|
result = s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (length < 2) { // ensure there's a size byte before accessing it
|
||||||
|
spdlog::warn("Current MODE SELECT page has no size");
|
||||||
|
throw scsi_exception(sense_key::illegal_request, asc::invalid_field_in_parameter_list);
|
||||||
|
}
|
||||||
// Advance to the next page
|
// Advance to the next page
|
||||||
const int size = buf[offset + 1] + 2;
|
const int size = buf[offset + 1] + 2;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue