seccomp: allow to filter syscalls by instruction pointer

PiperOrigin-RevId: 293029446
This commit is contained in:
Andrei Vagin
2020-02-03 16:16:18 -08:00
committed by gVisor bot
parent 6cd7901d7d
commit f37e913a35
3 changed files with 48 additions and 5 deletions
+16 -4
View File
@@ -219,24 +219,36 @@ func addSyscallArgsCheck(p *bpf.ProgramBuilder, rules []Rule, action linux.BPFAc
switch a := arg.(type) {
case AllowAny:
case AllowValue:
dataOffsetLow := seccompDataOffsetArgLow(i)
dataOffsetHigh := seccompDataOffsetArgHigh(i)
if i == RuleIP {
dataOffsetLow = seccompDataOffsetIPLow
dataOffsetHigh = seccompDataOffsetIPHigh
}
high, low := uint32(a>>32), uint32(a)
// assert arg_low == low
p.AddStmt(bpf.Ld|bpf.Abs|bpf.W, seccompDataOffsetArgLow(i))
p.AddStmt(bpf.Ld|bpf.Abs|bpf.W, dataOffsetLow)
p.AddJumpFalseLabel(bpf.Jmp|bpf.Jeq|bpf.K, low, 0, ruleViolationLabel(ruleSetIdx, sysno, ruleidx))
// assert arg_high == high
p.AddStmt(bpf.Ld|bpf.Abs|bpf.W, seccompDataOffsetArgHigh(i))
p.AddStmt(bpf.Ld|bpf.Abs|bpf.W, dataOffsetHigh)
p.AddJumpFalseLabel(bpf.Jmp|bpf.Jeq|bpf.K, high, 0, ruleViolationLabel(ruleSetIdx, sysno, ruleidx))
labelled = true
case GreaterThan:
dataOffsetLow := seccompDataOffsetArgLow(i)
dataOffsetHigh := seccompDataOffsetArgHigh(i)
if i == RuleIP {
dataOffsetLow = seccompDataOffsetIPLow
dataOffsetHigh = seccompDataOffsetIPHigh
}
labelGood := fmt.Sprintf("gt%v", i)
high, low := uint32(a>>32), uint32(a)
// assert arg_high < high
p.AddStmt(bpf.Ld|bpf.Abs|bpf.W, seccompDataOffsetArgHigh(i))
p.AddStmt(bpf.Ld|bpf.Abs|bpf.W, dataOffsetHigh)
p.AddJumpFalseLabel(bpf.Jmp|bpf.Jge|bpf.K, high, 0, ruleViolationLabel(ruleSetIdx, sysno, ruleidx))
// arg_high > high
p.AddJumpFalseLabel(bpf.Jmp|bpf.Jeq|bpf.K, high, 0, ruleLabel(ruleSetIdx, sysno, ruleidx, labelGood))
// arg_low < low
p.AddStmt(bpf.Ld|bpf.Abs|bpf.W, seccompDataOffsetArgLow(i))
p.AddStmt(bpf.Ld|bpf.Abs|bpf.W, dataOffsetLow)
p.AddJumpFalseLabel(bpf.Jmp|bpf.Jgt|bpf.K, low, 0, ruleViolationLabel(ruleSetIdx, sysno, ruleidx))
p.AddLabel(ruleLabel(ruleSetIdx, sysno, ruleidx, labelGood))
labelled = true
+5 -1
View File
@@ -62,7 +62,11 @@ func (a AllowValue) String() (s string) {
// rule := Rule {
// AllowValue(linux.ARCH_GET_FS | linux.ARCH_SET_FS), // arg0
// }
type Rule [6]interface{}
type Rule [7]interface{} // 6 arguments + RIP
// RuleIP indicates what rules in the Rule array have to be applied to
// instruction pointer.
const RuleIP = 6
func (r Rule) String() (s string) {
if len(r) == 0 {
+27
View File
@@ -388,6 +388,33 @@ func TestBasic(t *testing.T) {
},
},
},
{
ruleSets: []RuleSet{
{
Rules: SyscallRules{
1: []Rule{
{
RuleIP: AllowValue(0x7aabbccdd),
},
},
},
Action: linux.SECCOMP_RET_ALLOW,
},
},
defaultAction: linux.SECCOMP_RET_TRAP,
specs: []spec{
{
desc: "IP: Syscall instruction pointer allowed",
data: seccompData{nr: 1, arch: linux.AUDIT_ARCH_X86_64, args: [6]uint64{}, instructionPointer: 0x7aabbccdd},
want: linux.SECCOMP_RET_ALLOW,
},
{
desc: "IP: Syscall instruction pointer disallowed",
data: seccompData{nr: 1, arch: linux.AUDIT_ARCH_X86_64, args: [6]uint64{}, instructionPointer: 0x711223344},
want: linux.SECCOMP_RET_TRAP,
},
},
},
} {
instrs, err := BuildProgram(test.ruleSets, test.defaultAction)
if err != nil {