Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 11 additions & 1 deletion Sources/Fuzzilli/Corpus/RedisCorpus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,17 @@ public class RedisCorpus: ComponentBase, Collection, Corpus {
}
eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
if let group = eventLoopGroup {
let address = try? SocketAddress(ipAddress: "127.0.0.1", port: 6379)
// Use Redis container hostname from environment or default to localhost
let redisHost = ProcessInfo.processInfo.environment["REDIS_HOST"] ?? "127.0.0.1"
let redisPort = Int(ProcessInfo.processInfo.environment["REDIS_PORT"] ?? "6379") ?? 6379
let dockerNetwork = ProcessInfo.processInfo.environment["DOCKER_NETWORK"] ?? "false"

logger.info("RedisCorpus: Connecting to Redis at \(redisHost):\(redisPort)")
if dockerNetwork.lowercased() == "true" {
logger.info("RedisCorpus: Running in Docker network mode")
}

let address = try? SocketAddress(ipAddress: redisHost, port: redisPort)
let config = RedisConnectionPool.Configuration(
initialServerConnectionAddresses: [address!],
maximumConnectionCount: .maximumActiveConnections(1),
Expand Down
112 changes: 112 additions & 0 deletions vrig_docker/Dockerfile.fuzzillai
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive
ENV SWIFT_VERSION=6.2

# Install system dependencies including V8 build requirements
RUN apt-get update && apt-get install -y \
git \
wget \
curl \
build-essential \
cmake \
ninja-build \
clang \
llvm \
python3 \
python3-pip \
python3-venv \
pkg-config \
unzip \
redis-tools \
libnss3-dev \
libatk-bridge2.0-dev \
libdrm2 \
libxcomposite1 \
libxdamage1 \
libxrandr2 \
libgbm1 \
libxss1 \
libasound2t64 \
&& rm -rf /var/lib/apt/lists/*

# Install Swift 6.2 (using Ubuntu 22.04 package as 24.04 is not available yet)
RUN wget -q https://download.swift.org/swift-${SWIFT_VERSION}-release/ubuntu2204/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04.tar.gz \
&& tar xzf swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04.tar.gz \
&& mv swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04 /opt/swift \
&& rm swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04.tar.gz

ENV PATH="/opt/swift/usr/bin:${PATH}"

WORKDIR /app

# Clone and setup FuzzilliAI
RUN git clone https://github.com/VRIG-Ritsec/fuzzillai.git .

# Build FuzzilliAI
RUN swift build -c release

# Create necessary directories and clean up any old corpus
RUN mkdir -p ./Corpus ./logs
RUN rm -rf ./Corpus/old_corpus ./Corpus/corpus

# Create a startup script that runs FuzzilliAI with Redis corpus
RUN echo '#!/bin/bash\n\
# Start FuzzilliAI with Redis corpus support\n\
\n\
# Check if we are in Docker network\n\
if [ "${DOCKER_NETWORK}" = "true" ]; then\n\
echo "Running in Docker network mode"\n\
echo "Service: ${SERVICE_NAME:-fuzzillai}"\n\
echo "Redis Host: ${REDIS_HOST:-redis}"\n\
echo "Redis Port: ${REDIS_PORT:-6379}"\n\
echo "Profile: ${FUZZILLI_PROFILE:-v8}"\n\
echo "Engine: ${FUZZILLI_ENGINE:-multi}"\n\
fi\n\
\n\
# Check if V8 d8 binary exists in mounted directory\n\
if [ -f "/v8/out/fuzzbuild/d8" ]; then\n\
echo "Using mounted V8 binary from /v8/out/fuzzbuild/d8"\n\
V8_BINARY="/v8/out/fuzzbuild/d8"\n\
elif [ -f "/v8/out/d8" ]; then\n\
echo "Using mounted V8 binary from /v8/out/d8"\n\
V8_BINARY="/v8/out/d8"\n\
else\n\
echo "V8 binary not found in mounted directory. Available files:"\n\
find /v8 -name "d8" -type f 2>/dev/null || echo "No d8 binary found"\n\
exit 1\n\
fi\n\
\n\
# Wait for Redis to be ready\n\
echo "Waiting for Redis to be ready..."\n\
REDIS_HOST=${REDIS_HOST:-redis}\n\
REDIS_PORT=${REDIS_PORT:-6379}\n\
\n\
for i in {1..30}; do\n\
if redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" ping > /dev/null 2>&1; then\n\
echo "Redis is ready at $REDIS_HOST:$REDIS_PORT!"\n\
break\n\
fi\n\
echo "Redis not ready at $REDIS_HOST:$REDIS_PORT, waiting... (attempt $i/30)"\n\
sleep 2\n\
if [ $i -eq 30 ]; then\n\
echo "Redis connection timeout, proceeding anyway..."\n\
fi\n\
done\n\
\n\
# Clean up any problematic corpus directories\n\
echo "Cleaning up corpus directories..."\n\
rm -rf ./Corpus/old_corpus\n\
\n\
echo "Starting FuzzilliAI..."\n\
swift run -c release FuzzilliCli \\\n\
--profile=${FUZZILLI_PROFILE:-v8} \\\n\
--engine=${FUZZILLI_ENGINE:-multi} \\\n\
--corpus=redis \\\n\
--storagePath=./Corpus \\\n\
--resume \\\n\
"$V8_BINARY"' > /app/start.sh && chmod +x /app/start.sh

EXPOSE 6379

CMD ["/app/start.sh"]
26 changes: 26 additions & 0 deletions vrig_docker/Dockerfile.sync
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM python:3.11-slim

# Install system dependencies
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Copy requirements and install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the sync script
COPY sync.py .

# Create a startup script
RUN echo '#!/bin/bash\n\
echo "Starting sync service..."\n\
echo "PostgreSQL DSN: ${PG_DSN}"\n\
echo "Redis Streams: ${STREAMS}"\n\
echo "Group: ${GROUP}"\n\
echo "Consumer: ${CONSUMER}"\n\
python sync.py' > /app/start.sh && chmod +x /app/start.sh

CMD ["/app/start.sh"]
Binary file added vrig_docker/__pycache__/sync.cpython-312.pyc
Binary file not shown.
51 changes: 51 additions & 0 deletions vrig_docker/database.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
CREATE TABLE main (
fuzzer_id SERIAL PRIMARY KEY,
created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE fuzzer (
program_base64 TEXT PRIMARY KEY, -- Base64-encoded fuzzer program (unique identifier)
fuzzer_id INT NOT NULL REFERENCES main(fuzzer_id) ON DELETE CASCADE, -- Links to parent fuzzer instance
inserted_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE execution_type (
id SERIAL PRIMARY KEY,
title VARCHAR(32) NOT NULL UNIQUE
);

-- Program table: Stores generated test programs
CREATE TABLE program (
program_base64 TEXT PRIMARY KEY, -- Base64-encoded test program (unique identifier)
fuzzer_id INT NOT NULL REFERENCES main(fuzzer_id) ON DELETE CASCADE, -- Links to parent fuzzer instance
created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE execution (
execution_id SERIAL PRIMARY KEY, -- Unique identifier for each execution
program_base64 TEXT NOT NULL REFERENCES program(program_base64) ON DELETE CASCADE, -- Links to the executed program
execution_type_id INTEGER NOT NULL REFERENCES execution_type(id), -- Links to execution type
feedback_vector JSONB, -- JSON structure containing execution feedback data
turboshaft_ir TEXT, -- Turboshaft intermediate representation output
coverage_total NUMERIC(5,2), -- Total code coverage percentage (0.00 to 999.99)
created_at TIMESTAMP DEFAULT NOW(), -- Timestamp when execution occurred
execution_flags TEXT[] -- Array of flags/options used during execution
);

ALTER TABLE program
ADD CONSTRAINT fk_program_fuzzer
FOREIGN KEY (program_base64)
REFERENCES fuzzer(program_base64);

INSERT INTO execution_type (title) VALUES
('agentic_analysis'),
('delta_analysis'),
('directed_testcases'),
('generalistic_testcases');


-- Indexes for performance, just query indexes to save on speed
CREATE INDEX idx_execution_program ON execution(program_base64);
CREATE INDEX idx_execution_type ON execution(execution_type_id);
CREATE INDEX idx_execution_created ON execution(created_at);
CREATE INDEX idx_execution_coverage ON execution(coverage_total);
114 changes: 114 additions & 0 deletions vrig_docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
services:
# PostgreSQL Database
postgres:
image: postgres:15
environment:
POSTGRES_DB: main
POSTGRES_USER: fuzzuser
POSTGRES_PASSWORD: pass
DOCKER_NETWORK: "true"
SERVICE_NAME: "postgres"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./database.sql:/docker-entrypoint-initdb.d/01-init.sql
ports:
- "5432:5432"
networks:
- fuzzillai_network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U fuzzuser -d main"]
interval: 10s
timeout: 5s
retries: 5

# Redis for FuzzilliAI communication
redis:
image: redis:7-alpine
environment:
DOCKER_NETWORK: "true"
SERVICE_NAME: "redis"
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- fuzzillai_network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5

# FuzzilliAI Fuzzer Container
fuzzillai:
build:
context: ..
dockerfile: vrig_docker/Dockerfile.fuzzillai
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
- FUZZILLI_PROFILE=v8
- FUZZILLI_ENGINE=multi
- DOCKER_NETWORK=true
- SERVICE_NAME=fuzzillai
volumes:
- fuzzillai_corpus:/app/Corpus
- fuzzillai_logs:/app/logs
- /home/tropic/vrig/v8/v8:/v8:ro
- fuzzillai_corpus_data:/app/Corpus/corpus
depends_on:
redis:
condition: service_healthy
restart: unless-stopped
networks:
- fuzzillai_network
healthcheck:
test: ["CMD", "pgrep", "-f", "FuzzilliCli"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s

# Sync Service - Processes Redis streams and sends to PostgreSQL
sync:
build:
context: .
dockerfile: Dockerfile.sync
environment:
- PG_DSN=postgres://fuzzuser:pass@postgres:5432/main
- STREAMS=redis1=redis://redis:6379
- GROUP=g_fuzz
- CONSUMER=c_sync_1
- DB_WORKER_THREADS=4
- BATCH_SIZE=400
- BATCH_TIMEOUT=0.1
- DOCKER_NETWORK=true
- SERVICE_NAME=sync
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
networks:
- fuzzillai_network
healthcheck:
test: ["CMD", "pgrep", "-f", "sync.py"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s

volumes:
postgres_data:
redis_data:
fuzzillai_corpus:
fuzzillai_corpus_data:
fuzzillai_logs:

networks:
fuzzillai_network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
4 changes: 4 additions & 0 deletions vrig_docker/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
asyncpg==0.29.0
redis[hiredis]==5.0.1
asyncio-mqtt==0.16.1
backoff==2.2.1
Loading