Do not accept empty delta elements
authortb <tb@openbsd.org>
Tue, 26 Dec 2023 11:03:27 +0000 (11:03 +0000)
committertb <tb@openbsd.org>
Tue, 26 Dec 2023 11:03:27 +0000 (11:03 +0000)
Ties de Kock found RRDP content that doesn't match the XML schema, most
likely generated by krill: https://github.com/NLnetLabs/krill/issues/1180

Use the state machine to mark a new delta element as empty and check at
the end whether that state was changed (which means it contained publish
or withdraw elements). If so, raise a parse failure.

ok claudio job

usr.sbin/rpki-client/rrdp_delta.c

index 1e73f74..d977b92 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rrdp_delta.c,v 1.10 2023/12/24 10:48:58 job Exp $ */
+/*     $OpenBSD: rrdp_delta.c,v 1.11 2023/12/26 11:03:27 tb Exp $ */
 /*
  * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -31,6 +31,7 @@
 
 enum delta_scope {
        DELTA_SCOPE_NONE,
+       DELTA_SCOPE_EMPTY_DELTA,
        DELTA_SCOPE_DELTA,
        DELTA_SCOPE_PUBLISH,
        DELTA_SCOPE_END
@@ -91,7 +92,7 @@ start_delta_elem(struct delta_xml *dxml, const char **attr)
        if (dxml->current->serial != dxml->serial)
                PARSE_FAIL(p, "parse failed - serial mismatch");
 
-       dxml->scope = DELTA_SCOPE_DELTA;
+       dxml->scope = DELTA_SCOPE_EMPTY_DELTA;
 }
 
 static void
@@ -99,6 +100,8 @@ end_delta_elem(struct delta_xml *dxml)
 {
        XML_Parser p = dxml->parser;
 
+       if (dxml->scope == DELTA_SCOPE_EMPTY_DELTA)
+               PARSE_FAIL(p, "parse failed - empty delta");
        if (dxml->scope != DELTA_SCOPE_DELTA)
                PARSE_FAIL(p, "parse failed - exited delta "
                    "elem unexpectedely");
@@ -114,7 +117,8 @@ start_publish_withdraw_elem(struct delta_xml *dxml, const char **attr,
        int i, hasUri = 0, hasHash = 0;
        enum publish_type pub = PUB_UPD;
 
-       if (dxml->scope != DELTA_SCOPE_DELTA)
+       if (dxml->scope != DELTA_SCOPE_EMPTY_DELTA &&
+           dxml->scope != DELTA_SCOPE_DELTA)
                PARSE_FAIL(p, "parse failed - entered publish/withdraw "
                    "elem unexpectedely");
        for (i = 0; attr[i]; i += 2) {