public inbox for dev@dpdk.org
 help / color / mirror / Atom feed
From: Konstantin Ananyev <konstantin.ananyev@huawei.com>
To: Stephen Hemminger <stephen@networkplumber.org>
Cc: "dev@dpdk.org" <dev@dpdk.org>
Subject: RE: DPDK ACL library Security Analysis
Date: Thu, 9 Apr 2026 15:20:50 +0000	[thread overview]
Message-ID: <2fc0e47d6fca4cf1ad203f74f09db0b7@huawei.com> (raw)
In-Reply-To: <20260408195746.62e3b9f8@phoenix.local>



> # DPDK ACL Library Security Vulnerability Report
> ## Access Control List Packet Classification
> 
> **To:** ACL Library Maintainers
> **Date:** April 8, 2026
> **Severity:** CRITICAL
> **Library Path:** `lib/acl/`
> **Affected Files:** `acl_run_sse.h`, `acl_run_neon.h`, `acl_run_avx512.h`,
> `acl_run_altivec.h`, `acl_bld.c`
> 
> ---
> 
> ## Executive Summary
> 
> The ACL library contains **3 HIGH/CRITICAL vulnerabilities**: 1 in SIMD packet
> classification (affecting all architectures), and 2 in rule table building (DoS
> attacks). The SIMD vulnerability allows out-of-bounds reads during high-speed
> packet classification.
> 
> ### Vulnerability Summary
> 
> | ID | Description | Severity | CVSS |
> |----|-------------|----------|------|
> | ACL-001 | SIMD Unbounded Transition Index | CRITICAL | 7.5 |
> | ACL-002 | Algorithmic Complexity DoS | HIGH | 6.5 |
> | ACL-003 | Unbounded Node Creation | HIGH | 6.5 |

I had a look and believe all three are false positives.
Details below.

> ---
> 
> ## ACL-001: SIMD Unbounded Transition Array Index
> 
> **Severity:** CRITICAL
> **CVSS:** 7.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
> **CWE:** CWE-125 (Out-of-bounds Read)
> 
> ### Location
> 
> **SSE:** `lib/acl/acl_run_sse.h:167,173,179,185`
> **NEON:** `lib/acl/acl_run_neon.h:150-153`
> **AVX512:** `lib/acl/acl_run_avx512.h` (similar pattern)
File  with such name dimply doesn't exist
 
> **ALTIVEC:** `lib/acl/acl_run_altivec.h:173-177`
> 
> ### Vulnerable Code (SSE)
> 
> ```c
> 167: trans0 = trans[_mm_cvtsi128_si32(addr)];
> 173: trans2 = trans[_mm_cvtsi128_si32(addr)];
> 179: *indices1 = _mm_set_epi64x(trans[_mm_cvtsi128_si32(addr)], trans0);
> 185: *indices2 = _mm_set_epi64x(trans[_mm_cvtsi128_si32(addr)], trans2);
> ```
> 
> ### Problem
> 
> The `addr` value extracted from SIMD registers is used directly as an array index
> without bounds checking. The value comes from trie traversal calculations and
> could be any 32-bit value depending on packet data and ACL rule structure.

We don't need extra bound checking here.
Address is extracted from internal ACL tables which obviously contains only valid
Indexes. In the opposite case - our inernal ACL trie is already completely screwed up
and we are doomed anyway.
False positive.

> 
> ### Attack Scenario
> 
> ```
> Step 1: Attacker adds ACL rules creating specific trie patterns
> Step 2: Sends packets matching those patterns
> Step 3: SIMD calculation in transition4() computes arbitrary addr value
> Step 4: trans[addr] accesses memory beyond trans[] array
> Step 5: Out-of-bounds read leaks heap memory contents
> ```
> 
> ### Impact
> 
> - **Information Disclosure:** Reads arbitrary offsets from heap
> - **Potential Crash:** If addr points to unmapped memory
> - **ASLR Bypass:** Leaked addresses reveal memory layout
> 
> ### Recommended Fix
> 
> ```c
> /* Add bounds check before array access */
> static inline void
> transition4(uint64_t index, uint32_t *trans, ...)
> {
>     ...
>     uint32_t idx = _mm_cvtsi128_si32(addr);
> 
>     /* ADD BOUNDS CHECK */
>     if (unlikely(idx >= ctx->trans_table_size)) {
>         RTE_LOG(ERR, ACL, "Transition index %u out of bounds\n", idx);
>         idx = 0;  /* Fail-safe to root node */
>     }
> 
>     trans0 = trans[idx];
>     ...
> }
> ```
> 
> ### Testing
> 
> ```c
> /* Fuzz test with random packets */
> void test_acl_classify_fuzz(void)
> {
>     for (int i = 0; i < 100000; i++) {
>         uint8_t pkt_data[1500];
>         fill_random(pkt_data, sizeof(pkt_data));
> 
>         /* Should not crash even with random data */
>         uint32_t results[1];
>         rte_acl_classify(acl_ctx, (const uint8_t **)&pkt_data,
>                         results, 1, DEFAULT_MAX_CATEGORIES);
>     }
> }
> ```
> 
> ---
> 
> ## ACL-002: Algorithmic Complexity DoS in Trie Merge
> 
> **Severity:** HIGH
> **CVSS:** 6.5 (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H)
> **CWE:** CWE-407 (Algorithmic Complexity Attack)
> 
> ### Location
> 
> `lib/acl/acl_bld.c:595-772` (acl_merge_trie function)
> 
> ### Problem
> 
> Nested loops with recursion create O((N²)^depth) complexity during trie merging.
> With many pointers per node and 32 levels of recursion, this can cause CPU
> exhaustion.
> 
> ### Attack
> 
> ```
> 1. Add ACL rules creating wide trie nodes (many children)
> 2. Each rule can create nodes with 1000+ pointers
> 3. Call rte_acl_build() to trigger merge
> 4. Nested iterations cause exponential CPU consumption
> ```

Yes, building ACL trie is memory and CPU consuming process.
Unfortunately it is unavoidable, or a tleast I don't know a good
way to improve it significantly.
Again we a re talking about CP here.
False positive.

> ### Fix
> 
> ```c
> /* Add iteration limit */
> #define MAX_MERGE_ITERATIONS 10000
> 
> static int merge_iteration_count = 0;
> 
> /* In merge loops */
> if (++merge_iteration_count > MAX_MERGE_ITERATIONS) {
>     RTE_LOG(ERR, ACL, "Merge complexity limit exceeded\n");
>     return -E2BIG;
> }
> ```
> 
> ---
> 
> ## ACL-003: Unbounded Node Creation
> 
> **Severity:** HIGH
> **CVSS:** 6.5
> **CWE:** CWE-770 (Allocation without Limits)
> 
> ### Location
> 
> `lib/acl/acl_bld.c:160-182` (acl_alloc_node)
> 
> ### Problem
> 
> `context->num_nodes` incremented without limit, allowing memory exhaustion
> via complex rule patterns.
> 
> ### Fix
> 
> ```c
> #define MAX_ACL_NODES 1000000  /* 1M nodes max */
> 
> static struct rte_acl_node *
> acl_alloc_node(struct acl_build_context *context, int level)
> {
>     /* ADD LIMIT CHECK */
>     if (context->num_nodes >= MAX_ACL_NODES) {
>         RTE_LOG(ERR, ACL, "Maximum node count exceeded\n");
>         return NULL;
>     }
> 
>     ...
>     context->num_nodes++;
>     ...
> }

In fact, we do have mechanism that limits max number of nodes per trie:
static struct rte_acl_node *
build_trie(struct acl_build_context *context, struct rte_acl_build_rule *head,
        struct rte_acl_build_rule **last, uint32_t *count)
{
  ...
  
                node_count = context->num_nodes - node_count;
                if (node_count > context->cur_node_max) {
                        *last = prev;
                        return trie;
                }

The max possible value for it right now is:
#define NODE_MAX        0x4000

False positive.

> 
> ---
> 
> ## Impact Summary
> 
> - **ACL-001:** All packet classification affected, info leak possible
> - **ACL-002/003:** Control plane DoS via complex rules
> - **Scope:** Any DPDK app using ACL for firewall/classification
> 
> ---
> 
> ## Recommended Actions
> 
> 1. **Immediate:** Add bounds check to SIMD array access (ACL-001)
> 2. **Short-term:** Implement node/iteration limits (ACL-002, ACL-003)
> 3. **Long-term:** Comprehensive security review of all SIMD paths
> 
> ---
> 
> **Files Analyzed:** 9 C files, 4 SIMD header variants
> **Total:** ~5000 lines of ACL code
> 
> **Report Version:** 1.0
> 
> **END OF REPORT**

       reply	other threads:[~2026-04-09 15:20 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260408195746.62e3b9f8@phoenix.local>
2026-04-09 15:20 ` Konstantin Ananyev [this message]
2026-04-09 15:42   ` DPDK ACL library Security Analysis Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2fc0e47d6fca4cf1ad203f74f09db0b7@huawei.com \
    --to=konstantin.ananyev@huawei.com \
    --cc=dev@dpdk.org \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox