aboutsummaryrefslogtreecommitdiff
path: root/hw/block
diff options
context:
space:
mode:
authorKeith Busch <kbusch@kernel.org>2020-09-30 10:01:02 -0700
committerKlaus Jensen <k.jensen@samsung.com>2020-10-27 11:29:25 +0100
commita740facfbd05c9dd630e1f992a9dc6b5444096a7 (patch)
tree40b4fc09f755275e6e00cd7291d0868f4181b41f /hw/block
parent8c125590dfa33699a267c797a41939c1ac8b77bf (diff)
hw/block/nvme: fix log page offset check
Return error if the requested offset starts after the size of the log being returned. Also, move the check for earlier in the function so we're not doing unnecessary calculations. Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed- by: Dmitry Fomichev <dmitry.fomichev@wdc.com> Signed-off-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
Diffstat (limited to 'hw/block')
-rw-r--r--hw/block/nvme.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index a168f0bf4a..aa725d1141 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1179,6 +1179,10 @@ static uint16_t nvme_smart_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len,
return NVME_INVALID_FIELD | NVME_DNR;
}
+ if (off >= sizeof(smart)) {
+ return NVME_INVALID_FIELD | NVME_DNR;
+ }
+
for (int i = 1; i <= n->num_namespaces; i++) {
NvmeNamespace *ns = nvme_ns(n, i);
if (!ns) {
@@ -1193,10 +1197,6 @@ static uint16_t nvme_smart_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len,
write_commands += s->nr_ops[BLOCK_ACCT_WRITE];
}
- if (off > sizeof(smart)) {
- return NVME_INVALID_FIELD | NVME_DNR;
- }
-
trans_len = MIN(sizeof(smart) - off, buf_len);
memset(&smart, 0x0, sizeof(smart));
@@ -1234,12 +1234,11 @@ static uint16_t nvme_fw_log_info(NvmeCtrl *n, uint32_t buf_len, uint64_t off,
.afi = 0x1,
};
- strpadcpy((char *)&fw_log.frs1, sizeof(fw_log.frs1), "1.0", ' ');
-
- if (off > sizeof(fw_log)) {
+ if (off >= sizeof(fw_log)) {
return NVME_INVALID_FIELD | NVME_DNR;
}
+ strpadcpy((char *)&fw_log.frs1, sizeof(fw_log.frs1), "1.0", ' ');
trans_len = MIN(sizeof(fw_log) - off, buf_len);
return nvme_dma(n, (uint8_t *) &fw_log + off, trans_len,
@@ -1252,16 +1251,15 @@ static uint16_t nvme_error_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len,
uint32_t trans_len;
NvmeErrorLog errlog;
- if (!rae) {
- nvme_clear_events(n, NVME_AER_TYPE_ERROR);
+ if (off >= sizeof(errlog)) {
+ return NVME_INVALID_FIELD | NVME_DNR;
}
- if (off > sizeof(errlog)) {
- return NVME_INVALID_FIELD | NVME_DNR;
+ if (!rae) {
+ nvme_clear_events(n, NVME_AER_TYPE_ERROR);
}
memset(&errlog, 0x0, sizeof(errlog));
-
trans_len = MIN(sizeof(errlog) - off, buf_len);
return nvme_dma(n, (uint8_t *)&errlog, trans_len,