# GCC 16 -fanalyzer triage (analyzer.log, tree at 2e2f0d720c)

Build: buildtype=release, -O3, RTE_ASSERT compiled out.
1267 warnings in the log = 708 unique sites = 894 site+caller rows.

| Verdict | Rows |
|---|---|
| Real (path is feasible) | 246 |
| False positive | 631 |
| Unverified | 17 |

Of the 246 real rows, 88 are under app/ (75 in app/test unit tests), and a further
group is harmless (zero-length memcpy with NULL, uninitialised bytes copied but never
used, redundant NULL checks). The rest are the lib/driver bugs below. Several rows
share one root cause.

Coverage:
- 47 rows in the small classes (double-free, use-after-free, fd, infinite-loop,
  overlapping-buffers, deref-before-check): event path and source read for each.
- 847 rows in the bulk classes: triaged by seven separate passes. Non-header rows were
  read individually; repeated patterns (ifpga feature lookups, ring n=1 wrap, failsafe
  ETH(), test_cryptodev allocs, test failure-path leaks) were judged as a group from
  2-4 full paths plus a source check of the rest.
- (v) = the decisive source lines were re-read in a second pass. Items without (v)
  rest on one reading.
- Nothing was compiled or run; no source was changed.

## 1. Double free, bad pointer, wrong data

| Where | Problem |
|---|---|
| drivers/net/bnxt/tf_core/v3/tfc_msg.c:160,176 (v) | `tfc_msg_alloc_dma_buf()` frees `buf->va_addr` when virt2iova fails and leaves it set; the caller's cleanup frees it again. 5 callers. `tfc_msg_idx_tbl_set()` also calls the alloc twice (:647 and :653), leaking the first buffer on every DMA-sized set. |
| drivers/net/nfp/nfpcore/nfp_elf.c:870,275 (v) | `nfp_elf_read_section_headers()` frees `shdrs`/`shdrs_data`/`shdrs_host_endian` on error without clearing them; `nfp_elf_mutable_buf()` then calls `nfp_elf_free()`. Double free on a malformed firmware ELF. |
| drivers/bus/fslmc/fslmc_vfio.c:483,544 (v) | `fslmc_vfio_check_extensions()` closes the container fd on ioctl failure; the caller closes it again. |
| drivers/bus/fslmc/fslmc_vfio.c:1325-1328 (v) | return of `fslmc_vfio_setup_device()` ignored; `ioctl()` on uninitialised `mc_fd`. |
| lib/pipeline/rte_swx_ctl.c:3131,2896 (v) | table entry parser looks the action up globally, not per table; `entry->action_data` is sized for the table (or NULL). An action with larger args writes past it. Control-plane input. |
| lib/pdcp/pdcp_process.c:59,146,167 (v) | `rte_pktmbuf_prepend()` result used unchecked; NULL write when headroom < 8. |
| drivers/crypto/ccp/ccp_crypto.c:2034,2121 (v) | `rte_pktmbuf_append()` unchecked in AES-CMAC; NULL+32 write when tailroom < 64. Same at :1575, :1744, :2375. |
| drivers/net/nfp/nfd3/nfp_nfd3_dp.c:184 (v) | `rte_pktmbuf_prepend()` unchecked on Tx metadata. |
| drivers/net/r8169/r8169_rxtx.c:1568-1571 (v) | append failure is logged, then `memset(NULL, 0, pad_len)`. |
| drivers/net/zxdh/zxdh_common.c:230 (v) | `rte_memcpy(res, ..., tbl_reps->len)` with device-supplied length into a 1-byte caller buffer. |
| drivers/crypto/cnxk/cnxk_se.h:1259,317,556 (v) | SM4-ECB (no IV), SG mode, cipher offset not 8-aligned: memcpy of `pad_len` bytes from NULL `iv_buf`. |
| drivers/crypto/mlx5/mlx5_crypto_gcm.c:433,222 (v) | setup error path calls `qp_release()`, which reads `queue_pairs[qp_id]` (not yet assigned): NULL deref, new qp leaked. |
| drivers/net/bnxt/bnxt_rxtx_vec_sse.c:448,498 (v) | `rxcmp1[]` in `crx_burst_vec_sse()` is never written; `GET_DESC_FIELDS` blends it into `vlan_tci` of every mbuf on the compressed-CQE SSE Rx path. |
| drivers/net/intel/ice/ice_dcf_vf_representor.c:233 (v) | `ice_dcf_vf_repr_hw()` returns NULL once `dcf_valid` is cleared; vlan offload/pvid/tpid ops dereference it. |
| drivers/net/cxgbe/cxgbe_filter.c:179-182 (v) | `WARN_ON(!mbuf)` only logs; NULL deref on pool exhaustion. |
| drivers/compress/octeontx/otx_zip_pmd.c:255 (v) | frees `vf->zip_mp` (old or NULL) instead of the just-created `zip_buf_mp`. |
| drivers/net/cnxk/cnxk_rep_msg.c:338-343 (v) | for 8-byte acks the freshly allocated `adata->u.data` is overwritten by the memcpy (leak); allocation unchecked. |
| drivers/net/intel/cpfl/cpfl_flow_parser.c:1989 | `prog->prog` NULL when a JSON mod rule has a "parameter" content field but no prog action. |
| drivers/net/intel/cpfl/cpfl_representor.c:563,662 (v) | `ret` returned uninitialised when the allowlist loop creates nothing. |
| drivers/net/xsc/xsc_rx.c:231-240 (v) | BAD_IOVA path leaks the buffer and later uses the bad pointer. |
| drivers/crypto/ccp/ccp_dev.c:547-549 (v) | memzone reserve result unchecked. |
| drivers/net/dpaa2/dpaa2_recycle.c:406,469 (v) | `lsx_ccsr_map_region()` NULL (no /dev/mem) dereferenced. |
| drivers/raw/ifpga/base/ifpga_feature_dev.c:99,197 (v) | PR_MGMT / port ERROR feature lookup unchecked (hardware without the feature). |

## 2. Leaks in normal operation

| Where | Problem |
|---|---|
| lib/pipeline/rte_swx_pipeline_spec.c:2893,2210 (v) | `pipeline_spec_free()` memsets `s` but never frees it; leaks on every parse, success or failure. |
| drivers/net/cnxk/cnxk_rep_msg.c:552 (v) | `send_ack_message()` never frees `buffer`. |
| drivers/net/sfc/sfc_tbl_meta_cache.c:137 (v) | `fields` not freed on success. |
| drivers/net/zxdh/zxdh_flow.c:1256,1664 (v) | `flow` allocated when `dh_flow == NULL` (validate) is not freed on the `return 0` paths (:1494, :1831). |
| drivers/net/cxgbe/cxgbe_main.c:688 | `pi->rss` has no matching free anywhere in the driver. |
| drivers/net/mana/mana.c:2189,2236 (v) | secondary-process probe leaks `priv`. |
| drivers/raw/ntb/ntb.c:1240,1270 (v) | `xstats_names` leaked for an unknown name; allocation unchecked. |
| app/test-eventdev/test_perf_common.c:592 | `src`/`dst` never freed. |
| app/graph/l2fwd.c:34,46; l3fwd.c:76,90 | `node_patterns`, `pcap_filename` never freed (one-shot). |

## 3. Leaks on error paths (init/setup failure)

lib:
- lib/pdump/rte_pdump.c:403 (v): BPF filter not destroyed on the later error returns.
- lib/node/kernel_rx.c:214,222 (v): `recv_info` when `socket()` fails.
- lib/graph/graph_stats.c:354: `x = realloc(x, ...)`.
- lib/eal/linux/eal_dev.c:207: duplicate `PCI_SLOT_NAME=` key (theoretical).

drivers:
- bnxt/bnxt_ethdev.c:5043-5097 (ctx_pg_arr / ctx_dma_arr)
- intel/cpfl/cpfl_ethdev.c:2201-2213, 3096-3114; intel/idpf/idpf_ethdev.c:1666-1677
- intel/ice/base/ice_xlt_kb.c:135-148
- ntnic/ntnic_ethdev.c:2326 (p_drv)
- cnxk/cnxk_eswitch_flow.c:395, cnxk_rep.c:398, cnxk_tm.c:306, cnxk_tm.c:394
- failsafe/failsafe_ops.c:461-481 (v), gve/gve_tx_dqo.c:605-619 (v), ionic/ionic_lif.c:~691
- memif/rte_eth_memif.c:169, 1326, 1388, 1774 (v), 1812
- nbl/nbl_hw/nbl_channel.c:943; nbl_channel.c:596-607 (v): mailbox pipe fds not closed when thread create fails
- nfp/nfdk/nfp_nfdk_dp.c:460, nfp/nfp_ethdev.c:2847
- ring/rte_eth_ring.c:548-561, sfc/sfc.c:1435, softnic/rte_eth_softnic_thread.c:69
- vmxnet3/vmxnet3_rxtx.c:1047 (v), 1151; xsc/xsc_dev.c:359
- baseband/la12xx/bbdev_la12xx.c:891, bus/dpaa/base/fman/fman.c:60, common/qat/qat_qp.c:844,879
- raw/cnxk_gpio/cnxk_gpio.c:254-267, raw/ifpga/base/opae_i2c.c:472, opae_intel_max10.c:1358
- bus/platform/platform.c:301 (next to the flagged line: `name[i]` not freed)

## 4. Unchecked allocation (crash on malloc failure)

nfp/nfpcore/nfp_nsp.c:551, xsc/xsc_ethdev.c:546, cnxk/cnxk_rep_msg.c:391,419,451,613,
cnxk/cnxk_rep_flow.c:213,223, intel/idpf/idpf_common_virtchnl.c:439,
ntnic/nthw/flow_api/flow_id_table.c:68, ntnic/nthw/model/nthw_fpga_model.c (5 `*_new`),
crypto/caam_jr/caam_jr.c:2197,2202, event/opdl/opdl_test.c:988, app/test-dma-perf/main.c:190

## 5. Real but harmless

- lib/eventdev/rte_event_eth_rx_adapter.c:2961 (v): `rxa_sw_vector_limits()` leaves `log2_sz` unset (returned to the caller and traced).
- lib/compressdev/rte_compressdev.c:59: NULL capabilities if a PMD has no `dev_infos_get` (none in tree).
- lib/eal/common/eal_common_dev.c:405: `local_dev_remove(NULL)` on a narrow rollback path.
- net/ena/ena_ethdev.c:3677 (v): `metrics_stats[]` copied to xstats uninitialised when the admin command fails.
- net/octeon_ep/otx_ep_mbox.c:343: `rsp` read after a failed send.
- net/mlx5/mlx5_rx.c:1252, net/cxgbe/cxgbe_ethdev.c:616, intel/ixgbe/ixgbe_ethdev.c:5322, ixgbe_e610.c:240,395, hinic3_nic_cfg.c:701, cn10k/cn20k tls13_trim_mac: uninitialised value read, result unused.
- memcpy(NULL, x, 0) or memcpy(x, NULL, 0): crypto/cnxk/cnxk_ae.h:1242,1381 (12 rows), caam_jr.c:1564-1613, nbl_channel.c:737, netvsc/hn_rndis.c:593.
- lib/bpf/bpf_exec.c:487 (reg[5] passed to xsym), lib/telemetry/telemetry_json.h:45 (documented).
- net/bnxt/bnxt_ethdev.c:5196, net/ntnic/ntnic_ethdev.c:2688: redundant NULL check after dereference.
- app/proc-info/main.c:395 (v): `--collectd-format` given twice dups/closes a closed fd.

## 6. Test code and tools

- app/test-compress-perf/comp_perf_test_cyclecount.c:147,460 (v): `ops` freed in `cperf_cyclecount_op_setup()` and again in `main_loop()`.
- app/test-regex/main.c:222,310 (v): `read_file()` frees `*buf`, `init_port()` frees it again; :726 `rules_file` used uninitialised without `--rules`.
- app/test-crypto-perf/cperf_ops.c:429: `m->next` NULL after `rte_pktmbuf_reset()` (option dependent).
- app/test-fib/main.c:1131,1193, app/test-flow-perf/main.c:1865: leaks at exit.
- app/test/test_cryptodev.c: ~25 sites with unchecked `rte_pktmbuf_alloc()`; test_dmadev.c:308; 5 other unchecked allocs.
- app/test: 33 leaks on a test's failure-return path (test_bitset, test_lpm, test_lpm6, test_fib6, test_bpf, test_malloc, test_rcu_qsbr, ...).
- app/test: uninitialised reads in test_bitset.c:643, test_event_eth_tx_adapter.c:494, test_stack.c:524 (benign).

## 7. False-positive patterns (634 rows)

| Pattern | Rows (approx.) |
|---|---|
| ifpga: feature ops looking up their own feature, list invariant not visible | 96 |
| Pointer stored in a long-lived struct (`dev->data->mac_addrs`, queue arrays, lists, registries) reported as a leak | ~95 |
| rte_ring: n=1 enqueue/dequeue taking the wrap branch (`idx = head & mask` not related to `size`); rcu_qsbr `alloca(esize)` allocation-size | ~75 |
| Same condition assumed true and false on one path; invariants guarded by other code | ~120 |
| failsafe `ETH(sdev)` NULL (sub-device state guards) | 19 |
| intel common flow engine: `actions[0]` / engine ref non-NULL by construction | 19 |
| cnxk/cpt crypto session-type invariants | ~25 |
| Loop bound clamped at assignment (bnxt num_leds, tfc num_lvl, hugepage sizes, ...) | ~25 |
| LIST/TAILQ remove-then-free loops reported as double-free / use-after-free (eal_alarm, swx_ctl, vdev_netvsc, xsc, mlx5) | 12 |
| Busy-wait loops on hardware/atomic state reported as infinite loops | 10 |
| Negative tests and deliberately dropped handles in app/test | ~20 |
| `rte_flow_error_set()` / external helper assumed to return 0 | ~10 |
| Other one-offs | remainder |

Checked individually among these: lib/eal/linux/eal_alarm.c:110,225, lib/pipeline/rte_swx_ctl.c:292-294,
lib/graph/graph_stats.c:202,211, drivers/bus/pci/linux/pci_uio.c:339, virtio_user/vhost_kernel.c:432,
app/test-pmd/cmdline.c:9614, bonding rte_eth_bond_8023ad.c:358, the three `shuffle_input_keys()` memcpy
warnings (`swap_idx = rand % i` is never `i`), nbl_dev.c:210.

## 8. Unverified (17 rows)

- drivers/net/zxdh/zxdh_np.c:325,4801-4831 (5 rows): SDT parser writes a HASH/ETCAM-sized struct into a 20-byte ERAM struct if the sdt_no type differs; sdt_no sources not traced.
- drivers/net/zxdh/zxdh_ethdev.c:751: `hdr_mz` NULL if a Tx queue has 0 descriptors.
- drivers/net/pfe/pfe_hif_lib.c:445: `first_mbuf` NULL if a call starts mid-packet.
- drivers/net/enetfec/enet_rxtx.c:123: `rte_pktmbuf_adj()` NULL on a very short frame.
- drivers/net/bnxt/bnxt_hwrm.c:6207,6244,6301: `buf` leaked if `HWRM_PREP` returns early; needs `hwrm_cmd_resp_addr == NULL`.
- drivers/net/bnxt/tf_ulp/ulp_mapper.c:4060: cond list NULL for an out-of-range template index.
- drivers/bus/dpaa/base/qbman/qman.c:951: `fq` NULL guarded only by `DPAA_BUG_ON` (compiled out).
- app/test-crypto-perf/cperf_ops.c:491; app/test/test_graph_feature_arc.c:327,1278,1290.

## 9. Noticed in passing (not analyzer findings, not verified)

- lib/vhost/vhost_crypto.c:857: `*cur_desc = desc + 1` can point one past the last descriptor.
- lib/vhost/vduse.c:213-218: two `rte_malloc_socket()` results unchecked.
- drivers/net/softnic/rte_eth_softnic_thread.c: free loop covers workers only, init covers all lcores.
- drivers/net/mlx5/mlx5_hws_cnt.h:346-350: ring reservation size guarded only by MLX5_ASSERT.
- app/test/test_malloc.c:519-522: `ptr3` leaked when the second realloc fails.
