ctl: limit memory allocation in pci_virtio_scsi

The virtio_scsi device allows a VM guest to directly send SCSI commands
(ctsio->cdb array) to the kernel driver exposed on /dev/cam/ctl
(ctl.ko).

All kernel commands accessible from the guest are defined by
ctl_cmd_table.

The command ctl_persistent_reserve_out (cdb[0]=0x5F and cbd[1]=0) allows
the caller to call malloc() with an arbitrary size (uint32_t). This can
be used by the guest to overload the kernel memory (DOS attack).

Reported by:    Synacktiv
Reviewed by:	asomers
Security:       HYP-08
Sponsored by:   The Alpha-Omega Project
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D46044

(cherry picked from commit 64b0f52be2c9d7bcecebfeef393f8ec56cb85f47)
This commit is contained in:
Pierre Pronchery 2024-07-19 19:32:27 +02:00 committed by Ed Maste
parent a5be19efbb
commit 2e7f4728fa

View file

@ -8314,6 +8314,18 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio)
param_len = scsi_4btoul(cdb->length);
/* validate the parameter length */
if (param_len != 24) {
ctl_set_invalid_field(ctsio,
/*sks_valid*/ 1,
/*command*/ 1,
/*field*/ 5,
/*bit_valid*/ 1,
/*bit*/ 0);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
}
if ((ctsio->io_hdr.flags & CTL_FLAG_ALLOCATED) == 0) {
ctsio->kern_data_ptr = malloc(param_len, M_CTL, M_WAITOK);
ctsio->kern_data_len = param_len;