From 8cad9604bda22747d4330f463302fad690f43e05 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Wed, 4 Apr 2018 09:57:58 -0700 Subject: [PATCH] nvmf: verify that serial number is an ASCII string Don't allow the user to specify an invalid ASCII string for the controller serial number field. Change-Id: I1c3acf6997a0afcdbfc03caf9e8d9b5fab429106 Signed-off-by: Daniel Verkamp Reviewed-on: https://review.gerrithub.io/406441 Reviewed-by: Ben Walker Tested-by: SPDK Automated Test System Reviewed-by: Jim Harris --- lib/nvmf/subsystem.c | 22 ++++++++++++++++++ test/unit/lib/nvmf/subsystem.c/subsystem_ut.c | 23 ++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index 6e36d3eba..096a63593 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -61,6 +61,22 @@ enum spdk_nvmf_nqn_domain_states { SPDK_NVMF_DOMAIN_ACCEPT_ANY = 2 }; +/* Returns true if is a valid ASCII string as defined by the NVMe spec */ +static bool +spdk_nvmf_valid_ascii_string(const void *buf, size_t size) +{ + const uint8_t *str = buf; + size_t i; + + for (i = 0; i < size; i++) { + if (str[i] < 0x20 || str[i] > 0x7E) { + return false; + } + } + + return true; +} + static bool spdk_nvmf_valid_nqn(const char *nqn) { @@ -1073,6 +1089,12 @@ spdk_nvmf_subsystem_set_sn(struct spdk_nvmf_subsystem *subsystem, const char *sn return -1; } + if (!spdk_nvmf_valid_ascii_string(sn, len)) { + SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Non-ASCII sn\n"); + SPDK_TRACEDUMP(SPDK_LOG_NVMF, "sn", sn, len); + return -1; + } + snprintf(subsystem->sn, sizeof(subsystem->sn), "%s", sn); return 0; diff --git a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c index 98e13f974..6ef252219 100644 --- a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c +++ b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c @@ -385,6 +385,26 @@ nvmf_test_create_subsystem(void) free(tgt.subsystems); } +static void +test_spdk_nvmf_subsystem_set_sn(void) +{ + struct spdk_nvmf_subsystem subsystem = {}; + + /* Basic valid serial number */ + CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd xyz") == 0); + CU_ASSERT(strcmp(subsystem.sn, "abcd xyz") == 0); + + /* Exactly 20 characters (valid) */ + CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "12345678901234567890") == 0); + CU_ASSERT(strcmp(subsystem.sn, "12345678901234567890") == 0); + + /* 21 characters (too long, invalid) */ + CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "123456789012345678901") < 0); + + /* Non-ASCII characters (invalid) */ + CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd\txyz") < 0); +} + int main(int argc, char **argv) { CU_pSuite suite = NULL; @@ -402,7 +422,8 @@ int main(int argc, char **argv) if ( CU_add_test(suite, "create_subsystem", nvmf_test_create_subsystem) == NULL || - CU_add_test(suite, "nvmf_subsystem_add_ns", test_spdk_nvmf_subsystem_add_ns) == NULL) { + CU_add_test(suite, "nvmf_subsystem_add_ns", test_spdk_nvmf_subsystem_add_ns) == NULL || + CU_add_test(suite, "nvmf_subsystem_set_sn", test_spdk_nvmf_subsystem_set_sn) == NULL) { CU_cleanup_registry(); return CU_get_error(); }