gpt

package module
v0.0.0-...-3721db1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 22, 2026 License: BSD-3-Clause Imports: 4 Imported by: 0

README

gpt

Go Reference CI

A hardened GPT / MBR partition-table parser in pure Go (CGO_ENABLED=0, stdlib-only).

gpt is the single, neutral partition-table reader for the go-volumes block stack — shared by the go-filesystems drivers and (later) go-bootloaders, replacing the duplicated and individually buggy copies those projects used to carry.

It parses untrusted on-disk images, so every length, count, and offset is validated before use: the partition-entry size and count are capped, the entry-array LBA and every partition's start and length are checked against the device size, all offset arithmetic is done in int64 to reject overflow, and a truncated or short header returns an error instead of panicking. It never auto-follows nonsensical geometry.

512-byte logical sectors are assumed (matching hdiutil, mkfs, newfs_*, and parted defaults); 4Kn images are out of scope.

Usage

import "github.com/go-volumes/gpt"

// r is any io.ReaderAt over the raw device/image; deviceSize is its length.
parts, err := gpt.List(r, deviceSize)
if err != nil {
    return err // errors.Is(err, gpt.ErrGPT)
}
for _, p := range parts {
    fmt.Printf("[%d] %s %q start=%d len=%d\n",
        p.Index, p.Scheme, p.Name, p.StartOffset, p.Length)
}

// Convenience selectors:
p, err := gpt.First(r, deviceSize)
p, err = gpt.ByIndex(r, deviceSize, 0)
p, err = gpt.ByType(r, deviceSize, gpt.LinuxFilesystemGUID)

Documentation

Overview

Package gpt is a single hardened MBR + GPT partition-table parser for the go-filesystems drivers, replacing seven duplicated and individually buggy copies (ext4, xfs, btrfs, apfs, zfs, exfat, fat32).

It parses UNTRUSTED on-disk images, so every length, count, and offset is validated before use: the partition-entry size and count are capped, the entry-array LBA and every partition's start and length are validated against the device size, all offset arithmetic is performed in int64 to reject overflow, and a truncated or short header returns an error instead of panicking. It never auto-follows nonsensical geometry.

Pure Go, no dependencies outside the standard library, go 1.25 / CGO=0.

Index

Constants

View Source
const (
	// MinEntrySize is the smallest legal GPT partition-entry size (UEFI 2.x).
	MinEntrySize = 128
	// MaxEntrySize caps the entry size to defeat class-(A) over-allocation.
	MaxEntrySize = 4096
	// MaxPartitionEntries caps the entry count. UEFI's canonical layout has
	// 128; we allow up to this many to stay safe against a hostile count
	// such as 0xFFFFFFFF.
	MaxPartitionEntries = 256
)

Hardening bounds. Anything outside these is treated as a malformed image.

View Source
const SectorSize = 512

SectorSize is the LBA size assumed for both MBR and GPT. Every image these drivers handle (hdiutil, mkfs, newfs_*, parted defaults) uses 512-byte logical sectors; 4Kn images are out of scope, matching all seven callers.

Variables

View Source
var (
	// ErrNoTable means neither a GPT header nor an MBR signature was found:
	// the image is a bare filesystem with no partition table.
	ErrNoTable = fmt.Errorf("%w: no partition table", ErrGPT)
	// ErrMalformed means a partition table was present but its contents were
	// inconsistent, out of range, or impossibly sized.
	ErrMalformed = fmt.Errorf("%w: malformed partition table", ErrGPT)
	// ErrNotFound means the requested partition index, or an auto-selected
	// partition of the desired type, does not exist.
	ErrNotFound = fmt.Errorf("%w: partition not found", ErrGPT)
)
View Source
var (
	// LinuxFilesystemGUID is 0FC63DAF-8483-4772-8E79-3D69D8477DE4.
	LinuxFilesystemGUID = [16]byte{
		0xAF, 0x3D, 0xC6, 0x0F, 0x83, 0x84, 0x72, 0x47,
		0x8E, 0x79, 0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4,
	}
	// AppleAPFSGUID is 7C3457EF-0000-11AA-AA11-00306543ECAC.
	AppleAPFSGUID = [16]byte{
		0xEF, 0x57, 0x34, 0x7C, 0x00, 0x00, 0xAA, 0x11,
		0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC,
	}
	// EFISystemPartitionGUID (the ESP) is C12A7328-F81F-11D2-BA4B-00A0C93EC93B.
	EFISystemPartitionGUID = [16]byte{
		0x28, 0x73, 0x2A, 0xC1, 0x1F, 0xF8, 0xD2, 0x11,
		0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B,
	}
	// BIOSBootGUID is 21686148-6449-6E6F-744E-656564454649.
	BIOSBootGUID = [16]byte{
		0x48, 0x61, 0x68, 0x21, 0x49, 0x64, 0x6F, 0x6E,
		0x74, 0x4E, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49,
	}
)

Well-known GPT partition type GUIDs in on-disk ("wire") byte order, for callers that auto-select by type. Mixed-endian per UEFI: first three groups little-endian, the rest big-endian.

View Source
var ErrGPT = errors.New("gpt")

ErrGPT is the base error every sentinel below wraps, so callers can match the whole family with errors.Is(err, ErrGPT).

Functions

This section is empty.

Types

type Partition

type Partition struct {
	// Index is the 0-based slot in the table (GPT entry index, or MBR slot
	// 0..3). For GPT, empty (all-zero type GUID) slots are skipped, so Index
	// values may be non-contiguous.
	Index int
	// Scheme records whether this came from MBR or GPT.
	Scheme Scheme
	// StartOffset is the partition's first byte from the device start.
	StartOffset int64
	// Length is the partition size in bytes. For MBR it is derived from the
	// 32-bit sector count; it may be 0 if the on-disk count was 0.
	Length int64
	// TypeGUID is the GPT partition type GUID in on-disk ("wire") byte order.
	// Zero for MBR partitions.
	TypeGUID [16]byte
	// MBRType is the 1-byte MBR partition type (e.g. 0x83 Linux, 0xEE
	// protective). Zero for GPT partitions.
	MBRType byte
	// Name is the GPT partition name (UTF-16LE decoded to UTF-8). Empty for
	// MBR partitions.
	Name string
}

Partition describes one validated partition. All byte offsets and lengths are absolute, in bytes, relative to the start of the device, and are guaranteed to satisfy 0 <= StartOffset and StartOffset+Length <= deviceSize.

func ByIndex

func ByIndex(r io.ReaderAt, deviceSize int64, index int) (Partition, error)

ByIndex returns the populated partition at slot index (0-based). It mirrors the existing callers' partIndex>=0 path. For GPT, index matches the entry slot (empty slots are skipped, so a requested empty/out-of-range slot yields ErrNotFound). For MBR, index is the 0..3 slot.

func ByType

func ByType(r io.ReaderAt, deviceSize int64, want [16]byte) (Partition, error)

ByType returns the first populated GPT partition whose TypeGUID equals want. It is the auto-select path used by drivers that look for "the Linux filesystem" or "the Apple_APFS" partition regardless of slot.

func First

func First(r io.ReaderAt, deviceSize int64) (Partition, error)

First returns the first populated partition of any scheme/type. It is the "just give me the data partition" convenience matching the callers that auto-select the first non-empty entry (zfs/exfat/fat32 style).

func List

func List(r io.ReaderAt, deviceSize int64) ([]Partition, error)

List parses the partition table at the start of r and returns every populated partition, validated against deviceSize. A protective-MBR that fronts a GPT is transparently followed to the GPT. A bare image (no GPT header, no MBR signature) returns ([]Partition(nil), ErrNoTable).

deviceSize must be > 0; pass the image/device size in bytes. It is used to reject partitions or entry arrays that fall outside the device.

type Scheme

type Scheme int

Scheme identifies which partitioning scheme a Partition came from.

const (
	// SchemeMBR is a classic 4-entry MBR partition table.
	SchemeMBR Scheme = iota
	// SchemeGPT is a GUID Partition Table.
	SchemeGPT
)

func (Scheme) String

func (s Scheme) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL