Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account
Bool file symlinks #329
Closed
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
Jump to file or symbol
Failed to load files and symbols.
| @@ -21,8 +21,26 @@ package caps | ||
| import ( | ||
| "fmt" | ||
| + "path/filepath" | ||
| + | ||
| + "github.com/ubuntu-core/snappy/testutil" | ||
| ) | ||
| +type evalSymlinksFn func(string) (string, error) | ||
| + | ||
| +// evalSymlinks is either filepath.EvalSymlinks or a mocked function for | ||
| +// applicable for testing. | ||
| +var evalSymlinks = filepath.EvalSymlinks | ||
| + | ||
| +// MockEvalSymlinks replaces the path/filepath.EvalSymlinks function used inside the caps package. | ||
| +func MockEvalSymlinks(test *testutil.BaseTest, fn func(string) (string, error)) { | ||
| + orig := evalSymlinks | ||
| + evalSymlinks = fn | ||
| + test.AddCleanup(func() { | ||
| + evalSymlinks = orig | ||
| + }) | ||
| +} | ||
| + | ||
| // Type describes a group of interchangeable capabilities with common features. | ||
| // Types are managed centrally and act as a contract between system builders, | ||
| // application developers and end users. | ||
| @@ -53,6 +71,14 @@ func (t *BoolFileType) Name() string { | ||
| return "bool-file" | ||
| } | ||
| +// Error for reporting invalid/not-sanitized capabilities in places where we | ||
| +// expect everything to be valid. | ||
| +type notSanitizedError struct{} | ||
| + | ||
| +func (e *notSanitizedError) Error() string { | ||
| + return "capability is not sanitized" | ||
|
|
||
| +} | ||
| + | ||
| // Sanitize checks and possibly modifies a capability. | ||
| // Valid "bool-file" capabilities must contain the attribute "path". | ||
| func (t *BoolFileType) Sanitize(c *Capability) error { | ||
| @@ -72,8 +98,10 @@ func (t *BoolFileType) Sanitize(c *Capability) error { | ||
| func (t *BoolFileType) SecuritySnippet(c *Capability, securitySystem SecuritySystem) ([]byte, error) { | ||
| switch securitySystem { | ||
| case SecurityApparmor: | ||
| - // TODO: switch to the real path later | ||
| - path := c.Attrs["path"] | ||
| + path, err := t.dereferencedPath(c) | ||
| + if err != nil { | ||
| + return nil, err | ||
| + } | ||
| // Allow read, write and lock on the file designated by the path. | ||
| return []byte(fmt.Sprintf("%s rwl,\n", path)), nil | ||
| case SecuritySeccomp: | ||
| @@ -85,6 +113,18 @@ func (t *BoolFileType) SecuritySnippet(c *Capability, securitySystem SecuritySys | ||
| } | ||
| } | ||
| +func (t *BoolFileType) dereferencedPath(c *Capability) (string, error) { | ||
| + path := c.Attrs["path"] | ||
| + if path == "" { | ||
| + return "", ¬SanitizedError{} | ||
niemeyer
Contributor
|
||
| + } | ||
| + realPath, err := evalSymlinks(path) | ||
| + if err != nil { | ||
| + return "", fmt.Errorf("bool-file path is invalid: %s", err) | ||
niemeyer
Contributor
|
||
| + } | ||
| + return realPath, nil | ||
| +} | ||
| + | ||
| // TestType is a type for various kind of tests. | ||
| // It is public so that it can be consumed from other packages. | ||
| type TestType struct { | ||
I don't really understand what this is trying to say.. my guess is that other people likely won't as well.
It should also be a var:
Or even inline, since there's really a single occurrence right now, which is never used in an error check.