Skip to content

Commit

Permalink
vtpm: Run swtpm with an AppArmor profile
Browse files Browse the repository at this point in the history
Create an AppArmor profile and apply it so that swtpm runs with an AppArmor
profile.

Signed-off-by: Stefan Berger <[email protected]>
  • Loading branch information
stefanberger committed Jan 3, 2020
1 parent 550b0b6 commit a548859
Showing 1 changed file with 91 additions and 0 deletions.
91 changes: 91 additions & 0 deletions libcontainer/vtpm/vtpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"time"
"unsafe"

"github.com/opencontainers/runc/libcontainer/apparmor"

"github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -53,6 +55,9 @@ type VTPM struct {

// The minor number of the created device
minor uint32

// The AppArmor profile's full path
aaprofile string
}

// ioctl
Expand Down Expand Up @@ -432,6 +437,11 @@ again:
return false, err
}

err = vtpm.SetupAppArmor()
if err != nil {
return false, err
}

tpmname := vtpm.GetTPMDevname()
fdstr := fmt.Sprintf("%d", vtpm.fd)
tpmstate := fmt.Sprintf("dir=%s", vtpm.StatePath)
Expand Down Expand Up @@ -462,6 +472,8 @@ again:
return false, err
}

apparmor.ApplyProfileTid("unconfined")

cmd = exec.Command("swtpm_bios", "-n", "-cs", "-u", "--tpm-device", tpmname)
if vtpm.Vtpmversion == VTPM_VERSION_2 {
cmd.Args = append(cmd.Args, "--tpm2")
Expand Down Expand Up @@ -503,6 +515,8 @@ func (vtpm *VTPM) Stop(deleteStatePath bool) error {

vtpm.CloseServer()

vtpm.TeardownAppArmor()

vtpm.Tpm_dev_num = VTPM_DEV_NUM_INVALID

if deleteStatePath {
Expand Down Expand Up @@ -551,5 +565,82 @@ func (vtpm *VTPM) CloseServer() error {
os.NewFile(uintptr(vtpm.fd), "[vtpm]").Close()
vtpm.fd = ILLEGAL_FD
}

return nil
}

// SetupAppArmor creates an apparmor profile for swtpm if AppArmor is enabled and
// compiles it using apparmor_parser -r <filename> and activates it for the next
// exec.
func (vtpm *VTPM) SetupAppArmor() error {
var statefilepattern string

if !apparmor.IsEnabled() {
return nil
}

profilename := fmt.Sprintf("runc_%d_swtpm_tpm%d",os.Getpid(), vtpm.GetTPMDevNum())
if vtpm.Vtpmversion == VTPM_VERSION_1_2 {
statefilepattern = "tpm-00.*"
} else {
statefilepattern = "tpm2-00.*"
}

profile := fmt.Sprintf("\n#include <tunables/global>\n"+
"profile %s {\n"+
" #include <abstractions/base>\n"+
" capability setgid,\n"+
" capability setuid,\n"+
" /dev/tpm[0-9]* rw,\n"+
" owner /etc/group r,\n"+
" owner /etc/nsswitch.conf r,\n"+
" owner /etc/passwd r,\n"+
" %s/.lock wk,\n"+
" %s/swtpm.log w,\n"+
" %s/swtpm.pid rw,\n"+
" %s/%s rw,\n"+
"}\n",
profilename,
vtpm.StatePath,
vtpm.StatePath,
vtpm.StatePath,
vtpm.StatePath,
statefilepattern)

vtpm.aaprofile = path.Join(vtpm.StatePath, "swtpm.apparmor")

err := ioutil.WriteFile(vtpm.aaprofile, []byte(profile), 0600)
if err != nil {
return err
}
defer func() {
if err != nil {
vtpm.TeardownAppArmor()
}
}()

cmd := exec.Command("/sbin/apparmor_parser", "-r", vtpm.aaprofile)
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("apparmor_parser -r failed: %s", string(output))
}

err = apparmor.ApplyProfileTid(profilename)
if err != nil {
return err
}

return nil
}

// TeardownAppArmor removes the AppArmor profile from the system and ensures
// that the next time the process exec's no swtpm related profile is applied
func (vtpm *VTPM) TeardownAppArmor() {
apparmor.ApplyProfileTid("unconfined")
if len(vtpm.aaprofile) > 0 {
cmd := exec.Command("/sbin/apparmor_parser", "-R", vtpm.aaprofile)
cmd.Run()
os.Remove(vtpm.aaprofile)
vtpm.aaprofile = ""
}
}

0 comments on commit a548859

Please sign in to comment.