Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Multiple Netlink Decode Paths Can Panic on Malformed or Undersized Input

Abierto
#367 1 comentario 0 reacciones 0 asignados Ver en GitHub

@vulragrag-star ya está trabajando en esto.

Desde el 20/9/2026.

  • #368 de @vulragrag-star — abierto

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
68/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
go, linux
Área
networking

Línea de trabajo

Comienza con las rutas de decode indicadas en expr/ct.go, expr/verdict.go, expr/log.go, expr/connlimit.go, set.go, chain.go, obj.go y alignedbuff.go; después, ejecuta expr/ct_timeout_poc_test.go. Se considera terminado cuando los atributos malformados o demasiado pequeños devuelven errores sin provocar un panic y elementsFromMsg deja de producir SetElements vacíos espurios.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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

Lenguaje dominante
Go
Estrellas
1.4k
Forks
187
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de google/nftables

Todos los issues de google/nftables

Issues similares

Más issues de Go

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.