Skip to content

Commit 463e2f5

Browse files
committed
vtpm: Run swtpm with an AppArmor profile
Create an AppArmor profile and apply it so that swtpm runs with an AppArmor profile. Signed-off-by: Stefan Berger <[email protected]>
1 parent 7aff18c commit 463e2f5

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

libcontainer/vtpm/vtpm.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
"time"
1616
"unsafe"
1717

18+
"github.com/opencontainers/runc/libcontainer/apparmor"
19+
1820
"github.com/sirupsen/logrus"
1921
)
2022

@@ -56,6 +58,9 @@ type VTPM struct {
5658

5759
// process id of this vtpm
5860
Pid int
61+
62+
// The AppArmor profile's full path
63+
aaprofile string
5964
}
6065

6166
// ioctl
@@ -452,6 +457,11 @@ func (vtpm *VTPM) startSwtpm() error {
452457
return err
453458
}
454459

460+
err = vtpm.setupAppArmor()
461+
if err != nil {
462+
return err
463+
}
464+
455465
tpmstate := fmt.Sprintf("dir=%s", vtpm.StatePath)
456466
pidfile := fmt.Sprintf("file=%s", vtpm.getPidFile())
457467
logfile := fmt.Sprintf("file=%s", vtpm.getLogFile())
@@ -481,6 +491,9 @@ func (vtpm *VTPM) startSwtpm() error {
481491
if err != nil {
482492
return err
483493
}
494+
495+
vtpm.resetAppArmor()
496+
484497
return nil
485498
}
486499

@@ -561,6 +574,8 @@ func (vtpm *VTPM) Stop(deleteStatePath bool) error {
561574

562575
vtpm.CloseServer()
563576

577+
vtpm.teardownAppArmor()
578+
564579
vtpm.Tpm_dev_num = VTPM_DEV_NUM_INVALID
565580

566581
if deleteStatePath {
@@ -609,5 +624,85 @@ func (vtpm *VTPM) CloseServer() error {
609624
os.NewFile(uintptr(vtpm.fd), "[vtpm]").Close()
610625
vtpm.fd = ILLEGAL_FD
611626
}
627+
628+
return nil
629+
}
630+
631+
// setupAppArmor creates an apparmor profile for swtpm if AppArmor is enabled and
632+
// compiles it using apparmor_parser -r <filename> and activates it for the next
633+
// exec.
634+
func (vtpm *VTPM) setupAppArmor() error {
635+
var statefilepattern string
636+
637+
if !apparmor.IsEnabled() {
638+
return nil
639+
}
640+
641+
profilename := fmt.Sprintf("runc_%d_swtpm_tpm%d", os.Getpid(), vtpm.GetTPMDevNum())
642+
if vtpm.Vtpmversion == VTPM_VERSION_1_2 {
643+
statefilepattern = path.Join(vtpm.StatePath, "tpm-00.*")
644+
} else {
645+
statefilepattern = path.Join(vtpm.StatePath, "tpm2-00.*")
646+
}
647+
648+
profile := fmt.Sprintf("\n#include <tunables/global>\n"+
649+
"profile %s {\n"+
650+
" #include <abstractions/base>\n"+
651+
" capability setgid,\n"+
652+
" capability setuid,\n"+
653+
" /dev/tpm[0-9]* rw,\n"+
654+
" owner /etc/group r,\n"+
655+
" owner /etc/nsswitch.conf r,\n"+
656+
" owner /etc/passwd r,\n"+
657+
" %s/.lock wk,\n"+
658+
" %s w,\n"+
659+
" %s rw,\n"+
660+
" %s rw,\n"+
661+
"}\n",
662+
profilename,
663+
vtpm.StatePath,
664+
vtpm.getLogFile(),
665+
vtpm.getPidFile(),
666+
statefilepattern)
667+
668+
vtpm.aaprofile = path.Join(vtpm.StatePath, "swtpm.apparmor")
669+
670+
err := ioutil.WriteFile(vtpm.aaprofile, []byte(profile), 0600)
671+
if err != nil {
672+
return err
673+
}
674+
defer func() {
675+
if err != nil {
676+
vtpm.teardownAppArmor()
677+
}
678+
}()
679+
680+
cmd := exec.Command("/sbin/apparmor_parser", "-r", vtpm.aaprofile)
681+
output, err := cmd.CombinedOutput()
682+
if err != nil {
683+
return fmt.Errorf("apparmor_parser -r failed: %s", string(output))
684+
}
685+
686+
err = apparmor.ApplyProfileThread(profilename)
687+
if err != nil {
688+
return err
689+
}
690+
612691
return nil
613692
}
693+
694+
func (vtpm *VTPM) resetAppArmor() {
695+
apparmor.ApplyProfileThread("unconfined")
696+
}
697+
698+
// teardownAppArmor removes the AppArmor profile from the system and ensures
699+
// that the next time the process exec's no swtpm related profile is applied
700+
func (vtpm *VTPM) teardownAppArmor() {
701+
vtpm.resetAppArmor()
702+
if len(vtpm.aaprofile) > 0 {
703+
cmd := exec.Command("/sbin/apparmor_parser", "-R", vtpm.aaprofile)
704+
cmd.Run()
705+
os.Remove(vtpm.aaprofile)
706+
vtpm.aaprofile = ""
707+
}
708+
}

0 commit comments

Comments
 (0)