@@ -929,3 +929,115 @@ func TestUprobePtRegsPreloadSubstringIgnCaseNotMatch(t *testing.T) {
929929 false , /* single */
930930 )
931931}
932+
933+ func testUprobePtRegsPreloadSubstringOverride (t * testing.T , single bool ) {
934+ if ! bpf .HasKfunc ("bpf_copy_from_user_str" ) {
935+ t .Skip ("skipping, no string preload support" )
936+ }
937+ if ! bpf .HasUprobeRegsChange () {
938+ t .Skip ("skipping, no regs change support in kernel" )
939+ }
940+ if ! bpf .HasKfunc ("bpf_strnstr" ) {
941+ t .Skip ("skipping, no bpf_strnstr kfunc in kernel" )
942+ }
943+
944+ testBinary := testutils .RepoRootPath ("contrib/tester-progs/regs-override" )
945+
946+ // Put uprobe in test_3 function at:
947+ //
948+ // static const char *test_3_string = "test_3_string";
949+ //
950+ // "push %%rbp\n" /* +0 55 */
951+ // "mov %%rsp, %%rbp\n" /* +1 48 89 e5 */
952+ // "mov %[str], %%rdi\n" /* +4 48 8b 3d 96 2e 00 00 */
953+ // "pop %%rbp\n" /* +11 5d */
954+ // "mov $0x0,%%rax\n" /* +12 48 c7 c0 00 00 00 00 */
955+ // --> "mov $0xff,%%rax\n" /* +19 48 c7 c0 ff 00 00 00 */
956+ // "ret\n" /* +26 c3 */
957+ // :
958+ // : [str] "m" (test_3_string)
959+ //
960+ // Make sure we retrieve data with eax value (1) as int argument
961+ // and match the expected value via matchData.
962+
963+ options := ""
964+ if single {
965+ options = ` options:
966+ - name: "disable-uprobe-multi"
967+ value: "1"`
968+ }
969+
970+ pathHook := `
971+ apiVersion: cilium.io/v1alpha1
972+ kind: TracingPolicy
973+ metadata:
974+ name: "uprobe"
975+ spec:
976+ ` + options + `
977+ uprobes:
978+ - path: "` + testBinary + `"
979+ symbols:
980+ - "test_3+19"
981+ data:
982+ - index: 0
983+ type: "string"
984+ source: "pt_regs"
985+ resolve: "rdi"
986+ selectors:
987+ - matchData:
988+ - index: 0
989+ operator: "SubString"
990+ values:
991+ - "_3_"
992+ matchActions:
993+ - action: Override
994+ argRegs:
995+ - "rip=7%rip"
996+ `
997+
998+ pathConfigHook := []byte (pathHook )
999+ err := os .WriteFile (testConfigFile , pathConfigHook , 0644 )
1000+ if err != nil {
1001+ t .Fatalf ("writeFile(%s): err %s" , testConfigFile , err )
1002+ }
1003+
1004+ upChecker := ec .NewProcessUprobeChecker ("UPROBE_DATA_MATCH" ).
1005+ WithProcess (ec .NewProcessChecker ().
1006+ WithBinary (sm .Full (testBinary ))).
1007+ WithSymbol (sm .Full ("test_3+19" )).
1008+ WithData (ec .NewKprobeArgumentListMatcher ().
1009+ WithOperator (lc .Ordered ).
1010+ WithValues (
1011+ ec .NewKprobeArgumentChecker ().WithStringArg (sm .Full ("test_3_string_CASE" )),
1012+ ))
1013+
1014+ checker := ec .NewUnorderedEventChecker (upChecker )
1015+
1016+ var doneWG , readyWG sync.WaitGroup
1017+ defer doneWG .Wait ()
1018+
1019+ ctx , cancel := context .WithTimeout (context .Background (), tus .Conf ().CmdWaitTime )
1020+ defer cancel ()
1021+
1022+ obs , err := observertesthelper .GetDefaultObserverWithFile (t , ctx , testConfigFile , tus .Conf ().TetragonLib )
1023+ if err != nil {
1024+ t .Fatalf ("GetDefaultObserverWithFile error: %s" , err )
1025+ }
1026+ observertesthelper .LoopEvents (ctx , t , & doneWG , & readyWG , obs )
1027+ readyWG .Wait ()
1028+
1029+ cmd := exec .Command (testBinary , "3" )
1030+ require .NoError (t , cmd .Run ())
1031+ require .Equal (t , 0 , cmd .ProcessState .ExitCode ())
1032+
1033+ err = jsonchecker .JsonTestCheck (t , checker )
1034+ require .NoError (t , err )
1035+ }
1036+
1037+ func TestUprobePtRegsPreloadSubstringOverrideSingle (t * testing.T ) {
1038+ testUprobePtRegsPreloadSubstringOverride (t , true )
1039+ }
1040+
1041+ func TestUprobePtRegsPreloadSubstringOverrideMulti (t * testing.T ) {
1042+ testUprobePtRegsPreloadSubstringOverride (t , false )
1043+ }
0 commit comments