Skip to content

Reader.Read panics on a negative member size (slice bounds out of range) #16

Open

Description

@JayOfTheKeyboard

Reader.Read panics with slice bounds out of range [:-1000000] when an archive member's header has a negative size field. A small crafted ar or .deb file is enough to crash any program that reads one from an untrusted source.

numeric (reader.go:71-79) parses the size field with strconv.ParseInt, drops the error, and accepts a leading -. readHeader copies the result into header.Size and rd.nb (reader.go:119-121) without checking that it is non-negative. Read then slices b[0:rd.nb] (reader.go:149) with a negative bound, which panics.

Reproduction

A valid !<arch>\n global header plus one 60-byte member header whose size field is -1000000, read with the usage from the README:

package main

import (
	"bytes"
	"fmt"
	"io"

	"github.com/blakesmith/ar"
)

func main() {
	h := fmt.Sprintf("%-16s%-12s%-6s%-6s%-8s%-10s`\n", "data.txt", "0", "0", "0", "644", "-1000000")
	b := append([]byte("!<arch>\n"), []byte(h)...)

	r := ar.NewReader(bytes.NewReader(b))
	hdr, _ := r.Next()
	fmt.Printf("Next: size=%d\n", hdr.Size) // size=-1000000, err=nil
	io.Copy(io.Discard, r)                  // panic: slice bounds out of range [:-1000000]
}
Next: size=-1000000
panic: runtime error: slice bounds out of range [:-1000000]
	github.com/blakesmith/ar.(*Reader).Read(...)
		reader.go:149

Fix

Have numeric return an error, and have readHeader reject a negative size, so Next returns an error on a bad header instead of handing Read a negative length. I have a small fix and a regression test ready and can open a PR if that helps.

Why it matters

.deb files are ar archives, and this library reads them in tools that take packages from untrusted sources. A negative size in one member header turns a parse into a process crash.

(Found by fuzzing and reproduced with the help of an AI coding assistant.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions