Using AI Tools to Audit Linux Kernel Configuration for Hardening Gaps

Using AI Tools to Audit Linux Kernel Configuration for Hardening Gaps

Problem

The Linux kernel configuration file contains thousands of options. On a default distribution kernel, most of these are set to whatever the distribution maintainer considered reasonable for a general-purpose workload. For a production server, many of these defaults leave attack surface enabled that has no legitimate use: debugging interfaces, legacy network protocols, obscure hardware drivers, and experimental features that have historically been rich sources of privilege escalation vulnerabilities.

Manual kernel configuration auditing is thorough but expensive. Tools like kconfig-hardened-check automate much of this work against a known set of recommended settings. But they have limitations: they check options against a static list, they don’t understand the interactions between options, they don’t know about your specific deployment context (Kubernetes node vs. bare metal vs. cloud VM), and they can’t reason about architecture-specific risks.

AI language models are well-suited to fill these gaps. Kernel configuration auditing is fundamentally a reasoning task — “does CONFIG_X make sense given that CONFIG_Y is also set, and given that this machine is an internet-facing Kubernetes worker node?” — and LLMs trained on Linux kernel documentation, security advisories, and hardening guides can perform this reasoning reliably when given the right structure.

The value is in three specific areas where AI outperforms static tools:

Option interaction analysis. A kernel with CONFIG_USERFAULTFD=y and CONFIG_UNPRIVILEGED_USERFAULTFD=y is more exposed than a kernel with just CONFIG_USERFAULTFD=y, because the latter still requires CAP_SYS_PTRACE while the former allows unprivileged use. An AI auditor can reason about this dependency; a static checker only sees whether individual options match a target value.

Context-sensitive recommendations. A Kubernetes node has different hardening requirements from an interactive workstation. CONFIG_KCMP (used by container runtimes for checkpoint/restore) may be appropriate on a Kubernetes node but unnecessary on a bare-metal server. AI tools can contextualise recommendations based on the deployment role you describe.

Novel gap identification. Static tools check a known list; AI tools can reason about options not on the list. A recently-added kernel option with a known security implication may not be in kconfig-hardened-check yet, but an LLM with current training data can surface it.

The limitations are real too: AI tools can hallucinate option names, mis-state kernel version requirements, and produce plausible-sounding but incorrect interaction analysis. The workflow must treat AI output as a recommendation requiring human verification, not as authoritative guidance.

Target systems: any Linux kernel build from source or any environment where the kernel configuration can be reviewed; Kubernetes nodes, cloud VMs, bare-metal servers, and CI runner hosts running any distribution; security teams responsible for kernel hardening baselines.


Threat Model

The threat this article addresses is misconfiguration, not a direct adversary. The security risk is:

Unnecessary attack surface. Options like CONFIG_KEXEC, CONFIG_DEVMEM, CONFIG_BINFMT_MISC, and many others enable kernel features that have no legitimate use on a production server but have historically been used in privilege escalation and persistence attacks. Leaving them enabled is not an active exploit — it is risk carried unnecessarily.

Contradictory hardening settings. A kernel with CONFIG_HARDENED_USERCOPY=y and CONFIG_PAGE_TABLE_ISOLATION=y but also CONFIG_X86_VSYSCALL_EMULATION=y has partially undermined its own protections — vsyscall emulation at a fixed address is a ROP gadget source. These interactions require reasoning to detect.

Architecture-specific gaps. A hardening checklist developed for x86_64 may not flag CONFIG_ARM64_ERRATUM_* workarounds that have security implications on ARM64. AI tools trained on architecture-specific documentation can surface these.


Configuration / Implementation

Step 1 — Extract your kernel configuration

# Running kernel config (most distributions expose this)
cat /boot/config-$(uname -r) > /tmp/kernel-config.txt
# Or:
zcat /proc/config.gz > /tmp/kernel-config.txt 2>/dev/null || \
  cat /boot/config-$(uname -r) > /tmp/kernel-config.txt

# Verify it contains the expected format
head -5 /tmp/kernel-config.txt
# Expected: # Automatically generated file; DO NOT EDIT.
# CONFIG_64BIT=y

# Count total options
grep -c "^CONFIG_" /tmp/kernel-config.txt

Step 2 — Run kconfig-hardened-check first as baseline

pip3 install kconfig-hardened-check

kconfig-hardened-check -c /tmp/kernel-config.txt \
  --report --output /tmp/kconfig-baseline.txt

# Get a summary of failures
kconfig-hardened-check -c /tmp/kernel-config.txt | \
  grep "FAIL\|FAIL!" | wc -l
echo "FAIL count (above)"

# Show just the failures
kconfig-hardened-check -c /tmp/kernel-config.txt | grep "FAIL"

This gives you the static baseline. The AI audit adds context and interaction analysis on top.

Step 3 — Prepare context for AI audit

Extract the security-relevant subset of the config to stay within reasonable context:

#!/bin/bash
# extract-security-relevant-config.sh
# Extract options most relevant to security hardening

SECURITY_PATTERNS=(
  "CONFIG_SECURITY"
  "CONFIG_HARDENED"
  "CONFIG_STACKPROTECTOR"
  "CONFIG_FORTIFY"
  "CONFIG_RANDOMIZE"
  "CONFIG_STRICT"
  "CONFIG_DEBUG_"
  "CONFIG_KEXEC"
  "CONFIG_MODULES"
  "CONFIG_BPF"
  "CONFIG_USER_NS"
  "CONFIG_NET_NS"
  "CONFIG_USERFAULTFD"
  "CONFIG_DEVMEM"
  "CONFIG_DEVKMEM"
  "CONFIG_PROC_KCORE"
  "CONFIG_KALLSYMS"
  "CONFIG_KPTR_RESTRICT"
  "CONFIG_INTEGRITY"
  "CONFIG_IMA"
  "CONFIG_LOCKDOWN"
  "CONFIG_LSM"
  "CONFIG_SECCOMP"
  "CONFIG_NAMESPACES"
  "CONFIG_VSYSCALL"
  "CONFIG_ACPI"
  "CONFIG_EFI"
)

for pattern in "${SECURITY_PATTERNS[@]}"; do
  grep "^${pattern}" /tmp/kernel-config.txt
done | sort -u > /tmp/kernel-security-config.txt

echo "Extracted $(wc -l < /tmp/kernel-security-config.txt) security-relevant options"

Step 4 — Perform AI-assisted audit

#!/usr/bin/env python3
# kernel-config-audit.py
import anthropic
import sys
from pathlib import Path

client = anthropic.Anthropic()

SYSTEM_PROMPT = """You are a Linux kernel security expert auditing a kernel configuration 
for hardening gaps. You have deep knowledge of:
- Linux kernel security options and their interactions
- Known privilege escalation attack paths that specific configs enable or prevent
- Architecture-specific security considerations
- Distribution-specific defaults and their rationale

Your analysis must:
1. Identify options that should be changed for the given deployment context
2. Explain WHY each option matters (what attack it enables/prevents)
3. Flag interactions between options (A+B is worse than A alone)
4. Note kernel version requirements for recommended options
5. Distinguish between "should definitely change" and "consider changing"

IMPORTANT: If you are uncertain about a specific option's behavior, say so explicitly
rather than guessing. State the kernel version where a behavior was introduced."""

def audit_kernel_config(config_text: str, deployment_context: str) -> str:
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=4000,
        system=SYSTEM_PROMPT,
        messages=[{
            "role": "user",
            "content": f"""Audit this Linux kernel configuration for security hardening gaps.

DEPLOYMENT CONTEXT: {deployment_context}

KERNEL CONFIGURATION (security-relevant options):
{config_text}

Provide:
1. CRITICAL: Options that should be changed immediately (explain attack path)
2. HIGH: Options that significantly reduce attack surface (explain why)
3. INTERACTIONS: Any option combinations that undermine each other
4. CONTEXT-SPECIFIC: Options that matter specifically for {deployment_context}
5. VERIFY: List any recommendations where I should verify the kernel version requirement

Format each finding as:
[SEVERITY] CONFIG_OPTION_NAME
Current: <current value>
Recommended: <recommended value>
Reason: <2-3 sentences explaining the security impact>
"""
        }]
    )
    return response.content[0].text

def main():
    config_file = Path("/tmp/kernel-security-config.txt")
    deployment_context = sys.argv[1] if len(sys.argv) > 1 else "internet-facing Kubernetes worker node"
    
    config_text = config_file.read_text()
    
    print(f"Auditing kernel config for: {deployment_context}")
    print("=" * 60)
    
    analysis = audit_kernel_config(config_text, deployment_context)
    print(analysis)
    
    # Save for review
    output = Path("/tmp/ai-kernel-audit.txt")
    output.write_text(analysis)
    print(f"\nFull analysis saved to {output}")

if __name__ == "__main__":
    main()

Usage:

# For a Kubernetes worker node
python3 kernel-config-audit.py "Kubernetes worker node, AWS EC2, no physical access, x86_64"

# For a bare-metal server
python3 kernel-config-audit.py "Bare metal web server, internet-facing, running nginx, no containers"

# For an ARM64 edge device
python3 kernel-config-audit.py "ARM64 edge gateway, IoT environment, running custom application"

Step 5 — Validate AI recommendations before applying

For every AI recommendation, verify before acting:

#!/bin/bash
# validate-ai-recommendation.sh
# Verify an AI-recommended config change before applying

OPTION=$1  # e.g., "CONFIG_USERFAULTFD"
KERNEL_VERSION=$(uname -r | cut -d. -f1-2)

echo "=== Validating AI recommendation: $OPTION ==="

# 1. Check current value
CURRENT=$(grep "^${OPTION}" /boot/config-$(uname -r) 2>/dev/null || echo "NOT SET")
echo "Current value: $CURRENT"

# 2. Check kernel documentation
if [[ -d /usr/src/linux-headers-$(uname -r) ]]; then
  find /usr/src/linux-headers-$(uname -r) -name "Kconfig*" -exec grep -l "$OPTION" {} \; | \
    head -3 | while read -r f; do
    grep -A 10 "config ${OPTION#CONFIG_}" "$f" 2>/dev/null | head -15
  done
fi

# 3. Cross-reference with kconfig-hardened-check
kconfig-hardened-check -c /boot/config-$(uname -r) 2>/dev/null | grep "$OPTION"

# 4. Check kernel version availability
echo ""
echo "Kernel version: $KERNEL_VERSION"
echo "Verify the option exists in this kernel version before recommending a change"
echo "Option present in running kernel: $(grep -c "^${OPTION}" /boot/config-$(uname -r) 2>/dev/null)"

Step 6 — Build an AI-augmented hardening baseline

Combine AI recommendations with kconfig-hardened-check into a comprehensive baseline document:

# Generate combined baseline report
{
  echo "# Kernel Hardening Baseline Report"
  echo "# Generated: $(date)"
  echo "# Kernel: $(uname -r)"
  echo "# System: $(hostname)"
  echo ""
  echo "## Static Analysis (kconfig-hardened-check)"
  kconfig-hardened-check -c /boot/config-$(uname -r) 2>/dev/null | grep "FAIL"
  echo ""
  echo "## AI-Assisted Analysis"
  cat /tmp/ai-kernel-audit.txt
  echo ""
  echo "## Validation Status"
  echo "# Each AI recommendation must be marked as:"
  echo "# VERIFIED: Confirmed correct by human review"
  echo "# DISPUTED: AI recommendation appears incorrect — do not apply"
  echo "# DEFERRED: Valid but not yet applied — reason: ..."
} > /etc/security/kernel-hardening-baseline-$(date +%Y%m%d).txt

Expected Behaviour

Audit type Before AI augmentation After AI augmentation
Option interaction detection Not detected by static tools AI flags, e.g., CONFIG_USERFAULTFD=y + CONFIG_UNPRIVILEGED_USERFAULTFD=y interaction
Context-specific gaps Generic recommendations Deployment-specific: “on a Kubernetes node, CONFIG_KCMP is needed for CRIU; on bare metal, disable it”
Novel options not in kconfig-hardened-check Missed LLM surfaces recently-added options with security impact
False positive rate Low (static is certain) Moderate — human validation required for each AI finding
Time to complete audit 5 minutes (static only) 15 minutes (static + AI + validation)

Trade-offs

Aspect Benefit Cost Mitigation
AI interaction analysis Catches complex option dependencies LLM may hallucinate option names or behaviours Always verify option name exists in grep CONFIG_ /boot/config-$(uname -r) before acting
Context-sensitive recommendations More relevant findings Context must be described accurately; wrong context produces wrong advice Standardise context descriptions per node class; review with the team that knows the deployment
AI supplements static tools Deeper coverage AI findings are higher variance than static tool output Treat kconfig-hardened-check as ground truth; treat AI output as leads requiring verification
Natural language explanations Engineers understand why to make each change LLM may explain in terms of outdated attack patterns Cross-reference each explanation with a published CVE or security advisory

Failure Modes

Failure Symptom Detection Recovery
AI hallucinated option name Audit recommends CONFIG_OPTION_THAT_DOES_NOT_EXIST grep validation step shows option not present in kernel Discard the finding; note the model hallucination; run the prompt again with temperature=0
AI incorrect kernel version requirement Applied a config change that silently has no effect on old kernel grep shows option not set despite applying it; kernel version check Verify each recommendation’s kernel version; check using kconfig-hardened-check --version output
Applying AI recommendation breaks driver Critical device stops working after kernel rebuild System post-boot monitoring; driver init failures in dmesg Maintain a recovery kernel; test each change in staging before production; keep config backup
AI over-recommends disabling needed options Too many “disable this” recommendations for a specific deployment Manual review identifies legitimate needs Provide richer deployment context in the prompt; explicitly list workloads that require specific options