diff --git a/.gitignore b/.gitignore index 6c0791d..ac2aaf6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ /frr-8.0.1.tar.gz /frr-8.2.tar.gz /frr-8.2.2.tar.gz +/frr-8.3.1.tar.gz diff --git a/0006-cve-2022-26126.patch b/0006-cve-2022-26126.patch deleted file mode 100644 index cb47af9..0000000 --- a/0006-cve-2022-26126.patch +++ /dev/null @@ -1,461 +0,0 @@ -From ac3133450de12ba86c051265fc0f1b12bc57b40c Mon Sep 17 00:00:00 2001 -From: whichbug -Date: Thu, 10 Feb 2022 22:49:41 -0500 -Subject: [PATCH] isisd: fix #10505 using base64 encoding - -Using base64 instead of the raw string to encode -the binary data. - -Signed-off-by: whichbug ---- - isisd/isis_nb_notifications.c | 16 +-- - lib/base64.c | 193 ++++++++++++++++++++++++++++++++++ - lib/base64.h | 45 ++++++++ - lib/subdir.am | 2 + - lib/yang_wrappers.c | 59 +++++++++++ - lib/yang_wrappers.h | 7 ++ - 6 files changed, 314 insertions(+), 8 deletions(-) - create mode 100644 lib/base64.c - create mode 100644 lib/base64.h - -diff --git a/isisd/isis_nb_notifications.c b/isisd/isis_nb_notifications.c -index f219632acf7..fd7b1b3159a 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 00000000000..e3f238969b3 ---- /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 00000000000..3dc1559aa48 ---- /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 648ab7f14a1..f8f82f2766f 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 85aa003db72..bee76c6e0f5 100644 ---- a/lib/yang_wrappers.c -+++ b/lib/yang_wrappers.c -@@ -19,6 +19,7 @@ - - #include - -+#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 d781dfb1e42..56b314876f2 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, diff --git a/sources b/sources index 142485c..4c97c7d 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (frr-8.2.2.tar.gz) = 2a3e189d8de09bd66bc4a49147bec681d48626d8cb268dc03f42b58064c066b35082114ff97d7333ae4029f759b78e216c8460c2611df7f6659675dc5f9b69b2 +SHA512 (frr-8.3.1.tar.gz) = a15b53c98c9739f316663c723c35954284b63ffd49cf88e22d3ac82e66a4b63ffc5f43a8d622f531d129436464fdbfcf103b2866240762510ec490c03563a8ae SHA512 (remove-babeld-ldpd.sh) = a5bf67a3722cb20d43cef1dac28f839db68df73a1b7d34d8438e4f9366da3b67d85c1f44281f93434e8dd8ebcb2d3dc258b77eaa5627475b7395d207f020839d