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
```
This commit is contained in:
SqTER-PL
2025-03-20 16:44:40 +01:00
committed by Lucas Asvio
parent 5a4fc73b57
commit e9bc6318c0
2 changed files with 91 additions and 64 deletions

View File

@@ -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

View File

@@ -0,0 +1,91 @@
From a7c2db4fbccb5199ea3f3e2ce17cbd8cbce43924 Mon Sep 17 00:00:00 2001
From: Amitesh Anand <quic_amitesh@quicinc.com>
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 <quic_amitesh@quicinc.com>
---
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