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:
		| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 SqTER-PL
					SqTER-PL