Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
3b9769e
Merge branch 'develop'
salcock May 10, 2023
b8696ab
Merge branch 'develop'
salcock Jun 14, 2023
8639aa0
Merge branch 'develop'
salcock Nov 13, 2023
cc98f68
Merge branch 'develop'
salcock Jan 24, 2024
f53dd56
Merge branch 'develop'
salcock May 9, 2024
3bae42c
Merge branch 'master' of https://github.com/salcock/libtrace
salcock May 9, 2024
7bb1255
Merge branch 'develop'
salcock Jun 19, 2024
d9b8e3b
packaging: add fedora 40 and remove fedora 38 to rpm builds
salcock Jun 19, 2024
7b8f921
Fix missing fclose() in tracereport
salcock Jun 19, 2024
7a27350
ndag: do not set singlemsg if we're going to use the array
salcock Jul 31, 2024
e6c9ac3
Added help function for etsifile and etsilive
pvanstam Jul 17, 2024
ca1ddbc
small typos
pvanstam Jul 17, 2024
57abe6f
Remove skip of Keep Alives while decoding and keep in trace
pvanstam Jul 29, 2024
80d0109
set env LIBTRACE_ETSILI_SHOW_KEEPALIVE for decoding keepalives
pvanstam Aug 7, 2024
2fb9d37
Fix clang formatting
salcock Aug 8, 2024
293bc28
Set addrsize correctly before calling accept()
salcock Nov 12, 2024
7e00188
ndag: set error state on trace if packet parsing fails
salcock Jan 31, 2025
5749ada
Fix parsing error in trace_set_configuration()
salcock Jan 31, 2025
3117fdd
Add methods to fetch the uri format and body for a trace
salcock Jan 31, 2025
2e10a1a
ndagtcp: fix bug where recvmsg would instantly fail
salcock Jan 31, 2025
9334012
Reset paused flag when (re)starting an ndagtcp input
salcock Feb 3, 2025
61f2eb0
ndagtcp: fix bad parsing if a packet is spread over 3+ buffers
salcock Feb 3, 2025
ec76fe7
Update CI test workflows
salcock Feb 4, 2025
cd7d7a7
Add 24.11 to whitelist for DPDK testing
salcock Feb 4, 2025
86d3d09
Bump version to 4.0.27 and add Pim to contributors
salcock Feb 4, 2025
79ed361
Disable dpdk test build for 20.04 + dpdk 24.11
salcock Feb 4, 2025
240402c
More test workflow fixes
salcock Feb 4, 2025
c42a1ea
Testing: fix lzma-dev vs liblzma-dev confusion
salcock Feb 4, 2025
65e3620
dpdk testing: require libsystemd-dev as a dependency
salcock Feb 4, 2025
d6dfa9f
Disable automatic fedora package builds
salcock Feb 4, 2025
19eed89
rpm: update package group name for Fedora builds
salcock Feb 5, 2025
40f2088
Merge branch 'develop'
salcock Feb 16, 2025
1bbb090
Merge branch 'develop'
salcock Jun 6, 2025
2c14f89
Updates to distro packaging workflows
salcock Aug 15, 2025
87887ee
Fix bugs with 2-digit major RHEL versionsin rpmpkg-setup.sh
salcock Aug 15, 2025
0225ebd
Merge branch 'develop'
salcock Jan 6, 2026
dd1d16d
Add missing get_layer3 function pointer to bpf format (#218)
daeho-ro Jan 12, 2026
422dfa9
Merge branch 'develop'
salcock Feb 12, 2026
b9b0f78
Reduce block timeout threshold for ring: inputs from 60ms to 10ms
salcock Jan 8, 2026
4d66896
traceucast: fix bad buffer offset if re-sending after EAGAIN
salcock Feb 11, 2026
3d7508b
ndag: improve handling of bad/corrupt data to prevent infinite loops
salcock Feb 11, 2026
54c5027
Bump version to 4.0.30
salcock Feb 11, 2026
f607596
Update submodules to latest code versions
salcock Feb 11, 2026
9a595e8
Add memory barriers to data structs that need them for ARM64
salcock Feb 11, 2026
bc88c15
Add Daeho Ro to AUTHORS
salcock Feb 12, 2026
af53916
Add ubuntu 26.04 to packaging workflow
salcock Apr 19, 2026
395ef13
Add ubuntu 26.04 to packaging workflow
salcock Apr 19, 2026
1872626
Merge branch 'develop'
salcock Apr 28, 2026
6eb0200
ndag/ndagtcp: fix crash when a multi-stream sender connects
salcock Feb 18, 2026
2ea1990
clang format fixes
salcock Feb 18, 2026
83ab265
Bump version to 4.0.31
salcock Feb 18, 2026
0233cca
Add dpdk_per_thread_stats() method
salcock Feb 23, 2026
adcc619
Clang formatting fixes
salcock Feb 23, 2026
c16bdbf
etsilive: fix data corruption issues when reading from multiple sources
salcock Mar 30, 2026
7f1f73c
Add error detection to mmap calls in simple_circular_buffer.c
salcock Apr 20, 2026
08949fb
Fix various bugs observed when converting from etsifile to pcapfile
salcock Apr 22, 2026
1d295c3
Fix segfault when converting header-less formats to pcapng
salcock Apr 22, 2026
c95ea56
ring: and int: now correctly recognise gretap interfaces
salcock Apr 28, 2026
d740e2a
Fix build error on macosx due to Linux-ism
salcock Apr 28, 2026
0b99443
Update packaging changelogs for 4.0.31 release
salcock Apr 28, 2026
eff70c5
Merge branch 'LibtraceTeam:master' into master
salcock Apr 28, 2026
b1b0ab2
Merge branch 'develop'
salcock Jun 2, 2026
6505997
Reverse failed attempt to include static DPDK in libtrace4 rpm
salcock Jun 3, 2026
9db47f3
fix: V-002 security vulnerability
orbisai0security Jun 3, 2026
6a77a67
fix: add buffer-length check in tracereplay.c
orbisai0security Jun 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions rpm/libtrace4.spec
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
Name: libtrace4
Version: 4.0.32
Release: 1%{?rhel_release}
Release: 2%{?rhel_release}
Summary: C Library for capturing and analysing network packets

License: LGPLv3
URL: https://github.com/LibtraceTeam/libtrace
Source0: https://github.com/LibtraceTeam/libtrace/archive/%{version}.tar.gz

%define dpdk_version %(pkg-config --modversion libdpdk 2>/dev/null || echo "unknown")
%define dpdk_major %(echo %{dpdk_version} | cut -d. -f1-2)

%global __requires_exclude ^librte_.*$
Provides: bundled(dpdk) = %{dpdk_major}

BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: make
Expand All @@ -28,6 +22,7 @@ BuildRequires: libwandder2-devel >= 2.0.14
BuildRequires: libwandio1-devel
BuildRequires: dpdk-devel
BuildRequires: (flex-devel or libfl-static)
Requires: dpdk

Provides: libtrace4

Expand All @@ -42,10 +37,11 @@ University in New Zealand.
%package devel
Summary: Development files for %{name}
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: dpdk-devel

%package tools
Summary: Helper utilities for use with the %{name} library
Requires: %{name}%{?_isa} = %{version}-%{release}, libpacketdump4%{?_isa} = %{version}-%{release}
Requires: %{name}%{?_isa} = %{version}-%{release}, libpacketdump4%{?_isa} = %{version}-%{release}, dpdk

%package -n libpacketdump4
Summary: Network packet parsing and human-readable display library
Expand Down Expand Up @@ -132,6 +128,9 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'


%changelog
* Wed Jun 3 2026 Shane Alcock <shane@alcock.co.nz> - 4.0.32-2
- Fix broken DPDK dependency

* Thu May 28 2026 Shane Alcock <shane@alcock.co.nz> - 4.0.32-1
- Updated for 4.0.32 release

Expand Down
1 change: 0 additions & 1 deletion rpmpkg-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ dnf config-manager --set-enabled powertools || true
dnf module disable -y mariadb || true
/usr/bin/crb enable || true


curl -1sLf \
'https://dl.cloudsmith.io/public/wand/libwandio/cfg/setup/bash.rpm.sh' \
| bash
Expand Down
103 changes: 103 additions & 0 deletions tests/test_invariant_tracereplay.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include <check.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

/* We need to test that the memcpy in tracereplay doesn't overflow.
* The vulnerable pattern is:
* newbuf = malloc(sizeof(libtrace_ether_t) + remaining);
* memcpy(newbuf + sizeof(libtrace_ether_t), l2_header, remaining);
* where 'remaining' comes from untrusted packet metadata.
*
* We simulate the allocation logic and check the invariant:
* bytes copied must never exceed (allocated_size - header_size).
*/

#define LIBTRACE_ETHER_SIZE 14 /* sizeof(libtrace_ether_t) */
#define MAX_SAFE_PACKET 65535

/* Simulates the vulnerable allocation+copy logic from tracereplay.c lines 127-128.
* Returns 0 if safe (no overflow), -1 if overflow would occur. */
static int check_copy_bounds(uint32_t wire_length, uint32_t capture_length, size_t actual_data_size)
{
/* In the vulnerable code, 'remaining' is derived from packet metadata (wire_length or cap_length) */
uint32_t remaining = capture_length;

/* The allocation in tracereplay: newbuf = malloc(sizeof(libtrace_ether_t) + remaining) */
size_t alloc_size = LIBTRACE_ETHER_SIZE + remaining;

/* SECURITY INVARIANT: remaining must not exceed actual_data_size,
* and the copy must not exceed (alloc_size - LIBTRACE_ETHER_SIZE) */
if (remaining > actual_data_size) {
/* This is the overflow condition - reading beyond l2_header buffer */
return -1;
}
if (remaining > alloc_size - LIBTRACE_ETHER_SIZE) {
return -1;
}
return 0;
}

START_TEST(test_buffer_read_bounds)
{
/* Invariant: Buffer reads never exceed the declared/actual data length */
struct {
uint32_t wire_len;
uint32_t cap_len; /* attacker-controlled metadata */
size_t actual_data; /* real data available */
int expect_safe; /* 0 = safe, -1 = overflow */
} cases[] = {
/* Exact exploit: cap_len claims 2x actual data */
{ 2000, 2000, 1000, -1 },
/* Extreme: cap_len claims 10x actual data */
{ 10000, 10000, 1000, -1 },
/* Boundary: cap_len equals actual data exactly */
{ 1000, 1000, 1000, 0 },
/* Valid small packet */
{ 64, 64, 64, 0 },
/* cap_len is UINT32_MAX (integer overflow attempt) */
{ 0xFFFFFFFF, 0xFFFFFFFF, 100, -1 },
};
int num_cases = sizeof(cases) / sizeof(cases[0]);

for (int i = 0; i < num_cases; i++) {
int result = check_copy_bounds(cases[i].wire_len, cases[i].cap_len, cases[i].actual_data);
/* The security invariant: if cap_len > actual_data, it MUST be detected as unsafe */
if (cases[i].cap_len > cases[i].actual_data) {
ck_assert_msg(result == -1,
"Case %d: overflow not detected (cap_len=%u, actual=%zu)",
i, cases[i].cap_len, cases[i].actual_data);
} else {
ck_assert_msg(result == 0,
"Case %d: false positive (cap_len=%u, actual=%zu)",
i, cases[i].cap_len, cases[i].actual_data);
}
}
}
END_TEST

Suite *security_suite(void)
{
Suite *s;
TCase *tc_core;

s = suite_create("Security");
tc_core = tcase_create("Core");

tcase_add_test(tc_core, test_buffer_read_bounds);
suite_add_tcase(s, tc_core);

return s;
}

int main(void)
{
int number_failed;
Suite *s;
SRunner *sr;

s = security_suite();
sr = srunner_create(s);

srunner_run_all(sr, CK_NORMAL);
number_failed =
3 changes: 2 additions & 1 deletion tools/tracereplay/tracereplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ static libtrace_packet_t *per_packet(libtrace_packet_t *packet, char **localbuf)

if (linktype == TRACE_TYPE_NONE) {
newbuf = calloc(wire_length + sizeof(libtrace_ether_t), sizeof(char));
memcpy(newbuf + sizeof(libtrace_ether_t), l2_header, remaining);
memcpy(newbuf + sizeof(libtrace_ether_t), l2_header,
remaining < wire_length ? remaining : wire_length);
memcpy(newbuf, FAKE_ETHERNET_HEADER, sizeof(libtrace_ether_t));
l2_header = newbuf;
wire_length += sizeof(libtrace_ether_t);
Expand Down