forked from pool/tpm2.0-tools
Marcus Meissner
45f5061ef4
- Add 0001-tpm2_eventlog-read-eventlog-file-in-chunks.patch to fix the tpm2_eventlog command (boo#1187360) OBS-URL: https://build.opensuse.org/request/show/900773 OBS-URL: https://build.opensuse.org/package/show/security/tpm2.0-tools?expand=0&rev=78
146 lines
4.7 KiB
Diff
146 lines
4.7 KiB
Diff
From b95e41bccc64e488ca9c824e632b8ca5bc87db55 Mon Sep 17 00:00:00 2001
|
|
From: Alberto Planas <aplanas@suse.com>
|
|
Date: Fri, 18 Jun 2021 15:54:22 +0200
|
|
Subject: [PATCH] tpm2_eventlog: read eventlog file in chunks
|
|
|
|
The eventlog file lives is securityfs, that do not return the file size.
|
|
The current implementation first try to do a "fseek(fp, 0, SEEK_END)"
|
|
for this file, and this will always return 0.
|
|
|
|
This generate an error, and tpm2_eventlog exit with:
|
|
|
|
ERROR: Unable to run tpm2_eventlog
|
|
|
|
This patch replace the reading logic, now reading in chunks of 16KB and
|
|
reallocating the buffer if needed. Also introduces a new function in
|
|
files.c ("files_read_bytes_chunk") that helps counting the total read
|
|
size, that now is different from the ammount of allocated memory.
|
|
|
|
Fixes #2775
|
|
|
|
Signed-off-by: Alberto Planas <aplanas@suse.com>
|
|
---
|
|
lib/files.c | 9 +++++++++
|
|
lib/files.h | 15 ++++++++++++++
|
|
tools/misc/tpm2_eventlog.c | 40 +++++++++++++++++++-------------------
|
|
3 files changed, 44 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/lib/files.c b/lib/files.c
|
|
index 884dd23c..7f0fb39f 100644
|
|
--- a/lib/files.c
|
|
+++ b/lib/files.c
|
|
@@ -564,6 +564,15 @@ bool files_read_bytes(FILE *out, UINT8 bytes[], size_t len) {
|
|
return (readx(out, bytes, len) == len);
|
|
}
|
|
|
|
+bool files_read_bytes_chunk(FILE *out, UINT8 bytes[], size_t len, size_t *read_len) {
|
|
+
|
|
+ BAIL_ON_NULL("FILE", out);
|
|
+ BAIL_ON_NULL("bytes", bytes);
|
|
+ size_t chunk_len = readx(out, bytes, len);
|
|
+ *read_len += chunk_len;
|
|
+ return (chunk_len == len);
|
|
+}
|
|
+
|
|
bool files_write_bytes(FILE *out, uint8_t bytes[], size_t len) {
|
|
|
|
BAIL_ON_NULL("FILE", out);
|
|
diff --git a/lib/files.h b/lib/files.h
|
|
index 33022cbd..684b7eef 100644
|
|
--- a/lib/files.h
|
|
+++ b/lib/files.h
|
|
@@ -571,6 +571,21 @@ bool files_read_64(FILE *out, UINT64 *data);
|
|
*/
|
|
bool files_read_bytes(FILE *out, UINT8 data[], size_t size);
|
|
|
|
+/**
|
|
+ * Reads len bytes from a file and set the read length.
|
|
+ * @param out
|
|
+ * The file to read from.
|
|
+ * @param data
|
|
+ * The buffer to read into, only valid on a True return.
|
|
+ * @param size
|
|
+ * The number of bytes to read.
|
|
+ * @param read_size
|
|
+ * Total number of bytes readed.
|
|
+ * @return
|
|
+ * True on success, False otherwise.
|
|
+ */
|
|
+bool files_read_bytes_chunk(FILE *out, UINT8 data[], size_t size, size_t *read_size);
|
|
+
|
|
/**
|
|
* Converts a TPM2B_ATTEST to a TPMS_ATTEST using libmu.
|
|
* @param quoted
|
|
diff --git a/tools/misc/tpm2_eventlog.c b/tools/misc/tpm2_eventlog.c
|
|
index b51089bd..64ce6add 100644
|
|
--- a/tools/misc/tpm2_eventlog.c
|
|
+++ b/tools/misc/tpm2_eventlog.c
|
|
@@ -12,6 +12,8 @@
|
|
#include "tpm2_eventlog_yaml.h"
|
|
#include "tpm2_tool.h"
|
|
|
|
+#define CHUNK_SIZE 16384
|
|
+
|
|
static char *filename = NULL;
|
|
|
|
/* Set the default YAML version */
|
|
@@ -72,37 +74,35 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) {
|
|
return tool_rc_option_error;
|
|
}
|
|
|
|
- /* Get file size */
|
|
- unsigned long size = 0;
|
|
- bool ret = files_get_file_size_path(filename, &size);
|
|
- if (!ret || !size) {
|
|
+ /* Read the file in chunks. Usually the file will reside in
|
|
+ securityfs, and those files do not have a public file size */
|
|
+ tool_rc rc = tool_rc_success;
|
|
+ FILE *fileptr = fopen(filename, "rb");
|
|
+ if (!fileptr) {
|
|
return tool_rc_general_error;
|
|
}
|
|
|
|
- /* Allocate buffer to read file data */
|
|
- UINT8 *eventlog = calloc(1, size);
|
|
+ /* Reserve the buffer for the first chunk */
|
|
+ UINT8 *eventlog = calloc(1, CHUNK_SIZE);
|
|
if (eventlog == NULL){
|
|
- LOG_ERR("failed to allocate %lu bytes: %s", size, strerror(errno));
|
|
+ LOG_ERR("failed to allocate %d bytes: %s", CHUNK_SIZE, strerror(errno));
|
|
return tool_rc_general_error;
|
|
}
|
|
|
|
- /* Load buffer with file data */
|
|
- tool_rc rc = tool_rc_success;
|
|
- FILE *fileptr = fopen(filename, "rb");
|
|
- if (!fileptr) {
|
|
- rc = tool_rc_general_error;
|
|
- goto out;
|
|
+ unsigned long size = 0;
|
|
+ while (files_read_bytes_chunk(fileptr, eventlog, CHUNK_SIZE, &size)) {
|
|
+ UINT8 *eventlog_tmp = realloc(eventlog, size + CHUNK_SIZE);
|
|
+ if (eventlog_tmp == NULL){
|
|
+ LOG_ERR("failed to allocate %lu bytes: %s", size + CHUNK_SIZE, strerror(errno));
|
|
+ rc = tool_rc_general_error;
|
|
+ goto out;
|
|
+ }
|
|
+ eventlog = eventlog_tmp;
|
|
}
|
|
-
|
|
- ret = files_read_bytes(fileptr, eventlog, size);
|
|
fclose(fileptr);
|
|
- if (!ret) {
|
|
- rc = tool_rc_general_error;
|
|
- goto out;
|
|
- }
|
|
|
|
/* Parse eventlog data */
|
|
- ret = yaml_eventlog(eventlog, size, eventlog_version);
|
|
+ bool ret = yaml_eventlog(eventlog, size, eventlog_version);
|
|
if (!ret) {
|
|
LOG_ERR("failed to parse tpm2 eventlog");
|
|
rc = tool_rc_general_error;
|
|
--
|
|
2.32.0
|
|
|