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(); }