From e9bc6318c0d5a21d633f12d59ced0b3117b51d63 Mon Sep 17 00:00:00 2001 From: SqTER-PL Date: Thu, 20 Mar 2025 16:44:40 +0100 Subject: [PATCH] package: qca-nss: Replace patch 'qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db' with 'Validate dst_len before-calling-IP-addr-copy' This change fixes the following issue... ``` <0>[ 3372.560724] fortify_panic from ecm_db_exit+0x384/0x388 [ecm] <0>[ 3372.568927] ecm_db_exit [ecm] from ecm_db_ipv6_route_table_update_event+0x3c/0x5c [ecm] <0>[ 3372.574608] ecm_db_ipv6_route_table_update_event [ecm] from atomic_notifier_call_chain+0x58/0x6c <0>[ 3372.582769] atomic_notifier_call_chain from ip6_route_add+0xac/0xdc <0>[ 3372.591533] ip6_route_add from inet6_rtm_newroute+0xb0/0xc0 ``` --- .../patches/100-kernel-5.15-support.patch | 64 ------------- ...-dst_len-before-calling-IP-addr-copy.patch | 91 +++++++++++++++++++ 2 files changed, 91 insertions(+), 64 deletions(-) create mode 100644 package/qca-nss/qca-nss-ecm/patches/300-Validate-dst_len-before-calling-IP-addr-copy.patch diff --git a/package/qca-nss/qca-nss-ecm/patches/100-kernel-5.15-support.patch b/package/qca-nss/qca-nss-ecm/patches/100-kernel-5.15-support.patch index 6d74b253f2..36c143ccd2 100644 --- a/package/qca-nss/qca-nss-ecm/patches/100-kernel-5.15-support.patch +++ b/package/qca-nss/qca-nss-ecm/patches/100-kernel-5.15-support.patch @@ -912,70 +912,6 @@ }; #endif #endif ---- a/ecm_db/ecm_db.c -+++ b/ecm_db/ecm_db.c -@@ -242,11 +242,13 @@ static int ecm_db_ipv6_route_table_updat - unsigned long event, - void *ptr) - { -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)) - struct fib6_config *cfg = (struct fib6_config *)ptr; - struct ecm_db_connection_instance *ci; -- -+#endif - DEBUG_TRACE("route table update event v6\n"); - -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)) - if ((event != RTM_DELROUTE) && (event != RTM_NEWROUTE)) { - DEBUG_WARN("%px: Unhandled route table event: %lu\n", cfg, event); - return NOTIFY_DONE; -@@ -262,12 +264,13 @@ static int ecm_db_ipv6_route_table_updat - ecm_db_connection_defunct_ip_version(6); - return NOTIFY_DONE; - } -- -+#endif - /* - * Disable IPv6 frontend processing until defunct function call is completed. - */ - ecm_front_end_ipv6_stop(1); - -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)) - /* - * Iterate all connections - */ -@@ -298,7 +301,7 @@ static int ecm_db_ipv6_route_table_updat - * Compute ECM connection's prefix destination address by masking it with the - * route config's destination address prefix length. - */ -- ipv6_addr_prefix(&prefix_addr, &ecm_in6, cfg->fc_dst_len); -+ ipv6_addr_prefix(&prefix_addr, &ecm_in6, min(128, cfg->fc_dst_len)); - - DEBUG_TRACE("dest addr prefix: %pI6 prefix_len: %d ecm_in6: %pI6\n", &prefix_addr, cfg->fc_dst_len, &ecm_in6); - -@@ -326,7 +329,7 @@ static int ecm_db_ipv6_route_table_updat - * Compute ECM connection's prefix source address by masking it with the - * route config's destination address prefix length. - */ -- ipv6_addr_prefix(&prefix_addr, &ecm_in6, cfg->fc_dst_len); -+ ipv6_addr_prefix(&prefix_addr, &ecm_in6, min(128, cfg->fc_dst_len)); - - DEBUG_TRACE("src addr prefix: %pI6 prefix_len: %d ecm_in6: %pI6\n", &prefix_addr, cfg->fc_dst_len, &ecm_in6); - -@@ -402,11 +405,12 @@ next: - ecm_db_connection_deref(ci); - ci = cin; - } -- -+#else - /* - * Re-enable IPv6 frontend processing. - */ - ecm_front_end_ipv6_stop(0); -+#endif - return NOTIFY_DONE; - } - --- a/ecm_db/ecm_db_connection.c +++ b/ecm_db/ecm_db_connection.c @@ -446,7 +446,9 @@ EXPORT_SYMBOL(ecm_db_connection_make_def diff --git a/package/qca-nss/qca-nss-ecm/patches/300-Validate-dst_len-before-calling-IP-addr-copy.patch b/package/qca-nss/qca-nss-ecm/patches/300-Validate-dst_len-before-calling-IP-addr-copy.patch new file mode 100644 index 0000000000..65c9f4a2bb --- /dev/null +++ b/package/qca-nss/qca-nss-ecm/patches/300-Validate-dst_len-before-calling-IP-addr-copy.patch @@ -0,0 +1,91 @@ +From a7c2db4fbccb5199ea3f3e2ce17cbd8cbce43924 Mon Sep 17 00:00:00 2001 +From: Amitesh Anand +Date: Fri, 12 Apr 2024 17:07:38 +0530 +Subject: [PATCH] [qca-nss-ecm] Validate dst_len before calling IP addr copy + +Incorrect lenght passed for as parameter ipv6_addr_prefix(), +which crashes during memcpy. Linux mandates the caller to +ensure len is between 0 to 128. + +Crash signature: +PC points to "fortify_panic+0x18/0x1c" +LR points to "fortify_panic+0x18/0x1c". +The Backtrace obtained is as follows: +fortify_panic+0x18/0x1c +ecm_db_init+0x51c/0x948 [ecm] +notifier_call_chain+0x64/0x84 +atomic_notifier_call_chain+0x38/0x54 +ip6_route_add+0x6c/0xc0 +addrconf_prefix_route+0xd8/0x10c +inet6_rtm_newaddr+0x42c/0x5a4 +rtnetlink_rcv_msg+0x260/0x2ac +netlink_rcv_skb+0x9c/0x108 +rtnetlink_rcv+0x14/0x1c +netlink_unicast+0x168/0x244 +netlink_sendmsg+0x35c/0x3b8 +__sock_sendmsg+0x18/0x2c +____sys_sendmsg+0x27c/0x31c +___sys_sendmsg+0x74/0xbc +__sys_sendmsg+0x64/0xb0 +__arm64_sys_sendmsg+0x1c/0x24 +el0_svc_common.constprop.0+0xc8/0x128 +do_el0_svc+0x18/0x20 +el0_svc+0x18/0x40 +el0t_64_sync_handler+0x88/0x124 + +Change-Id: I7547eedb1f2af70180ca22d373c5cd6426510776 +Signed-off-by: Amitesh Anand +--- + ecm_db/ecm_db.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/ecm_db/ecm_db.c b/ecm_db/ecm_db.c +index 722d6d5e..201f2b91 100644 +--- a/ecm_db/ecm_db.c ++++ b/ecm_db/ecm_db.c +@@ -283,6 +283,7 @@ static int ecm_db_ipv6_route_table_update_event(struct notifier_block *nb, + struct net_device *fc_dev; + bool is_dest_ip_match = true; + ecm_db_obj_dir_t obj_dir = ECM_DB_OBJ_DIR_TO; ++ int fc_dst_len = cfg->fc_dst_len; + + if (ci->ip_version != 6) { + goto next; +@@ -297,10 +298,19 @@ static int ecm_db_ipv6_route_table_update_event(struct notifier_block *nb, + /* + * Compute ECM connection's prefix destination address by masking it with the + * route config's destination address prefix length. ++ * ++ * Validate dst_len to be 0 <= len <= 128 + */ +- ipv6_addr_prefix(&prefix_addr, &ecm_in6, cfg->fc_dst_len); ++ if (cfg->fc_dst_len > 128) { ++ fc_dst_len = 128; ++ } else if (cfg->fc_dst_len < 0){ ++ fc_dst_len = 0; ++ } ++ ++ ipv6_addr_prefix(&prefix_addr, &ecm_in6, fc_dst_len); + +- DEBUG_TRACE("dest addr prefix: %pI6 prefix_len: %d ecm_in6: %pI6\n", &prefix_addr, cfg->fc_dst_len, &ecm_in6); ++ DEBUG_TRACE("dest addr prefix: %pI6 prefix_len: %d(cfg=%d) ecm_in6: %pI6\n", ++ &prefix_addr, fc_dst_len, cfg->fc_dst_len, &ecm_in6); + + /* + * Compare the ECM connection's destination address prefix with the route config's +@@ -326,9 +336,10 @@ static int ecm_db_ipv6_route_table_update_event(struct notifier_block *nb, + * Compute ECM connection's prefix source address by masking it with the + * route config's destination address prefix length. + */ +- ipv6_addr_prefix(&prefix_addr, &ecm_in6, cfg->fc_dst_len); ++ ipv6_addr_prefix(&prefix_addr, &ecm_in6, fc_dst_len); + +- DEBUG_TRACE("src addr prefix: %pI6 prefix_len: %d ecm_in6: %pI6\n", &prefix_addr, cfg->fc_dst_len, &ecm_in6); ++ DEBUG_TRACE("src addr prefix: %pI6 prefix_len: %d(cfg=%d) ecm_in6: %pI6\n", ++ &prefix_addr, fc_dst_len, cfg->fc_dst_len, &ecm_in6); + + if (ipv6_addr_cmp(&prefix_addr, &cfg->fc_dst)) { + DEBUG_TRACE("src addr prefix: %pI6 not equal to cfg->fc_dst: %pI6, go to next connection\n", &prefix_addr, &cfg->fc_dst); +-- +GitLab +