[Replicant] [libsamsung-ipc] [PATCH v2 3/3] ipc_nv_data_md5_calculate: handle size mismatch better

Denis 'GNUtoo' Carikli GNUtoo at cyberdimension.org
Thu Dec 3 01:09:29 UTC 2020


Currently libsamsung-ipc assumes that the size of nv_data.bin
files are always 0x200000.

While it's supposed to be the case for all the devices we support,
it is still a good idea to make sure that a meaningful error message
is reported to the users of nv_data-md5.

For instance if we created an empty file of 1 kB with the following
command:
    $ ddrescue -s 1k /dev/zero zero.img

and that we used nv_data-md5 on it:
    $ ./tools/nv_data-md5 zero.img
    [ipc] file_data_read: Error: rc < 0
    [ipc] ipc_nv_data_md5_calculate failed: data is NULL
    Calculating nv_data backup md5 failed
we had a completely meaningless error message.

With this patch the error message looks like that instead:
    $ ./tools/nv_data-md5 zero.img
    [ipc] ipc_nv_data_md5_calculate: Checking zero.img size failed:
          requested size: 2097152, file size: 1000
    Calculating nv_data backup md5 failed
Here users have at least a fighting chance of being able to understand
what is going wrong.

Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo at cyberdimension.org>
---
ChangeLog since v1:
- improved error handling (errno, etc)
- fixed compilation warning about comparing unsigned and signed
---
 samsung-ipc/rfs.c   | 18 ++++++++++++++++++
 samsung-ipc/utils.c | 10 ++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/samsung-ipc/rfs.c b/samsung-ipc/rfs.c
index 93d2b6e..c9cee1b 100644
--- a/samsung-ipc/rfs.c
+++ b/samsung-ipc/rfs.c
@@ -38,16 +38,34 @@ char *ipc_nv_data_md5_calculate(struct ipc_client *client,
 				const char *path, const char *secret,
 				size_t size, size_t chunk_size)
 {
+	struct stat st;
 	void *data = NULL;
 	char *md5_string = NULL;
 	unsigned char md5_hash[MD5_DIGEST_LENGTH] = { 0 };
 	MD5_CTX ctx;
+	int rc;
 
 	if (secret == NULL) {
 		ipc_client_log(client, "%s: Failed: secret is NULL", __func__);
 		return NULL;
 	}
 
+	rc = stat(path, &st);
+	if (rc == -1) {
+		rc = errno;
+		ipc_client_log(client, "%s: stat failed with error %d",
+			       __func__, rc, strerror(rc));
+		return NULL;
+	}
+
+	if ((unsigned long)st.st_size != size) {
+		ipc_client_log(client,
+			       "%s: Checking %s size failed: "
+			       "requested size: %d, file size: %d\n",
+			       __func__, path, size, st.st_size);
+		return NULL;
+	}
+
 	data = file_data_read(client, path, size, chunk_size, 0);
 	if (data == NULL) {
 		ipc_client_log(client, "%s failed: data is NULL", __func__);
diff --git a/samsung-ipc/utils.c b/samsung-ipc/utils.c
index a2ef2bf..c0734ac 100644
--- a/samsung-ipc/utils.c
+++ b/samsung-ipc/utils.c
@@ -93,8 +93,14 @@ void *file_data_read(struct ipc_client *client, const char *path, size_t size,
 		rc = read(fd, p,
 			  size - count > chunk_size ?
 			  chunk_size : size - count);
-		if (rc <= 0) {
-			ipc_client_log(client, "%s: Error: rc < 0", __func__);
+		if (rc == -1) {
+			rc = errno;
+			ipc_client_log(client, "%s: read error: %d: %s",
+				       __func__, rc, strerror(rc));
+			goto error;
+		} else if (rc == 0) {
+			ipc_client_log(client, "%s: read error: end of file",
+				       __func__);
 			goto error;
 		}
 
-- 
2.29.2



More information about the Replicant mailing list