mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
seccomp: Make SyscallRules.Copy do a deep copy.
This adds a `Copy` function to the `SyscallRule` interface, so that syscall rules can be deeply copied. This is useful in the context of precompiled rules, which can be precompiled in parallel and where some optimizers will modify the `SyscallRule` objects themselves (e.g. removing the `MatchAll` rules from an `Or` rule). When this happens in parallel, this causes a race of two goroutines writing to the same slice when the rules are based on a similar source. Each goroutine should be dealing with its own set of rules, hence making `Copy` a deep copy. PiperOrigin-RevId: 584169637
This commit is contained in:
committed by
gVisor bot
parent
9c6f50d59e
commit
f221e212aa
@@ -488,6 +488,9 @@ type SyscallRule interface {
|
||||
// next into the program.
|
||||
Render(program *syscallProgram, labelSet *labelSet)
|
||||
|
||||
// Copy returns a copy of this `SyscallRule`.
|
||||
Copy() SyscallRule
|
||||
|
||||
// Recurse should call the given function on all `SyscallRule`s that are
|
||||
// part of this `SyscallRule`, and should replace them with the returned
|
||||
// `SyscallRule`. For example, conjunctive rules should call the given
|
||||
@@ -507,6 +510,11 @@ func (MatchAll) Render(program *syscallProgram, labelSet *labelSet) {
|
||||
program.JumpTo(labelSet.Matched())
|
||||
}
|
||||
|
||||
// Copy implements `SyscallRule.Copy`.
|
||||
func (MatchAll) Copy() SyscallRule {
|
||||
return MatchAll{}
|
||||
}
|
||||
|
||||
// Recurse implements `SyscallRule.Recurse`.
|
||||
func (MatchAll) Recurse(func(SyscallRule) SyscallRule) {}
|
||||
|
||||
@@ -534,6 +542,15 @@ func (or Or) Render(program *syscallProgram, labelSet *labelSet) {
|
||||
program.JumpTo(labelSet.Mismatched())
|
||||
}
|
||||
|
||||
// Copy implements `SyscallRule.Copy`.
|
||||
func (or Or) Copy() SyscallRule {
|
||||
orCopy := make([]SyscallRule, len(or))
|
||||
for i, rule := range or {
|
||||
orCopy[i] = rule.Copy()
|
||||
}
|
||||
return Or(orCopy)
|
||||
}
|
||||
|
||||
// Recurse implements `SyscallRule.Recurse`.
|
||||
func (or Or) Recurse(fn func(SyscallRule) SyscallRule) {
|
||||
for i, rule := range or {
|
||||
@@ -583,6 +600,15 @@ func (and And) Render(program *syscallProgram, labelSet *labelSet) {
|
||||
program.JumpTo(labelSet.Matched())
|
||||
}
|
||||
|
||||
// Copy implements `SyscallRule.Copy`.
|
||||
func (and And) Copy() SyscallRule {
|
||||
andCopy := make([]SyscallRule, len(and))
|
||||
for i, rule := range and {
|
||||
andCopy[i] = rule.Copy()
|
||||
}
|
||||
return And(andCopy)
|
||||
}
|
||||
|
||||
// Recurse implements `SyscallRule.Recurse`.
|
||||
func (and And) Recurse(fn func(SyscallRule) SyscallRule) {
|
||||
for i, rule := range and {
|
||||
@@ -624,8 +650,8 @@ type PerArg [7]ValueMatcher // 6 arguments + RIP
|
||||
// instruction pointer.
|
||||
const RuleIP = 6
|
||||
|
||||
// clone returns a copy of this `PerArg`.
|
||||
func (pa PerArg) clone() PerArg {
|
||||
// Copy implements `SyscallRule.Copy`.
|
||||
func (pa PerArg) Copy() SyscallRule {
|
||||
return PerArg{
|
||||
pa[0],
|
||||
pa[1],
|
||||
@@ -829,11 +855,11 @@ func (sr SyscallRules) Merge(other SyscallRules) SyscallRules {
|
||||
return sr
|
||||
}
|
||||
|
||||
// Copy returns a copy of these SyscallRules.
|
||||
// Copy returns a deep copy of these SyscallRules.
|
||||
func (sr SyscallRules) Copy() SyscallRules {
|
||||
rulesCopy := make(map[uintptr]SyscallRule, len(sr.rules))
|
||||
for sysno, r := range sr.rules {
|
||||
rulesCopy[sysno] = r
|
||||
rulesCopy[sysno] = r.Copy()
|
||||
}
|
||||
return MakeSyscallRules(rulesCopy)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user