patch 'telemetry: fix escaping of invalid json characters' has been queued to stable release 20.11.7

luca.boccassi at gmail.com luca.boccassi at gmail.com
Thu Nov 3 10:26:35 CET 2022


Hi,

FYI, your patch has been queued to stable release 20.11.7

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 11/05/22. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/kevintraynor/dpdk-stable

This queued commit can be viewed at:
https://github.com/kevintraynor/dpdk-stable/commit/8d11cb48eb40641e17af79149b3297488dd9f7ec

Thanks.

Luca Boccassi

---
>From 8d11cb48eb40641e17af79149b3297488dd9f7ec Mon Sep 17 00:00:00 2001
From: Bruce Richardson <bruce.richardson at intel.com>
Date: Fri, 9 Sep 2022 10:35:13 +0100
Subject: [PATCH] telemetry: fix escaping of invalid json characters
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

[ upstream commit babc5214449d3566134294f30e6b4907bd813ac9 ]

For string values returned from telemetry, escape any values that cannot
normally appear in a json string. According to the json spec[1], the
characters than need to be handled are control chars (char value < 0x20)
and '"' and '\' characters.

To handle this, we replace the snprintf call with a separate string
copying and encapsulation routine which checks each character as it
copies it to the final array.

[1] https://www.rfc-editor.org/rfc/rfc8259.txt

Bugzilla ID: 1037
Fixes: 6dd571fd07c3 ("telemetry: introduce new functionality")

Signed-off-by: Bruce Richardson <bruce.richardson at intel.com>
Acked-by: Ciara Power <ciara.power at intel.com>
Acked-by: Morten Brørup <mb at smartsharesystems.com>
Acked-by: Chengwen Feng <fengchengwen at huawei.com>
---
 lib/librte_telemetry/telemetry.c      | 11 ++++--
 lib/librte_telemetry/telemetry_json.h | 48 ++++++++++++++++++++++++++-
 2 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/lib/librte_telemetry/telemetry.c b/lib/librte_telemetry/telemetry.c
index 9d970d167e..c3522b7173 100644
--- a/lib/librte_telemetry/telemetry.c
+++ b/lib/librte_telemetry/telemetry.c
@@ -181,9 +181,14 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s)
 				MAX_CMD_LEN, cmd ? cmd : "none");
 		break;
 	case RTE_TEL_STRING:
-		used = snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":\"%.*s\"}",
-				MAX_CMD_LEN, cmd,
-				RTE_TEL_MAX_SINGLE_STRING_LEN, d->data.str);
+		prefix_used = snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":",
+				MAX_CMD_LEN, cmd);
+		cb_data_buf = &out_buf[prefix_used];
+		buf_len = sizeof(out_buf) - prefix_used - 1; /* space for '}' */
+
+		used = rte_tel_json_str(cb_data_buf, buf_len, 0, d->data.str);
+		used += prefix_used;
+		used += strlcat(out_buf + used, "}", sizeof(out_buf) - used);
 		break;
 	case RTE_TEL_DICT:
 		prefix_used = snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":",
diff --git a/lib/librte_telemetry/telemetry_json.h b/lib/librte_telemetry/telemetry_json.h
index db70690274..13df5d07e3 100644
--- a/lib/librte_telemetry/telemetry_json.h
+++ b/lib/librte_telemetry/telemetry_json.h
@@ -44,6 +44,52 @@ __json_snprintf(char *buf, const int len, const char *format, ...)
 	return 0; /* nothing written or modified */
 }
 
+static const char control_chars[0x20] = {
+		['\n'] = 'n',
+		['\r'] = 'r',
+		['\t'] = 't',
+};
+
+/**
+ * @internal
+ * Does the same as __json_snprintf(buf, len, "\"%s\"", str)
+ * except that it does proper escaping as necessary.
+ * Drops any invalid characters we don't support
+ */
+static inline int
+__json_format_str(char *buf, const int len, const char *str)
+{
+	char tmp[len];
+	int tmpidx = 0;
+
+	tmp[tmpidx++] = '"';
+	while (*str != '\0') {
+		if (*str < (int)RTE_DIM(control_chars)) {
+			int idx = *str;  /* compilers don't like char type as index */
+			if (control_chars[idx] != 0) {
+				tmp[tmpidx++] = '\\';
+				tmp[tmpidx++] = control_chars[idx];
+			}
+		} else if (*str == '"' || *str == '\\') {
+			tmp[tmpidx++] = '\\';
+			tmp[tmpidx++] = *str;
+		} else
+			tmp[tmpidx++] = *str;
+		/* we always need space for closing quote and null character.
+		 * Ensuring at least two free characters also means we can always take an
+		 * escaped character like "\n" without overflowing
+		 */
+		if (tmpidx > len - 2)
+			return 0;
+		str++;
+	}
+	tmp[tmpidx++] = '"';
+	tmp[tmpidx] = '\0';
+
+	strcpy(buf, tmp);
+	return tmpidx;
+}
+
 /* Copies an empty array into the provided buffer. */
 static inline int
 rte_tel_json_empty_array(char *buf, const int len, const int used)
@@ -62,7 +108,7 @@ rte_tel_json_empty_obj(char *buf, const int len, const int used)
 static inline int
 rte_tel_json_str(char *buf, const int len, const int used, const char *str)
 {
-	return used + __json_snprintf(buf + used, len - used, "\"%s\"", str);
+	return used + __json_format_str(buf + used, len - used, str);
 }
 
 /* Appends a string into the JSON array in the provided buffer. */
-- 
2.34.1

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2022-11-03 09:27:26.507441742 +0000
+++ 0017-telemetry-fix-escaping-of-invalid-json-characters.patch	2022-11-03 09:27:25.321421435 +0000
@@ -1 +1 @@
-From babc5214449d3566134294f30e6b4907bd813ac9 Mon Sep 17 00:00:00 2001
+From 8d11cb48eb40641e17af79149b3297488dd9f7ec Mon Sep 17 00:00:00 2001
@@ -8,0 +9,2 @@
+[ upstream commit babc5214449d3566134294f30e6b4907bd813ac9 ]
+
@@ -28,2 +30,2 @@
- lib/telemetry/telemetry.c      | 11 +++++---
- lib/telemetry/telemetry_json.h | 48 +++++++++++++++++++++++++++++++++-
+ lib/librte_telemetry/telemetry.c      | 11 ++++--
+ lib/librte_telemetry/telemetry_json.h | 48 ++++++++++++++++++++++++++-
@@ -32,5 +34,5 @@
-diff --git a/lib/telemetry/telemetry.c b/lib/telemetry/telemetry.c
-index 164ea0601a..72334d2429 100644
---- a/lib/telemetry/telemetry.c
-+++ b/lib/telemetry/telemetry.c
-@@ -234,9 +234,14 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s)
+diff --git a/lib/librte_telemetry/telemetry.c b/lib/librte_telemetry/telemetry.c
+index 9d970d167e..c3522b7173 100644
+--- a/lib/librte_telemetry/telemetry.c
++++ b/lib/librte_telemetry/telemetry.c
+@@ -181,9 +181,14 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s)
@@ -54 +56 @@
-diff --git a/lib/telemetry/telemetry_json.h b/lib/telemetry/telemetry_json.h
+diff --git a/lib/librte_telemetry/telemetry_json.h b/lib/librte_telemetry/telemetry_json.h
@@ -56,2 +58,2 @@
---- a/lib/telemetry/telemetry_json.h
-+++ b/lib/telemetry/telemetry_json.h
+--- a/lib/librte_telemetry/telemetry_json.h
++++ b/lib/librte_telemetry/telemetry_json.h


More information about the stable mailing list