-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Import SElinux module #477 #486
base: main
Are you sure you want to change the base?
Changes from all commits
3cf4dd3
363a23e
47441f1
ad0fd81
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ package v1_6_exp | |
import ( | ||
"fmt" | ||
"strings" | ||
"text/template" | ||
|
||
baseutil "github.com/coreos/butane/base/util" | ||
"github.com/coreos/butane/config/common" | ||
|
@@ -55,6 +56,20 @@ const ( | |
bootV1SizeMiB = 384 | ||
) | ||
|
||
var ( | ||
mountUnitTemplate = template.Must(template.New("unit").Parse(` | ||
# Generated by Butane | ||
[Unit] | ||
Description=Import SELinux module - {{.ModuleName}} | ||
[Service] | ||
Type=oneshot | ||
RemainAfterExit=yes | ||
ExecStart={{.CmdToExecute}} | ||
[Install] | ||
WantedBy=multi-user.target | ||
`)) | ||
) | ||
|
||
// Return FieldFilters for this spec. | ||
func (c Config) FieldFilters() *cutil.FieldFilters { | ||
return nil | ||
|
@@ -85,11 +100,8 @@ func (c Config) ToIgn3_5Unvalidated(options common.TranslateOptions) (types.Conf | |
} | ||
} | ||
|
||
retp, tsp, rp := c.handleUserGrubCfg(options) | ||
retConfig, ts := baseutil.MergeTranslatedConfigs(retp, tsp, ret, ts) | ||
ret = retConfig.(types.Config) | ||
r.Merge(rp) | ||
return ret, ts, r | ||
return mergeAndHandleOptions(c, ret, ts, r, options) | ||
|
||
} | ||
|
||
// ToIgn3_5 translates the config to an Ignition config. It returns a | ||
|
@@ -108,6 +120,20 @@ func ToIgn3_5Bytes(input []byte, options common.TranslateBytesOptions) ([]byte, | |
return cutil.TranslateBytes(input, &Config{}, "ToIgn3_5", options) | ||
} | ||
|
||
func mergeAndHandleOptions(c Config, ret types.Config, ts translate.TranslationSet, r report.Report, options common.TranslateOptions) (types.Config, translate.TranslationSet, report.Report) { | ||
retp, tsp, rp := c.handleUserGrubCfg(options) | ||
retConfig, ts := baseutil.MergeTranslatedConfigs(retp, tsp, ret, ts) | ||
ret = retConfig.(types.Config) | ||
r.Merge(rp) | ||
|
||
retr, trs, rr := c.handleSelinux(options) | ||
returnConfig, ts := baseutil.MergeTranslatedConfigs(retr, trs, ret, ts) | ||
ret = returnConfig.(types.Config) | ||
r.Merge(rr) | ||
|
||
return ret, ts, r | ||
} | ||
|
||
func (c Config) processBootDevice(config *types.Config, ts *translate.TranslationSet, options common.TranslateOptions) report.Report { | ||
var rendered types.Config | ||
renderedTranslations := translate.NewTranslationSet("yaml", "json") | ||
|
@@ -376,3 +402,64 @@ func buildGrubConfig(gb Grub) string { | |
superUserCmd := fmt.Sprintf("set superusers=\"%s\"\n", strings.Join(allUsers, " ")) | ||
return "# Generated by Butane\n\n" + superUserCmd + strings.Join(cmds, "\n") + "\n" | ||
} | ||
|
||
func (c Config) handleSelinux(options common.TranslateOptions) (types.Config, translate.TranslationSet, report.Report) { | ||
rendered := types.Config{} | ||
ts := translate.NewTranslationSet("yaml", "json") | ||
var r report.Report | ||
|
||
for i, module := range c.Selinux.Modules { | ||
rendered = processModule(rendered, module, options, ts, r, path.New("yaml", "selinux", "module", i)) | ||
} | ||
return rendered, ts, r | ||
} | ||
|
||
func processModule(rendered types.Config, module Module, options common.TranslateOptions, ts translate.TranslationSet, r report.Report, yamlPath path.ContextPath) types.Config { | ||
src, compression, err := baseutil.MakeDataURL(([]byte(*module.Contents.Inline)), nil, !options.NoResourceAutoCompression) | ||
if err != nil { | ||
r.AddOnError(yamlPath, err) | ||
return rendered | ||
} | ||
|
||
// Create module file | ||
modulePath := fmt.Sprintf("/etc/selinux/targeted/modules/active/extra/%s.cil", module.Name) | ||
|
||
rendered.Storage.Files = append(rendered.Storage.Files, types.File{ | ||
Node: types.Node{ | ||
Path: modulePath, | ||
}, | ||
FileEmbedded1: types.FileEmbedded1{ | ||
Append: []types.Resource{ | ||
{ | ||
Source: util.StrToPtr(src), | ||
Compression: compression, | ||
}, | ||
}, | ||
}, | ||
}) | ||
ts.AddFromCommonSource(yamlPath, path.New("json", "storage"), rendered.Storage) | ||
|
||
// Create systemd unit to import module | ||
cmdToExecute := "/usr/sbin/semodule -i" + modulePath | ||
yasminvalim marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
var contents strings.Builder | ||
err = mountUnitTemplate.Execute(&contents, map[string]interface{}{ | ||
"ModuleName": module.Name, | ||
"CmdToExecute": cmdToExecute, | ||
}) | ||
if err != nil { | ||
r.AddOnError(yamlPath, err) | ||
return rendered | ||
} | ||
|
||
result := contents.String() | ||
|
||
rendered.Systemd.Units = append(rendered.Systemd.Units, types.Unit{ | ||
Name: module.Name + ".conf", | ||
Contents: util.StrToPtr(result), | ||
Enabled: util.BoolToPtr(true), | ||
}) | ||
ts.AddFromCommonSource(yamlPath, path.New("json", "systemd"), rendered.Systemd) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So while this certainly passes the validate, I am having difficulty understanding why this should not be
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And I think this is correct too. |
||
|
||
return rendered | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So while this certainly passes the validate, I am having difficulty understanding why this should not be
ts.AddFromCommonSource(yamlPath, path.New("json", "storage","files",len(rendred.storage.files)), rendered.storage.files)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I understand this better now.
So I do think this is correct. It's saying that everything under and including the
.storage
key is associated with that module (after adding the index like I mentioned above, it'd be.selinux.module.0 -> .storage
and-> .storage.files
and so on). Essentially, we're not just adding a file and a unit because of this module, we have to add all the keys leading up to it. All keys in the output need a source translation associated, so e.g..storage
needs to be associated to something on the YAML side.