hashicorp / hashicorp/go-rootcerts

LoadCAPath fails in directories that contain symbolic links

Open
#15 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
Go
Stars
84
Forks
18
PR merge metrics
No merged PRs in 30d

Description

If you use a Kubernetes _ConfigMap_ or _Secret_ object to convey a set of X.509 certificate bundles to the Vault client, nominating the mounted directory path in the "VAULT_CAPATH" environment variable, the `ConfigureTLS` function fails when it calls on the `LoadCAPath`, because the directory contains several symbolic links, some of which point to other symbolic links, and some to directories.

Perhaps we could call `os.Lstat` on each candidate file in the directory, and if it's a symbolic link, make sure that it eventually leads to a regular file. Here's a sketch:
```go
func resolveStep(path string, info os.FileInfo, seen map[string]struct{}) (string, bool, error) {
mode := info.Mode()
if mode.IsRegular() {
return path, true, nil
}
if (mode & os.ModeSymlink) == 0 {
return "", false, nil
}
target, err := os.Readlink(path)
if err != nil {
return "", false, err
}
// Assume that self-referential links are rare, so don't bother comparing "path" and "target"
// here directly.
seen[path] = struct{}{}
if _, ok := seen[target]; ok {
return "", false, fmt.Errorf("link %q forms a cycle", target)
}
fi, err := os.Lstat(path)
if err != nil {
return "", false, err
}
return resolveStep(target, fi, seen)
}

func resolveToRegularFile(path string, info os.FileInfo) (string, bool, error) {
return resolveStep(path, info, make(map[string]struct{}, 2))
}
```
Then, either before each call to `ioutil.ReadFile` for file entries in the nominated directory, we could check first whether it looks to either be or lead to a regular file (inside of `LoadCAPath`'s `walkFn`:
```go
if err != nil {
return err
}

target, regular, err := resolveToRegularFile(path, ionf)
if err != nil {
return fmt.Errorf("path resolution failed: %w\n", err)
}
if !regular {
return nil
}
path = target
```

Would you entertain such a patch?

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with ConfigureTLS and LoadCAPath, then inspect LoadCAPath's walkFn and the ioutil.ReadFile calls for entries in the nominated directory. Reproduce the failure with a directory containing chained symbolic links, verify that certificate bundles are loaded without the failure, and add or update tests for the reported Kubernetes-style layout.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.