Use this skill whenever you need to fuzz the Linux in-kernel SMB server (ksmbd) with syzkaller, set up SMB2/SMB3 protocol fuzzing, configure ksmbd for maximum attack surface, or build stateful fuzzing harnesses for SMB protocol testing. Make sure to use this skill when the user mentions ksmbd, SMB fuzzing, syzkaller kernel fuzzing, SMB2/SMB3 protocol testing, or wants to find vulnerabilities in the Linux SMB server implementation.
Use this skill whenever you need to fuzz the Linux in-kernel SMB server (ksmbd) with syzkaller, set up SMB2/SMB3 protocol fuzzing, configure ksmbd for maximum attack surface, or build stateful fuzzing harnesses for SMB protocol testing. Make sure to use this skill when the user mentions ksmbd, SMB fuzzing, syzkaller kernel fuzzing, SMB2/SMB3 protocol testing, or wants to find vulnerabilities in the Linux SMB server implementation.
A skill for fuzzing the Linux in-kernel SMB server (ksmbd) using syzkaller. This covers expanding the protocol attack surface, building stateful harnesses, generating grammar-valid PDUs, and leveraging syzkaller features like focus_areas and ANYBLOB.
Target scope: SMB2/SMB3 over TCP. Kerberos and RDMA are intentionally out-of-scope to keep the harness simple.
Configure focus_areas to target weakly-covered code (see Directed Fuzzing)
Seed with ANYBLOB from real pcaps to break plateaus (see ANYBLOB Seeding)
Expand ksmbd Attack Surface via Configuration
By default, a minimal ksmbd setup leaves large parts of the server untested. Enable these features to drive the server through additional parsers/handlers and reach deeper code paths:
Global-level settings
Durable handles - Alters state machines and lifetimes, often surfacing UAF/refcount/OOB bugs under concurrency
Server multi-channel - Increases complexity in connection handling
SMB2 leases - Exercises lease negotiation and break paths
Per-share-level settings
Oplocks (on by default) - Request/break handling in oplock.c
VFS objects - VFS operations and lookup cache
Modules affected
Enabling these increases execution in:
smb2pdu.c (command parsing/dispatch)
ndr.c (NDR encode/decode)
oplock.c (oplock request/break)
smbacl.c (ACL parsing/enforcement)
vfs.c (VFS ops)
vfs_cache.c (lookup cache)
Configuration steps
Review /etc/ksmbd/ksmbd.conf and per-share sections
Enable durable handles, leases, oplocks and VFS objects
Use the helper script: ./scripts/ksmbd_fuzz_config.sh
Note: Exact options depend on your distro's ksmbd userspace (ksmbd-tools).
Authentication and Rate-Limiting Adjustments for Fuzzing
SMB3 needs a valid session. Implementing Kerberos in harnesses adds complexity, so prefer NTLM/guest for fuzzing:
Recommended settings
Allow guest access and set map to guest = bad user so unknown users fall back to GUEST
Accept NTLMv2 (patch policy if disabled) - keeps the handshake simple while exercising SMB3 code paths
Patch out strict credit checks when experimenting (post-hardening for CVE-2024-50285 made simultaneous-op crediting stricter). Otherwise, rate-limits can reject fuzzed sequences too early
Increase max connections (e.g., to 65536) to avoid early rejections during high-throughput fuzzing
⚠️ Caution
These relaxations are to facilitate fuzzing only. Do not deploy with these settings in production.
Stateful Harness: Extract Resources and Chain Requests
SMB is stateful: many requests depend on identifiers returned by prior responses (SessionId, TreeID, FileID pairs). Your harness must parse responses and reuse IDs within the same program to reach deep handlers (e.g., smb2_create → smb2_ioctl → smb2_close).
Response processing pattern
// process response. does not contain +4B PDU lengthvoidprocess_buffer(int msg_no, constchar *buffer, size_t received) {
uint16_t cmd_rsp = u16((constuint8_t *)(buffer + CMD_OFFSET));
switch (cmd_rsp) {
case SMB2_TREE_CONNECT:
if (received >= TREE_ID_OFFSET + sizeof(uint32_t))
tree_id = u32((constuint8_t *)(buffer + TREE_ID_OFFSET));
break;
case SMB2_SESS_SETUP:
// first session setup response carries session_idif (msg_no == 0x01 && received >= SESSION_ID_OFFSET + sizeof(uint64_t))
session_id = u64((constuint8_t *)(buffer + SESSION_ID_OFFSET));
break;
case SMB2_CREATE:
if (received >= CREATE_VFID_OFFSET + sizeof(uint64_t)) {
persistent_file_id = u64((constuint8_t *)(buffer + CREATE_PFID_OFFSET));
volatile_file_id = u64((constuint8_t *)(buffer + CREATE_VFID_OFFSET));
}
break;
default:
break;
}
}
Key tips
Keep one fuzzer process sharing authentication/state: better stability and coverage with ksmbd's global/session tables. syzkaller still injects concurrency by marking ops async, rerun internally.
Sykzaller's experimental reset_acc_state can reset global state but may introduce heavy slowdown. Prefer stability and focus fuzzing instead.
Grammar-Driven SMB2 Generation (Valid PDUs)
Translate the Microsoft Open Specifications SMB2 structures into a fuzzer grammar so your generator produces structurally valid PDUs, which systematically reach dispatchers and IOCTL handlers.
This helps construct valid ACLs that hit arithmetic/overflow paths in smbacl.c. For instance, a malicious Security Descriptor with an oversized dacloffset reproduces an integer-overflow.
Reproducing ACL bugs
Use the helper script to build malicious Security Descriptors:
syzkaller's anyTypes (ANYBLOB/ANYRES) allow collapsing complex structures into blobs that mutate generically. Seed a new corpus from public SMB pcaps and convert payloads into syzkaller programs calling your pseudo-syscall (e.g., syz_ksmbd_send_req).
Convert pcap to corpus
# Extract SMB payloads to JSON
tshark -r smb2_dac_sample.pcap -Y "smb || smb2" -T json -e tcp.payload > packets.json
# Convert to syzkaller corpus
python scripts/convert_pcap_to_corpus.py packets.json corpus/
This jump-starts exploration and can immediately trigger UAFs (e.g., in ksmbd_sessions_deregister) while lifting coverage a few percent.
Sanitizers: Beyond KASAN
KASAN remains the primary detector for heap bugs (UAF/OOB)
KCSAN often yields false positives or low-severity data races in this target
UBSAN/KUBSAN can catch declared-bounds mistakes that KASAN misses due to array-index semantics
Setting num_subauth = 0 triggers an in-struct OOB read of sub_auth[-1], caught by UBSAN's declared-bounds checks.
Recommendation: Run with KASAN + UBSAN; triage UBSAN declared-bounds reports carefully.
Throughput and Parallelism Notes
A single fuzzer process (shared auth/state) tends to be significantly more stable for ksmbd and still surfaces races/UAFs thanks to syzkaller's internal async executor
With multiple VMs, you can still hit hundreds of SMB commands/second overall
Function-level coverage around ~60% of fs/smb/server and ~70% of smb2pdu.c is attainable, though state-transition coverage is under-represented by such metrics
Practical Checklist
Enable durable handles, leases, multi-channel, oplocks, and VFS objects in ksmbd
Allow guest and map-to-guest; accept NTLMv2
Patch out credit limits and raise max connections for fuzzer stability
Build a stateful harness that caches SessionId/TreeID/FileIDs and chains create → ioctl → close
Use a grammar for SMB2 PDUs to maintain structural validity
Use focus_areas to overweight weakly-covered functions (e.g., smbacl.c paths like smb_check_perm_dacl)
Seed with ANYBLOB from real pcaps to break plateaus; pack seeds with syz-db for reuse
Run with KASAN + UBSAN; triage UBSAN declared-bounds reports carefully