Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Multiple Netlink Decode Paths Can Panic on Malformed or Undersized Input

Aperta
#367 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

@vulragrag-star ci sta già lavorando.

Dal 20/9/2026.

  • #368 di @vulragrag-star — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
68/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
go, linux
Ambito
networking

Direzione di ricerca

Inizia con i percorsi di decode elencati in expr/ct.go, expr/verdict.go, expr/log.go, expr/connlimit.go, set.go, chain.go, obj.go e alignedbuff.go, quindi esegui expr/ct_timeout_poc_test.go. Il lavoro è completato quando gli attributi malformati o sottodimensionati restituiscono errori senza causare un panic e elementsFromMsg non produce più SetElements vuoti spurii.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Description

Summary

Several decode paths consume kernel-controlled netlink attribute data without length validation, and one has a check-after-use bug. On malformed/undersized kernel input these panic instead of returning an error. Normal, healthy kernel replies provide correct lengths, so these are robustness/hardening issues rather than easily-triggered vulnerabilities. Worth fixing together for crash-safety.

1. expr/ct.go:416-418 — error checked AFTER decoder is dereferenced (nil deref)
decoder, err := netlink.NewAttributeDecoder(ad.Bytes())

decoder.ByteOrder = binary.BigEndian // deref before err is checked

if err != nil {
    return err
}

NewAttributeDecoder returns (nil, err) when the input ends in a partial (<4-byte) attribute header (attribute.go available() returns errInvalidAttribute when len(b[i:]) < nlaHeaderLen).

Dereferencing decoder before checking err then crashes.

Every other similar call site in the repo checks err first; this one is the only inversion.

PoC (expr/ct_timeout_poc_test.go):

package expr

import (
    "testing"

    "github.com/mdlayher/netlink"
)

func TestCtTimeoutUnmarshalMalformedPanic(t *testing.T) {
    data, err := netlink.MarshalAttributes([]netlink.Attribute{
        {Type: NFTA_CT_TIMEOUT_DATA, Data: []byte{0xff}},
    })
    if err != nil {
        t.Fatal(err)
    }

    ct := &CtTimeout{}
    _ = ct.unmarshal(0, data)
}

Observed:

panic: runtime error: invalid memory address or nil pointer dereference
github.com/google/nftables/expr.(*CtTimeout).unmarshal ... expr/ct.go:417
2. Unbounded binary reads / slicing on ad.Bytes()

These call binaryutil.BigEndian.Uint* / binary.BigEndian.Uint* / slice an ad.Bytes() result without checking length; a short attribute panics (slice bounds / index out of range) instead of returning an error.

Location Code Panics when
expr/verdict.go:119 binaryutil.BigEndian.Uint32(nestedAD.Bytes()[4:8]) verdict data < 8 bytes
expr/log.go:142 e.Data = data[:len(data)-1] empty NFTA_LOG_PREFIX → negative slice index
expr/log.go:139,144,146,148,150 binaryutil.BigEndian.Uint16/32(data) short NFTA_LOG_*
expr/connlimit.go:68,70 binaryutil.BigEndian.Uint32(ad.Bytes()) short attr
set.go:828,830,849,862,883 binary.BigEndian.Uint32/64(ad.Bytes()) short attr
chain.go:310 binaryutil.BigEndian.Uint32(ad.Bytes()) short NFTA_CHAIN_POLICY
obj.go:234,247 msg.Data[0] / msg.Data[4:] empty message

binaryutil.NativeEndian.Uint16/32/64 and binaryutil.Int32 additionally dereference &b[0] via unsafe and panic on empty/too-short slices (they are only safe when length is pre-verified, as in alignedbuff).

3. set.go:940-948 — spurious empty element (logic, not a panic)
for ad.Next() {
    var elem SetElement
    switch ad.Type() {
    case unix.NFTA_LIST_ELEM:
        ad.Do(elem.decode(fam))
    }

    elements = append(elements, elem) // appended for every attribute
}

elements = append(elements, elem) runs for every attribute, not just NFTA_LIST_ELEM, producing spurious empty SetElements.

4. alignedbuff.go:144-156 / :160-164 — String() / StringWithLength()

Have no bounds checks and can read OOB / panic, but are currently not reachable from production code (only used in tests). Future-facing hardening.


Impact

  • Availability: process crash (panic) triggered only by malformed / undersized kernel input — not expected from a healthy kernel.
  • Confidentiality / Integrity: none.
  • Severity: low; these are robustness/code-quality issues. Fixes are trivial (check length / reorder error check).

Suggested fixes

  • ct.go:417: move decoder.ByteOrder below if err != nil { return err }.
  • For the Uint* / slice call sites: either use the bounded decoder methods (ad.Uint32/64) or validate len(...) before reading.
  • elementsFromMsg: only append inside the case NFTA_LIST_ELEM.

-Eneshan Erdoğan Karaca

Lingua principale
Go
Stelle
1.4k
Fork
187
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di google/nftables

Tutte le issue di google/nftables

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.