Tighten opaque plugin content boundaries

This commit is contained in:
npc0-hue
2026-09-03 18:24:39 +08:00
parent 80cddbf19d
commit 14cbc63e61
31 changed files with 452 additions and 558 deletions
+76
View File
@@ -23,6 +23,7 @@ type ArtifactBodyStore interface {
SaveTransfer(domain.ArtifactTransferSession) error
LoadTransfers() ([]domain.ArtifactTransferSession, error)
PutPayload(string, []byte) error
PutPayloadFromFile(string, string) error
GetPayload(string) ([]byte, error)
ReadPayloadRange(string, int64, int) ([]byte, error)
OpenPayloadRange(string, int64, int64) (io.ReadCloser, error)
@@ -68,6 +69,14 @@ func (store *MemoryArtifactBodyStore) PutPayload(artifactID string, payload []by
return nil
}
func (store *MemoryArtifactBodyStore) PutPayloadFromFile(artifactID string, sourcePath string) error {
payload, err := os.ReadFile(sourcePath)
if err != nil {
return fmt.Errorf("read artifact source file: %w", err)
}
return store.PutPayload(artifactID, payload)
}
func (store *MemoryArtifactBodyStore) GetPayload(artifactID string) ([]byte, error) {
store.mu.Lock()
defer store.mu.Unlock()
@@ -218,6 +227,12 @@ func (store *FileArtifactBodyStore) PutPayload(artifactID string, payload []byte
return writeAtomicFile(store.payloadPath(artifactID), payload, 0o600)
}
func (store *FileArtifactBodyStore) PutPayloadFromFile(artifactID string, sourcePath string) error {
store.mu.Lock()
defer store.mu.Unlock()
return copyAtomicFile(store.payloadPath(artifactID), sourcePath, 0o600)
}
func (store *FileArtifactBodyStore) GetPayload(artifactID string) ([]byte, error) {
store.mu.Lock()
defer store.mu.Unlock()
@@ -379,6 +394,67 @@ func stableStorageKey(value string) string {
return hex.EncodeToString(sum[:])
}
func fileSizeAndChecksum(path string) (int64, string, error) {
file, err := os.Open(path)
if err != nil {
return 0, "", err
}
defer file.Close()
info, err := file.Stat()
if err != nil {
return 0, "", err
}
if !info.Mode().IsRegular() {
return 0, "", fmt.Errorf("artifact source is not a regular file")
}
hash := sha256.New()
size, err := io.Copy(hash, file)
if err != nil {
return 0, "", err
}
return size, "sha256:" + hex.EncodeToString(hash.Sum(nil)), nil
}
func copyAtomicFile(destinationPath string, sourcePath string, mode os.FileMode) error {
if err := os.MkdirAll(filepath.Dir(destinationPath), 0o700); err != nil {
return fmt.Errorf("create durable body directory: %w", err)
}
source, err := os.Open(sourcePath)
if err != nil {
return fmt.Errorf("open durable body source file: %w", err)
}
defer source.Close()
tmp := destinationPath + ".tmp"
file, err := os.OpenFile(tmp, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, mode)
if err != nil {
return fmt.Errorf("open durable body temporary file: %w", err)
}
if err := file.Chmod(mode); err != nil {
_ = file.Close()
_ = os.Remove(tmp)
return fmt.Errorf("chmod durable body temporary file: %w", err)
}
if _, err := io.Copy(file, source); err != nil {
_ = file.Close()
_ = os.Remove(tmp)
return fmt.Errorf("copy durable body: %w", err)
}
if err := file.Sync(); err != nil {
_ = file.Close()
_ = os.Remove(tmp)
return fmt.Errorf("sync durable body: %w", err)
}
if err := file.Close(); err != nil {
_ = os.Remove(tmp)
return fmt.Errorf("close durable body: %w", err)
}
if err := os.Rename(tmp, destinationPath); err != nil {
_ = os.Remove(tmp)
return fmt.Errorf("replace durable body: %w", err)
}
return nil
}
func writeAtomicFile(path string, payload []byte, mode os.FileMode) error {
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
return fmt.Errorf("create durable body directory: %w", err)