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. : 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** **Example**

View file

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

View file

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

View file

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

View file

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

View file

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