Project

General

Profile

Actions

Bug #9006

open
TS SB

type: ip dataset rejects standard IPv4 addresses

Bug #9006: type: ip dataset rejects standard IPv4 addresses

Added by Tim Schustermann 16 days ago. Updated 16 days ago.

Status:
Assigned
Priority:
Normal
Target version:
Affected Versions:
Effort:
low
Difficulty:
Label:
Rust

Description

type: ip dataset rejects standard IPv4 addresses

Environment

Suricata 8.0.6
OPNsense 26.7
FreeBSD 15.1

Problem

The ip dataset type is documented to support both IPv4 and IPv6 addresses.

Source:

https://docs.suricata.io/en/suricata-8.0.6/rules/datasets.html#data-types

The documentation states:

8.49.5. File formats 

Datasets use a simple CSV format where data is per line in the file. 

8.49.5.1. data types 

ipv4 
  in the file as string 

ip 
 in the file as string, it can be IPv6 or IPv4 address 
 (standard notation or IPv4 in IPv6 one)

However, a file-backed type: ip dataset rejects standard IPv4 notation.

Dataset configuration:

datasets:
  tortest:
    type: ip
    load: /usr/local/etc/suricata/test-tor.list

Dataset file, aka /usr/local/etc/suricata/test-tor.list:

1.1.1.1
8.8.8.8

Running:

 suricata -T -c /usr/local/etc/suricata/suricata.yaml 

does not print the dataset error to the terminal. The error is logged in:

 /var/log/suricata/latest.log 

The log contains:

 invalid Ipv6 value tortest in /usr/local/etc/suricata/test-tor.list 

The exact same file works correctly when using:

 type: ipv4 

Relevant code

In Suricata 8.0.6, process_ipv6_set() parses the dataset entry using Ipv6Addr::from_str():

https://raw.githubusercontent.com/OISF/suricata/suricata-8.0.6/rust/src/detect/datasets.rs

 let ipv6 = match Ipv6Addr::from_str(v[0]) { 

Therefore, standard IPv4 input such as 1.1.1.1 is rejected as an IPv6 address before it can be handled as IPv4.

The same function does explicitly handle IPv4-mapped IPv6 addresses such as:

 ::ffff:1.1.1.1 

using to_ipv4_mapped().

This appears inconsistent with the documented behavior of the ip dataset type, which is supposed to accept both IPv4 and IPv6 addresses.

C implementation

The corresponding C implementation in Suricata 8.0.6 appears to handle both IPv6 and standard IPv4 input in DatasetParseIpv6String():

https://raw.githubusercontent.com/OISF/suricata/suricata-8.0.6/src/datasets.c

It distinguishes IPv6 and IPv4 input and uses inet_pton(AF_INET6, ...) for IPv6 and inet_pton(AF_INET, ...) for standard IPv4.

This appears to indicate that the current Rust dataset parser does not preserve the previous behavior for standard IPv4 input when processing a dataset of type ip.

Expected behavior

The following should load successfully with type: ip:

1.1.1.1
8.8.8.8

Actual behavior

Standard IPv4 addresses are rejected as invalid IPv6 values:

 invalid Ipv6 value tortest in /usr/local/etc/suricata/test-tor.list 

The ipv4 dataset type works correctly with the same IPv4 input.

Note

Sorry if I made any mistakes in this report. I used some help from ChatGPT while working on this late at night and being quite tired, but I also checked the relevant documentation, source code, and behavior myself.

I am not very familiar with Rust syntax, so it is possible that I may be misunderstanding something in the process_ipv6_set() implementation. If I have misunderstood the code or the intended behavior, please feel free to correct me.

Thanks a lot for taking the time to look into this and for all the work on Suricata!
Greetings from Switzerland

Actions

Also available in: PDF Atom