ctl: fix Out-Of-Bounds access in ctl_report_supported_opcodes

This vulnerability is directly accessible to a guest VM through the
pci_virtio_scsi bhyve device.

In the function ctl_report_supported_opcodes() accessible from the VM,
the option RSO_OPTIONS_OC_ASA does not check the requested
service_action value before accessing &ctl_cmd_table[].

Reported by:	Synacktiv
Reviewed by:	asomers
Security:	FreeBSD-SA-24:11.ctl
Security:	CVE-2024-42416
Security:	HYP-06
Sponsored by:	The Alpha-Omega Project
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D46027

(cherry picked from commit af438acbfd)
(cherry picked from commit 803e0c2ab2)

Approved by:	so
This commit is contained in:
Pierre Pronchery 2024-09-04 14:38:12 +00:00 committed by Franco Fichtner
parent ed86a05c4b
commit 5c2797b287

View file

@ -7514,20 +7514,19 @@ ctl_report_supported_opcodes(struct ctl_scsiio *ctsio)
case RSO_OPTIONS_OC_SA:
if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) == 0 ||
service_action >= 32) {
ctl_set_invalid_field(/*ctsio*/ ctsio,
/*sks_valid*/ 1,
/*command*/ 1,
/*field*/ 2,
/*bit_valid*/ 1,
/*bit*/ 2);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
goto invalid;
}
/* FALLTHROUGH */
total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32;
break;
case RSO_OPTIONS_OC_ASA:
if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) != 0 &&
service_action >= 32) {
goto invalid;
}
total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32;
break;
default:
invalid:
ctl_set_invalid_field(/*ctsio*/ ctsio,
/*sks_valid*/ 1,
/*command*/ 1,