build: add the X option to the stack directive.

This commit is contained in:
Alexandre Pujol 2024-09-10 18:13:48 +01:00
parent 67c5181ba9
commit f3094cc741
Failed to generate hash of commit
6 changed files with 30 additions and 8 deletions

View file

@ -115,6 +115,10 @@ The `exec` directive is useful to allow executing transitions to a profile witho
: List a profile **files** to stack at the end of the current profile.
**`[X]`**
: If `X` is set, the directive will conserve the `x` file rules regardless of the transition. Not enabled by default as it may conflict with the parent profile.
**Example**

View file

@ -14,7 +14,7 @@ import (
var (
regFlags = regexp.MustCompile(`flags=\(([^)]+)\)`)
regProfileHeader = regexp.MustCompile(` {`)
regProfileHeader = regexp.MustCompile(` {\n`)
)
type Complain struct {
@ -40,7 +40,7 @@ func (b Complain) Apply(opt *Option, profile string) (string, error) {
}
}
flags = append(flags, "complain")
strFlags := " flags=(" + strings.Join(flags, ",") + ") {"
strFlags := " flags=(" + strings.Join(flags, ",") + ") {\n"
// Remove all flags definition, then set manifest' flags
profile = regFlags.ReplaceAllLiteralString(profile, "")

View file

@ -36,9 +36,9 @@ func (b Enforce) Apply(opt *Option, profile string) (string, error) {
return profile, nil
}
flags = slices.Delete(flags, idx, idx+1)
strFlags := "{"
strFlags := "{\n"
if len(flags) >= 1 {
strFlags = " flags=(" + strings.Join(flags, ",") + ") {"
strFlags = " flags=(" + strings.Join(flags, ",") + ") {\n"
}
// Remove all flags definition, then set new flags

View file

@ -7,6 +7,7 @@
package directive
import (
"fmt"
"slices"
"strings"
@ -30,6 +31,9 @@ func init() {
}
func (d Exec) Apply(opt *Option, profileRaw string) (string, error) {
if len(opt.ArgList) == 0 {
return "", fmt.Errorf("No profile to exec")
}
transition := "Px"
transitions := []string{"P", "U", "p", "u", "PU", "pu"}
t := opt.ArgList[0]

View file

@ -7,6 +7,7 @@ package directive
import (
"fmt"
"regexp"
"slices"
"strings"
"github.com/roddhjav/apparmor.d/pkg/prebuild/cfg"
@ -19,7 +20,6 @@ var (
regCleanStakedRules = util.ToRegexRepl([]string{
`(?m)^.*include <abstractions/base>.*$`, ``, // Remove mandatory base abstraction
`(?m)^.*@{exec_path}.*$`, ``, // Remove entry point
`(?m)^.*(|P|p)(|U|u)(|i)x,.*$`, ``, // Remove transition rules
`(?m)^(?:[\t ]*(?:\r?\n))+`, ``, // Remove empty lines
})
)
@ -33,12 +33,26 @@ func init() {
Base: cfg.Base{
Keyword: "stack",
Msg: "Stack directive applied",
Help: Keyword + `stack profiles...`,
Help: Keyword + `stack [X] profiles...`,
},
})
}
func (s Stack) Apply(opt *Option, profile string) (string, error) {
if len(opt.ArgList) == 0 {
return "", fmt.Errorf("No profile to stack")
}
t := opt.ArgList[0]
if t != "X" {
regCleanStakedRules = slices.Insert(regCleanStakedRules, 0,
util.ToRegexRepl([]string{
`(?m)^.*(|P|p)(|U|u)(|i)x,.*$`, ``, // Remove X transition rules
})...,
)
} else {
delete(opt.ArgMap, t)
}
res := ""
for name := range opt.ArgMap {
stackedProfile := util.MustReadFile(cfg.RootApparmord.Join(name))

View file

@ -15,7 +15,7 @@ import (
var (
regFlags = regexp.MustCompile(`flags=\(([^)]+)\)`)
regProfileHeader = regexp.MustCompile(` {`)
regProfileHeader = regexp.MustCompile(` {\n`)
)
type SetFlags struct {
@ -43,7 +43,7 @@ func (p SetFlags) Apply() ([]string, error) {
// Overwrite profile flags
if len(flags) > 0 {
flagsStr := " flags=(" + strings.Join(flags, ",") + ") {"
flagsStr := " flags=(" + strings.Join(flags, ",") + ") {\n"
out, err := util.ReadFile(file)
if err != nil {
return res, err