aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2018-07-31 15:51:54 -0400
committerJens Axboe <axboe@kernel.dk>2018-08-02 17:23:51 -0400
commit704f83928c8e7da6e06144569efb15dec73278e8 (patch)
tree6603bc65758e0c761fc773b8341bf9875dc5fe76
parent429296cc51c4cf145b240a78c8d68545e4d67e4c (diff)
scsi: Check sense buffer size at build time
To avoid introducing problems like those fixed in commit f7068114d45e ("sr: pass down correctly sized SCSI sense buffer"), this creates a macro wrapper for scsi_execute() that verifies the size of the sense buffer similar to what was done for command string sizes in commit 3756f6401c30 ("exec: avoid gcc-8 warning for get_task_comm"). Another solution could be to add a length argument to scsi_execute(), but this function already takes a lot of arguments and Jens was not fond of that approach. Additionally, this moves the SCSI_SENSE_BUFFERSIZE definition into scsi_device.h, and removes a redundant include for scsi_device.h from scsi_cmnd.h. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--drivers/scsi/scsi_lib.c6
-rw-r--r--include/scsi/scsi_cmnd.h6
-rw-r--r--include/scsi/scsi_device.h14
3 files changed, 18 insertions, 8 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 41e9ac9fc138..9cb9a166fa0c 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -238,7 +238,7 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
238 238
239 239
240/** 240/**
241 * scsi_execute - insert request and wait for the result 241 * __scsi_execute - insert request and wait for the result
242 * @sdev: scsi device 242 * @sdev: scsi device
243 * @cmd: scsi command 243 * @cmd: scsi command
244 * @data_direction: data direction 244 * @data_direction: data direction
@@ -255,7 +255,7 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
255 * Returns the scsi_cmnd result field if a command was executed, or a negative 255 * Returns the scsi_cmnd result field if a command was executed, or a negative
256 * Linux error code if we didn't get that far. 256 * Linux error code if we didn't get that far.
257 */ 257 */
258int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, 258int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
259 int data_direction, void *buffer, unsigned bufflen, 259 int data_direction, void *buffer, unsigned bufflen,
260 unsigned char *sense, struct scsi_sense_hdr *sshdr, 260 unsigned char *sense, struct scsi_sense_hdr *sshdr,
261 int timeout, int retries, u64 flags, req_flags_t rq_flags, 261 int timeout, int retries, u64 flags, req_flags_t rq_flags,
@@ -309,7 +309,7 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
309 309
310 return ret; 310 return ret;
311} 311}
312EXPORT_SYMBOL(scsi_execute); 312EXPORT_SYMBOL(__scsi_execute);
313 313
314/* 314/*
315 * Function: scsi_init_cmd_errh() 315 * Function: scsi_init_cmd_errh()
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index cae229b5395c..c891ada3c5c2 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -15,8 +15,6 @@
15struct Scsi_Host; 15struct Scsi_Host;
16struct scsi_driver; 16struct scsi_driver;
17 17
18#include <scsi/scsi_device.h>
19
20/* 18/*
21 * MAX_COMMAND_SIZE is: 19 * MAX_COMMAND_SIZE is:
22 * The longest fixed-length SCSI CDB as per the SCSI standard. 20 * The longest fixed-length SCSI CDB as per the SCSI standard.
@@ -121,11 +119,11 @@ struct scsi_cmnd {
121 struct request *request; /* The command we are 119 struct request *request; /* The command we are
122 working on */ 120 working on */
123 121
124#define SCSI_SENSE_BUFFERSIZE 96
125 unsigned char *sense_buffer; 122 unsigned char *sense_buffer;
126 /* obtained by REQUEST SENSE when 123 /* obtained by REQUEST SENSE when
127 * CHECK CONDITION is received on original 124 * CHECK CONDITION is received on original
128 * command (auto-sense) */ 125 * command (auto-sense). Length must be
126 * SCSI_SENSE_BUFFERSIZE bytes. */
129 127
130 /* Low-level done function - can be used by low-level driver to point 128 /* Low-level done function - can be used by low-level driver to point
131 * to completion function. Not used by mid/upper level code. */ 129 * to completion function. Not used by mid/upper level code. */
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 4c36af6edd79..202f4d6a4342 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -17,6 +17,8 @@ struct scsi_sense_hdr;
17 17
18typedef __u64 __bitwise blist_flags_t; 18typedef __u64 __bitwise blist_flags_t;
19 19
20#define SCSI_SENSE_BUFFERSIZE 96
21
20struct scsi_mode_data { 22struct scsi_mode_data {
21 __u32 length; 23 __u32 length;
22 __u16 block_descriptor_length; 24 __u16 block_descriptor_length;
@@ -426,11 +428,21 @@ extern const char *scsi_device_state_name(enum scsi_device_state);
426extern int scsi_is_sdev_device(const struct device *); 428extern int scsi_is_sdev_device(const struct device *);
427extern int scsi_is_target_device(const struct device *); 429extern int scsi_is_target_device(const struct device *);
428extern void scsi_sanitize_inquiry_string(unsigned char *s, int len); 430extern void scsi_sanitize_inquiry_string(unsigned char *s, int len);
429extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, 431extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
430 int data_direction, void *buffer, unsigned bufflen, 432 int data_direction, void *buffer, unsigned bufflen,
431 unsigned char *sense, struct scsi_sense_hdr *sshdr, 433 unsigned char *sense, struct scsi_sense_hdr *sshdr,
432 int timeout, int retries, u64 flags, 434 int timeout, int retries, u64 flags,
433 req_flags_t rq_flags, int *resid); 435 req_flags_t rq_flags, int *resid);
436/* Make sure any sense buffer is the correct size. */
437#define scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense, \
438 sshdr, timeout, retries, flags, rq_flags, resid) \
439({ \
440 BUILD_BUG_ON((sense) != NULL && \
441 sizeof(sense) != SCSI_SENSE_BUFFERSIZE); \
442 __scsi_execute(sdev, cmd, data_direction, buffer, bufflen, \
443 sense, sshdr, timeout, retries, flags, rq_flags, \
444 resid); \
445})
434static inline int scsi_execute_req(struct scsi_device *sdev, 446static inline int scsi_execute_req(struct scsi_device *sdev,
435 const unsigned char *cmd, int data_direction, void *buffer, 447 const unsigned char *cmd, int data_direction, void *buffer,
436 unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, 448 unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout,