2024-03-21 23:07:41 +01:00
|
|
|
// apparmor.d - Full set of apparmor profiles
|
|
|
|
// Copyright (C) 2021-2024 Alexandre Pujol <alexandre@pujol.io>
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
|
2024-05-29 22:12:54 +02:00
|
|
|
// TODO: Local variables in profile header need to be resolved
|
|
|
|
|
2024-03-21 23:07:41 +01:00
|
|
|
package directive
|
|
|
|
|
|
|
|
import (
|
2024-09-10 19:13:48 +02:00
|
|
|
"fmt"
|
2024-04-12 21:07:05 +02:00
|
|
|
"slices"
|
2024-03-21 23:07:41 +01:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/roddhjav/apparmor.d/pkg/aa"
|
2024-10-02 17:22:46 +02:00
|
|
|
"github.com/roddhjav/apparmor.d/pkg/prebuild"
|
2024-03-21 23:07:41 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type Exec struct {
|
2024-10-02 17:22:46 +02:00
|
|
|
prebuild.Base
|
2024-03-21 23:07:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
2024-03-25 23:40:25 +01:00
|
|
|
RegisterDirective(&Exec{
|
2024-10-02 17:22:46 +02:00
|
|
|
Base: prebuild.Base{
|
2024-03-25 23:40:25 +01:00
|
|
|
Keyword: "exec",
|
|
|
|
Msg: "Exec directive applied",
|
2024-09-26 23:05:47 +02:00
|
|
|
Help: []string{"[P|U|p|u|PU|pu|] profiles..."},
|
2024-03-21 23:07:41 +01:00
|
|
|
},
|
2024-03-25 23:40:25 +01:00
|
|
|
})
|
2024-03-21 23:07:41 +01:00
|
|
|
}
|
|
|
|
|
2024-05-25 23:30:20 +02:00
|
|
|
func (d Exec) Apply(opt *Option, profileRaw string) (string, error) {
|
2024-09-10 19:13:48 +02:00
|
|
|
if len(opt.ArgList) == 0 {
|
|
|
|
return "", fmt.Errorf("No profile to exec")
|
|
|
|
}
|
2024-03-21 23:07:41 +01:00
|
|
|
transition := "Px"
|
2024-03-22 20:47:45 +01:00
|
|
|
transitions := []string{"P", "U", "p", "u", "PU", "pu"}
|
2024-03-23 18:41:10 +01:00
|
|
|
t := opt.ArgList[0]
|
|
|
|
if slices.Contains(transitions, t) {
|
|
|
|
transition = t + "x"
|
|
|
|
delete(opt.ArgMap, t)
|
2024-03-22 20:47:45 +01:00
|
|
|
}
|
|
|
|
|
2024-04-23 22:43:22 +02:00
|
|
|
rules := aa.Rules{}
|
2024-03-23 18:41:10 +01:00
|
|
|
for name := range opt.ArgMap {
|
2024-10-12 16:31:24 +02:00
|
|
|
profiletoTransition := prebuild.RootApparmord.Join(name).MustReadFileAsString()
|
2024-03-22 20:47:45 +01:00
|
|
|
dstProfile := aa.DefaultTunables()
|
2024-06-20 00:24:43 +02:00
|
|
|
if _, err := dstProfile.Parse(profiletoTransition); err != nil {
|
2024-05-30 15:23:56 +02:00
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
if err := dstProfile.Resolve(); err != nil {
|
2024-05-30 13:28:12 +02:00
|
|
|
return "", err
|
|
|
|
}
|
2024-05-29 22:12:54 +02:00
|
|
|
for _, variable := range dstProfile.Preamble.GetVariables() {
|
2024-03-21 23:07:41 +01:00
|
|
|
if variable.Name == "exec_path" {
|
2024-03-22 20:47:45 +01:00
|
|
|
for _, v := range variable.Values {
|
2024-04-23 22:43:22 +02:00
|
|
|
rules = append(rules, &aa.File{
|
2024-03-22 20:47:45 +01:00
|
|
|
Path: v,
|
2024-04-23 22:43:22 +02:00
|
|
|
Access: []string{transition},
|
2024-03-22 20:47:45 +01:00
|
|
|
})
|
2024-03-21 23:07:41 +01:00
|
|
|
}
|
2024-03-22 20:47:45 +01:00
|
|
|
break
|
2024-03-21 23:07:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-04-23 22:43:22 +02:00
|
|
|
|
2024-05-05 00:54:39 +02:00
|
|
|
aa.IndentationLevel = strings.Count(
|
|
|
|
strings.SplitN(opt.Raw, Keyword, 1)[0], aa.Indentation,
|
2024-04-23 22:43:22 +02:00
|
|
|
)
|
2024-05-29 22:12:54 +02:00
|
|
|
rules = rules.Sort()
|
2024-04-23 22:43:22 +02:00
|
|
|
new := rules.String()
|
|
|
|
new = new[:len(new)-1]
|
2024-05-25 23:30:20 +02:00
|
|
|
return strings.Replace(profileRaw, opt.Raw, new, -1), nil
|
2024-03-21 23:07:41 +01:00
|
|
|
}
|