summaryrefslogtreecommitdiff
path: root/src/test/test-json.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-10-12 15:38:17 +0200
committerLennart Poettering <lennart@poettering.net>2018-10-18 16:44:51 +0200
commitb2fa0d4fcab75f7012fc899dedfa68afeea9903c (patch)
tree97ac022a45c4863b1be9c152b5a6494df7f09ff6 /src/test/test-json.c
parenta7efb030391547d01b4c0bcc5a296404decc75ab (diff)
downloadsystemd-b2fa0d4fcab75f7012fc899dedfa68afeea9903c.tar.gz
json: enforce a maximum nesting depth for json variants
Simply as a safety precaution so that json objects we read are not arbitrary amounts deep, so that code that processes json objects recursively can't be easily exploited (by hitting stack limits). Follow-up for oss-fuzz#10908 (Nice is that we can accomodate for this counter without increasing the size of the JsonVariant object.)
Diffstat (limited to 'src/test/test-json.c')
-rw-r--r--src/test/test-json.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/test/test-json.c b/src/test/test-json.c
index e145559ae9..bcf94b211c 100644
--- a/src/test/test-json.c
+++ b/src/test/test-json.c
@@ -354,6 +354,38 @@ static void test_source(void) {
printf("--- pretty end ---\n");
}
+static void test_depth(void) {
+ _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *k = NULL;
+ unsigned i;
+ int r;
+
+ assert_se(json_variant_new_string(&k, "hallo") >= 0);
+ v = json_variant_ref(k);
+
+ /* Let's verify that the maximum depth checks work */
+
+ for (i = 0;; i++) {
+ _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
+
+ assert_se(i <= UINT16_MAX);
+ if (i & 1)
+ r = json_variant_new_array(&w, &v, 1);
+ else
+ r = json_variant_new_object(&w, (JsonVariant*[]) { k, v }, 2);
+ if (r == -ELNRNG) {
+ log_info("max depth at %u", i);
+ break;
+ }
+
+ assert_se(r >= 0);
+
+ json_variant_unref(v);
+ v = TAKE_PTR(w);
+ }
+
+ json_variant_dump(v, 0, stdout, NULL);
+}
+
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
@@ -407,5 +439,7 @@ int main(int argc, char *argv[]) {
test_source();
+ test_depth();
+
return 0;
}