|WARNING| [v2] examples: use strlcpy and strlcat

dpdklab at iol.unh.edu dpdklab at iol.unh.edu
Wed Jun 24 14:49:11 CEST 2026


Test-Label: ai-code-review
Test-Status: WARNING
https://dpdk.org/patch/166091

_AI Code Review_

=== Patch Review: series.patch (via Claude) ===
Review date: 2026-06-24

# DPDK Patch Review

## Summary
This patch replaces unsafe string functions (`strncpy`, `strcpy`, `strcat`) with safer alternatives (`strlcpy`, `strlcat`, `memcpy`) in the examples directory. Overall, the changes improve safety, but there are issues with the `memcpy` conversions and missing header inclusion.

---

## Errors

### 1. `memcpy` does not guarantee null termination (sa.c)

**File:** `examples/ipsec-secgw/sa.c`

**Issue:** The patch replaces `strncpy` with `memcpy` for string operations, but `memcpy` does not null-terminate the destination. The original code relied on `strncpy` to null-pad or the fact that `sub_str` was zero-initialized, but switching to `memcpy` without ensuring null termination could lead to undefined behavior when `sub_str` is later used as a string.

**Lines:**
```c
-			strncpy(sub_str, pt_start, 2);
+			memcpy(sub_str, pt_start, 2);
```
and
```c
-			strncpy(sub_str, pt_start, pt_end - pt_start);
+			memcpy(sub_str, pt_start, pt_end - pt_start);
```

**Fix:** Use `strlcpy` instead of `memcpy` to ensure null termination, or manually null-terminate after `memcpy`:
```c
/* Option 1: Use strlcpy */
strlcpy(sub_str, pt_start, sizeof(sub_str));

/* Option 2: Manually null-terminate after memcpy */
size_t len = (pt_end == NULL) ? 2 : (pt_end - pt_start);
if (len >= sizeof(sub_str))
	return 0;
memcpy(sub_str, pt_start, len);
sub_str[len] = '\0';
```

**Note:** Without seeing the full context of how `sub_str` is declared and used, I cannot determine if the original code already had safeguards (e.g., `sub_str` declared as `char sub_str[3] = {0}`). However, `memcpy` is semantically wrong for string operations that require null termination.

---

### 2. Missing header inclusion (ip_pipeline/conn.c, pipeline/conn.c)

**File:** `examples/ip_pipeline/conn.c`, `examples/pipeline/conn.c`

**Issue:** The patch adds `#include <rte_string_fns.h>` to provide `strlcpy`, which is correct for portability. However, verify that this header exists and is available in all supported DPDK versions. The commit message mentions "older distros without a built-in strlcpy fn", which suggests this is intentional.

**Status:** This appears correct based on the v2 changelog. No action needed, but confirm `rte_string_fns.h` is the correct header in the DPDK version being targeted.

---

## Warnings

### 1. Potential buffer size mismatch (conn.c files)

**File:** `examples/ip_pipeline/conn.c`, `examples/pipeline/conn.c`

**Lines:**
```c
-	strncpy(conn->welcome, p->welcome, CONN_WELCOME_LEN_MAX);
-	strncpy(conn->prompt, p->prompt, CONN_PROMPT_LEN_MAX);
+	strlcpy(conn->welcome, p->welcome, CONN_WELCOME_LEN_MAX + 1);
+	strlcpy(conn->prompt, p->prompt, CONN_PROMPT_LEN_MAX + 1);
```

**Issue:** The original `strncpy` uses `CONN_WELCOME_LEN_MAX` as the count, which typically writes up to `CONN_WELCOME_LEN_MAX` bytes (not including null terminator if the source is longer). The patch changes to `CONN_WELCOME_LEN_MAX + 1`, which is correct for `strlcpy`'s size parameter (the total buffer size including null terminator). However, this assumes the destination buffers (`conn->welcome`, `conn->prompt`) are actually sized as `CONN_WELCOME_LEN_MAX + 1` or larger.

**Verification needed:** Check the declaration of `conn->welcome` and `conn->prompt` to confirm they are sized appropriately:
- If declared as `char welcome[CONN_WELCOME_LEN_MAX]`, then using `CONN_WELCOME_LEN_MAX + 1` as the `strlcpy` size is **wrong** (buffer overflow).
- If declared as `char welcome[CONN_WELCOME_LEN_MAX + 1]`, then the change is correct.

**Suggested fix (if buffers are sized `CONN_WELCOME_LEN_MAX`):**
```c
strlcpy(conn->welcome, p->welcome, CONN_WELCOME_LEN_MAX);
strlcpy(conn->prompt, p->prompt, CONN_PROMPT_LEN_MAX);
```

Without access to the structure definitions, I flag this as a potential off-by-one error. The reviewer must verify the buffer sizes.

---

### 2. Inconsistent conversion strategy (sa.c)

**File:** `examples/ipsec-secgw/sa.c`

**Issue:** The patch converts two `strncpy` calls to `memcpy`, while all other conversions in the patch use `strlcpy` or `strlcat`. This inconsistency suggests either:
1. The `sa.c` changes are operating on binary data (not strings), or
2. The conversion is incorrect and should use `strlcpy`.

Given that the code is parsing a key string and extracting hex digit pairs, the data is likely binary after parsing, but the intermediate `sub_str` buffer appears to be used as a string (e.g., passed to `strtol` or similar). Confirm the intended semantics.

**Recommendation:** If `sub_str` is used as a string, use `strlcpy` with proper bounds checking. If it's binary data, document why `memcpy` is appropriate and ensure null termination is not expected.

---

## Info

### 1. `strlcat` size parameter correctness (cli.c)

**File:** `examples/pipeline/cli.c`

**Lines:**
```c
-		strcat(line, " ");
+		strlcat(line, " ", MAX_LINE_SIZE);

-	strcat(line, tokens[i]);
+	strlcat(line, tokens[i], MAX_LINE_SIZE);
```

**Observation:** The conversion to `strlcat` is correct. The size parameter `MAX_LINE_SIZE` should be the total size of the `line` buffer. Verify that `line` is declared as `char line[MAX_LINE_SIZE]` or larger.

**No issue** if the buffer size matches the constant.

---

### 2. Original `strncpy` already correct in vm_power_manager (channel_manager.c)

**File:** `examples/vm_power_manager/channel_manager.c`

**Original code:**
```c
strncpy(new_domain->name, vm_name, sizeof(new_domain->name));
new_domain->name[sizeof(new_domain->name) - 1] = '\0';
```

**New code:**
```c
strlcpy(new_domain->name, vm_name, sizeof(new_domain->name));
```

**Observation:** The original code was already safe (manually null-terminating after `strncpy`). The conversion to `strlcpy` is an improvement (more concise), but not a bug fix. This is fine.

---

## Summary of Required Actions

1. **Fix `memcpy` in sa.c** (Error): Replace with `strlcpy` or ensure null termination manually.
2. **Verify buffer sizes in conn.c** (Warning): Confirm that `CONN_WELCOME_LEN_MAX + 1` does not exceed the actual buffer size.
3. **Clarify `memcpy` usage** (Warning): Document why `memcpy` is used in `sa.c` if it's intentional, or convert to `strlcpy`.

All other changes appear correct.


More information about the test-report mailing list