Two holes the review proved. The ask's subject proved nothing — a responder can reach it through a reply — so the engine now verifies the mesh's signature over a fixed context with the key it verifies declarations with, before reading anything, and refuses an ask for another node, expired, good too long, without a nonce, or replayed. And the apply followed a link the hand-over had refused: a component swapped for a link after the record carried root's chmod and chown to its target. A handed-over directory must now still resolve to itself, and is changed only through one descriptor opened from / with no link followed (fchmod, fchown). Tests for the reply guard, the run loop's hook, the fallback renewal on proof and a non-regular fallback; 27 checks each removed in turn, each failing a test.
67 lines
1.9 KiB
Go
67 lines
1.9 KiB
Go
//go:build !linux
|
|
|
|
package apply
|
|
|
|
// Where there is no openat with O_NOFOLLOW to rely on, the check before use is all: a link below a home is
|
|
// refused, and the call is made by path. The node-engine runs on Linux; this keeps the package building.
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
func chmodUnder(home, path string, mode os.FileMode) error {
|
|
if err := refuseLinksUnderHome(path); err != nil {
|
|
return err
|
|
}
|
|
return os.Chmod(path, mode)
|
|
}
|
|
|
|
func chmodUnderAs(home, path string, mode os.FileMode, _ int) error {
|
|
return chmodUnder(home, path, mode)
|
|
}
|
|
|
|
const kindDir = 1
|
|
|
|
func chownUnder(home, path string, uid, gid int) error {
|
|
if err := refuseLinksUnderHome(path); err != nil {
|
|
return err
|
|
}
|
|
return os.Lchown(path, uid, gid)
|
|
}
|
|
|
|
func readUnder(home, path string) ([]byte, error) {
|
|
if err := refuseLinksUnderHome(path); err != nil {
|
|
return nil, err
|
|
}
|
|
return os.ReadFile(path)
|
|
}
|
|
|
|
func mkdirAllUnder(home, dir string, mode os.FileMode) ([]string, error) {
|
|
if err := refuseLinksUnderHome(dir); err != nil {
|
|
return nil, err
|
|
}
|
|
var made []string
|
|
for d := filepath.Clean(dir); d != home; d = filepath.Dir(d) {
|
|
if _, err := os.Lstat(d); err == nil {
|
|
break
|
|
}
|
|
made = append(made, d)
|
|
}
|
|
return made, os.MkdirAll(dir, mode)
|
|
}
|
|
|
|
func writeUnder(home, path string, content []byte, mode os.FileMode) error {
|
|
if err := refuseLinksUnderHome(path); err != nil {
|
|
return err
|
|
}
|
|
return writeAtomicallyByPath(path, content, mode)
|
|
}
|
|
|
|
// giveHandedOver is refused where there is no openat with O_NOFOLLOW: a handed-over directory is never changed by
|
|
// path (novox/hq issue 356). The node-engine runs on Linux.
|
|
func giveHandedOver(path string, _ os.FileMode, _, _ int, _ bool) (os.FileMode, int, int, error) {
|
|
return 0, 0, 0, &PlacementRefusedError{Path: path, Why: "a handed-over directory is changed only through a " +
|
|
"descriptor that followed no link, which this system cannot open"}
|
|
}
|