Skip to content

Commit a8982b1

Browse files
committed
Use chroot to label previously binded mountpoints
This prevents errors with non chrooted setfiles calls in which fail due to policy divergences between host and target. For that purpose a new option to chroot utility has been included to allow chroot without setting the default bind mounts for /dev/, /sys and /proc. Signed-off-by: David Cassany <[email protected]>
1 parent c16e1d5 commit a8982b1

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

pkg/elemental/elemental.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,6 @@ func SelinuxRelabel(c types.Config, rootDir string, extraPaths ...string) error
670670
// ApplySELinuxLabels relables with setfiles the given root in a chroot env. Additionaly after the first
671671
// chrooted call it runs a non chrooted call to relabel any mountpoint used within the chroot.
672672
func ApplySELinuxLabels(c types.Config, rootDir string, bind map[string]string) (err error) {
673-
var out []byte
674673
extraPaths := []string{}
675674

676675
for _, v := range bind {
@@ -685,14 +684,32 @@ func ApplySELinuxLabels(c types.Config, rootDir string, bind map[string]string)
685684
contextsFile := filepath.Join(rootDir, cnst.SELinuxTargetedContextFile)
686685
existsCon, _ := utils.Exists(c.Fs, contextsFile)
687686

688-
if existsCon && c.Runner.CommandExists("setfiles") {
689-
args := []string{"-r", rootDir, "-i", "-F", contextsFile}
690-
for _, path := range append([]string{"/dev", "/proc", "/sys"}, extraPaths...) {
691-
args = append(args, filepath.Join(rootDir, path))
687+
if !existsCon || !c.Runner.CommandExists("setfiles") {
688+
return nil
689+
}
690+
691+
// Now we call setfiles to label the directories and mountpoints that were bind mounted
692+
// inside the previous chrooted call. Since /dev is likely to be an empty folder in that context
693+
// we create a /dev/null device as setfiles will complain without it.
694+
devnull := filepath.Join(rootDir, "/dev/null")
695+
if ok, _ := utils.Exists(c.Fs, devnull); !ok {
696+
_, err = c.Runner.Run("mknod", "-m", "666", devnull, "c", "1", "3")
697+
if err != nil {
698+
return err
692699
}
693-
out, err = c.Runner.Run("setfiles", args...)
694-
c.Logger.Debugf("SELinux setfiles output: %s", string(out))
700+
defer func() {
701+
_ = c.Fs.RemoveAll(devnull)
702+
}()
703+
}
704+
705+
var restoreOut []byte
706+
args := append([]string{"-i", "-F", cnst.SELinuxTargetedContextFile, "/dev", "/proc", "/sys"}, extraPaths...)
707+
restoreLabels := func() error {
708+
restoreOut, err = c.Runner.Run("setfiles", args...)
709+
return err
695710
}
711+
err = utils.ChrootedCallback(&c, rootDir, map[string]string{}, restoreLabels, utils.NoDefaultBinds())
712+
c.Logger.Debugf("SELinux setfiles output: %s", string(restoreOut))
696713

697714
return err
698715
}

pkg/utils/chroot.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ import (
2828
"github.com/rancher/elemental-toolkit/v2/pkg/types"
2929
)
3030

31+
type ChrootOpt func(ch *Chroot)
32+
33+
func NoDefaultBinds() ChrootOpt {
34+
return func(ch *Chroot) {
35+
ch.defaultMounts = []string{}
36+
}
37+
}
38+
3139
// Chroot represents the struct that will allow us to run commands inside a given chroot
3240
type Chroot struct {
3341
path string
@@ -37,19 +45,23 @@ type Chroot struct {
3745
config *types.Config
3846
}
3947

40-
func NewChroot(path string, config *types.Config) *Chroot {
41-
return &Chroot{
48+
func NewChroot(path string, config *types.Config, opts ...ChrootOpt) *Chroot {
49+
ch := &Chroot{
4250
path: path,
4351
defaultMounts: []string{"/dev", "/dev/pts", "/proc", "/sys"},
4452
extraMounts: map[string]string{},
4553
activeMounts: []string{},
4654
config: config,
4755
}
56+
for _, opt := range opts {
57+
opt(ch)
58+
}
59+
return ch
4860
}
4961

5062
// ChrootedCallback runs the given callback in a chroot environment
51-
func ChrootedCallback(cfg *types.Config, path string, bindMounts map[string]string, callback func() error) error {
52-
chroot := NewChroot(path, cfg)
63+
func ChrootedCallback(cfg *types.Config, path string, bindMounts map[string]string, callback func() error, opts ...ChrootOpt) error {
64+
chroot := NewChroot(path, cfg, opts...)
5365
if bindMounts == nil {
5466
bindMounts = map[string]string{}
5567
}

0 commit comments

Comments
 (0)