-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
libcontainer: add support for Landlock
This patch introduces Landlock Linux Security Module (LSM) support in runc, which was landed in Linux kernel 5.13. This allows unprivileged processes to create safe security sandboxes that can securely restrict the ambient rights (e.g. global filesystem access) for themselves. runtime-spec: opencontainers/runtime-spec#1111 Fixes #2859 Co-authored-by: Zheao Li <[email protected]> Signed-off-by: Kailun Qin <[email protected]> Signed-off-by: Manjusaka <[email protected]>
- Loading branch information
1 parent
2e906e2
commit 4bac159
Showing
9 changed files
with
312 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package landlock | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/landlock-lsm/go-landlock/landlock" | ||
ll "github.com/landlock-lsm/go-landlock/landlock/syscall" | ||
) | ||
|
||
var accessFSSets = map[string]landlock.AccessFSSet{ | ||
"execute": ll.AccessFSExecute, | ||
"write_file": ll.AccessFSWriteFile, | ||
"read_file": ll.AccessFSReadFile, | ||
"read_dir": ll.AccessFSReadDir, | ||
"remove_dir": ll.AccessFSRemoveDir, | ||
"remove_file": ll.AccessFSRemoveFile, | ||
"make_char": ll.AccessFSMakeChar, | ||
"make_dir": ll.AccessFSMakeDir, | ||
"make_reg": ll.AccessFSMakeReg, | ||
"make_sock": ll.AccessFSMakeSock, | ||
"make_fifo": ll.AccessFSMakeFifo, | ||
"make_block": ll.AccessFSMakeBlock, | ||
"make_sym": ll.AccessFSMakeSym, | ||
} | ||
|
||
// ConvertStringToAccessFSSet converts a string into a go-landlock AccessFSSet | ||
// access right. | ||
// This gives more explicit control over the mapping between the permitted | ||
// values in the spec and the ones supported in go-landlock library. | ||
func ConvertStringToAccessFSSet(in string) (landlock.AccessFSSet, error) { | ||
if access, ok := accessFSSets[in]; ok { | ||
return access, nil | ||
} | ||
return 0, fmt.Errorf("string %s is not a valid access right for landlock", in) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package landlock | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/landlock-lsm/go-landlock/landlock" | ||
|
||
"github.com/opencontainers/runc/libcontainer/configs" | ||
) | ||
|
||
// Initialize Landlock unprivileged access control for the container process | ||
// based on the given settings. | ||
// The specified `ruleset` identifies a set of rules (i.e., actions on objects) | ||
// that need to be handled (i.e., restricted) by Landlock. And if no `rule` | ||
// explicitly allow them, they should then be forbidden. | ||
// The `disableBestEffort` input gives control over whether the best-effort | ||
// security approach should be applied for Landlock access rights. | ||
func InitLandlock(config *configs.Landlock) error { | ||
if config == nil { | ||
return errors.New("cannot initialize Landlock - nil config passed") | ||
} | ||
|
||
ruleset := config.Ruleset.HandledAccessFS | ||
llConfig, err := landlock.NewConfig(ruleset) | ||
if err != nil { | ||
return fmt.Errorf("could not create ruleset: %w", err) | ||
} | ||
|
||
if !config.DisableBestEffort { | ||
*llConfig = llConfig.BestEffort() | ||
} | ||
|
||
if err := llConfig.RestrictPaths( | ||
pathAccesses(config.Rules)..., | ||
); err != nil { | ||
return fmt.Errorf("could not restrict paths: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Convert Libcontainer RulePathBeneath to go-landlock PathOpt. | ||
func pathAccess(rule *configs.RulePathBeneath) landlock.PathOpt { | ||
return landlock.PathAccess(rule.AllowedAccess, rule.Paths...) | ||
} | ||
|
||
// Convert Libcontainer Rules to an array of go-landlock PathOpt. | ||
func pathAccesses(rules *configs.Rules) []landlock.PathOpt { | ||
pathAccesses := []landlock.PathOpt{} | ||
|
||
for _, rule := range rules.PathBeneath { | ||
opt := pathAccess(rule) | ||
pathAccesses = append(pathAccesses, opt) | ||
} | ||
|
||
return pathAccesses | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.