git: 0e3a21196101 - main - ctl_report_supported_opcodes: Handle invalid requested service action

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Mon, 21 Oct 2024 14:54:26 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=0e3a211961014e0991a54f583b2866ac19ed0e76

commit 0e3a211961014e0991a54f583b2866ac19ed0e76
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2024-10-21 14:53:48 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2024-10-21 14:53:48 +0000

    ctl_report_supported_opcodes: Handle invalid requested service action
    
    Service actions are only valid up to 31 as they are encoded in the low
    5 bits of byte 1 in CDBs.  Fail requests with a requested service
    action of 32 or higher with an INVALID FIELD IN COMMAND specifying
    byte 4 as the illegal byte.
    
    Reviewed by:    asomers
    Differential Revision:  https://reviews.freebsd.org/D46611
---
 sys/cam/ctl/ctl.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index da147f0ec914..6533bf98011c 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -7461,16 +7461,20 @@ ctl_report_supported_opcodes(struct ctl_scsiio *ctsio)
 		total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32;
 		break;
 	case RSO_OPTIONS_OC_SA:
-		if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) == 0 ||
-		    service_action >= 32) {
+		if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) == 0) {
 			goto invalid_options;
 		}
-		total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32;
-		break;
+		/* FALLTHROUGH */
 	case RSO_OPTIONS_OC_ASA:
-		if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) != 0 &&
-		    service_action >= 32) {
-			goto invalid_options;
+		if (service_action >= 32) {
+			ctl_set_invalid_field(/*ctsio*/ ctsio,
+					      /*sks_valid*/ 1,
+					      /*command*/ 1,
+					      /*field*/ 4,
+					      /*bit_valid*/ 0,
+					      /*bit*/ 0);
+			ctl_done((union ctl_io *)ctsio);
+			return (CTL_RETVAL_COMPLETE);
 		}
 		total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32;
 		break;