Skip to content

Commit 2891d55

Browse files
committed
Ensure we never leave the config directory when parsing config files and databases
1 parent 7fc5ff8 commit 2891d55

3 files changed

Lines changed: 29 additions & 13 deletions

File tree

internal/pacman/packages.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ package pacman
33
import (
44
"fmt"
55
"os"
6-
"path/filepath"
76
)
87

98
func (p *Pacman) GetInstalledPackages() ([]string, error) {
109
const verParts = 2
1110

12-
db, err := os.Open(filepath.Join(p.config.dbPath, "local"))
11+
db, err := os.OpenInRoot(p.config.dbPath, "local")
1312
if err != nil {
1413
return nil, fmt.Errorf("failed to open pacman DB: %w", err)
1514
}

internal/pacman/parser.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,39 @@ type Pacman struct {
2525
}
2626

2727
type parser struct {
28+
baseDir *os.Root
2829
includeFileCache map[string][]string
2930
}
3031

3132
func Parse(pacmanConfPath string) (*Pacman, error) {
32-
conf, err := newParser().parseConfigFile(pacmanConfPath, defaultDBPath)
33+
baseDir, err := os.OpenRoot(filepath.Dir(pacmanConfPath))
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
conf, err := newParser(baseDir).parseConfigFile(pacmanConfPath, defaultDBPath)
3339
if err != nil {
3440
return nil, err
3541
}
3642

3743
return &Pacman{config: conf}, nil
3844
}
3945

40-
func newParser() *parser {
46+
func newParser(baseDir *os.Root) *parser {
4147
return &parser{
48+
baseDir: baseDir,
4249
includeFileCache: make(map[string][]string),
4350
}
4451
}
4552

53+
func (parser *parser) openFile(name string) (*os.File, error) {
54+
fileName, ok := strings.CutPrefix(name, parser.baseDir.Name()+"/")
55+
if !ok {
56+
return nil, fmt.Errorf("filename %s is not relative to %s", name, parser.baseDir.Name())
57+
}
58+
return parser.baseDir.Open(fileName)
59+
}
60+
4661
func (parser *parser) parseConfigFile(configPath string, defaultDBPath string) (*config, error) {
4762
lines, err := parser.readConfigFile(configPath, 0)
4863
if err != nil {
@@ -69,7 +84,7 @@ func (parser *parser) readConfigFile(fileName string, depth int) ([]string, erro
6984
if depth >= configMaxRecursion {
7085
return nil, fmt.Errorf("reached maximum Include depth of %d", depth)
7186
}
72-
readFile, err := os.Open(fileName)
87+
readFile, err := parser.openFile(fileName)
7388
if err != nil {
7489
return nil, err
7590
}

tests/unit/internal/pacman/pacman_test.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,10 @@ func TestGetServer(t *testing.T) {
9595
}
9696

9797
func TestPacmanConfIncludes(t *testing.T) {
98-
pacmanConfFile := filepath.Join(t.TempDir(), "pacman.conf")
99-
pacmanConfFileInclude1 := filepath.Join(t.TempDir(), "pacman-include1.conf")
100-
pacmanConfFileInclude2 := filepath.Join(t.TempDir(), "pacman-include2.conf")
98+
tempDir := t.TempDir()
99+
pacmanConfFile := filepath.Join(tempDir, "pacman.conf")
100+
pacmanConfFileInclude1 := filepath.Join(tempDir, "pacman-include1.conf")
101+
pacmanConfFileInclude2 := filepath.Join(tempDir, "pacman-include2.conf")
101102

102103
if err := os.WriteFile(pacmanConfFile, fmt.Appendf(nil, "[core]\nInclude=%s\n", pacmanConfFileInclude1), 0o600); err != nil {
103104
t.Fatalf("Failed to create pacman.conf: %v", err)
@@ -123,12 +124,13 @@ func TestPacmanConfIncludes(t *testing.T) {
123124
}
124125

125126
func TestPacmanConfIncludesGlob(t *testing.T) {
126-
pacmanConfFile := filepath.Join(t.TempDir(), "pacman.conf")
127-
d := t.TempDir()
128-
pacmanConfFileInclude1 := filepath.Join(d, "pacman-include1.conf")
129-
pacmanConfFileInclude2 := filepath.Join(d, "pacman-include2.conf")
127+
tempDir := t.TempDir()
128+
129+
pacmanConfFile := filepath.Join(tempDir, "pacman.conf")
130+
pacmanConfFileInclude1 := filepath.Join(tempDir, "pacman-include1.conf")
131+
pacmanConfFileInclude2 := filepath.Join(tempDir, "pacman-include2.conf")
130132

131-
if err := os.WriteFile(pacmanConfFile, fmt.Appendf(nil, "[core]\nInclude=%s/pacman-*.conf\n", d), 0o600); err != nil {
133+
if err := os.WriteFile(pacmanConfFile, fmt.Appendf(nil, "[core]\nInclude=%s/pacman-*.conf\n", tempDir), 0o600); err != nil {
132134
t.Fatalf("Failed to create pacman.conf: %v", err)
133135
}
134136
if err := os.WriteFile(pacmanConfFileInclude1, []byte(""), 0o600); err != nil {

0 commit comments

Comments
 (0)