Skip to content

Commit 06e7a29

Browse files
committed
golang: Resolve bug with handling of multiple argument rules
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 <matthew.heon@gmail.com>
1 parent fc02980 commit 06e7a29

File tree

1 file changed

+37
-27
lines changed

1 file changed

+37
-27
lines changed

seccomp_internal.go

+37-27
Original file line numberDiff line numberDiff line change
@@ -120,23 +120,27 @@ unsigned int get_micro_version()
120120
121121
typedef struct scmp_arg_cmp* scmp_cast_t;
122122
123-
// Wrapper to create an scmp_arg_cmp struct
124-
void*
125-
make_struct_arg_cmp(
126-
unsigned int arg,
127-
int compare,
128-
uint64_t a,
129-
uint64_t b
130-
)
123+
void* make_arg_cmp_array(unsigned int length)
131124
{
132-
struct scmp_arg_cmp *s = malloc(sizeof(struct scmp_arg_cmp));
125+
return calloc(length, sizeof(struct scmp_arg_cmp));
126+
}
133127
134-
s->arg = arg;
135-
s->op = compare;
136-
s->datum_a = a;
137-
s->datum_b = b;
128+
// Wrapper to add an scmp_arg_cmp struct to an existing arg_cmp array
129+
void add_struct_arg_cmp(
130+
struct scmp_arg_cmp* arr,
131+
unsigned int pos,
132+
unsigned int arg,
133+
int compare,
134+
uint64_t a,
135+
uint64_t b
136+
)
137+
{
138+
arr[pos].arg = arg;
139+
arr[pos].op = compare;
140+
arr[pos].datum_a = a;
141+
arr[pos].datum_b = b;
138142
139-
return s;
143+
return;
140144
}
141145
*/
142146
import "C"
@@ -239,12 +243,9 @@ func (f *ScmpFilter) setFilterAttr(attr scmpFilterAttr, value C.uint32_t) error
239243
// DOES NOT LOCK OR CHECK VALIDITY
240244
// Assumes caller has already done this
241245
// Wrapper for seccomp_rule_add_... functions
242-
func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact bool, cond C.scmp_cast_t) error {
243-
var length C.uint
244-
if cond != nil {
245-
length = 1
246-
} else {
247-
length = 0
246+
func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact bool, length C.uint, cond C.scmp_cast_t) error {
247+
if length != 0 && cond == nil {
248+
return fmt.Errorf("null conditions list, but length is nonzero")
248249
}
249250

250251
var retCode C.int
@@ -258,6 +259,8 @@ func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact b
258259
return fmt.Errorf("unrecognized syscall")
259260
} else if syscall.Errno(-1*retCode) == syscall.EPERM {
260261
return fmt.Errorf("requested action matches default action of filter")
262+
} else if syscall.Errno(-1*retCode) == syscall.EINVAL {
263+
return fmt.Errorf("two checks on same syscall argument")
261264
} else if retCode != 0 {
262265
return syscall.Errno(-1 * retCode)
263266
}
@@ -275,7 +278,7 @@ func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact b
275278
}
276279

277280
if len(conds) == 0 {
278-
if err := f.addRuleWrapper(call, action, exact, nil); err != nil {
281+
if err := f.addRuleWrapper(call, action, exact, 0, nil); err != nil {
279282
return err
280283
}
281284
} else {
@@ -287,13 +290,20 @@ func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact b
287290
}
288291
}
289292

290-
for _, cond := range conds {
291-
cmpStruct := C.make_struct_arg_cmp(C.uint(cond.Argument), cond.Op.toNative(), C.uint64_t(cond.Operand1), C.uint64_t(cond.Operand2))
292-
defer C.free(cmpStruct)
293+
argsArr := C.make_arg_cmp_array(C.uint(len(conds)))
294+
if argsArr == nil {
295+
return fmt.Errorf("error allocating memory for conditions")
296+
}
297+
defer C.free(argsArr)
298+
299+
for i, cond := range conds {
300+
C.add_struct_arg_cmp(C.scmp_cast_t(argsArr), C.uint(i),
301+
C.uint(cond.Argument), cond.Op.toNative(),
302+
C.uint64_t(cond.Operand1), C.uint64_t(cond.Operand2))
303+
}
293304

294-
if err := f.addRuleWrapper(call, action, exact, C.scmp_cast_t(cmpStruct)); err != nil {
295-
return err
296-
}
305+
if err := f.addRuleWrapper(call, action, exact, C.uint(len(conds)), C.scmp_cast_t(argsArr)); err != nil {
306+
return err
297307
}
298308
}
299309

0 commit comments

Comments
 (0)