Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package frr for openSUSE:Factory checked in 
at 2022-03-01 17:03:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/frr (Old)
 and      /work/SRC/openSUSE:Factory/.frr.new.1958 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "frr"

Tue Mar  1 17:03:26 2022 rev:18 rq:958103 version:8.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/frr/frr.changes  2021-12-09 19:46:25.077156612 
+0100
+++ /work/SRC/openSUSE:Factory/.frr.new.1958/frr.changes        2022-03-01 
17:04:02.656341019 +0100
@@ -1,0 +2,18 @@
+Mon Feb 28 11:05:48 UTC 2022 - Marius Tomaschewski <m...@suse.com>
+
+- Apply fix for a buffer overflow in isisd due to the use of strdup
+  with a non-zero-terminated binary string (bsc#1196506,CVE-2022-26126)
+  [+ 0006-isisd-fix-10505-using-base64-encoding.patch]
+- Apply fix for a buffer overflow in isisd due to wrong checks on
+  the input packet length (bsc#1196505,CVE-2022-26125) with workaround
+  for the GIT binary patch to tests/isisd/test_fuzz_isis_tlv_tests.h.gz
+  [+ 0005-isisd-fix-router-capability-TLV-parsing-issues.patch]
+- Apply fix for a buffer overflow in babeld due to wrong checks on
+  the input packet length in the packet_examin and subtlv parsing
+  (bsc#1196504,bsc#1196507,CVE-2022-26128,CVE-2022-26129)
+  [+ 0004-babeld-fix-10502-10503-by-repairing-the-checks-on-le.patch]
+- Apply fix for a heap buffer overflow in babeld due to missing check
+  on the input packet length (bsc#1196503,CVE-2022-26127)
+  [+ 0003-babeld-fix-10487-by-adding-a-check-on-packet-length.patch]
+
+-------------------------------------------------------------------

New:
----
  0003-babeld-fix-10487-by-adding-a-check-on-packet-length.patch
  0004-babeld-fix-10502-10503-by-repairing-the-checks-on-le.patch
  0005-isisd-fix-router-capability-TLV-parsing-issues.patch
  0006-isisd-fix-10505-using-base64-encoding.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ frr.spec ++++++
--- /var/tmp/diff_new_pack.YWGqFE/_old  2022-03-01 17:04:03.404341218 +0100
+++ /var/tmp/diff_new_pack.YWGqFE/_new  2022-03-01 17:04:03.408341218 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package frr
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 # Copyright (c) 2019-2021, Martin Hauke <mar...@gmx.de>
 #
 # All modifications and additions to the file contributed by third parties
@@ -43,6 +43,10 @@
 Source1:        %{name}-tmpfiles.d
 Patch1:         0001-disable-zmq-test.patch
 Patch2:         harden_frr.service.patch
+Patch3:         0003-babeld-fix-10487-by-adding-a-check-on-packet-length.patch
+Patch4:         0004-babeld-fix-10502-10503-by-repairing-the-checks-on-le.patch
+Patch5:         0005-isisd-fix-router-capability-TLV-parsing-issues.patch
+Patch6:         0006-isisd-fix-10505-using-base64-encoding.patch
 BuildRequires:  %{python_module Sphinx}
 BuildRequires:  %{python_module devel}
 BuildRequires:  %{python_module pytest}
@@ -79,7 +83,7 @@
 Requires(post): %{install_info_prereq}
 Requires(pre):  %{install_info_prereq}
 Requires(pre):  shadow
-Requires(preun): %{install_info_prereq}
+Requires(preun):%{install_info_prereq}
 Recommends:     logrotate
 Conflicts:      quagga
 Provides:       zebra = %{version}
@@ -183,6 +187,12 @@
 %setup -q -n %{name}-%{name}-%{version}
 %patch1 -p1
 %patch2 -p1
+%patch3 -p1
+%patch4 -p1
+gzip -d tests/isisd/test_fuzz_isis_tlv_tests.h.gz
+%patch5 -p1
+gzip -9 tests/isisd/test_fuzz_isis_tlv_tests.h
+%patch6 -p1
 
 %build
 # GCC LTO objects must be "fat" to avoid assembly errors

++++++ 0003-babeld-fix-10487-by-adding-a-check-on-packet-length.patch ++++++
>From 50044ec7fe129e0a74d3a679dd29fe17ce30e6bf Mon Sep 17 00:00:00 2001
From: whichbug <which...@github.com>
Date: Thu, 3 Feb 2022 12:01:31 -0500
Upstream: yes
References: bsc#1196503,CVE-2022-26127
Subject: [PATCH] babeld: fix #10487 by adding a check on packet length

The body length of a packet should satisfy the condition:
packetlen >= bodylen + 4. Otherwise, heap overflows may happen.

Signed-off-by: whichbug <which...@github.com>

diff --git a/babeld/message.c b/babeld/message.c
index 5c2e29d8b..3a29b6a60 100644
--- a/babeld/message.c
+++ b/babeld/message.c
@@ -288,13 +288,18 @@ channels_len(unsigned char *channels)
 static int
 babel_packet_examin(const unsigned char *packet, int packetlen)
 {
-    unsigned i = 0, bodylen;
+    int i = 0, bodylen;
     const unsigned char *message;
     unsigned char type, len;
 
     if(packetlen < 4 || packet[0] != 42 || packet[1] != 2)
         return 1;
     DO_NTOHS(bodylen, packet + 2);
+    if(bodylen + 4 > packetlen) {
+        debugf(BABEL_DEBUG_COMMON, "Received truncated packet (%d + 4 > %d).",
+                 bodylen, packetlen);
+        return 1;
+    }
     while (i < bodylen){
         message = packet + 4 + i;
         type = message[0];
@@ -366,12 +371,6 @@ parse_packet(const unsigned char *from, struct interface 
*ifp,
 
     DO_NTOHS(bodylen, packet + 2);
 
-    if(bodylen + 4 > packetlen) {
-        flog_err(EC_BABEL_PACKET, "Received truncated packet (%d + 4 > %d).",
-                 bodylen, packetlen);
-        bodylen = packetlen - 4;
-    }
-
     i = 0;
     while(i < bodylen) {
         message = packet + 4 + i;
-- 
2.34.1


++++++ 0004-babeld-fix-10502-10503-by-repairing-the-checks-on-le.patch ++++++
>From c3793352a8d76d2eee1edc38a9a16c1c8a6573f4 Mon Sep 17 00:00:00 2001
From: qingkaishi <qingkai...@gmail.com>
Date: Fri, 4 Feb 2022 16:41:11 -0500
Upstream: yes
References: bsc#1196504,bsc#1196507,CVE-2022-26128,CVE-2022-26129
Subject: [PATCH] babeld: fix #10502 #10503 by repairing the checks on length

This patch repairs the checking conditions on length in four functions:
babel_packet_examin, parse_hello_subtlv, parse_ihu_subtlv, and 
parse_update_subtlv

Signed-off-by: qingkaishi <qingkai...@gmail.com>

diff --git a/babeld/message.c b/babeld/message.c
index 5c2e29d8b..053538700 100644
--- a/babeld/message.c
+++ b/babeld/message.c
@@ -140,12 +140,12 @@ parse_update_subtlv(const unsigned char *a, int alen,
             continue;
         }
 
-        if(i + 1 > alen) {
+        if(i + 1 >= alen) {
             flog_err(EC_BABEL_PACKET, "Received truncated attributes.");
             return;
         }
         len = a[i + 1];
-        if(i + len > alen) {
+        if(i + len + 2 > alen) {
             flog_err(EC_BABEL_PACKET, "Received truncated attributes.");
             return;
         }
@@ -182,19 +182,19 @@ parse_hello_subtlv(const unsigned char *a, int alen,
     int type, len, i = 0, ret = 0;
 
     while(i < alen) {
-        type = a[0];
+        type = a[i];
         if(type == SUBTLV_PAD1) {
             i++;
             continue;
         }
 
-        if(i + 1 > alen) {
+        if(i + 1 >= alen) {
             flog_err(EC_BABEL_PACKET,
                      "Received truncated sub-TLV on Hello message.");
             return -1;
         }
         len = a[i + 1];
-        if(i + len > alen) {
+        if(i + len + 2 > alen) {
             flog_err(EC_BABEL_PACKET,
                      "Received truncated sub-TLV on Hello message.");
             return -1;
@@ -228,19 +228,19 @@ parse_ihu_subtlv(const unsigned char *a, int alen,
     int type, len, i = 0, ret = 0;
 
     while(i < alen) {
-        type = a[0];
+        type = a[i];
         if(type == SUBTLV_PAD1) {
             i++;
             continue;
         }
 
-        if(i + 1 > alen) {
+        if(i + 1 >= alen) {
             flog_err(EC_BABEL_PACKET,
                      "Received truncated sub-TLV on IHU message.");
             return -1;
         }
         len = a[i + 1];
-        if(i + len > alen) {
+        if(i + len + 2 > alen) {
             flog_err(EC_BABEL_PACKET,
                      "Received truncated sub-TLV on IHU message.");
             return -1;
@@ -302,12 +302,12 @@ babel_packet_examin(const unsigned char *packet, int 
packetlen)
             i++;
             continue;
         }
-        if(i + 1 > bodylen) {
+        if(i + 2 > bodylen) {
             debugf(BABEL_DEBUG_COMMON,"Received truncated message.");
             return 1;
         }
         len = message[1];
-        if(i + len > bodylen) {
+        if(i + len + 2 > bodylen) {
             debugf(BABEL_DEBUG_COMMON,"Received truncated message.");
             return 1;
         }
-- 
2.34.1


++++++ 0005-isisd-fix-router-capability-TLV-parsing-issues.patch ++++++
>From 9ba865f54d331c550629304cb25e77ac81455803 Mon Sep 17 00:00:00 2001
From: Juraj Vijtiuk <juraj.vijt...@sartura.hr>
Date: Wed, 13 Oct 2021 18:32:53 +0200
Upstream: yes
References: bsc#1196505, CVE-2022-26125
Subject: [PATCH] isisd: fix router capability TLV parsing issues

isis_tlvs.c would fail at multiple places if incorrect TLVs were
received causing stream assertion violations.
This patch fixes the issues by adding missing length checks, missing
consumed length updates and handling malformed Segment Routing subTLVs.

Signed-off-by: Juraj Vijtiuk <juraj.vijt...@sartura.hr>

Small adjustments by Igor Ryzhov:
- fix incorrect replacement of srgb by srlb on lines 3052 and 3054
- add length check for ISIS_SUBTLV_ALGORITHM
- fix conflict in fuzzing data during rebase

Signed-off-by: Igor Ryzhov <iryz...@nfware.com>

diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c
index 9a442e037..f1aae7caf 100644
--- a/isisd/isis_tlvs.c
+++ b/isisd/isis_tlvs.c
@@ -3007,28 +3007,55 @@ static int unpack_tlv_router_cap(enum isis_tlv_context 
context,
 
                type = stream_getc(s);
                length = stream_getc(s);
+
+               if (length > STREAM_READABLE(s) || length > subtlv_len - 2) {
+                       sbuf_push(
+                               log, indent,
+                               "WARNING: Router Capability subTLV length too 
large compared to expected size\n");
+                       stream_forward_getp(s, STREAM_READABLE(s));
+
+                       return 0;
+               }
+
                switch (type) {
                case ISIS_SUBTLV_SID_LABEL_RANGE:
                        /* Check that SRGB is correctly formated */
                        if (length < SUBTLV_RANGE_LABEL_SIZE
                            || length > SUBTLV_RANGE_INDEX_SIZE) {
                                stream_forward_getp(s, length);
-                               continue;
+                               break;
                        }
                        /* Only one SRGB is supported. Skip subsequent one */
                        if (rcap->srgb.range_size != 0) {
                                stream_forward_getp(s, length);
-                               continue;
+                               break;
                        }
                        rcap->srgb.flags = stream_getc(s);
                        rcap->srgb.range_size = stream_get3(s);
                        /* Skip Type and get Length of SID Label */
                        stream_getc(s);
                        size = stream_getc(s);
-                       if (size == ISIS_SUBTLV_SID_LABEL_SIZE)
+
+                       if (size == ISIS_SUBTLV_SID_LABEL_SIZE
+                           && length != SUBTLV_RANGE_LABEL_SIZE) {
+                               stream_forward_getp(s, length - 6);
+                               break;
+                       }
+
+                       if (size == ISIS_SUBTLV_SID_INDEX_SIZE
+                           && length != SUBTLV_RANGE_INDEX_SIZE) {
+                               stream_forward_getp(s, length - 6);
+                               break;
+                       }
+
+                       if (size == ISIS_SUBTLV_SID_LABEL_SIZE) {
                                rcap->srgb.lower_bound = stream_get3(s);
-                       else
+                       } else if (size == ISIS_SUBTLV_SID_INDEX_SIZE) {
                                rcap->srgb.lower_bound = stream_getl(s);
+                       } else {
+                               stream_forward_getp(s, length - 6);
+                               break;
+                       }
 
                        /* SRGB sanity checks. */
                        if (rcap->srgb.range_size == 0
@@ -3042,9 +3069,12 @@ static int unpack_tlv_router_cap(enum isis_tlv_context 
context,
                        /* Only one range is supported. Skip subsequent one */
                        size = length - (size + SUBTLV_SR_BLOCK_SIZE);
                        if (size > 0)
-                               stream_forward_getp(s, length);
+                               stream_forward_getp(s, size);
+
                        break;
                case ISIS_SUBTLV_ALGORITHM:
+                       if (length == 0)
+                               break;
                        /* Only 2 algorithms are supported: SPF & Strict SPF */
                        stream_get(&rcap->algo, s,
                                   length > SR_ALGORITHM_COUNT
@@ -3059,12 +3089,12 @@ static int unpack_tlv_router_cap(enum isis_tlv_context 
context,
                        if (length < SUBTLV_RANGE_LABEL_SIZE
                            || length > SUBTLV_RANGE_INDEX_SIZE) {
                                stream_forward_getp(s, length);
-                               continue;
+                               break;
                        }
                        /* RFC 8667 section #3.3: Only one SRLB is authorized */
                        if (rcap->srlb.range_size != 0) {
                                stream_forward_getp(s, length);
-                               continue;
+                               break;
                        }
                        /* Ignore Flags which are not defined */
                        stream_getc(s);
@@ -3072,10 +3102,27 @@ static int unpack_tlv_router_cap(enum isis_tlv_context 
context,
                        /* Skip Type and get Length of SID Label */
                        stream_getc(s);
                        size = stream_getc(s);
-                       if (size == ISIS_SUBTLV_SID_LABEL_SIZE)
+
+                       if (size == ISIS_SUBTLV_SID_LABEL_SIZE
+                           && length != SUBTLV_RANGE_LABEL_SIZE) {
+                               stream_forward_getp(s, length - 6);
+                               break;
+                       }
+
+                       if (size == ISIS_SUBTLV_SID_INDEX_SIZE
+                           && length != SUBTLV_RANGE_INDEX_SIZE) {
+                               stream_forward_getp(s, length - 6);
+                               break;
+                       }
+
+                       if (size == ISIS_SUBTLV_SID_LABEL_SIZE) {
                                rcap->srlb.lower_bound = stream_get3(s);
-                       else
+                       } else if (size == ISIS_SUBTLV_SID_INDEX_SIZE) {
                                rcap->srlb.lower_bound = stream_getl(s);
+                       } else {
+                               stream_forward_getp(s, length - 6);
+                               break;
+                       }
 
                        /* SRLB sanity checks. */
                        if (rcap->srlb.range_size == 0
@@ -3089,13 +3136,14 @@ static int unpack_tlv_router_cap(enum isis_tlv_context 
context,
                        /* Only one range is supported. Skip subsequent one */
                        size = length - (size + SUBTLV_SR_BLOCK_SIZE);
                        if (size > 0)
-                               stream_forward_getp(s, length);
+                               stream_forward_getp(s, size);
+
                        break;
                case ISIS_SUBTLV_NODE_MSD:
                        /* Check that MSD is correctly formated */
                        if (length < MSD_TLV_SIZE) {
                                stream_forward_getp(s, length);
-                               continue;
+                               break;
                        }
                        msd_type = stream_getc(s);
                        rcap->msd = stream_getc(s);
diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h
index 38470ef85..0c6ed11cb 100644
--- a/isisd/isis_tlvs.h
+++ b/isisd/isis_tlvs.h
@@ -447,6 +447,7 @@ enum ext_subtlv_size {
 
        /* RFC 8667 sections #2 & #3 */
        ISIS_SUBTLV_SID_LABEL_SIZE = 3,
+       ISIS_SUBTLV_SID_INDEX_SIZE = 4,
        ISIS_SUBTLV_SID_LABEL_RANGE_SIZE = 9,
        ISIS_SUBTLV_ALGORITHM_SIZE = 4,
        ISIS_SUBTLV_ADJ_SID_SIZE = 5,
#
# Extracted:
#  diff --git a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz 
b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
#  index 
accc906bf25853bd417cff25840b233f98d1221e..20b1dc33f9593661b8310dc0c205e68d022de480
 100644
#  GIT binary patch
#  literal 222652
#
--- a/tests/isisd/test_fuzz_isis_tlv_tests.h
+++ b/tests/isisd/test_fuzz_isis_tlv_tests.h
@@ -1139,9 +1139,9 @@
        {
                .input = 
"\xc1\x0d\x49\x10\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x0c\xfd\xd4\x80\xf2\xff\xfc\x7f\x08\xf5\xeb\x0d\xee\x97\x01\xa1\xa5\x65\x80\xf2\xf0\xe7\x21\x04\x7f\xff\x08\xf5\x54\x54\xcc\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x64\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x34\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\xcc\x54\x54\x54\x54\x54\x54\x43\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
 
x00\x00\x00\x00\x00\x00\xde\xff\xff\xf6\x00\x00\x00\x00\x00\x00\x00\x80\xff\xff\xff\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x00\x00\x00\x80\xff\xff\xff\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2c\x30\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xd8\xd8\xd8\xd8\xd8\x05\xff\xff\x05\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xf2\x00\x00\x10\xde\xff\xff\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
 
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12",
                .input_len = 564,
-               .output = 
"\x43\x6f\x75\x6c\x64\x20\x6e\x6f\x74\x20\x75\x6e\x70\x61\x63\x6b\x20\x54\x4c\x56\x73\x3a\x0a\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x35\x36\x34\x20\x62\x79\x74\x65\x73\x20\x6f\x66\x20\x54\x4c\x56\x73\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x39\x33\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x33\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x31\x39\x33\x20\x28\x31\x33\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e
 
\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x32\x34\x32\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x32\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\
 
x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x
 
20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0
 
a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79
 
\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x41\x76\x61\x69\x6c\x61\x62\x6c\x65\x20\x64\x61\x74\x61\x20\x31\x20\x74\x6f\x6f\x20\x73\x68\x6f\x72\x74\x20\x74\x6f\x20\x63\x6f\x6e\x74\x61\x69\x6e\x20\x61\x20\x54\x4c\x56\x20\x68\x65\x61\x64\x65\x72\x2e\x0a\x0a",
-               .output_len = 1415,
-               .ret = 2
+               .output = 
"\x55\x6e\x70\x61\x63\x6b\x20\x6c\x6f\x67\x3a\x0a\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x35\x36\x34\x20\x62\x79\x74\x65\x73\x20\x6f\x66\x20\x54\x4c\x56\x73\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x39\x33\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x33\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x31\x39\x33\x20\x28\x31\x33\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56
 
\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x32\x34\x32\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x32\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x57\x41\x52\x4e\x49\x4e\x47\x3a\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x73\x75\x62\x54\x4c\x56\x20\x6c\x65\x6e\x67\x74\x68\x20\x74\x6f\x6f\x20\x6c\x61\x72\x67\x65\x20\x63\x6f\x6d\x70\x61\x72\x65\x64\x20\x74\x6f\x20\x65\x78\x70\x65\x63\x74\x65\x64\x20\x73\
 x69\x7a\x65\x0a\x55\x6e\x70\x61\x63\x6b\x65\x64\x20\x54\x4c\x56\x73\x3a\x0a",
+               .output_len = 514,
+               .ret = 0
        },
 
        {
@@ -1227,9 +1227,9 @@
        {
                .input = 
"\x81\x0d\x49\x10\xff\xff\xff\x65\x0a\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x54\x54\x08\xf5\xeb\x0d\x97\x80\xf2\x0c\xfd\xd4\x80\xf2\xff\xfc\x7f\x08\xf5\xeb\x0d\xee\x97\x01\xa1\xa7\x65\x80\xf2\xf0\xf5\x21\x04\x7f\xff\x08\xf5\x54\x54\xcc\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x00\xfd\x0a\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x54\x54\x6b\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\xcc\x54\x54\x54\x54\x54\x54\x41\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x00\x00\x2c\x2c\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x00\x0b\x00\x00\x00\x05\xff\xff\x05\x00\x00\x00\x00\x00\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x36\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x54\x54\x54\x54\x54\x00\x00\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\
 
x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\x00\x00\x00\x00\x00\x00\x00\x52\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfb\x00\x00\x04\x00\x00\x00\x00\x00\xff\x00\x00\xff\xf2\x00\x00\x00\xde\xff\xff\x00\xff\xff\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x12",
                .input_len = 403,
-               .output = 
"\x43\x6f\x75\x6c\x64\x20\x6e\x6f\x74\x20\x75\x6e\x70\x61\x63\x6b\x20\x54\x4c\x56\x73\x3a\x0a\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x34\x30\x33\x20\x62\x79\x74\x65\x73\x20\x6f\x66\x20\x54\x4c\x56\x73\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x32\x39\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x33\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x73\x20\x53\x75\x70\x70\x6f\x72\x74\x65\x64\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x20\x20\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x73\x20\x53\x75\x70\x70\x6f\x72\x74\x65\x64\x3a\x20\x37\x33\x2c\x20\x31\x36\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x31\x30\x31\x2c\x20\x31\x30\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20
 
\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x31\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x31\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x31\x31\x20\x28\x31\x31\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x32\x34\x32\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x32\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\
 
x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x
 
20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x2
 
0\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x32\x35\x35\x2e\x0a\x20\x20\x20\x20\x41\x76\x61\x69\x6c\x61\x62\x6c\x65\x20\x64\x61\x74\x61\x20\x39\x31\x20\x74\x6f\x6f\x20\x73\x68\x6f\x72\x74\x20\x66\x6f\x72\x20\x63\x6c\x61\x69\x6d\x65\x64\x20\x54\x4c\x56\x20\x6c\x65\x6e\x20\x32\x35\x35\x2e\x0a\x0a",
-               .output_len = 1176,
-               .ret = 2
+               .output = 
"\x55\x6e\x70\x61\x63\x6b\x20\x6c\x6f\x67\x3a\x0a\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x34\x30\x33\x20\x62\x79\x74\x65\x73\x20\x6f\x66\x20\x54\x4c\x56\x73\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x32\x39\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x33\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x73\x20\x53\x75\x70\x70\x6f\x72\x74\x65\x64\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x20\x20\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x73\x20\x53\x75\x70\x70\x6f\x72\x74\x65\x64\x3a\x20\x37\x33\x2c\x20\x31\x36\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x31\x30\x31\x2c\x20\x31\x30\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20
 
\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x31\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x31\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x31\x31\x20\x28\x31\x31\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x32\x34\x32\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x32\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x57\x41\x52\x4e\x49\x4e\x47\x3a\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x73\x75\x62\x54\x4c\x56\x20\x6c\x65\x6e\x67\x74\x68\x20\x74\x6f\x6f\x20\x6c\x61\x72\x67\x65\x20\x63\x6f\x6d\x70\x61\x72\x65\x64\x20\x74\x6f\x20\x65\x78\x70\x65\x63\x74\x65\x64\x20\x73\x69\x7a\x65\x0a\
 
x55\x6e\x70\x61\x63\x6b\x65\x64\x20\x54\x4c\x56\x73\x3a\x0a\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x73\x20\x53\x75\x70\x70\x6f\x72\x74\x65\x64\x3a\x20\x37\x33\x2c\x20\x31\x36\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x31\x30\x31\x2c\x20\x31\x30\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x0a",
+               .output_len = 586,
+               .ret = 0
        },
 
        {

++++++ 0006-isisd-fix-10505-using-base64-encoding.patch ++++++
>From ac3133450de12ba86c051265fc0f1b12bc57b40c Mon Sep 17 00:00:00 2001
From: whichbug <which...@github.com>
Date: Thu, 10 Feb 2022 22:49:41 -0500
Upstream: yes
References: bsc#1196506,CVE-2022-26126
Subject: [PATCH] isisd: fix #10505 using base64 encoding

Using base64 instead of the raw string to encode
the binary data.

Signed-off-by: whichbug <which...@github.com>

diff --git a/isisd/isis_nb_notifications.c b/isisd/isis_nb_notifications.c
index f219632ac..fd7b1b315 100644
--- a/isisd/isis_nb_notifications.c
+++ b/isisd/isis_nb_notifications.c
@@ -245,7 +245,7 @@ void isis_notif_max_area_addr_mismatch(const struct 
isis_circuit *circuit,
        data = yang_data_new_uint8(xpath_arg, max_area_addrs);
        listnode_add(arguments, data);
        snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
-       data = yang_data_new(xpath_arg, raw_pdu);
+       data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
        listnode_add(arguments, data);
 
        hook_call(isis_hook_max_area_addr_mismatch, circuit, max_area_addrs,
@@ -270,7 +270,7 @@ void isis_notif_authentication_type_failure(const struct 
isis_circuit *circuit,
        notif_prep_instance_hdr(xpath, area, "default", arguments);
        notif_prepr_iface_hdr(xpath, circuit, arguments);
        snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
-       data = yang_data_new(xpath_arg, raw_pdu);
+       data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
        listnode_add(arguments, data);
 
        hook_call(isis_hook_authentication_type_failure, circuit, raw_pdu,
@@ -294,7 +294,7 @@ void isis_notif_authentication_failure(const struct 
isis_circuit *circuit,
        notif_prep_instance_hdr(xpath, area, "default", arguments);
        notif_prepr_iface_hdr(xpath, circuit, arguments);
        snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
-       data = yang_data_new(xpath_arg, raw_pdu);
+       data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
        listnode_add(arguments, data);
 
        hook_call(isis_hook_authentication_failure, circuit, raw_pdu,
@@ -361,7 +361,7 @@ void isis_notif_reject_adjacency(const struct isis_circuit 
*circuit,
        data = yang_data_new_string(xpath_arg, reason);
        listnode_add(arguments, data);
        snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
-       data = yang_data_new(xpath_arg, raw_pdu);
+       data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
        listnode_add(arguments, data);
 
        hook_call(isis_hook_reject_adjacency, circuit, raw_pdu, raw_pdu_len);
@@ -384,7 +384,7 @@ void isis_notif_area_mismatch(const struct isis_circuit 
*circuit,
        notif_prep_instance_hdr(xpath, area, "default", arguments);
        notif_prepr_iface_hdr(xpath, circuit, arguments);
        snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
-       data = yang_data_new(xpath_arg, raw_pdu);
+       data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
        listnode_add(arguments, data);
 
        hook_call(isis_hook_area_mismatch, circuit, raw_pdu, raw_pdu_len);
@@ -467,7 +467,7 @@ void isis_notif_id_len_mismatch(const struct isis_circuit 
*circuit,
        data = yang_data_new_uint8(xpath_arg, rcv_id_len);
        listnode_add(arguments, data);
        snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
-       data = yang_data_new(xpath_arg, raw_pdu);
+       data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
        listnode_add(arguments, data);
 
        hook_call(isis_hook_id_len_mismatch, circuit, rcv_id_len, raw_pdu,
@@ -495,7 +495,7 @@ void isis_notif_version_skew(const struct isis_circuit 
*circuit,
        data = yang_data_new_uint8(xpath_arg, version);
        listnode_add(arguments, data);
        snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
-       data = yang_data_new(xpath_arg, raw_pdu);
+       data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
        listnode_add(arguments, data);
 
        hook_call(isis_hook_version_skew, circuit, version, raw_pdu,
@@ -525,7 +525,7 @@ void isis_notif_lsp_error(const struct isis_circuit 
*circuit,
        data = yang_data_new_string(xpath_arg, rawlspid_print(lsp_id));
        listnode_add(arguments, data);
        snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
-       data = yang_data_new(xpath_arg, raw_pdu);
+       data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
        listnode_add(arguments, data);
        /* ignore offset and tlv_type which cannot be set properly */
 
diff --git a/lib/base64.c b/lib/base64.c
new file mode 100644
index 000000000..e3f238969
--- /dev/null
+++ b/lib/base64.c
@@ -0,0 +1,193 @@
+/*
+ * This is part of the libb64 project, and has been placed in the public 
domain.
+ * For details, see http://sourceforge.net/projects/libb64
+ */
+
+#include "base64.h"
+
+static const int CHARS_PER_LINE = 72;
+static const char *ENCODING =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+void base64_init_encodestate(struct base64_encodestate *state_in)
+{
+       state_in->step = step_A;
+       state_in->result = 0;
+       state_in->stepcount = 0;
+}
+
+char base64_encode_value(char value_in)
+{
+       if (value_in > 63)
+               return '=';
+       return ENCODING[(int)value_in];
+}
+
+int base64_encode_block(const char *plaintext_in, int length_in, char 
*code_out,
+                       struct base64_encodestate *state_in)
+{
+       const char *plainchar = plaintext_in;
+       const char *const plaintextend = plaintext_in + length_in;
+       char *codechar = code_out;
+       char result;
+       char fragment;
+
+       result = state_in->result;
+
+       switch (state_in->step) {
+               while (1) {
+                       case step_A:
+                               if (plainchar == plaintextend) {
+                                       state_in->result = result;
+                                       state_in->step = step_A;
+                                       return codechar - code_out;
+                               }
+                               fragment = *plainchar++;
+                               result = (fragment & 0x0fc) >> 2;
+                               *codechar++ = base64_encode_value(result);
+                               result = (fragment & 0x003) << 4;
+                               /* fall through */
+                       case step_B:
+                               if (plainchar == plaintextend) {
+                                       state_in->result = result;
+                                       state_in->step = step_B;
+                                       return codechar - code_out;
+                               }
+                               fragment = *plainchar++;
+                               result |= (fragment & 0x0f0) >> 4;
+                               *codechar++ = base64_encode_value(result);
+                               result = (fragment & 0x00f) << 2;
+                               /* fall through */
+                       case step_C:
+                               if (plainchar == plaintextend) {
+                                       state_in->result = result;
+                                       state_in->step = step_C;
+                                       return codechar - code_out;
+                               }
+                               fragment = *plainchar++;
+                               result |= (fragment & 0x0c0) >> 6;
+                               *codechar++ = base64_encode_value(result);
+                               result  = (fragment & 0x03f) >> 0;
+                               *codechar++ = base64_encode_value(result);
+
+                               ++(state_in->stepcount);
+                               if (state_in->stepcount == CHARS_PER_LINE/4) {
+                                       *codechar++ = '\n';
+                                       state_in->stepcount = 0;
+                               }
+               }
+       }
+       /* control should not reach here */
+       return codechar - code_out;
+}
+
+int base64_encode_blockend(char *code_out, struct base64_encodestate *state_in)
+{
+       char *codechar = code_out;
+
+       switch (state_in->step) {
+       case step_B:
+               *codechar++ = base64_encode_value(state_in->result);
+               *codechar++ = '=';
+               *codechar++ = '=';
+               break;
+       case step_C:
+               *codechar++ = base64_encode_value(state_in->result);
+               *codechar++ = '=';
+               break;
+       case step_A:
+               break;
+       }
+       *codechar++ = '\n';
+
+       return codechar - code_out;
+}
+
+
+signed char base64_decode_value(signed char value_in)
+{
+       static const signed char decoding[] = {
+               62, -1, -1, -1, 63, 52, 53, 54,
+               55, 56, 57, 58, 59, 60, 61, -1,
+               -1, -1, -2, -1, -1, -1, 0, 1,
+               2,  3, 4, 5, 6, 7, 8, 9,
+               10, 11, 12, 13, 14, 15, 16, 17,
+               18, 19, 20, 21, 22, 23, 24, 25,
+               -1, -1, -1, -1, -1, -1, 26, 27,
+               28, 29, 30, 31, 32, 33, 34, 35,
+               36, 37, 38, 39, 40, 41, 42, 43,
+               44, 45, 46, 47, 48, 49, 50, 51
+       };
+       value_in -= 43;
+       if (value_in < 0 || value_in >= 80)
+               return -1;
+       return decoding[(int)value_in];
+}
+
+void base64_init_decodestate(struct base64_decodestate *state_in)
+{
+       state_in->step = step_a;
+       state_in->plainchar = 0;
+}
+
+int base64_decode_block(const char *code_in, int length_in, char 
*plaintext_out,
+                       struct base64_decodestate *state_in)
+{
+       const char *codec = code_in;
+       char *plainc = plaintext_out;
+       signed char fragmt;
+
+       *plainc = state_in->plainchar;
+
+       switch (state_in->step) {
+               while (1) {
+                       case step_a:
+                               do {
+                                       if (codec == code_in+length_in) {
+                                               state_in->step = step_a;
+                                               state_in->plainchar = *plainc;
+                                               return plainc - plaintext_out;
+                                       }
+                                       fragmt = base64_decode_value(*codec++);
+                               } while (fragmt < 0);
+                               *plainc = (fragmt & 0x03f) << 2;
+                               /* fall through */
+                       case step_b:
+                               do {
+                                       if (codec == code_in+length_in) {
+                                               state_in->step = step_b;
+                                               state_in->plainchar = *plainc;
+                                               return plainc - plaintext_out;
+                                       }
+                                       fragmt = base64_decode_value(*codec++);
+                               } while (fragmt < 0);
+                               *plainc++ |= (fragmt & 0x030) >> 4;
+                               *plainc = (fragmt & 0x00f) << 4;
+                               /* fall through */
+                       case step_c:
+                               do {
+                                       if (codec == code_in+length_in) {
+                                               state_in->step = step_c;
+                                               state_in->plainchar = *plainc;
+                                               return plainc - plaintext_out;
+                                       }
+                                       fragmt = base64_decode_value(*codec++);
+                               } while (fragmt < 0);
+                               *plainc++ |= (fragmt & 0x03c) >> 2;
+                               *plainc = (fragmt & 0x003) << 6;
+                               /* fall through */
+                       case step_d:
+                               do {
+                                       if (codec == code_in+length_in) {
+                                               state_in->step = step_d;
+                                               state_in->plainchar = *plainc;
+                                               return plainc - plaintext_out;
+                                       }
+                                       fragmt = base64_decode_value(*codec++);
+                               } while (fragmt < 0);
+                               *plainc++   |= (fragmt & 0x03f);
+               }
+       }
+       /* control should not reach here */
+       return plainc - plaintext_out;
+}
diff --git a/lib/base64.h b/lib/base64.h
new file mode 100644
index 000000000..3dc1559aa
--- /dev/null
+++ b/lib/base64.h
@@ -0,0 +1,45 @@
+/*
+ * This is part of the libb64 project, and has been placed in the public 
domain.
+ * For details, see http://sourceforge.net/projects/libb64
+ */
+
+#ifndef _BASE64_H_
+#define _BASE64_H_
+
+enum base64_encodestep {
+       step_A, step_B, step_C
+};
+
+struct base64_encodestate {
+       enum base64_encodestep step;
+       char result;
+       int stepcount;
+};
+
+void base64_init_encodestate(struct base64_encodestate *state_in);
+
+char base64_encode_value(char value_in);
+
+int base64_encode_block(const char *plaintext_in, int length_in, char 
*code_out,
+                       struct base64_encodestate *state_in);
+
+int base64_encode_blockend(char *code_out, struct base64_encodestate 
*state_in);
+
+
+enum base64_decodestep {
+       step_a, step_b, step_c, step_d
+};
+
+struct base64_decodestate {
+       enum base64_decodestep step;
+       char plainchar;
+};
+
+void base64_init_decodestate(struct base64_decodestate *state_in);
+
+signed char base64_decode_value(signed char value_in);
+
+int base64_decode_block(const char *code_in, int length_in, char 
*plaintext_out,
+                       struct base64_decodestate *state_in);
+
+#endif /* _BASE64_H_ */
diff --git a/lib/subdir.am b/lib/subdir.am
index 648ab7f14..f8f82f276 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -8,6 +8,7 @@ lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) 
$(LUA_LIB) $(UST
 lib_libfrr_la_SOURCES = \
        lib/agg_table.c \
        lib/atomlist.c \
+       lib/base64.c \
        lib/bfd.c \
        lib/buffer.c \
        lib/checksum.c \
@@ -177,6 +178,7 @@ clippy_scan += \
 pkginclude_HEADERS += \
        lib/agg_table.h \
        lib/atomlist.h \
+       lib/base64.h \
        lib/bfd.h \
        lib/bitfield.h \
        lib/buffer.h \
diff --git a/lib/yang_wrappers.c b/lib/yang_wrappers.c
index 85aa003db..bee76c6e0 100644
--- a/lib/yang_wrappers.c
+++ b/lib/yang_wrappers.c
@@ -19,6 +19,7 @@
 
 #include <zebra.h>
 
+#include "base64.h"
 #include "log.h"
 #include "lib_errors.h"
 #include "northbound.h"
@@ -676,6 +677,64 @@ void yang_get_default_string_buf(char *buf, size_t size, 
const char *xpath_fmt,
                          xpath);
 }
 
+/*
+ * Primitive type: binary.
+ */
+struct yang_data *yang_data_new_binary(const char *xpath, const char *value,
+                                      size_t len)
+{
+       char *value_str;
+       struct base64_encodestate s;
+       int cnt;
+       char *c;
+       struct yang_data *data;
+
+       value_str = (char *)malloc(len * 2);
+       base64_init_encodestate(&s);
+       cnt = base64_encode_block(value, len, value_str, &s);
+       c = value_str + cnt;
+       cnt = base64_encode_blockend(c, &s);
+       c += cnt;
+       *c = 0;
+       data = yang_data_new(xpath, value_str);
+       free(value_str);
+       return data;
+}
+
+size_t yang_dnode_get_binary_buf(char *buf, size_t size,
+                                const struct lyd_node *dnode,
+                                const char *xpath_fmt, ...)
+{
+       const char *canon;
+       size_t cannon_len;
+       size_t decode_len;
+       size_t ret_len;
+       size_t cnt;
+       char *value_str;
+       struct base64_decodestate s;
+
+       canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+       cannon_len = strlen(canon);
+       decode_len = cannon_len;
+       value_str = (char *)malloc(decode_len);
+       base64_init_decodestate(&s);
+       cnt = base64_decode_block(canon, cannon_len, value_str, &s);
+
+       ret_len = size > cnt ? cnt : size;
+       memcpy(buf, value_str, ret_len);
+       if (size < cnt) {
+               char xpath[XPATH_MAXLEN];
+
+               yang_dnode_get_path(dnode, xpath, sizeof(xpath));
+               flog_warn(EC_LIB_YANG_DATA_TRUNCATED,
+                         "%s: value was truncated [xpath %s]", __func__,
+                         xpath);
+       }
+       free(value_str);
+       return ret_len;
+}
+
+
 /*
  * Primitive type: empty.
  */
diff --git a/lib/yang_wrappers.h b/lib/yang_wrappers.h
index d781dfb1e..56b314876 100644
--- a/lib/yang_wrappers.h
+++ b/lib/yang_wrappers.h
@@ -118,6 +118,13 @@ extern const char *yang_get_default_string(const char 
*xpath_fmt, ...);
 extern void yang_get_default_string_buf(char *buf, size_t size,
                                        const char *xpath_fmt, ...);
 
+/* binary */
+extern struct yang_data *yang_data_new_binary(const char *xpath,
+                                             const char *value, size_t len);
+extern size_t yang_dnode_get_binary_buf(char *buf, size_t size,
+                                       const struct lyd_node *dnode,
+                                       const char *xpath_fmt, ...);
+
 /* empty */
 extern struct yang_data *yang_data_new_empty(const char *xpath);
 extern bool yang_dnode_get_empty(const struct lyd_node *dnode,
-- 
2.34.1

Reply via email to