A hard link swapped in for ~/.claude would have had root chown another account's file; fstat on the descriptor now refuses a second link, a fifo or an unexpected kind before anything is changed (hq ADR 0266, the re-review). The judge also finds polkit rules for every account, a runtime's API on TCP, setgid-to-root programs whoever owns them, setuid programs on every suid filesystem, and unprotected links; the rest is listed as not judged.
60 lines
1.4 KiB
Go
60 lines
1.4 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)
|
|
}
|