From fb7d2b6bd6a16ffdbe4a69428e3ba5b487719e78 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Tue, 17 Dec 2019 15:24:29 -0500 Subject: [PATCH] Add support for FIPS-Mode backends If host is running in fips mode, then RHEL8.2 and beyond container images will come with a directory /usr/share/crypto-policies/back-ends/FIPS. This directory needs to be bind mounted over /etc/crypto-policies/back-ends in order to make all tools in the container follow the FIPS Mode rules. Signed-off-by: Daniel J Walsh --- pkg/secrets/secrets.go | 48 +++++++++++++++++++++++++++++++++--------- run_linux.go | 2 +- 2 files changed, 39 insertions(+), 11 deletions(-) diff -up ./buildah-9513cb8c7bec0f7789c696aee4d252ebf85194cc/pkg/secrets/secrets.go.1784950 ./buildah-9513cb8c7bec0f7789c696aee4d252ebf85194cc/pkg/secrets/secrets.go --- buildah-9513cb8c7bec0f7789c696aee4d252ebf85194cc/pkg/secrets/secrets.go.1784950 2020-02-19 16:09:40.446764064 +0100 +++ buildah-9513cb8c7bec0f7789c696aee4d252ebf85194cc/pkg/secrets/secrets.go 2020-02-19 16:09:40.448764092 +0100 @@ -148,12 +148,21 @@ func getMountsMap(path string) (string, } // SecretMounts copies, adds, and mounts the secrets to the container root filesystem +// Deprecated, Please use SecretMountWithUIDGID func SecretMounts(mountLabel, containerWorkingDir, mountFile string, rootless, disableFips bool) []rspec.Mount { return SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, containerWorkingDir, 0, 0, rootless, disableFips) } -// SecretMountsWithUIDGID specifies the uid/gid of the owner -func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPrefix string, uid, gid int, rootless, disableFips bool) []rspec.Mount { +// SecretMountsWithUIDGID copies, adds, and mounts the secrets to the container root filesystem +// mountLabel: MAC/SELinux label for container content +// containerWorkingDir: Private data for storing secrets on the host mounted in container. +// mountFile: Additional mount points required for the container. +// mountPoint: Container image mountpoint +// uid: to assign to content created for secrets +// gid: to assign to content created for secrets +// rootless: indicates whether container is running in rootless mode +// disableFips: indicates whether system should ignore fips mode +func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPoint string, uid, gid int, rootless, disableFips bool) []rspec.Mount { var ( secretMounts []rspec.Mount mountFiles []string @@ -171,7 +180,7 @@ func SecretMountsWithUIDGID(mountLabel, } for _, file := range mountFiles { if _, err := os.Stat(file); err == nil { - mounts, err := addSecretsFromMountsFile(file, mountLabel, containerWorkingDir, mountPrefix, uid, gid) + mounts, err := addSecretsFromMountsFile(file, mountLabel, containerWorkingDir, uid, gid) if err != nil { logrus.Warnf("error mounting secrets, skipping entry in %s: %v", file, err) } @@ -187,7 +196,7 @@ func SecretMountsWithUIDGID(mountLabel, // Add FIPS mode secret if /etc/system-fips exists on the host _, err := os.Stat("/etc/system-fips") if err == nil { - if err := addFIPSModeSecret(&secretMounts, containerWorkingDir, mountPrefix, mountLabel, uid, gid); err != nil { + if err := addFIPSModeSecret(&secretMounts, containerWorkingDir, mountPoint, mountLabel, uid, gid); err != nil { logrus.Errorf("error adding FIPS mode secret to container: %v", err) } } else if os.IsNotExist(err) { @@ -206,7 +215,7 @@ func rchown(chowndir string, uid, gid in // addSecretsFromMountsFile copies the contents of host directory to container directory // and returns a list of mounts -func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir, mountPrefix string, uid, gid int) ([]rspec.Mount, error) { +func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir string, uid, gid int) ([]rspec.Mount, error) { var mounts []rspec.Mount defaultMountsPaths := getMounts(filePath) for _, path := range defaultMountsPaths { @@ -285,7 +294,7 @@ func addSecretsFromMountsFile(filePath, } m := rspec.Mount{ - Source: filepath.Join(mountPrefix, ctrDirOrFile), + Source: ctrDirOrFileOnHost, Destination: ctrDirOrFile, Type: "bind", Options: []string{"bind", "rprivate"}, @@ -300,15 +309,15 @@ func addSecretsFromMountsFile(filePath, // root filesystem if /etc/system-fips exists on hosts. // This enables the container to be FIPS compliant and run openssl in // FIPS mode as the host is also in FIPS mode. -func addFIPSModeSecret(mounts *[]rspec.Mount, containerWorkingDir, mountPrefix, mountLabel string, uid, gid int) error { +func addFIPSModeSecret(mounts *[]rspec.Mount, containerWorkingDir, mountPoint, mountLabel string, uid, gid int) error { secretsDir := "/run/secrets" ctrDirOnHost := filepath.Join(containerWorkingDir, secretsDir) if _, err := os.Stat(ctrDirOnHost); os.IsNotExist(err) { if err = idtools.MkdirAllAs(ctrDirOnHost, 0755, uid, gid); err != nil { - return errors.Wrapf(err, "making container directory on host failed") + return errors.Wrapf(err, "making container directory %q on host failed", ctrDirOnHost) } if err = label.Relabel(ctrDirOnHost, mountLabel, false); err != nil { - return errors.Wrap(err, "error applying correct labels") + return errors.Wrapf(err, "error applying correct labels on %q", ctrDirOnHost) } } fipsFile := filepath.Join(ctrDirOnHost, "system-fips") @@ -323,7 +332,7 @@ func addFIPSModeSecret(mounts *[]rspec.M if !mountExists(*mounts, secretsDir) { m := rspec.Mount{ - Source: filepath.Join(mountPrefix, secretsDir), + Source: ctrDirOnHost, Destination: secretsDir, Type: "bind", Options: []string{"bind", "rprivate"}, @@ -331,6 +340,25 @@ func addFIPSModeSecret(mounts *[]rspec.M *mounts = append(*mounts, m) } + srcBackendDir := "/usr/share/crypto-policies/back-ends/FIPS" + destDir := "/etc/crypto-policies/back-ends" + srcOnHost := filepath.Join(mountPoint, srcBackendDir) + if _, err := os.Stat(srcOnHost); err != nil { + if os.IsNotExist(err) { + return nil + } + return errors.Wrapf(err, "failed to stat FIPS Backend directory %q", ctrDirOnHost) + } + + if !mountExists(*mounts, destDir) { + m := rspec.Mount{ + Source: srcOnHost, + Destination: destDir, + Type: "bind", + Options: []string{"bind", "rprivate"}, + } + *mounts = append(*mounts, m) + } return nil } diff -up ./buildah-9513cb8c7bec0f7789c696aee4d252ebf85194cc/run_linux.go.1784950 ./buildah-9513cb8c7bec0f7789c696aee4d252ebf85194cc/run_linux.go --- buildah-9513cb8c7bec0f7789c696aee4d252ebf85194cc/run_linux.go.1784950 2020-02-19 16:09:40.416763645 +0100 +++ buildah-9513cb8c7bec0f7789c696aee4d252ebf85194cc/run_linux.go 2020-02-19 16:09:40.419763687 +0100 @@ -460,7 +460,7 @@ func (b *Builder) setupMounts(mountPoint } // Get the list of secrets mounts. - secretMounts := secrets.SecretMountsWithUIDGID(b.MountLabel, cdir, b.DefaultMountsFilePath, cdir, int(rootUID), int(rootGID), unshare.IsRootless(), false) + secretMounts := secrets.SecretMountsWithUIDGID(b.MountLabel, cdir, b.DefaultMountsFilePath, mountPoint, int(rootUID), int(rootGID), unshare.IsRootless(), false) // Add temporary copies of the contents of volume locations at the // volume locations, unless we already have something there.