Files
Baradb/BUG_AUDIT_2026-08.md
dimgigov 1ed97fb075
CI / test (push) Has been cancelled
CI / raft-e2e (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled
fix: audit batches 3–4 — TLS verify, WS, OFFSET, B-tree, NULL equality
Close the remaining 2026-08 findings: peer TLS on leader forward, disttxn
SO_ERROR, compaction catalog order, OFFSET without LIMIT, window aggregates,
WebSocket mask/size/auth, SCRAM timing and cbind, B-tree leaf left-max
separators, and SQL three-valued NULL comparisons.
2026-08-28 13:53:02 +03:00

8.2 KiB
Raw Permalink Blame History

BaraDB — Deep Audit (август 2026)

Дата: 2026-08-02 Метод: 4 паралелни одит-агента по слоеве (Storage / Query / Core / Protocol), всеки чете всички файлове в обхвата си и проверява находките срещу реалния код. Обхват: само нови дефекти — 80-те вече оправени в BUGS.md / BUG_AUDIT.md / BARADB_CLIENT_BUGS.md са изключени. Общо: ~28 находки | Поправени: 28 (батч 1: 5 + батч 2: 12 + батч 3: 10 + батч 4: 2) | Остават: 0


Поправени — батч 1 (5)

# Severity Проблем Файл Fix
C1 🔴 CRITICAL MIGRATE handler без auth gate — неавтентикиран клиент пишеше произволни key/value в базата (handleMigrationMessage → applyMigrationBatch → storeKeys → db.put). Открито независимо от 2 агента. core/server.nim:682 Добавен if not authenticated: ... continue (като REP/DISTTXN блоковете)
C2 🔴 CRITICAL Raft commit quorum off-by-one за even-N(N+1) div 2 commit-ваше с малцинство при четен брой възли (N=4 → 2/4). Election-ът ползваше коректното strict majority. GA обхватът е 3-node (нечетно), където формулите съвпадат. core/raft.nim:653 let majority = (node.peers.len + 1) div 2 + 1 (съвпада с election); регресионен тест за 4-node
H1 🟠 HIGH Pre-auth memory-exhaustion DoSparseHeader не ограничаваше length (uint32 до ~4 GiB); recvExactWithTimeout пре-алокира преди auth check. core/server.nim:168 Reject length > uint32(MaxWireStringLen) (64 MB) преди алокация
H4 🟠 HIGH ** и ++ се lower-ваха към equalitybkPow/bkConcat липсваха в op-mapping case-а и попадаха в else: irEq (2 ** 3false, 'a' ++ 'b'false). query/exec/lower.nim:79 of bkPow: irOp = irPow, of bkConcat: irOp = irAdd; 2 регресионни теста
H5 🟠 HIGH != не е отрицание на =irNeq short-circuit-ваше на string inequality, така че 5 != 5.0 → true, но 5 = 5.0 → true. query/exec/eval.nim:438 irNeq numeric-first (точно допълнение на irEq); регресионен тест

Поправени — батч 2 (12)

# Severity Проблем Файл Fix
H3 🟠 HIGH Semi-sync partial/zero ack — връщаше LSN дори при 0 acks core/replication.nim return 0 когато connected replicas < syncReplicaCount acks; 0 connected → local-only (като sync)
H6 🟠 HIGH COUNT/SUM/AVG(DISTINCT) игнорира DISTINCT query/exec/lower.nim, plan_exec.nim aggDistinct = node.funcDistinct; dedup с HashSet в agg пътищата
H7 🟠 HIGH UNION/INTERSECT/EXCEPT KeyError query/executor.nim Dedup fingerprint от projected cols, не row["$value"]
H8 🟠 HIGH MERGE … THEN DELETE / matched condition no-op query/executor.nim Honor mergeMatchedDelete + mergeMatchedCondition
H9 🟠 HIGH WAL recovery crash на torn record storage/lsm.nim, wal.nim, recovery.nim Bound key/val ≤ 64 MB; validate kind преди enum cast
M1 🟡 MEDIUM MVCC write delete-during-iteration core/mvcc.nim Collect-then-delete stale txn ids
M3 🟡 MEDIUM checkpoint lock leak storage/lsm.nim try/finally около write lock + walLock
M4 🟡 MEDIUM flushUnsafe clear-before-write storage/lsm.nim Clear memtable едва след успешен writeSSTable
M5 🟡 MEDIUM Compaction empty-key skip storage/compaction.nim haveLast флаг вместо lastKey = "" sentinel
M6 🟡 MEDIUM rewriteLive remove-before-move storage/wal.nim Само атомен moveFile (rename replace)
L3 🟢 LOW mmap offset+size overflow storage/mmap.nim Overflow-safe: offset > size - length
hygiene Stray ELF protocol/scram .gitignore Премахнат binary + ignore entry

Верификация (батч 2): baradadb build чист; tests/bugfix_test.nim (вкл. batch-2 suite) и tests/test_all.nim (501 OK) минават без [FAILED]. tests/prop_test.nim B-Tree suite OK (H10 не е в този батч — naive left-max fix чупи interleaved remove).

Поправени — батч 3 (10)

# Severity Проблем Файл Fix
H2 🟠 HIGH TLS client връзките не верифицираха сертификата core/server.nim, core/config.nim Отделен tlsClient контекст; CA auto-enable verify; production fail-closed
M2 🟡 MEDIUM disttxn refused-connect wedge core/disttxn.nim getsockopt(SO_ERROR) + try/except около RPC
M7 🟡 MEDIUM Compaction unlink преди catalog load storage/compaction.nim, baradadb.nim Unlink след load + MANIFEST
M8 🟡 MEDIUM OFFSET без LIMIT → 0 реда query/exec/lower.nim, plan_exec.nim limitCount = -1 unlimited; clamp negative
M9 🟡 MEDIUM Window SUM/AVG/COUNT/MIN/MAX → NULL query/exec/window.nim Frame aggregates
M10 🟡 MEDIUM WebSocket unmasked client frames core/websocket.nim Protocol error / close
M11 🟡 MEDIUM WebSocket unbounded buffer core/websocket.nim 1 MiB frame / 4 MiB message / 125-byte control
M12 🟡 MEDIUM SUBSCRIBE без table auth core/websocket.nim, httpserver.nim canSubscribe + hasPrivilegeFor SELECT
L1 🟢 LOW SCRAM timing user enumeration protocol/auth.nim Dummy nonce+encode work за unknown users
L2 🟢 LOW SCRAM c= не се верифицира protocol/auth.nim, scram.nim c= must match gs2 header (biws за n,,)

Поправени — батч 4 (2)

# Severity Проблем Файл Fix
H10 🟠 HIGH B-tree remove separator conventionsplitChild/search са left-max (key > sep → right); removeRec копираше first key на дясното дете (right-min). Naive left-max върху internal ключове чупи prop_test. storage/btree.nim Leaf borrow/remove пишат left-max; merge underflow се качва нагоре; invariant max(left) <= sep (boundary duplicates са позволени, next ги събира)
L4 🟢 LOW NULL equalityNULL = NULL / col = NULL бяха true през string sentinel query/exec/eval.nim Сравнения, LIKE, IN, NOT, AND/OR: NULL operand → unknown (\N); IS NULL непроменен

Остават (0)

Няма отворени находки от този одит.


Проверени и чисти (не са бъгове)

  • JWT exp/alg-confusion: pinned jwt-nim-baraba#fbe084b verify() enforce-ва alg-match, reject-ва NONE, проверява exp/nbf/iat, constant-time compare.
  • auth.nim constantTimeCompare и SCRAM verifyClientProof са constant-time; празен JWT secret fail-closed (server.nim:59).
  • wire.nim deserialize bounds/depth caps са sound.
  • CRC byte ranges / headerSize = 40 са консистентни между write/verify/load (format коментарът още казва "36" — само коментар).
  • Lock ordering (walLock в db.lock; gate преди db.lock), mmap negative offset / close() recursion / fd handling (BUG-036/046) — непокътнати.
  • COUNT(col) изключва NULLs (v.kind != vkNull); LIMIT 0 → празно е коректно; IN-list се lower-ва към OR/AND вериги.

Виж също: PLAN.md (Сесия 13), docs/en/known-limitations.md.