boundedio

package
v0.22.0 Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package boundedio puts blocking local-filesystem work behind a cancellation boundary so the evidence publish/sign/verify paths cannot hang indefinitely on a dead NFS/FUSE mount.

Why a goroutine and not a context: a context deadline bounds *observation*, not the syscall. os.Stat, os.Open, and the ReadDir calls inside filepath.WalkDir block in the kernel on a wedged mount, so a ctx.Err() check between chunks or between walk entries never runs. Only moving the syscall off the calling goroutine lets the caller return.

The accepted tradeoff: on timeout the worker stays parked in the syscall until the kernel returns or the process exits. That is fine for the short-lived CLI leaf commands that use this package, and it is the reason this is internal rather than a general-purpose utility.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Do

func Do(ctx context.Context, what string, fn func() error) error

Do runs fn behind a defaults.FileReadTimeout-bounded derivative of ctx and returns fn's own error, or a boundary error if the bound elapses or the operator aborts first. fn must be a self-contained unit of blocking filesystem work that owns everything it opens: once Do returns, the caller must not touch any handle fn is still using.

func IsCanceled

func IsCanceled(err error) bool

IsCanceled reports whether err is a deliberate operator abort rather than an environmental fault. Callers that bucket failures as retry-vs-stop use this to keep a Ctrl-C out of the retryable bucket.

func IsStorageFault

func IsStorageFault(err error) bool

IsStorageFault reports whether err is the filesystem saying it could not answer, as opposed to answering "no such file". These are environmental and must stay distinguishable from a verdict about the bundle's contents: callers that stat outside this package (the verifier's signature probe) need the same split.

EACCES/EPERM are included deliberately, accepting a known imprecision: a permanently-unreadable local file (mode 000) is labeled transient and invites a retry that will never succeed. The alternative — treating them as verdicts — would misreport the far more consequential case, a soft-mounted NFS returning EACCES while the server is unreachable, as "this bundle is invalid". Both directions fail closed (nothing is ever accepted), so the tradeoff is which useless remediation the operator is pointed at, and distinguishing a local-fs EACCES from a network-mount one is not portably worth it.

func ReadFile

func ReadFile(ctx context.Context, path, label string, max int64) ([]byte, error)

ReadFile reads path into memory bounded three ways: by size (max bytes), by time (the Do boundary), and by shape (descriptor-first validation).

The shape checks matter because a bundle root can be attacker-influenced — an extracted archive, a symlink-rich tarball, a path on a network mount. O_NONBLOCK keeps a FIFO substituted for a regular file from blocking the open, and validating the *opened descriptor* rather than the path closes the swap window between the check and the read.

Symlink scope, precisely: O_NOFOLLOW rejects a symlink at the FINAL path component only. An intermediate directory component that is a symlink (bundle/ctrf -> /elsewhere) is still traversed, so this is not a containment boundary — callers needing one must resolve against an os.Root. Callers here rely on containment from elsewhere: manifest entries are rejected by filepath.IsLocal before use, and every byte read is hash-bound to a manifest that is itself digest-bound to the predicate, so content read through such a path cannot pass verification. Closing the traversal gap is tracked as follow-up work on #2083.

label names the input in error messages (e.g. "in-toto Statement").

Types

This section is empty.

Jump to

Keyboard shortcuts

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