From: Matthew Heon <[email protected]>

In the upstream library, when added with a single API call,
multiple syscall argument rules should be matched with AND
logic - if all of them match, the rule matches.

At present, the Golang bindings apply OR logic to this case.
This commit resolves this and reverts to the behavior of the
main library.

Signed-off-by: Matthew Heon <[email protected]>
---
 seccomp_internal.go | 64 +++++++++++++++++++++++++++++++----------------------
 1 file changed, 37 insertions(+), 27 deletions(-)

diff --git a/seccomp_internal.go b/seccomp_internal.go
index c9fd616..369f194 100644
--- a/seccomp_internal.go
+++ b/seccomp_internal.go
@@ -120,23 +120,27 @@ unsigned int get_micro_version()
 
 typedef struct scmp_arg_cmp* scmp_cast_t;
 
-// Wrapper to create an scmp_arg_cmp struct
-void*
-make_struct_arg_cmp(
-                    unsigned int arg,
-                    int compare,
-                    uint64_t a,
-                    uint64_t b
-                   )
+void* make_arg_cmp_array(unsigned int length)
 {
-       struct scmp_arg_cmp *s = malloc(sizeof(struct scmp_arg_cmp));
+        return calloc(length, sizeof(struct scmp_arg_cmp));
+}
 
-       s->arg = arg;
-       s->op = compare;
-       s->datum_a = a;
-       s->datum_b = b;
+// Wrapper to add an scmp_arg_cmp struct to an existing arg_cmp array
+void add_struct_arg_cmp(
+                        struct scmp_arg_cmp* arr,
+                        unsigned int pos,
+                        unsigned int arg,
+                        int compare,
+                        uint64_t a,
+                        uint64_t b
+                       )
+{
+        arr[pos].arg = arg;
+        arr[pos].op = compare;
+        arr[pos].datum_a = a;
+        arr[pos].datum_b = b;
 
-       return s;
+        return;
 }
 */
 import "C"
@@ -239,12 +243,9 @@ func (f *ScmpFilter) setFilterAttr(attr scmpFilterAttr, 
value C.uint32_t) error
 // DOES NOT LOCK OR CHECK VALIDITY
 // Assumes caller has already done this
 // Wrapper for seccomp_rule_add_... functions
-func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact 
bool, cond C.scmp_cast_t) error {
-       var length C.uint
-       if cond != nil {
-               length = 1
-       } else {
-               length = 0
+func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact 
bool, length C.uint, cond C.scmp_cast_t) error {
+       if length != 0 && cond == nil {
+               return fmt.Errorf("null conditions list, but length is nonzero")
        }
 
        var retCode C.int
@@ -258,6 +259,8 @@ func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, 
action ScmpAction, exact b
                return fmt.Errorf("unrecognized syscall")
        } else if syscall.Errno(-1*retCode) == syscall.EPERM {
                return fmt.Errorf("requested action matches default action of 
filter")
+       } else if syscall.Errno(-1*retCode) == syscall.EINVAL {
+               return fmt.Errorf("two checks on same syscall argument")
        } else if retCode != 0 {
                return syscall.Errno(-1 * retCode)
        }
@@ -275,7 +278,7 @@ func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, 
action ScmpAction, exact b
        }
 
        if len(conds) == 0 {
-               if err := f.addRuleWrapper(call, action, exact, nil); err != 
nil {
+               if err := f.addRuleWrapper(call, action, exact, 0, nil); err != 
nil {
                        return err
                }
        } else {
@@ -287,13 +290,20 @@ func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, 
action ScmpAction, exact b
                        }
                }
 
-               for _, cond := range conds {
-                       cmpStruct := 
C.make_struct_arg_cmp(C.uint(cond.Argument), cond.Op.toNative(), 
C.uint64_t(cond.Operand1), C.uint64_t(cond.Operand2))
-                       defer C.free(cmpStruct)
+               argsArr := C.make_arg_cmp_array(C.uint(len(conds)))
+               if argsArr == nil {
+                       return fmt.Errorf("error allocating memory for 
conditions")
+               }
+               defer C.free(argsArr)
+
+               for i, cond := range conds {
+                       C.add_struct_arg_cmp(C.scmp_cast_t(argsArr), C.uint(i),
+                               C.uint(cond.Argument), cond.Op.toNative(),
+                               C.uint64_t(cond.Operand1), 
C.uint64_t(cond.Operand2))
+               }
 
-                       if err := f.addRuleWrapper(call, action, exact, 
C.scmp_cast_t(cmpStruct)); err != nil {
-                               return err
-                       }
+               if err := f.addRuleWrapper(call, action, exact, 
C.uint(len(conds)), C.scmp_cast_t(argsArr)); err != nil {
+                       return err
                }
        }
 
-- 
2.9.3

-- 
You received this message because you are subscribed to the Google Groups 
"libseccomp" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to