2222 actErrno = libseccomp .ActErrno .SetReturnCode (int16 (unix .EPERM ))
2323)
2424
25+ const (
26+ // Linux system calls can have at most 6 arguments
27+ syscallMaxArguments int = 6
28+ )
29+
2530// Filters given syscalls in a container, preventing them from being used
2631// Started in the container init process, and carried over to all child processes
2732// Setns calls, however, require a separate invocation, as they are not children
@@ -45,11 +50,11 @@ func InitSeccomp(config *configs.Seccomp) error {
4550 for _ , arch := range config .Architectures {
4651 scmpArch , err := libseccomp .GetArchFromString (arch )
4752 if err != nil {
48- return err
53+ return fmt . Errorf ( "error validating Seccomp architecture: %s" , err )
4954 }
5055
5156 if err := filter .AddArch (scmpArch ); err != nil {
52- return err
57+ return fmt . Errorf ( "error adding architecture to seccomp filter: %s" , err )
5358 }
5459 }
5560
@@ -170,29 +175,55 @@ func matchCall(filter *libseccomp.ScmpFilter, call *configs.Syscall) error {
170175 // Convert the call's action to the libseccomp equivalent
171176 callAct , err := getAction (call .Action )
172177 if err != nil {
173- return err
178+ return fmt . Errorf ( "action in seccomp profile is invalid: %s" , err )
174179 }
175180
176181 // Unconditional match - just add the rule
177182 if len (call .Args ) == 0 {
178183 if err = filter .AddRule (callNum , callAct ); err != nil {
179- return err
184+ return fmt . Errorf ( "error adding seccomp filter rule for syscall %s: %s" , call . Name , err )
180185 }
181186 } else {
182- // Conditional match - convert the per-arg rules into library format
187+ // If two or more arguments have the same condition,
188+ // Revert to old behavior, adding each condition as a separate rule
189+ argCounts := make ([]uint , syscallMaxArguments )
183190 conditions := []libseccomp.ScmpCondition {}
184191
185192 for _ , cond := range call .Args {
186193 newCond , err := getCondition (cond )
187194 if err != nil {
188- return err
195+ return fmt . Errorf ( "error creating seccomp syscall condition for syscall %s: %s" , call . Name , err )
189196 }
190197
198+ argCounts [cond .Index ] += 1
199+
191200 conditions = append (conditions , newCond )
192201 }
193202
194- if err = filter .AddRuleConditional (callNum , callAct , conditions ); err != nil {
195- return err
203+ hasMultipleArgs := false
204+ for _ , count := range argCounts {
205+ if count > 1 {
206+ hasMultipleArgs = true
207+ break
208+ }
209+ }
210+
211+ if hasMultipleArgs {
212+ // Revert to old behavior
213+ // Add each condition attached to a separate rule
214+ for _ , cond := range conditions {
215+ condArr := []libseccomp.ScmpCondition {cond }
216+
217+ if err = filter .AddRuleConditional (callNum , callAct , condArr ); err != nil {
218+ return fmt .Errorf ("error adding seccomp rule for syscall %s: %s" , call .Name , err )
219+ }
220+ }
221+ } else {
222+ // No conditions share same argument
223+ // Use new, proper behavior
224+ if err = filter .AddRuleConditional (callNum , callAct , conditions ); err != nil {
225+ return fmt .Errorf ("error adding seccomp rule for syscall %s: %s" , call .Name , err )
226+ }
196227 }
197228 }
198229
0 commit comments