diff --git a/scripts/kernel/generate-kernel-patch b/scripts/kernel/generate-kernel-patch index 6f649d861..57f9c4a72 100755 --- a/scripts/kernel/generate-kernel-patch +++ b/scripts/kernel/generate-kernel-patch @@ -315,6 +315,7 @@ scst/src/scst_event.c scst/src/scst_event_priv.h scst/src/scst_no_dlm.c \ scst/src/scst_test.h \ scst/src/scst_event_test.h \ scst/src/scst_dlm_test.h \ +scst/src/scst_main_test.h \ scst/src/scst_copy_mgr_test.h" scst_05_targ="scst/src/scst_targ.c scst/src/scst_local_cmd.c \ scst/src/scst_local_cmd.h \ diff --git a/scst/src/kunit/lib/suites/scst_kunit_lib.c b/scst/src/kunit/lib/suites/scst_kunit_lib.c index 0d910c1d6..e4ec17c08 100644 --- a/scst/src/kunit/lib/suites/scst_kunit_lib.c +++ b/scst/src/kunit/lib/suites/scst_kunit_lib.c @@ -8,6 +8,7 @@ #endif #include "../../../scst_lib_test.h" +#include "../../../scst_main_test.h" #include "../../../scst_dlm.h" #include "../../../scst_dlm_test.h" @@ -198,7 +199,45 @@ static void scst_dlm_directory_error_preserves_membership(struct kunit *test) } #endif +static void scst_cdb_trace_bounds(struct kunit *test) +{ + static const struct { + unsigned int cdb_len; + size_t capacity; + const char *expected; + } cases[] = { + { 0, 16, "" }, + { 3, 16, "00 ab ff" }, + { 3, 5, "00 a" }, + { 3, 1, "" }, + }; + u8 cdb[] = { 0x00, 0xab, 0xff }; + struct scst_cmd *cmd; + char buf[18]; + unsigned int i; + + cmd = kunit_kzalloc(test, sizeof(*cmd), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, cmd); + cmd->cdb = cdb; + for (i = 0; i < ARRAY_SIZE(cases); i++) { + memset(buf, 'x', sizeof(buf)); + cmd->cdb_len = cases[i].cdb_len; + KUNIT_EXPECT_PTR_EQ(test, scst_dump_cdb(buf + 1, cases[i].capacity, cmd), + buf + 1); + KUNIT_EXPECT_EQ(test, buf[0], 'x'); + KUNIT_EXPECT_EQ(test, buf[cases[i].capacity + 1], 'x'); + /* memcmp bounds the check even if the formatter misses the NUL. */ + KUNIT_EXPECT_EQ(test, memcmp(buf + 1, cases[i].expected, + strlen(cases[i].expected) + 1), 0); + } + + memset(buf, 'x', sizeof(buf)); + KUNIT_EXPECT_PTR_EQ(test, scst_dump_cdb(buf + 1, 0, cmd), buf + 1); + KUNIT_EXPECT_EQ(test, buf[1], 'x'); +} + static struct kunit_case scst_lib_cases[] = { + KUNIT_CASE(scst_cdb_trace_bounds), #if (defined(CONFIG_DLM) || defined(CONFIG_DLM_MODULE)) && !defined(CONFIG_SCST_NO_DLM) KUNIT_CASE(scst_dlm_directory_error_preserves_membership), #endif diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index 91051cf2b..fb6d866a1 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -39,7 +39,7 @@ #include "scst_priv.h" #include "scst_mem.h" #include "scst_pres.h" -#include "scst_test.h" +#include "scst_main_test.h" #undef DEFAULT_SYMBOL_NAMESPACE #define DEFAULT_SYMBOL_NAMESPACE SCST_NAMESPACE @@ -626,11 +626,17 @@ char *scst_get_cmd_state_name(char *name, int len, unsigned int state) return name; } -static char *scst_dump_cdb(char *buf, int buf_len, struct scst_cmd *cmd) +SCST_KUNIT_VISIBLE +char *scst_dump_cdb(char *buf, size_t buf_len, const struct scst_cmd *cmd) { - char *p = buf, *end = buf + buf_len; + char *p = buf, *end; int i; + if (!buf_len) + return buf; + *buf = '\0'; + end = buf + buf_len; + for (i = 0; i < cmd->cdb_len && p < end; i++) p += scnprintf(p, end - p, "%s%02x", i ? " " : "", cmd->cdb[i]); diff --git a/scst/src/scst_main_test.h b/scst/src/scst_main_test.h new file mode 100644 index 000000000..3a0c2a1b0 --- /dev/null +++ b/scst/src/scst_main_test.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SCST_MAIN_TEST_H +#define SCST_MAIN_TEST_H + +#include "scst_test.h" + +#ifdef SCST_KUNIT_ENABLED +#include + +struct scst_cmd; + +char *scst_dump_cdb(char *buf, size_t buf_len, const struct scst_cmd *cmd); +#endif + +#endif /* SCST_MAIN_TEST_H */