mirror of
https://github.com/SCST-project/scst.git
synced 2026-10-22 06:02:33 +00:00
scst_lib: Decode unaligned LUN buffers safely
Manual review found alignment-dependent loads in scst_unpack_lun; no saved analyzer diagnostic directly reports this defect. The helper accepts a byte pointer without an alignment contract, then casts it to 16-, 32- or 64-bit pointers. In particular, a six-byte LUN reads a 32-bit tail at offset two even when the start is aligned. Use unaligned big-endian loads for each supported length while retaining flat-address decoding and rejection of nonzero tail bytes. This preserves the public interface and avoids faults on strict-alignment architectures. Add KUnit coverage for all eight alignments and supported lengths, nonzero bytes outside the supplied length, and every rejected tail byte.
This commit is contained in:
@@ -236,7 +236,35 @@ static void scst_cdb_trace_bounds(struct kunit *test)
|
||||
KUNIT_EXPECT_EQ(test, buf[1], 'x');
|
||||
}
|
||||
|
||||
static void scst_lun_unaligned_encoding(struct kunit *test)
|
||||
{
|
||||
u8 data[16] __aligned(8);
|
||||
unsigned int offset, len, tail;
|
||||
|
||||
for (offset = 0; offset < 8; offset++) {
|
||||
for (len = 2; len <= 8; len += 2) {
|
||||
u8 *lun = data + offset;
|
||||
|
||||
/* Nonzero bytes outside len must not affect decoding. */
|
||||
memset(data, 0x5a, sizeof(data));
|
||||
memset(lun, 0, len);
|
||||
lun[0] = 0x52;
|
||||
lun[1] = 0x34;
|
||||
KUNIT_EXPECT_EQ_MSG(test, scst_unpack_lun(lun, len), (u64)0x1234,
|
||||
"offset=%u len=%u", offset, len);
|
||||
for (tail = 2; tail < len; tail++) {
|
||||
lun[tail] = 1;
|
||||
KUNIT_EXPECT_EQ_MSG(test, scst_unpack_lun(lun, len),
|
||||
(u64)NO_SUCH_LUN, "offset=%u len=%u tail=%u",
|
||||
offset, len, tail);
|
||||
lun[tail] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct kunit_case scst_lib_cases[] = {
|
||||
KUNIT_CASE(scst_lun_unaligned_encoding),
|
||||
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),
|
||||
|
||||
+3
-3
@@ -12371,15 +12371,15 @@ uint64_t scst_unpack_lun(const uint8_t *lun, int len)
|
||||
case 2:
|
||||
break;
|
||||
case 8:
|
||||
if ((*((__be64 const *)lun) & cpu_to_be64(0x0000FFFFFFFFFFFFLL)) != 0)
|
||||
if (get_unaligned_be64(lun) & 0x0000FFFFFFFFFFFFULL)
|
||||
goto out_err;
|
||||
break;
|
||||
case 4:
|
||||
if (*((__be16 const *)&lun[2]) != 0)
|
||||
if (get_unaligned_be16(lun + 2) != 0)
|
||||
goto out_err;
|
||||
break;
|
||||
case 6:
|
||||
if (*((__be32 const *)&lun[2]) != 0)
|
||||
if (get_unaligned_be32(lun + 2) != 0)
|
||||
goto out_err;
|
||||
break;
|
||||
case 1:
|
||||
|
||||
Reference in New Issue
Block a user