From: Steven Seungcheol Lee Date: Thu, 26 Aug 2021 03:06:11 +0000 (+0900) Subject: nvme: PEL need to check gen number for verification of collected log X-Git-Tag: v1.16~30^2~3 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=7af853ec77dbda8b63f07e96874cb2ff01c99b96;p=users%2Fsagi%2Fnvme-cli.git nvme: PEL need to check gen number for verification of collected log +fix bug(unallocated pointer free) If the Persistent Event Log is not read with a single Get Log Page command, then host software should read the Generation Number field in the Persistent Event Log header after establishing a reporting context but before reading the remainder of the log and then re-read the Generation Number field after it has read the entire log. If the generation numbers do not match, then: • the reporting context may have been lost while reading the log; • the Persistent Event Log contents read may be invalid; and • host software should re-read the log. Signed-off-by: Steven Seungcheol Lee --- diff --git a/nvme.c b/nvme.c index c10932f0..8f970bb1 100644 --- a/nvme.c +++ b/nvme.c @@ -929,7 +929,7 @@ static int get_persistent_event_log(int argc, char **argv, const char *log_len = "number of bytes to retrieve"; const char *raw = "use binary output"; void *pevent_log_info; - struct nvme_persistent_event_log_head *pevent_log_head = NULL; + struct nvme_persistent_event_log_head *pevent_log_head, *collected_head; enum nvme_print_flags flags; int err = -1, fd; bool huge; @@ -985,22 +985,22 @@ static int get_persistent_event_log(int argc, char **argv, sizeof(*pevent_log_head), pevent_log_head); if (err < 0) { perror("persistent event log"); - goto close_fd; + goto free_head; } else if (err) { nvme_show_status(err); - goto close_fd; + goto free_head; } if (cfg.action == NVME_PEVENT_LOG_RELEASE_CTX) { printf("Releasing Persistent Event Log Context\n"); - goto close_fd; + goto free_head; } if (!cfg.log_len && cfg.action != NVME_PEVENT_LOG_EST_CTX_AND_READ) { cfg.log_len = le64_to_cpu(pevent_log_head->tll); } else if (!cfg.log_len && cfg.action == NVME_PEVENT_LOG_EST_CTX_AND_READ) { printf("Establishing Persistent Event Log Context\n"); - goto close_fd; + goto free_head; } /* @@ -1018,22 +1018,39 @@ static int get_persistent_event_log(int argc, char **argv, perror("could not alloc buffer for persistent event log page\n"); errno = ENOMEM; err = -1; - goto close_fd; + goto free_head; } err = nvme_persistent_event_log(fd, cfg.action, cfg.log_len, pevent_log_info); - if (!err) + if (!err) { + err = nvme_persistent_event_log(fd, cfg.action, + sizeof(*pevent_log_head), pevent_log_head); + if (err < 0) { + perror("persistent event log"); + goto free; + } else if (err) { + nvme_show_status(err); + goto free; + } + collected_head = pevent_log_info; + if(collected_head->gen_number != pevent_log_head->gen_number) { + printf("Collected Persistent Event Log may be invalid, "\ + "Re-read the log is reiquired\n"); + goto free; + } nvme_show_persistent_event_log(pevent_log_info, cfg.action, cfg.log_len, devicename, flags); + } else if (err > 0) nvme_show_status(err); else perror("persistent event log"); +free: nvme_free(pevent_log_info, huge); - -close_fd: +free_head: free(pevent_log_head); +close_fd: close(fd); ret: return nvme_status_to_errno(err, false);