Skip to content

Commit 8cbbfd6

Browse files
authored
Merge pull request #499 from CodeConstruct/pr/log-page
mi: fix get_log_page chunked offset check
2 parents 86edb55 + 4c1d3d2 commit 8cbbfd6

2 files changed

Lines changed: 82 additions & 1 deletion

File tree

src/nvme/mi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ static int __nvme_mi_admin_get_log(nvme_mi_ctrl_t ctrl,
498498
return -1;
499499
}
500500

501-
if (offset < 0 || offset >= len) {
501+
if (offset < 0 || offset >= args->len || offset + len > args->len) {
502502
errno = EINVAL;
503503
return -1;
504504
}

test/mi.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,6 +1699,86 @@ static void test_admin_sanitize_nvm(struct nvme_mi_ep *ep)
16991699
assert(!rc);
17001700
}
17011701

1702+
/* test that we set the correct offset and size on get_log() calls that
1703+
* are split into multiple requests */
1704+
struct log_data {
1705+
int n;
1706+
};
1707+
1708+
static int test_admin_get_log_split_cb(struct nvme_mi_ep *ep,
1709+
struct nvme_mi_req *req,
1710+
struct nvme_mi_resp *resp,
1711+
void *data)
1712+
{
1713+
struct log_data *ldata = data;
1714+
uint32_t len, off;
1715+
__u8 *rq_hdr;
1716+
1717+
assert(req->data_len == 0);
1718+
1719+
rq_hdr = (__u8 *)req->hdr;
1720+
1721+
assert(rq_hdr[4] == nvme_admin_get_log_page);
1722+
1723+
/* from the MI message's DOFST/DLEN fields */
1724+
off = rq_hdr[31] << 24 | rq_hdr[30] << 16 | rq_hdr[29] << 8 | rq_hdr[28];
1725+
len = rq_hdr[35] << 24 | rq_hdr[34] << 16 | rq_hdr[33] << 8 | rq_hdr[32];
1726+
1727+
/* we should have a full-sized start and middle, and a short end */
1728+
switch (ldata->n) {
1729+
case 0:
1730+
assert(len == 4096);
1731+
assert(off == 0);
1732+
break;
1733+
case 1:
1734+
assert(len == 4096);
1735+
assert(off == 4096);
1736+
break;
1737+
case 2:
1738+
assert(len == 4);
1739+
assert(off == 4096 * 2);
1740+
break;
1741+
default:
1742+
assert(0);
1743+
}
1744+
1745+
/* ensure we've sized the expected response correctly */
1746+
assert(resp->data_len == len);
1747+
memset(resp->data, ldata->n & 0xff, len);
1748+
1749+
test_transport_resp_calc_mic(resp);
1750+
1751+
ldata->n++;
1752+
1753+
return 0;
1754+
}
1755+
1756+
static void test_admin_get_log_split(struct nvme_mi_ep *ep)
1757+
{
1758+
unsigned char buf[4096 * 2 + 4];
1759+
struct nvme_get_log_args args;
1760+
struct log_data ldata;
1761+
nvme_mi_ctrl_t ctrl;
1762+
int rc;
1763+
1764+
ldata.n = 0;
1765+
test_set_transport_callback(ep, test_admin_get_log_split_cb, &ldata);
1766+
1767+
ctrl = nvme_mi_init_ctrl(ep, 5);
1768+
1769+
args.args_size = sizeof(args);
1770+
args.lid = 1;
1771+
args.log = buf;
1772+
args.len = sizeof(buf);
1773+
1774+
rc = nvme_mi_admin_get_log(ctrl, &args);
1775+
1776+
assert(!rc);
1777+
1778+
/* we should have sent three commands */
1779+
assert(ldata.n == 3);
1780+
}
1781+
17021782
#define DEFINE_TEST(name) { #name, test_ ## name }
17031783
struct test {
17041784
const char *name;
@@ -1738,6 +1818,7 @@ struct test {
17381818
DEFINE_TEST(admin_fw_commit),
17391819
DEFINE_TEST(admin_format_nvm),
17401820
DEFINE_TEST(admin_sanitize_nvm),
1821+
DEFINE_TEST(admin_get_log_split),
17411822
};
17421823

17431824
static void run_test(struct test *test, FILE *logfd, nvme_mi_ep_t ep)

0 commit comments

Comments
 (0)