Skip to content

Commit

Permalink
WIP: Composite rule implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
gnoack committed Oct 13, 2024
1 parent d2bedb6 commit 09b2b53
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 8 deletions.
13 changes: 5 additions & 8 deletions landlock/llrules/experimental.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
// Package llrules experimentally implements commonly used groups of
// Landlock rules.
// Package llrules implements commonly used groups of Landlock rules.
//
// This package is *experimental*.
package llrules

import "github.com/landlock-lsm/go-landlock/landlock"

func DNSOverTCP() landlock.Rule {
return landlock.CompositeRule(landlock.ConnectTCP(53), dnsFiles())
}

func DNSOverUDP() landlock.Rule {
func DNS() landlock.Rule {
// UDP is not restrictable yet, but it can be added here once
// Landlock can do that.
return dnsFiles()
return landlock.CompositeRule(landlock.ConnectTCP(53), dnsFiles())
}

func dnsFiles() landlock.Rule {
Expand Down
47 changes: 47 additions & 0 deletions landlock/llrules/llrules_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package llrules_test

import (
"context"
"net"
"testing"

"github.com/landlock-lsm/go-landlock/landlock"
"github.com/landlock-lsm/go-landlock/landlock/llrules"
"github.com/landlock-lsm/go-landlock/landlock/lltest"
)

func TestDNSOverTCP(t *testing.T) {
lltest.RunInSubprocess(t, func() {
err := landlock.V5.BestEffort().Restrict(llrules.DNS())
if err != nil {
t.Fatalf("Enabling Landlock: %v", err)
}

r := net.Resolver{
PreferGo: true,
}
_, err = r.LookupHost(context.Background(), "localhost")
if err != nil {
t.Errorf("Unexpected DNS error: %v", err)
}
})
}

func TestDNSOverTCP_fail(t *testing.T) {
lltest.RequireABI(t, 1)

lltest.RunInSubprocess(t, func() {
err := landlock.V5.BestEffort().Restrict()
if err != nil {
t.Fatalf("Enabling Landlock: %v", err)
}

r := net.Resolver{
PreferGo: true,
}
_, err = r.LookupHost(context.Background(), "localhost")
if err == nil {
t.Errorf("Expected DNS error, but got success")
}
})
}
49 changes: 49 additions & 0 deletions landlock/rule_composite.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package landlock

import "fmt"

type RuleGroup struct {
rules []Rule
}

// GroupRules groups the given rules into a single Rule value.
// The result behaves the same in a Landlock restriction call
// as listing all of the individual rules separately.
func GroupRules(rules ...Rule) RuleGroup {
return RuleGroup{rules: rules}
}

func (g RuleGroup) compatibleWithConfig(c Config) bool {
for _, r := range g.rules {
if !r.compatibleWithConfig(c) {
return false
}
}
return true
}

func (g RuleGroup) downgrade(c Config) (out Rule, ok bool) {
rs := make([]Rule, 0, len(g.rules))
for _, r := range g.rules {
r, ok := r.downgrade(c)
if !ok {
return GroupRules(), false
}
rs = append(rs, r)
}
return GroupRules(rs...), true
}

func (g RuleGroup) addToRuleset(rulesetFD int, c Config) error {
for _, r := range g.rules {
err := r.addToRuleset(rulesetFD, c)
if err != nil {
return err
}
}
return nil
}

func (g RuleGroup) String() string {
return fmt.Sprintf("rules: %v", g.rules)
}

0 comments on commit 09b2b53

Please sign in to comment.