aboutsummaryrefslogtreecommitdiff
path: root/sys/cam
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/scsi/scsi_enc_ses.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/sys/cam/scsi/scsi_enc_ses.c b/sys/cam/scsi/scsi_enc_ses.c
index 6b40af1b5a9f..e2ebaa6e56d4 100644
--- a/sys/cam/scsi/scsi_enc_ses.c
+++ b/sys/cam/scsi/scsi_enc_ses.c
@@ -110,7 +110,7 @@ typedef struct ses_addl_status {
typedef struct ses_element {
uint8_t eip; /* eip bit is set */
uint16_t descr_len; /* length of the descriptor */
- char *descr; /* descriptor for this object */
+ const char *descr; /* descriptor for this object */
struct ses_addl_status addl; /* additional status info */
} ses_element_t;
@@ -1977,6 +1977,35 @@ ses_publish_cache(enc_softc_t *enc, struct enc_fsm_state *state,
return (0);
}
+/*
+ * \brief Sanitize an element descriptor
+ *
+ * The SES4r3 standard, sections 3.1.2 and 6.1.10, specifies that element
+ * descriptors may only contain ASCII characters in the range 0x20 to 0x7e.
+ * But some vendors violate that rule. Ensure that we only expose compliant
+ * descriptors to userland.
+ *
+ * \param desc SES element descriptor as reported by the hardware
+ * \param len Length of desc in bytes, not necessarily including
+ * trailing NUL. It will be modified if desc is invalid.
+ */
+static const char*
+ses_sanitize_elm_desc(const char *desc, uint16_t *len)
+{
+ const char *invalid = "<invalid>";
+ int i;
+
+ for (i = 0; i < *len; i++) {
+ if (desc[i] < 0x20 || desc[i] > 0x7e) {
+ *len = strlen(invalid);
+ return (invalid);
+ } else if (desc[i] == 0) {
+ break;
+ }
+ }
+ return (desc);
+}
+
/**
* \brief Parse the descriptors for each object.
*
@@ -2061,7 +2090,8 @@ ses_process_elm_descs(enc_softc_t *enc, struct enc_fsm_state *state,
if (length > 0) {
elmpriv = element->elm_private;
elmpriv->descr_len = length;
- elmpriv->descr = &buf[offset];
+ elmpriv->descr = ses_sanitize_elm_desc(&buf[offset],
+ &elmpriv->descr_len);
}
/* skip over the descriptor itself */