From b9152f2d633ee1847b1c38d0fc4e24809e642fa6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 7 Dec 2022 09:35:41 +0900 Subject: [PATCH] resolve: optimize conversion of TXT fields to json Fixes oss-fuzz#54080 (https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54080). Fixes #25654. --- src/resolve/resolved-dns-rr.c | 50 ++++++++++++------ test/fuzz/fuzz-resource-record/oss-fuzz-54080 | Bin 0 -> 29703 bytes 2 files changed, 33 insertions(+), 17 deletions(-) create mode 100644 test/fuzz/fuzz-resource-record/oss-fuzz-54080 diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index f4fa219ab7c..a4ba6bdc6d0 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -1889,6 +1889,36 @@ static int type_bitmap_to_json(Bitmap *b, JsonVariant **ret) { return 0; } +static int txt_to_json(DnsTxtItem *items, JsonVariant **ret) { + JsonVariant **elements = NULL; + size_t n = 0; + int r; + + assert(ret); + + LIST_FOREACH(items, i, items) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = json_variant_new_octescape(elements + n, i->data, i->length); + if (r < 0) + goto finalize; + + n++; + } + + r = json_variant_new_array(ret, elements, n); + +finalize: + for (size_t i = 0; i < n; i++) + json_variant_unref(elements[i]); + + free(elements); + return r; +} + int dns_resource_record_to_json(DnsResourceRecord *rr, JsonVariant **ret) { _cleanup_(json_variant_unrefp) JsonVariant *k = NULL; int r; @@ -1931,23 +1961,9 @@ int dns_resource_record_to_json(DnsResourceRecord *rr, JsonVariant **ret) { case DNS_TYPE_TXT: { _cleanup_(json_variant_unrefp) JsonVariant *l = NULL; - LIST_FOREACH(items, i, rr->txt.items) { - _cleanup_(json_variant_unrefp) JsonVariant *b = NULL; - - r = json_variant_new_octescape(&b, i->data, i->length); - if (r < 0) - return r; - - r = json_variant_append_array(&l, b); - if (r < 0) - return r; - } - - if (!l) { - r = json_variant_new_array(&l, NULL, 0); - if (r < 0) - return r; - } + r = txt_to_json(rr->txt.items, &l); + if (r < 0) + return r; return json_build(ret, JSON_BUILD_OBJECT( diff --git a/test/fuzz/fuzz-resource-record/oss-fuzz-54080 b/test/fuzz/fuzz-resource-record/oss-fuzz-54080 new file mode 100644 index 0000000000000000000000000000000000000000..2577e653d44bf96c1d5d5d3d8460c59f9cf2256a GIT binary patch literal 29703 zcmeI(&1%9x5Ww-#y?7}I1<&HC^w3x6*+&q(Sm<-)>Z|k_?7OAeB!w8VxMR>{Xa9Q$ zn*DI*7tk+KmY**0s?*~pw|K;IgNk~fj1jzL}syw9LF#O<|{zG zZob!s$PhpP0R(avP?YNqxm%Gx0tg_W6X@0I{9D}uj7A_afu!qo%|lEa6BlsKy{>#~ zpGr$Sosr?Yk@K0300LtLoLi1vBBS|{H$9XvBB2Fa9n8i6SUsPt*nBkx41^hH833;_fXPz&&9B{dln5HKsi_kr0