Skip to content

Commit 9a49157

Browse files
Brian Kaomartinkpetersen
authored andcommitted
scsi: core: Fix error handler encryption support
Some low-level drivers (LLD) access block layer crypto fields, such as rq->crypt_keyslot and rq->crypt_ctx within `struct request`, to configure hardware for inline encryption. However, SCSI Error Handling (EH) commands (e.g., TEST UNIT READY, START STOP UNIT) should not involve any encryption setup. To prevent drivers from erroneously applying crypto settings during EH, this patch saves the original values of rq->crypt_keyslot and rq->crypt_ctx before an EH command is prepared via scsi_eh_prep_cmnd(). These fields in the 'struct request' are then set to NULL. The original values are restored in scsi_eh_restore_cmnd() after the EH command completes. This ensures that the block layer crypto context does not leak into EH command execution. Signed-off-by: Brian Kao <powenkao@google.com> Link: https://patch.msgid.link/20251218031726.2642834-1-powenkao@google.com Cc: stable@vger.kernel.org Reviewed-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 1523d50 commit 9a49157

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

drivers/scsi/scsi_error.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,9 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
10631063
unsigned char *cmnd, int cmnd_size, unsigned sense_bytes)
10641064
{
10651065
struct scsi_device *sdev = scmd->device;
1066+
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
1067+
struct request *rq = scsi_cmd_to_rq(scmd);
1068+
#endif
10661069

10671070
/*
10681071
* We need saved copies of a number of fields - this is because
@@ -1114,6 +1117,18 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
11141117
scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
11151118
(sdev->lun << 5 & 0xe0);
11161119

1120+
/*
1121+
* Encryption must be disabled for the commands submitted by the error handler.
1122+
* Hence, clear the encryption context information.
1123+
*/
1124+
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
1125+
ses->rq_crypt_keyslot = rq->crypt_keyslot;
1126+
ses->rq_crypt_ctx = rq->crypt_ctx;
1127+
1128+
rq->crypt_keyslot = NULL;
1129+
rq->crypt_ctx = NULL;
1130+
#endif
1131+
11171132
/*
11181133
* Zero the sense buffer. The scsi spec mandates that any
11191134
* untransferred sense data should be interpreted as being zero.
@@ -1131,6 +1146,10 @@ EXPORT_SYMBOL(scsi_eh_prep_cmnd);
11311146
*/
11321147
void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
11331148
{
1149+
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
1150+
struct request *rq = scsi_cmd_to_rq(scmd);
1151+
#endif
1152+
11341153
/*
11351154
* Restore original data
11361155
*/
@@ -1143,6 +1162,11 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
11431162
scmd->underflow = ses->underflow;
11441163
scmd->prot_op = ses->prot_op;
11451164
scmd->eh_eflags = ses->eh_eflags;
1165+
1166+
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
1167+
rq->crypt_keyslot = ses->rq_crypt_keyslot;
1168+
rq->crypt_ctx = ses->rq_crypt_ctx;
1169+
#endif
11461170
}
11471171
EXPORT_SYMBOL(scsi_eh_restore_cmnd);
11481172

include/scsi/scsi_eh.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ struct scsi_eh_save {
4141
unsigned char cmnd[32];
4242
struct scsi_data_buffer sdb;
4343
struct scatterlist sense_sgl;
44+
45+
/* struct request fields */
46+
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
47+
struct bio_crypt_ctx *rq_crypt_ctx;
48+
struct blk_crypto_keyslot *rq_crypt_keyslot;
49+
#endif
4450
};
4551

4652
extern void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd,

0 commit comments

Comments
 (0)