gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/bpf/bpf_test.go (about)

     1  // Copyright 2023 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package bpf
    16  
    17  import (
    18  	"testing"
    19  )
    20  
    21  func TestEqual(t *testing.T) {
    22  	for _, test := range []struct {
    23  		name string
    24  		a, b Instruction
    25  		want bool
    26  	}{
    27  		{
    28  			name: "empty instructions",
    29  			want: true,
    30  		},
    31  		{
    32  			name: "two different invalid instructions",
    33  			a: Instruction{
    34  				OpCode: 0xffff,
    35  			},
    36  			b: Instruction{
    37  				OpCode: 0xfffe,
    38  			},
    39  			want: false,
    40  		},
    41  		{
    42  			name: "two loads from different offsets",
    43  			a: Instruction{
    44  				OpCode: Ld | Imm | W,
    45  				K:      1234,
    46  			},
    47  			b: Instruction{
    48  				OpCode: Ld | Imm | W,
    49  				K:      5678,
    50  			},
    51  			want: false,
    52  		},
    53  		{
    54  			name: "two loads from same offsets but different source",
    55  			a: Instruction{
    56  				OpCode: Ld | Mem | W,
    57  				K:      1234,
    58  			},
    59  			b: Instruction{
    60  				OpCode: Ld | Imm | W,
    61  				K:      1234,
    62  			},
    63  			want: false,
    64  		},
    65  		{
    66  			name: "two loads from same offsets but different conditional jump fields",
    67  			a: Instruction{
    68  				OpCode:     Ld | Mem | W,
    69  				K:          1234,
    70  				JumpIfTrue: 12,
    71  			},
    72  			b: Instruction{
    73  				OpCode: Ld | Mem | W,
    74  				K:      1234,
    75  			},
    76  			want: true,
    77  		},
    78  		{
    79  			name: "two length loads",
    80  			a: Instruction{
    81  				OpCode:     Ld | Len | W,
    82  				K:          1234,
    83  				JumpIfTrue: 12,
    84  			},
    85  			b: Instruction{
    86  				OpCode:     Ld | Len | W,
    87  				K:          5678,
    88  				JumpIfTrue: 99,
    89  			},
    90  			want: true,
    91  		},
    92  		{
    93  			name: "two length loads in different registers",
    94  			a: Instruction{
    95  				OpCode:     Ld | Len | W,
    96  				K:          1234,
    97  				JumpIfTrue: 12,
    98  			},
    99  			b: Instruction{
   100  				OpCode:     Ldx | Len | W,
   101  				K:          1234,
   102  				JumpIfTrue: 12,
   103  			},
   104  			want: false,
   105  		},
   106  		{
   107  			name: "two stores at different offsets",
   108  			a: Instruction{
   109  				OpCode: St,
   110  				K:      1234,
   111  			},
   112  			b: Instruction{
   113  				OpCode: St,
   114  				K:      5678,
   115  			},
   116  			want: false,
   117  		},
   118  		{
   119  			name: "two stores at same offsets but different source",
   120  			a: Instruction{
   121  				OpCode: St,
   122  				K:      1234,
   123  			},
   124  			b: Instruction{
   125  				OpCode: Stx,
   126  				K:      1234,
   127  			},
   128  			want: false,
   129  		},
   130  		{
   131  			name: "two stores at same offsets but different conditional jump fields",
   132  			a: Instruction{
   133  				OpCode:     St,
   134  				K:          1234,
   135  				JumpIfTrue: 12,
   136  			},
   137  			b: Instruction{
   138  				OpCode: St,
   139  				K:      1234,
   140  			},
   141  			want: true,
   142  		},
   143  		{
   144  			name: "two negation ALUs with different other fields",
   145  			a: Instruction{
   146  				OpCode:     Alu | Neg,
   147  				K:          1234,
   148  				JumpIfTrue: 12,
   149  			},
   150  			b: Instruction{
   151  				OpCode:     Alu | Neg,
   152  				K:          5678,
   153  				JumpIfTrue: 34,
   154  			},
   155  			want: true,
   156  		},
   157  		{
   158  			name: "two 'add K' ALUs with different K",
   159  			a: Instruction{
   160  				OpCode:     Alu | Add | K,
   161  				K:          1234,
   162  				JumpIfTrue: 12,
   163  			},
   164  			b: Instruction{
   165  				OpCode:     Alu | Add | K,
   166  				K:          5678,
   167  				JumpIfTrue: 34,
   168  			},
   169  			want: false,
   170  		},
   171  		{
   172  			name: "two 'add X' ALUs with different K",
   173  			a: Instruction{
   174  				OpCode:     Alu | Add | X,
   175  				K:          1234,
   176  				JumpIfTrue: 12,
   177  			},
   178  			b: Instruction{
   179  				OpCode:     Alu | Add | X,
   180  				K:          5678,
   181  				JumpIfTrue: 34,
   182  			},
   183  			want: true,
   184  		},
   185  		{
   186  			name: "two 'return A' instructions with different K",
   187  			a: Instruction{
   188  				OpCode:     Ret | A,
   189  				K:          1234,
   190  				JumpIfTrue: 12,
   191  			},
   192  			b: Instruction{
   193  				OpCode:     Ret | A,
   194  				K:          5678,
   195  				JumpIfTrue: 34,
   196  			},
   197  			want: true,
   198  		},
   199  		{
   200  			name: "two 'return K' instructions with same K",
   201  			a: Instruction{
   202  				OpCode:     Ret | K,
   203  				K:          1234,
   204  				JumpIfTrue: 12,
   205  			},
   206  			b: Instruction{
   207  				OpCode:     Ret | K,
   208  				K:          1234,
   209  				JumpIfTrue: 34,
   210  			},
   211  			want: true,
   212  		},
   213  		{
   214  			name: "two 'return K' instructions with different K",
   215  			a: Instruction{
   216  				OpCode: Ret | K,
   217  				K:      1234,
   218  			},
   219  			b: Instruction{
   220  				OpCode: Ret | K,
   221  				K:      5678,
   222  			},
   223  			want: false,
   224  		},
   225  		{
   226  			name: "two unconditional jumps with different K",
   227  			a: Instruction{
   228  				OpCode: Jmp | Ja,
   229  				K:      1234,
   230  			},
   231  			b: Instruction{
   232  				OpCode: Jmp | Ja,
   233  				K:      5678,
   234  			},
   235  			want: false,
   236  		},
   237  		{
   238  			name: "two unconditional jumps with same K",
   239  			a: Instruction{
   240  				OpCode:     Jmp | Ja,
   241  				K:          1234,
   242  				JumpIfTrue: 12,
   243  			},
   244  			b: Instruction{
   245  				OpCode:     Jmp | Ja,
   246  				K:          1234,
   247  				JumpIfTrue: 34,
   248  			},
   249  			want: true,
   250  		},
   251  		{
   252  			name: "two conditional jumps using K with same K",
   253  			a: Instruction{
   254  				OpCode:      Jmp | Jgt | K,
   255  				K:           1234,
   256  				JumpIfTrue:  12,
   257  				JumpIfFalse: 21,
   258  			},
   259  			b: Instruction{
   260  				OpCode:      Jmp | Jgt | K,
   261  				K:           1234,
   262  				JumpIfTrue:  12,
   263  				JumpIfFalse: 21,
   264  			},
   265  			want: true,
   266  		},
   267  		{
   268  			name: "two conditional jumps using K with different K",
   269  			a: Instruction{
   270  				OpCode:      Jmp | Jgt | K,
   271  				K:           1234,
   272  				JumpIfTrue:  12,
   273  				JumpIfFalse: 21,
   274  			},
   275  			b: Instruction{
   276  				OpCode:      Jmp | Jgt | K,
   277  				K:           5678,
   278  				JumpIfTrue:  12,
   279  				JumpIfFalse: 21,
   280  			},
   281  			want: false,
   282  		},
   283  		{
   284  			name: "two conditional jumps using X with different K",
   285  			a: Instruction{
   286  				OpCode:      Jmp | Jgt | X,
   287  				K:           1234,
   288  				JumpIfTrue:  12,
   289  				JumpIfFalse: 21,
   290  			},
   291  			b: Instruction{
   292  				OpCode:      Jmp | Jgt | X,
   293  				K:           5678,
   294  				JumpIfTrue:  12,
   295  				JumpIfFalse: 21,
   296  			},
   297  			want: true,
   298  		},
   299  		{
   300  			name: "two conditional jumps with different 'true' jump target",
   301  			a: Instruction{
   302  				OpCode:      Jmp | Jgt | X,
   303  				K:           1234,
   304  				JumpIfTrue:  12,
   305  				JumpIfFalse: 21,
   306  			},
   307  			b: Instruction{
   308  				OpCode:      Jmp | Jgt | X,
   309  				K:           1234,
   310  				JumpIfTrue:  99,
   311  				JumpIfFalse: 21,
   312  			},
   313  			want: false,
   314  		},
   315  		{
   316  			name: "two conditional jumps with different 'false' jump target",
   317  			a: Instruction{
   318  				OpCode:      Jmp | Jgt | X,
   319  				K:           1234,
   320  				JumpIfTrue:  12,
   321  				JumpIfFalse: 21,
   322  			},
   323  			b: Instruction{
   324  				OpCode:      Jmp | Jgt | X,
   325  				K:           1234,
   326  				JumpIfTrue:  12,
   327  				JumpIfFalse: 99,
   328  			},
   329  			want: false,
   330  		},
   331  		{
   332  			name: "two txa instructions",
   333  			a: Instruction{
   334  				OpCode:      Misc | Txa,
   335  				K:           1234,
   336  				JumpIfTrue:  12,
   337  				JumpIfFalse: 21,
   338  			},
   339  			b: Instruction{
   340  				OpCode:      Misc | Txa,
   341  				K:           5678,
   342  				JumpIfTrue:  34,
   343  				JumpIfFalse: 42,
   344  			},
   345  			want: true,
   346  		},
   347  		{
   348  			name: "two tax instructions",
   349  			a: Instruction{
   350  				OpCode:      Misc | Tax,
   351  				K:           1234,
   352  				JumpIfTrue:  12,
   353  				JumpIfFalse: 21,
   354  			},
   355  			b: Instruction{
   356  				OpCode:      Misc | Tax,
   357  				K:           5678,
   358  				JumpIfTrue:  34,
   359  				JumpIfFalse: 42,
   360  			},
   361  			want: true,
   362  		},
   363  		{
   364  			name: "two different misc instructions",
   365  			a: Instruction{
   366  				OpCode:      Misc | Txa,
   367  				K:           1234,
   368  				JumpIfTrue:  12,
   369  				JumpIfFalse: 21,
   370  			},
   371  			b: Instruction{
   372  				OpCode:      Misc | Tax,
   373  				K:           1234,
   374  				JumpIfTrue:  12,
   375  				JumpIfFalse: 21,
   376  			},
   377  			want: false,
   378  		},
   379  	} {
   380  		t.Run(test.name, func(t *testing.T) {
   381  			as := test.a.String()
   382  			bs := test.b.String()
   383  			got := test.a.Equal(test.b)
   384  			if got != test.want {
   385  				t.Errorf("%v.Equal(%v) = %v, want %v", as, bs, got, test.want)
   386  			}
   387  			if reverse := test.b.Equal(test.a); reverse != got {
   388  				t.Errorf("%v.Equal(%v) [%v] != %v.Equal(%v) [%v]", as, bs, got, bs, as, reverse)
   389  			}
   390  			if !t.Failed() && !got && test.a == test.b {
   391  				t.Errorf("%v == %v, yet %v.Equal(%v) is false", as, bs, as, bs)
   392  			}
   393  		})
   394  	}
   395  }