From 64787abcccf1dc96116bc541317c6c7b1b795130 Mon Sep 17 00:00:00 2001 From: Tomaz Zaman Date: Tue, 18 Aug 2026 12:21:11 +0200 Subject: [PATCH 70/72] package/ask, libnfnetlink: sync mono-ask patches to ASK 12a79e2 fmc and fmlib are fetched from nxp-qoriq upstream and libnfnetlink is the stock OpenWrt package, so the ASK extensions reach these sources only through downstream patch copies. Re-sync all three to the ASK masters reworked in ASK 051b8c4 (five audit-confirmed bug fixes): - fmc: all_htnodes[port.htnodes[ii]] indexing fix; CHECK_ERR on FM_PCD_HashTableAddKey; drop a dead ApplyOrder local. - fmlib: DPAA>=11 external-hash struct fields plus a _Static_assert guarding the ioctl-struct layout the HashTableSet memcpy relies on. - libnfnetlink: allocate the replacement rcv buffer before freeing the live one; free on the open-error and close paths. Byte-identical to the ASK masters at 12a79e2. Co-Authored-By: Claude Opus 4.8 --- .../fmc/patches/100-mono-ask-extensions.patch | 29 ++++-- .../patches/100-mono-ask-extensions.patch | 58 +++++++++--- .../900-nxp-ask-nonblocking-heap-buffer.patch | 90 +++++++++++-------- 3 files changed, 121 insertions(+), 56 deletions(-) diff --git a/package/ask/fmc/patches/100-mono-ask-extensions.patch b/package/ask/fmc/patches/100-mono-ask-extensions.patch index 6e7f676ebd..b2874697e3 100644 --- a/package/ask/fmc/patches/100-mono-ask-extensions.patch +++ b/package/ask/fmc/patches/100-mono-ask-extensions.patch @@ -55,10 +55,10 @@ index 4bd05b2..ddefce1 100644 class CGenericError { diff --git a/source/FMCPCDModel.cpp b/source/FMCPCDModel.cpp -index d785eee..7a25f91 100755 +index d785eee..bb6435f 100755 --- a/source/FMCPCDModel.cpp +++ b/source/FMCPCDModel.cpp -@@ -133,12 +133,131 @@ CFMCModel::CFMCModel() +@@ -133,12 +133,129 @@ CFMCModel::CFMCModel() } @@ -70,7 +70,7 @@ index d785eee..7a25f91 100755 + + for( ii = 0; ii < port.htnodes.size(); ii++) { + if (all_htnodes[port.htnodes[ii]].name == refnode.name) { -+ return all_htnodes[ii]; ++ return all_htnodes[port.htnodes[ii]]; + } + } + @@ -114,8 +114,6 @@ index d785eee..7a25f91 100755 + htNode.headerOnMiss = refnode.headerOnMiss; + htNode.port_signature = port.name; + -+ ApplyOrder::Entry root( ApplyOrder::CCTree, port.getIndex() ); -+ + port.cctrees.push_back( htNode.getIndex() ); + port.cctrees_type.push_back( e_FM_PCD_HASH ); + port.hdrmanips.push_back( 0 ); @@ -190,7 +188,7 @@ index d785eee..7a25f91 100755 assert( pTaskDef ); // For all engines -@@ -192,6 +311,23 @@ CFMCModel::createModel( CTaskDef* pTaskDef ) +@@ -192,6 +309,23 @@ CFMCModel::createModel( CTaskDef* pTaskDef ) Scheme& scheme = all_schemes[index]; scheme.scheme_index_per_port = scheme_index; @@ -214,7 +212,7 @@ index d785eee..7a25f91 100755 // Add scheme's protocols to the port's protocol list std::set< Protocol >::iterator protoIt; -@@ -1011,6 +1147,7 @@ CFMCModel::createScheme( const CTaskDef* pTaskDef, Port& port, const CDistributi +@@ -1011,6 +1145,7 @@ CFMCModel::createScheme( const CTaskDef* pTaskDef, Port& port, const CDistributi // Add next engine entry scheme.nextEngine = getEngineByType( xmlDist.action ); scheme.nextEngineStr = getEngineByTypeStr( xmlDist.action ); @@ -222,7 +220,7 @@ index d785eee..7a25f91 100755 scheme.doneAction = e_FM_PCD_ENQ_FRAME; scheme.doneActionStr = "e_FM_PCD_ENQ_FRAME"; scheme.actionHandleIndex = 0xFFFFFFFF; -@@ -2920,7 +3057,7 @@ CFMCModel::getNetCommFieldType( std::string fieldname ) +@@ -2920,7 +3055,7 @@ CFMCModel::getNetCommFieldType( std::string fieldname ) fields["pppoe.code"] = NET_HEADER_FIELD_PPPoE_CODE; fields["pppoe.session_ID"] = NET_HEADER_FIELD_PPPoE_SID; fields["pppoe.hlen"] = NET_HEADER_FIELD_PPPoE_LEN; @@ -231,7 +229,7 @@ index d785eee..7a25f91 100755 fields["minencap.dst"] = NET_HEADER_FIELD_MINENCAP_DST_IP; fields["sctp.sport"] = NET_HEADER_FIELD_SCTP_PORT_SRC; fields["sctp.dport"] = NET_HEADER_FIELD_SCTP_PORT_DST; -@@ -3007,7 +3144,7 @@ CFMCModel::getNetCommFieldTypeStr( std::string fieldname ) +@@ -3007,7 +3142,7 @@ CFMCModel::getNetCommFieldTypeStr( std::string fieldname ) fields["pppoe.code"] = "NET_HEADER_FIELD_PPPoE_CODE"; fields["pppoe.session_ID"] = "NET_HEADER_FIELD_PPPoE_SID"; fields["pppoe.hlen"] = "NET_HEADER_FIELD_PPPoE_LEN"; @@ -288,3 +286,16 @@ index 700ce41..0657530 100644 t_FmPcdNetEnvParams distinctionUnits; ///< Port's network env t_FmPortPcdParams pcdParam; t_FmPortPcdPrsParams prsParam; +diff --git a/source/fmc_exec.c b/source/fmc_exec.c +index c105037..fb766a6 100755 +--- a/source/fmc_exec.c ++++ b/source/fmc_exec.c +@@ -697,7 +697,7 @@ fmc_exec_port_end( fmc_model* model, unsigned int engine, unsigned int port ) + err = FM_PCD_HashTableAddKey( model->htnode_handle[index], + model->htnode[index].matchKeySize, + &(model->htentry[index][i]) ); +- /*CHECK_HANDLE( FM_PCD_HashTableAddKey, model->htnode_name[index], !res ); */ ++ CHECK_ERR( FM_PCD_HashTableAddKey, model->htnode_name[index] ); + } + } + /* End of adding HT entries */ diff --git a/package/ask/fmlib/patches/100-mono-ask-extensions.patch b/package/ask/fmlib/patches/100-mono-ask-extensions.patch index 8a06997834..c7f626d724 100644 --- a/package/ask/fmlib/patches/100-mono-ask-extensions.patch +++ b/package/ask/fmlib/patches/100-mono-ask-extensions.patch @@ -62,7 +62,7 @@ index 3607b86..e6db99a 100644 /** @} */ /* end of lnx_usr_FM_lib_grp group */ /** @} */ /* end of lnx_usr_FM_grp group */ diff --git a/include/fmd/Peripherals/fm_pcd_ext.h b/include/fmd/Peripherals/fm_pcd_ext.h -index 7f32680..81d2186 100644 +index 7f32680..8bfecfd 100644 --- a/include/fmd/Peripherals/fm_pcd_ext.h +++ b/include/fmd/Peripherals/fm_pcd_ext.h @@ -1717,6 +1717,7 @@ typedef struct t_FmPcdKgSchemeParams { @@ -101,23 +101,38 @@ index 7f32680..81d2186 100644 typedef struct t_FmPcdHashTableParams { uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */ e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the -@@ -1989,6 +2011,14 @@ typedef struct t_FmPcdHashTableParams { - uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */ +@@ -1990,6 +2012,29 @@ typedef struct t_FmPcdHashTableParams { t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */ -+ uint32_t table_type; /* ip reassembly table */ + ++ bool agingSupport; /**< Reserved; hash-key aging is not implemented. Kept so this struct ++ stays layout-identical to the driver's t_FmPcdHashTableParams and ++ to ioc_fm_pcd_hash_table_params_t, which FM_PCD_HashTableSet() ++ memcpy()s this struct into. */ ++ ++#if (DPAA_VERSION >= 11) ++ bool externalHash; /**< TRUE to use external hash table */ ++ ++ uint32_t table_type; /**< ip reassembly table type */ + struct { -+ uint32_t timeout_val; //reassembly timeout -+ uint32_t timeout_fqid; //fqid for reassmebly failures -+ uint32_t max_frags; //max allowed fragments -+ uint32_t min_frag_size; //min allowed frag size except last frag -+ uint32_t max_sessions; //max conn reassembly sessions ++ uint32_t timeout_val; /**< reassembly timeout */ ++ uint32_t timeout_fqid; /**< fqid for reassembly failures */ ++ uint32_t max_frags; /**< max allowed fragments */ ++ uint32_t min_frag_size; /**< min allowed frag size except last frag */ ++ uint32_t max_sessions; /**< max conn reassembly sessions */ + }; - ++ ++ struct { ++ uint8_t dataMemId; /**< Memory partition ID for external hash table */ ++ uint16_t dataLiodnOffs; /**< LIODN offset for external hash access */ ++ uintptr_t missMonitorAddr; /**< User-allocated miss monitor address */ ++ } externalHashParams; ++#endif /* (DPAA_VERSION >= 11) */ } t_FmPcdHashTableParams; + /**************************************************************************//** diff --git a/src/fm_lib.c b/src/fm_lib.c -index 4de5168..907d5d4 100644 +index 4de5168..81828d4 100644 --- a/src/fm_lib.c +++ b/src/fm_lib.c @@ -317,6 +317,44 @@ t_Error FM_GetApiVersion(t_Handle h_Fm, ioc_fm_api_version_t *p_version) @@ -178,3 +193,24 @@ index 4de5168..907d5d4 100644 t_Handle FM_PCD_KgSchemeSet (t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme) { t_Device *p_PcdDev = (t_Device*) h_FmPcd; +@@ -1191,6 +1235,12 @@ t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode, + return E_OK; + } + ++/* The ioctl struct is this struct plus a trailing 'void *id'; the memcpy below ++ * relies on the two being field-for-field identical up to that point. */ ++_Static_assert(sizeof(ioc_fm_pcd_hash_table_params_t) == ++ sizeof(t_FmPcdHashTableParams) + sizeof(void *), ++ "t_FmPcdHashTableParams and ioc_fm_pcd_hash_table_params_t layouts diverged"); ++ + t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) + { + t_Device *p_PcdDev = (t_Device*) h_FmPcd; +@@ -1201,6 +1251,7 @@ t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) + + _fml_dbg("Calling...\n"); + ++ memset(¶ms, 0, sizeof(params)); + memcpy(¶ms, p_Param, sizeof(t_FmPcdHashTableParams)); + params.id = NULL; + diff --git a/package/libs/libnfnetlink/patches/900-nxp-ask-nonblocking-heap-buffer.patch b/package/libs/libnfnetlink/patches/900-nxp-ask-nonblocking-heap-buffer.patch index f1d609b472..6b9929a55f 100644 --- a/package/libs/libnfnetlink/patches/900-nxp-ask-nonblocking-heap-buffer.patch +++ b/package/libs/libnfnetlink/patches/900-nxp-ask-nonblocking-heap-buffer.patch @@ -4,7 +4,16 @@ Subject: [PATCH] libnfnetlink: Add non-blocking mode and heap buffer management NXP ASK (Applications Solutions Kit) extensions for libnfnetlink: - Add nfnl_set_nonblocking_mode() and nfnl_unset_nonblocking_mode() APIs -- Move receive buffer from stack to heap to prevent stack overflow with large buffers +- Move receive buffer from stack to heap to prevent stack overflow with large + buffers: nfnl_catch() used a VLA sized by rcv_buffer_size, and cmm raises + that to 128 KiB +- nfnl_set_rcv_buffer_size() allocates the replacement before releasing the + live buffer, so an allocation failure leaves the handle usable at its + previous size instead of leaving a freed pointer behind a grown size +- The buffer is plain calloc()'d memory used directly; malloc alignment is + already sufficient for the netlink message walk, which is what the VLA's + bare __attribute__((aligned)) provided +- Free the buffer on the nfnl_open() error path and in nfnl_close() - Required for CMM daemon high-throughput netlink communication Upstream-Status: Inappropriate [NXP vendor-specific extension] @@ -25,7 +34,7 @@ index 49ce878..03d6c1d 100644 extern NFNL_EXPORT unsigned int nfnl_portid(const struct nfnl_handle *h); diff --git a/src/libnfnetlink.c b/src/libnfnetlink.c -index 667e5ef..96ecbbb 100644 +index 667e5ef..3b013eb 100644 --- a/src/libnfnetlink.c +++ b/src/libnfnetlink.c @@ -42,6 +42,7 @@ @@ -36,57 +45,65 @@ index 667e5ef..96ecbbb 100644 #include #include #include -@@ -103,6 +104,10 @@ struct nfnl_subsys_handle { +@@ -103,6 +104,7 @@ struct nfnl_subsys_handle { #define NFNL_MAX_SUBSYS 16 /* enough for now */ #define NFNL_F_SEQTRACK_ENABLED (1 << 0) +#define NFNL_F_NONBLOCKING_MODE (1 << 1) -+#define NFNL_F_ALIGN_SIZE 64 -+ -+#define NFNL_F_ALIGN(buf, sz) (uint8_t *)(((unsigned long)buf + sz - 1) & (~(sz - 1))) struct nfnl_handle { int fd; -@@ -112,6 +117,8 @@ struct nfnl_handle { +@@ -112,6 +114,7 @@ struct nfnl_handle { uint32_t seq; uint32_t dump; uint32_t rcv_buffer_size; /* for nfnl_catch */ + uint8_t *rcv_buff; -+ uint8_t *rcv_buff_aligned; uint32_t flags; struct nlmsghdr *last_nlhdr; struct nfnl_subsys_handle subsys[NFNL_MAX_SUBSYS+1]; -@@ -222,8 +229,13 @@ struct nfnl_handle *nfnl_open(void) +@@ -222,8 +225,12 @@ struct nfnl_handle *nfnl_open(void) } nfnlh->seq = time(NULL); nfnlh->rcv_buffer_size = NFNL_BUFFSIZE; + /* allocate a buffer which can be used to receive data */ -+ nfnlh->rcv_buff = (uint8_t *)calloc(nfnlh->rcv_buffer_size + NFNL_F_ALIGN_SIZE, sizeof(uint8_t)); ++ nfnlh->rcv_buff = (uint8_t *)calloc(1, nfnlh->rcv_buffer_size); + if (!nfnlh->rcv_buff) + goto err_close; -+ nfnlh->rcv_buff_aligned = NFNL_F_ALIGN(nfnlh->rcv_buff, NFNL_F_ALIGN_SIZE); - /* don't set pid here, only first socket of process has real pid !!! + /* don't set pid here, only first socket of process has real pid !!! * binding to pid '0' will default */ /* let us do the initial bind */ -@@ -279,6 +291,58 @@ void nfnl_unset_sequence_tracking(struct nfnl_handle *h) +@@ -244,6 +251,8 @@ struct nfnl_handle *nfnl_open(void) + return nfnlh; + + err_close: ++ if (nfnlh->rcv_buff) ++ free(nfnlh->rcv_buff); + close(nfnlh->fd); + err_free: + free(nfnlh); +@@ -278,9 +287,64 @@ void nfnl_unset_sequence_tracking(struct nfnl_handle *h) + */ void nfnl_set_rcv_buffer_size(struct nfnl_handle *h, unsigned int size) { - h->rcv_buffer_size = size; -+ /* free existing rcv_buff as there is a change in size */ -+ if (h->rcv_buff) -+ free(h->rcv_buff); -+ /* allocate a buffer which can be used to receive data */ -+ h->rcv_buff = (uint8_t *)calloc(h->rcv_buffer_size + NFNL_F_ALIGN_SIZE, 1); -+ if (!h->rcv_buff) { ++ uint8_t *new_buff; ++ ++ /* allocate the replacement before dropping the live receive buffer, ++ * so that a failure leaves both the buffer and the advertised size ++ * untouched instead of stranding a dangling pointer */ ++ new_buff = (uint8_t *)calloc(1, size); ++ if (!new_buff) { + fprintf(stderr, "%s :: calloc failed\n", __func__); + return; + } -+ h->rcv_buff_aligned = NFNL_F_ALIGN(h->rcv_buff, NFNL_F_ALIGN_SIZE); -+} -+ ++ if (h->rcv_buff) ++ free(h->rcv_buff); ++ h->rcv_buff = new_buff; + h->rcv_buffer_size = size; + } + +/** + * nfnl_set_nonblocking_mode - set non blocking mode for netlink socket + * @h: nfnetlink handler @@ -127,9 +144,11 @@ index 667e5ef..96ecbbb 100644 + h->flags &= ~NFNL_F_NONBLOCKING_MODE; + + return 0; - } - ++} ++ /** + * nfnl_subsys_open - open a netlink subsystem + * @nfnlh: libnfnetlink handle @@ -369,6 +433,9 @@ int nfnl_close(struct nfnl_handle *nfnlh) for (i = 0; i < NFNL_MAX_SUBSYS; i++) nfnl_subsys_close(&nfnlh->subsys[i]); @@ -140,22 +159,21 @@ index 667e5ef..96ecbbb 100644 ret = close(nfnlh->fd); if (ret < 0) return ret; -@@ -1549,11 +1616,18 @@ int nfnl_catch(struct nfnl_handle *h) +@@ -1549,11 +1616,17 @@ int nfnl_catch(struct nfnl_handle *h) assert(h); - while (1) { - unsigned char buf[h->rcv_buffer_size] - __attribute__ ((aligned)); -+ unsigned char *buf = h->rcv_buff_aligned; -+ if (!buf) { -+ h->rcv_buff = (unsigned char *)calloc(1, h->rcv_buffer_size); -+ if (!h->rcv_buff) { ++ unsigned char *buf; ++ ++ if (!h->rcv_buff) { ++ h->rcv_buff = (uint8_t *)calloc(1, h->rcv_buffer_size); ++ if (!h->rcv_buff) + return -1; -+ } -+ h->rcv_buff_aligned = NFNL_F_ALIGN(h->rcv_buff, NFNL_F_ALIGN_SIZE); -+ buf = h->rcv_buff_aligned; + } ++ buf = h->rcv_buff; + do { - ret = nfnl_recv(h, buf, sizeof(buf)); @@ -163,7 +181,7 @@ index 667e5ef..96ecbbb 100644 if (ret == -1) { /* interrupted syscall must retry */ if (errno == EINTR) -@@ -1563,8 +1637,9 @@ int nfnl_catch(struct nfnl_handle *h) +@@ -1563,8 +1636,9 @@ int nfnl_catch(struct nfnl_handle *h) ret = nfnl_process(h, buf, ret); if (ret <= NFNL_CB_STOP) @@ -172,14 +190,14 @@ index 667e5ef..96ecbbb 100644 + break; + + } while (!(h->flags & NFNL_F_NONBLOCKING_MODE)); - + return ret; } diff --git a/src/nfnl.version b/src/nfnl.version -index d123456..e789abc 100644 +index c3817dd..c5fd71d 100644 --- a/src/nfnl.version +++ b/src/nfnl.version -@@ -8,6 +8,8 @@ NFNETLINK_1.0.1 { +@@ -9,6 +9,8 @@ NFNETLINK_1.0.1 { nfnl_set_sequence_tracking; nfnl_unset_sequence_tracking; nfnl_set_rcv_buffer_size; -- 2.47.3