From 4dfba277487a7023ab9f5783302da4a9b5e9bef8 Mon Sep 17 00:00:00 2001 From: "Jiao, Joey" Date: Wed, 6 Nov 2024 13:41:21 +0800 Subject: all: support || operator in syzlang if condition ex. f3 field has logic or operator in if condition: conditional_struct { mask int32 f1 field1 (if[value[mask] & FIELD_FLAG1]) f2 int64 (if[value[mask] & FIELD_FLAG2]) f3 int64 (if[value[mask] == FIELD_FLAG1 || value[mask] == FIELD_FLAG2]) } [packed] --- prog/expr.go | 5 +++++ prog/expr_test.go | 23 +++++++++++++++-------- prog/types.go | 1 + 3 files changed, 21 insertions(+), 8 deletions(-) (limited to 'prog') diff --git a/prog/expr.go b/prog/expr.go index e9446ab2c..87fb056a9 100644 --- a/prog/expr.go +++ b/prog/expr.go @@ -30,6 +30,11 @@ func (bo *BinaryExpression) Evaluate(finder ArgFinder) (uint64, bool) { return 0, true case OperatorBinaryAnd: return left & right, true + case OperatorOr: + if left != 0 || right != 0 { + return 1, true + } + return 0, true } panic(fmt.Sprintf("unknown operator %q", bo.Operator)) } diff --git a/prog/expr_test.go b/prog/expr_test.go index 74818ea55..1558248f5 100644 --- a/prog/expr_test.go +++ b/prog/expr_test.go @@ -92,13 +92,20 @@ func TestEvaluateConditionalFields(t *testing.T) { }{ { good: []string{ - `test$conditional_struct(&AUTO={0x0, @void, @void})`, - `test$conditional_struct(&AUTO={0x4, @void, @value=0x123})`, - `test$conditional_struct(&AUTO={0x6, @value={AUTO}, @value=0x123})`, + `test$conditional_struct(&AUTO={0x0, @void, @void, @void})`, + `test$conditional_struct(&AUTO={0x2, @value={AUTO}, @void, @value=0x456})`, + `test$conditional_struct(&AUTO={0x4, @void, @value=0x123, @value=0x456})`, + `test$conditional_struct(&AUTO={0x6, @value={AUTO}, @value=0x123, @void})`, }, bad: []string{ - `test$conditional_struct(&AUTO={0x0, @void, @value=0x123})`, - `test$conditional_struct(&AUTO={0x0, @value={AUTO}, @value=0x123})`, + `test$conditional_struct(&AUTO={0x0, @void, @void, @value=0x123})`, + `test$conditional_struct(&AUTO={0x0, @value={AUTO}, @void, @value=0x123})`, + `test$conditional_struct(&AUTO={0x0, @void, @value=0x123, @void})`, + `test$conditional_struct(&AUTO={0x0, @void, @void, @value=0x123})`, + `test$conditional_struct(&AUTO={0x2, @value={AUTO}, @void, @void})`, + `test$conditional_struct(&AUTO={0x2, @value={AUTO}, @value=0x123, @void})`, + `test$conditional_struct(&AUTO={0x4, @void, @value=0x123, @void})`, + `test$conditional_struct(&AUTO={0x4, @void, @void, @value=0x123})`, }, }, { @@ -141,14 +148,14 @@ func TestConditionalMinimize(t *testing.T) { output string }{ { - input: `test$conditional_struct(&AUTO={0x6, @value={AUTO}, @value=0x123})`, + input: `test$conditional_struct(&AUTO={0x6, @value={AUTO}, @value=0x123, @void})`, pred: func(p *Prog, _ int) bool { return len(p.Calls) == 1 && p.Calls[0].Meta.Name == `test$conditional_struct` }, output: `test$conditional_struct(0x0)`, }, { - input: `test$conditional_struct(&(0x7f0000000040)={0x6, @value, @value=0x123})`, + input: `test$conditional_struct(&(0x7f0000000040)={0x6, @value, @value=0x123, @void})`, pred: func(p *Prog, _ int) bool { return bytes.Contains(p.Serialize(), []byte("0x123")) }, @@ -236,7 +243,7 @@ func parseConditionalStructCall(t *testing.T, c *Call) (bool, bool) { if !ok { t.Fatalf("expected GroupArg: %v", va.Res) } - if len(ga.Inner) != 3 { + if len(ga.Inner) != 4 { t.Fatalf("wrong number of struct args %v", len(ga.Inner)) } mask := ga.Inner[0].(*ConstArg).Val diff --git a/prog/types.go b/prog/types.go index 0d6fa1596..5f2360946 100644 --- a/prog/types.go +++ b/prog/types.go @@ -110,6 +110,7 @@ const ( OperatorCompareEq BinaryOperator = iota OperatorCompareNeq OperatorBinaryAnd + OperatorOr ) type BinaryExpression struct { -- cgit mrf-deployment