From aae45f197e988266985b8c20a141180e1c145b45 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 13 Jan 2025 16:59:35 +0000 Subject: [PATCH 01/11] tetragon: Update ebpf version kprobe session Signed-off-by: Jiri Olsa --- go.mod | 2 +- go.sum | 4 +- vendor/github.com/cilium/ebpf/asm/func.go | 6 -- .../github.com/cilium/ebpf/asm/func_string.go | 5 +- .../cilium/ebpf/attachtype_string.go | 5 +- vendor/github.com/cilium/ebpf/elf_sections.go | 2 + .../github.com/cilium/ebpf/features/prog.go | 44 ++++++++--- .../cilium/ebpf/internal/sys/types.go | 51 ++++++++---- .../cilium/ebpf/link/kprobe_multi.go | 78 +++++++++++++++++-- vendor/github.com/cilium/ebpf/types.go | 1 + vendor/modules.txt | 2 +- 11 files changed, 154 insertions(+), 46 deletions(-) diff --git a/go.mod b/go.mod index 795e8726a1b..473806fc8fd 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/alecthomas/kong v1.6.1 github.com/bombsimon/logrusr/v4 v4.1.0 github.com/cilium/cilium v1.17.0-rc.1 - github.com/cilium/ebpf v0.17.1 + github.com/cilium/ebpf v0.17.2-0.20250113160858-6d6c5e322573 github.com/cilium/little-vm-helper v0.0.19 github.com/cilium/lumberjack/v2 v2.4.1 github.com/cilium/tetragon/api v0.0.0-00010101000000-000000000000 diff --git a/go.sum b/go.sum index 08eb30df952..d8619482d2e 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cilium/cilium v1.17.0-rc.1 h1:jUiwwJ2qyajW2YY8/sOqJSy8enMhClG4FT1Dq6MELTU= github.com/cilium/cilium v1.17.0-rc.1/go.mod h1:UAK2rIorqcHHxtkCG33wcQ++jAtDUknXCa42hOvhrR4= -github.com/cilium/ebpf v0.17.1 h1:G8mzU81R2JA1nE5/8SRubzqvBMmAmri2VL8BIZPWvV0= -github.com/cilium/ebpf v0.17.1/go.mod h1:vay2FaYSmIlv3r8dNACd4mW/OCaZLJKJOo+IHBvCIO8= +github.com/cilium/ebpf v0.17.2-0.20250113160858-6d6c5e322573 h1:gj9/PN7T0a/RGgVAYtWH0JrzQU/KALDFuswfSsiReEw= +github.com/cilium/ebpf v0.17.2-0.20250113160858-6d6c5e322573/go.mod h1:9X5VAsIOck/nCAp0+nCSVzub1Q7x+zKXXItTMYfNE+E= github.com/cilium/hive v0.0.0-20241213121623-605c1412b9b3 h1:RfmUH1ouzj0LzORYJRhp43e1rlGpx6GNv4NIRUakU2w= github.com/cilium/hive v0.0.0-20241213121623-605c1412b9b3/go.mod h1:pI2GJ1n3SLKIQVFrKF7W6A6gb6BQkZ+3Hp4PAEo5SuI= github.com/cilium/little-vm-helper v0.0.19 h1:eJeJM/03MGLrLUXXTBDZo2JoX5cIbm5+9iWjoHgpy/M= diff --git a/vendor/github.com/cilium/ebpf/asm/func.go b/vendor/github.com/cilium/ebpf/asm/func.go index 84a40b2277f..7a59acf3830 100644 --- a/vendor/github.com/cilium/ebpf/asm/func.go +++ b/vendor/github.com/cilium/ebpf/asm/func.go @@ -5,10 +5,6 @@ package asm // BuiltinFunc is a built-in eBPF function. type BuiltinFunc int32 -func (_ BuiltinFunc) Max() BuiltinFunc { - return maxBuiltinFunc - 1 -} - // eBPF built-in functions // // You can regenerate this list using the following gawk script: @@ -237,8 +233,6 @@ const ( FnUserRingbufDrain FnCgrpStorageGet FnCgrpStorageDelete - - maxBuiltinFunc ) // Call emits a function call. diff --git a/vendor/github.com/cilium/ebpf/asm/func_string.go b/vendor/github.com/cilium/ebpf/asm/func_string.go index 47150bc4f2d..6c4ba378926 100644 --- a/vendor/github.com/cilium/ebpf/asm/func_string.go +++ b/vendor/github.com/cilium/ebpf/asm/func_string.go @@ -220,12 +220,11 @@ func _() { _ = x[FnUserRingbufDrain-209] _ = x[FnCgrpStorageGet-210] _ = x[FnCgrpStorageDelete-211] - _ = x[maxBuiltinFunc-212] } -const _BuiltinFunc_name = "FnUnspecFnMapLookupElemFnMapUpdateElemFnMapDeleteElemFnProbeReadFnKtimeGetNsFnTracePrintkFnGetPrandomU32FnGetSmpProcessorIdFnSkbStoreBytesFnL3CsumReplaceFnL4CsumReplaceFnTailCallFnCloneRedirectFnGetCurrentPidTgidFnGetCurrentUidGidFnGetCurrentCommFnGetCgroupClassidFnSkbVlanPushFnSkbVlanPopFnSkbGetTunnelKeyFnSkbSetTunnelKeyFnPerfEventReadFnRedirectFnGetRouteRealmFnPerfEventOutputFnSkbLoadBytesFnGetStackidFnCsumDiffFnSkbGetTunnelOptFnSkbSetTunnelOptFnSkbChangeProtoFnSkbChangeTypeFnSkbUnderCgroupFnGetHashRecalcFnGetCurrentTaskFnProbeWriteUserFnCurrentTaskUnderCgroupFnSkbChangeTailFnSkbPullDataFnCsumUpdateFnSetHashInvalidFnGetNumaNodeIdFnSkbChangeHeadFnXdpAdjustHeadFnProbeReadStrFnGetSocketCookieFnGetSocketUidFnSetHashFnSetsockoptFnSkbAdjustRoomFnRedirectMapFnSkRedirectMapFnSockMapUpdateFnXdpAdjustMetaFnPerfEventReadValueFnPerfProgReadValueFnGetsockoptFnOverrideReturnFnSockOpsCbFlagsSetFnMsgRedirectMapFnMsgApplyBytesFnMsgCorkBytesFnMsgPullDataFnBindFnXdpAdjustTailFnSkbGetXfrmStateFnGetStackFnSkbLoadBytesRelativeFnFibLookupFnSockHashUpdateFnMsgRedirectHashFnSkRedirectHashFnLwtPushEncapFnLwtSeg6StoreBytesFnLwtSeg6AdjustSrhFnLwtSeg6ActionFnRcRepeatFnRcKeydownFnSkbCgroupIdFnGetCurrentCgroupIdFnGetLocalStorageFnSkSelectReuseportFnSkbAncestorCgroupIdFnSkLookupTcpFnSkLookupUdpFnSkReleaseFnMapPushElemFnMapPopElemFnMapPeekElemFnMsgPushDataFnMsgPopDataFnRcPointerRelFnSpinLockFnSpinUnlockFnSkFullsockFnTcpSockFnSkbEcnSetCeFnGetListenerSockFnSkcLookupTcpFnTcpCheckSyncookieFnSysctlGetNameFnSysctlGetCurrentValueFnSysctlGetNewValueFnSysctlSetNewValueFnStrtolFnStrtoulFnSkStorageGetFnSkStorageDeleteFnSendSignalFnTcpGenSyncookieFnSkbOutputFnProbeReadUserFnProbeReadKernelFnProbeReadUserStrFnProbeReadKernelStrFnTcpSendAckFnSendSignalThreadFnJiffies64FnReadBranchRecordsFnGetNsCurrentPidTgidFnXdpOutputFnGetNetnsCookieFnGetCurrentAncestorCgroupIdFnSkAssignFnKtimeGetBootNsFnSeqPrintfFnSeqWriteFnSkCgroupIdFnSkAncestorCgroupIdFnRingbufOutputFnRingbufReserveFnRingbufSubmitFnRingbufDiscardFnRingbufQueryFnCsumLevelFnSkcToTcp6SockFnSkcToTcpSockFnSkcToTcpTimewaitSockFnSkcToTcpRequestSockFnSkcToUdp6SockFnGetTaskStackFnLoadHdrOptFnStoreHdrOptFnReserveHdrOptFnInodeStorageGetFnInodeStorageDeleteFnDPathFnCopyFromUserFnSnprintfBtfFnSeqPrintfBtfFnSkbCgroupClassidFnRedirectNeighFnPerCpuPtrFnThisCpuPtrFnRedirectPeerFnTaskStorageGetFnTaskStorageDeleteFnGetCurrentTaskBtfFnBprmOptsSetFnKtimeGetCoarseNsFnImaInodeHashFnSockFromFileFnCheckMtuFnForEachMapElemFnSnprintfFnSysBpfFnBtfFindByNameKindFnSysCloseFnTimerInitFnTimerSetCallbackFnTimerStartFnTimerCancelFnGetFuncIpFnGetAttachCookieFnTaskPtRegsFnGetBranchSnapshotFnTraceVprintkFnSkcToUnixSockFnKallsymsLookupNameFnFindVmaFnLoopFnStrncmpFnGetFuncArgFnGetFuncRetFnGetFuncArgCntFnGetRetvalFnSetRetvalFnXdpGetBuffLenFnXdpLoadBytesFnXdpStoreBytesFnCopyFromUserTaskFnSkbSetTstampFnImaFileHashFnKptrXchgFnMapLookupPercpuElemFnSkcToMptcpSockFnDynptrFromMemFnRingbufReserveDynptrFnRingbufSubmitDynptrFnRingbufDiscardDynptrFnDynptrReadFnDynptrWriteFnDynptrDataFnTcpRawGenSyncookieIpv4FnTcpRawGenSyncookieIpv6FnTcpRawCheckSyncookieIpv4FnTcpRawCheckSyncookieIpv6FnKtimeGetTaiNsFnUserRingbufDrainFnCgrpStorageGetFnCgrpStorageDeletemaxBuiltinFunc" +const _BuiltinFunc_name = "FnUnspecFnMapLookupElemFnMapUpdateElemFnMapDeleteElemFnProbeReadFnKtimeGetNsFnTracePrintkFnGetPrandomU32FnGetSmpProcessorIdFnSkbStoreBytesFnL3CsumReplaceFnL4CsumReplaceFnTailCallFnCloneRedirectFnGetCurrentPidTgidFnGetCurrentUidGidFnGetCurrentCommFnGetCgroupClassidFnSkbVlanPushFnSkbVlanPopFnSkbGetTunnelKeyFnSkbSetTunnelKeyFnPerfEventReadFnRedirectFnGetRouteRealmFnPerfEventOutputFnSkbLoadBytesFnGetStackidFnCsumDiffFnSkbGetTunnelOptFnSkbSetTunnelOptFnSkbChangeProtoFnSkbChangeTypeFnSkbUnderCgroupFnGetHashRecalcFnGetCurrentTaskFnProbeWriteUserFnCurrentTaskUnderCgroupFnSkbChangeTailFnSkbPullDataFnCsumUpdateFnSetHashInvalidFnGetNumaNodeIdFnSkbChangeHeadFnXdpAdjustHeadFnProbeReadStrFnGetSocketCookieFnGetSocketUidFnSetHashFnSetsockoptFnSkbAdjustRoomFnRedirectMapFnSkRedirectMapFnSockMapUpdateFnXdpAdjustMetaFnPerfEventReadValueFnPerfProgReadValueFnGetsockoptFnOverrideReturnFnSockOpsCbFlagsSetFnMsgRedirectMapFnMsgApplyBytesFnMsgCorkBytesFnMsgPullDataFnBindFnXdpAdjustTailFnSkbGetXfrmStateFnGetStackFnSkbLoadBytesRelativeFnFibLookupFnSockHashUpdateFnMsgRedirectHashFnSkRedirectHashFnLwtPushEncapFnLwtSeg6StoreBytesFnLwtSeg6AdjustSrhFnLwtSeg6ActionFnRcRepeatFnRcKeydownFnSkbCgroupIdFnGetCurrentCgroupIdFnGetLocalStorageFnSkSelectReuseportFnSkbAncestorCgroupIdFnSkLookupTcpFnSkLookupUdpFnSkReleaseFnMapPushElemFnMapPopElemFnMapPeekElemFnMsgPushDataFnMsgPopDataFnRcPointerRelFnSpinLockFnSpinUnlockFnSkFullsockFnTcpSockFnSkbEcnSetCeFnGetListenerSockFnSkcLookupTcpFnTcpCheckSyncookieFnSysctlGetNameFnSysctlGetCurrentValueFnSysctlGetNewValueFnSysctlSetNewValueFnStrtolFnStrtoulFnSkStorageGetFnSkStorageDeleteFnSendSignalFnTcpGenSyncookieFnSkbOutputFnProbeReadUserFnProbeReadKernelFnProbeReadUserStrFnProbeReadKernelStrFnTcpSendAckFnSendSignalThreadFnJiffies64FnReadBranchRecordsFnGetNsCurrentPidTgidFnXdpOutputFnGetNetnsCookieFnGetCurrentAncestorCgroupIdFnSkAssignFnKtimeGetBootNsFnSeqPrintfFnSeqWriteFnSkCgroupIdFnSkAncestorCgroupIdFnRingbufOutputFnRingbufReserveFnRingbufSubmitFnRingbufDiscardFnRingbufQueryFnCsumLevelFnSkcToTcp6SockFnSkcToTcpSockFnSkcToTcpTimewaitSockFnSkcToTcpRequestSockFnSkcToUdp6SockFnGetTaskStackFnLoadHdrOptFnStoreHdrOptFnReserveHdrOptFnInodeStorageGetFnInodeStorageDeleteFnDPathFnCopyFromUserFnSnprintfBtfFnSeqPrintfBtfFnSkbCgroupClassidFnRedirectNeighFnPerCpuPtrFnThisCpuPtrFnRedirectPeerFnTaskStorageGetFnTaskStorageDeleteFnGetCurrentTaskBtfFnBprmOptsSetFnKtimeGetCoarseNsFnImaInodeHashFnSockFromFileFnCheckMtuFnForEachMapElemFnSnprintfFnSysBpfFnBtfFindByNameKindFnSysCloseFnTimerInitFnTimerSetCallbackFnTimerStartFnTimerCancelFnGetFuncIpFnGetAttachCookieFnTaskPtRegsFnGetBranchSnapshotFnTraceVprintkFnSkcToUnixSockFnKallsymsLookupNameFnFindVmaFnLoopFnStrncmpFnGetFuncArgFnGetFuncRetFnGetFuncArgCntFnGetRetvalFnSetRetvalFnXdpGetBuffLenFnXdpLoadBytesFnXdpStoreBytesFnCopyFromUserTaskFnSkbSetTstampFnImaFileHashFnKptrXchgFnMapLookupPercpuElemFnSkcToMptcpSockFnDynptrFromMemFnRingbufReserveDynptrFnRingbufSubmitDynptrFnRingbufDiscardDynptrFnDynptrReadFnDynptrWriteFnDynptrDataFnTcpRawGenSyncookieIpv4FnTcpRawGenSyncookieIpv6FnTcpRawCheckSyncookieIpv4FnTcpRawCheckSyncookieIpv6FnKtimeGetTaiNsFnUserRingbufDrainFnCgrpStorageGetFnCgrpStorageDelete" -var _BuiltinFunc_index = [...]uint16{0, 8, 23, 38, 53, 64, 76, 89, 104, 123, 138, 153, 168, 178, 193, 212, 230, 246, 264, 277, 289, 306, 323, 338, 348, 363, 380, 394, 406, 416, 433, 450, 466, 481, 497, 512, 528, 544, 568, 583, 596, 608, 624, 639, 654, 669, 683, 700, 714, 723, 735, 750, 763, 778, 793, 808, 828, 847, 859, 875, 894, 910, 925, 939, 952, 958, 973, 990, 1000, 1022, 1033, 1049, 1066, 1082, 1096, 1115, 1133, 1148, 1158, 1169, 1182, 1202, 1219, 1238, 1259, 1272, 1285, 1296, 1309, 1321, 1334, 1347, 1359, 1373, 1383, 1395, 1407, 1416, 1429, 1446, 1460, 1479, 1494, 1517, 1536, 1555, 1563, 1572, 1586, 1603, 1615, 1632, 1643, 1658, 1675, 1693, 1713, 1725, 1743, 1754, 1773, 1794, 1805, 1821, 1849, 1859, 1875, 1886, 1896, 1908, 1928, 1943, 1959, 1974, 1990, 2004, 2015, 2030, 2044, 2066, 2087, 2102, 2116, 2128, 2141, 2156, 2173, 2193, 2200, 2214, 2227, 2241, 2259, 2274, 2285, 2297, 2311, 2327, 2346, 2365, 2378, 2396, 2410, 2424, 2434, 2450, 2460, 2468, 2487, 2497, 2508, 2526, 2538, 2551, 2562, 2579, 2591, 2610, 2624, 2639, 2659, 2668, 2674, 2683, 2695, 2707, 2722, 2733, 2744, 2759, 2773, 2788, 2806, 2820, 2833, 2843, 2864, 2880, 2895, 2917, 2938, 2960, 2972, 2985, 2997, 3021, 3045, 3071, 3097, 3112, 3130, 3146, 3165, 3179} +var _BuiltinFunc_index = [...]uint16{0, 8, 23, 38, 53, 64, 76, 89, 104, 123, 138, 153, 168, 178, 193, 212, 230, 246, 264, 277, 289, 306, 323, 338, 348, 363, 380, 394, 406, 416, 433, 450, 466, 481, 497, 512, 528, 544, 568, 583, 596, 608, 624, 639, 654, 669, 683, 700, 714, 723, 735, 750, 763, 778, 793, 808, 828, 847, 859, 875, 894, 910, 925, 939, 952, 958, 973, 990, 1000, 1022, 1033, 1049, 1066, 1082, 1096, 1115, 1133, 1148, 1158, 1169, 1182, 1202, 1219, 1238, 1259, 1272, 1285, 1296, 1309, 1321, 1334, 1347, 1359, 1373, 1383, 1395, 1407, 1416, 1429, 1446, 1460, 1479, 1494, 1517, 1536, 1555, 1563, 1572, 1586, 1603, 1615, 1632, 1643, 1658, 1675, 1693, 1713, 1725, 1743, 1754, 1773, 1794, 1805, 1821, 1849, 1859, 1875, 1886, 1896, 1908, 1928, 1943, 1959, 1974, 1990, 2004, 2015, 2030, 2044, 2066, 2087, 2102, 2116, 2128, 2141, 2156, 2173, 2193, 2200, 2214, 2227, 2241, 2259, 2274, 2285, 2297, 2311, 2327, 2346, 2365, 2378, 2396, 2410, 2424, 2434, 2450, 2460, 2468, 2487, 2497, 2508, 2526, 2538, 2551, 2562, 2579, 2591, 2610, 2624, 2639, 2659, 2668, 2674, 2683, 2695, 2707, 2722, 2733, 2744, 2759, 2773, 2788, 2806, 2820, 2833, 2843, 2864, 2880, 2895, 2917, 2938, 2960, 2972, 2985, 2997, 3021, 3045, 3071, 3097, 3112, 3130, 3146, 3165} func (i BuiltinFunc) String() string { if i < 0 || i >= BuiltinFunc(len(_BuiltinFunc_index)-1) { diff --git a/vendor/github.com/cilium/ebpf/attachtype_string.go b/vendor/github.com/cilium/ebpf/attachtype_string.go index bece896bb61..84445a32562 100644 --- a/vendor/github.com/cilium/ebpf/attachtype_string.go +++ b/vendor/github.com/cilium/ebpf/attachtype_string.go @@ -52,6 +52,7 @@ func _() { _ = x[AttachSkReuseportSelectOrMigrate-40] _ = x[AttachPerfEvent-41] _ = x[AttachTraceKprobeMulti-42] + _ = x[AttachTraceKprobeSession-56] _ = x[AttachLSMCgroup-43] _ = x[AttachStructOps-44] _ = x[AttachNetfilter-45] @@ -67,9 +68,9 @@ func _() { _ = x[AttachNetkitPeer-55] } -const _AttachType_name = "NoneCGroupInetEgressCGroupInetSockCreateCGroupSockOpsSkSKBStreamParserSkSKBStreamVerdictCGroupDeviceSkMsgVerdictCGroupInet4BindCGroupInet6BindCGroupInet4ConnectCGroupInet6ConnectCGroupInet4PostBindCGroupInet6PostBindCGroupUDP4SendmsgCGroupUDP6SendmsgLircMode2FlowDissectorCGroupSysctlCGroupUDP4RecvmsgCGroupUDP6RecvmsgCGroupGetsockoptCGroupSetsockoptTraceRawTpTraceFEntryTraceFExitModifyReturnLSMMacTraceIterCgroupInet4GetPeernameCgroupInet6GetPeernameCgroupInet4GetSocknameCgroupInet6GetSocknameXDPDevMapCgroupInetSockReleaseXDPCPUMapSkLookupXDPSkSKBVerdictSkReuseportSelectSkReuseportSelectOrMigratePerfEventTraceKprobeMultiLSMCgroupStructOpsNetfilterTCXIngressTCXEgressTraceUprobeMultiCgroupUnixConnectCgroupUnixSendmsgCgroupUnixRecvmsgCgroupUnixGetpeernameCgroupUnixGetsocknameNetkitPrimaryNetkitPeer" +const _AttachType_name = "NoneCGroupInetEgressCGroupInetSockCreateCGroupSockOpsSkSKBStreamParserSkSKBStreamVerdictCGroupDeviceSkMsgVerdictCGroupInet4BindCGroupInet6BindCGroupInet4ConnectCGroupInet6ConnectCGroupInet4PostBindCGroupInet6PostBindCGroupUDP4SendmsgCGroupUDP6SendmsgLircMode2FlowDissectorCGroupSysctlCGroupUDP4RecvmsgCGroupUDP6RecvmsgCGroupGetsockoptCGroupSetsockoptTraceRawTpTraceFEntryTraceFExitModifyReturnLSMMacTraceIterCgroupInet4GetPeernameCgroupInet6GetPeernameCgroupInet4GetSocknameCgroupInet6GetSocknameXDPDevMapCgroupInetSockReleaseXDPCPUMapSkLookupXDPSkSKBVerdictSkReuseportSelectSkReuseportSelectOrMigratePerfEventTraceKprobeMultiLSMCgroupStructOpsNetfilterTCXIngressTCXEgressTraceUprobeMultiCgroupUnixConnectCgroupUnixSendmsgCgroupUnixRecvmsgCgroupUnixGetpeernameCgroupUnixGetsocknameNetkitPrimaryNetkitPeerTraceKprobeSession" -var _AttachType_index = [...]uint16{0, 4, 20, 40, 53, 70, 88, 100, 112, 127, 142, 160, 178, 197, 216, 233, 250, 259, 272, 284, 301, 318, 334, 350, 360, 371, 381, 393, 399, 408, 430, 452, 474, 496, 505, 526, 535, 543, 546, 558, 575, 601, 610, 626, 635, 644, 653, 663, 672, 688, 705, 722, 739, 760, 781, 794, 804} +var _AttachType_index = [...]uint16{0, 4, 20, 40, 53, 70, 88, 100, 112, 127, 142, 160, 178, 197, 216, 233, 250, 259, 272, 284, 301, 318, 334, 350, 360, 371, 381, 393, 399, 408, 430, 452, 474, 496, 505, 526, 535, 543, 546, 558, 575, 601, 610, 626, 635, 644, 653, 663, 672, 688, 705, 722, 739, 760, 781, 794, 804, 822} func (i AttachType) String() string { if i >= AttachType(len(_AttachType_index)-1) { diff --git a/vendor/github.com/cilium/ebpf/elf_sections.go b/vendor/github.com/cilium/ebpf/elf_sections.go index 4b58251d9ab..43dcfb103ee 100644 --- a/vendor/github.com/cilium/ebpf/elf_sections.go +++ b/vendor/github.com/cilium/ebpf/elf_sections.go @@ -18,6 +18,7 @@ var elfSectionDefs = []libbpfElfSectionDef{ {"uretprobe.s+", sys.BPF_PROG_TYPE_KPROBE, 0, _SEC_SLEEPABLE}, {"kprobe.multi+", sys.BPF_PROG_TYPE_KPROBE, sys.BPF_TRACE_KPROBE_MULTI, _SEC_NONE}, {"kretprobe.multi+", sys.BPF_PROG_TYPE_KPROBE, sys.BPF_TRACE_KPROBE_MULTI, _SEC_NONE}, + {"kprobe.session+", sys.BPF_PROG_TYPE_KPROBE, sys.BPF_TRACE_KPROBE_SESSION, _SEC_NONE}, {"uprobe.multi+", sys.BPF_PROG_TYPE_KPROBE, sys.BPF_TRACE_UPROBE_MULTI, _SEC_NONE}, {"uretprobe.multi+", sys.BPF_PROG_TYPE_KPROBE, sys.BPF_TRACE_UPROBE_MULTI, _SEC_NONE}, {"uprobe.multi.s+", sys.BPF_PROG_TYPE_KPROBE, sys.BPF_TRACE_UPROBE_MULTI, _SEC_SLEEPABLE}, @@ -69,6 +70,7 @@ var elfSectionDefs = []libbpfElfSectionDef{ {"sockops", sys.BPF_PROG_TYPE_SOCK_OPS, sys.BPF_CGROUP_SOCK_OPS, _SEC_ATTACHABLE_OPT}, {"sk_skb/stream_parser", sys.BPF_PROG_TYPE_SK_SKB, sys.BPF_SK_SKB_STREAM_PARSER, _SEC_ATTACHABLE_OPT}, {"sk_skb/stream_verdict", sys.BPF_PROG_TYPE_SK_SKB, sys.BPF_SK_SKB_STREAM_VERDICT, _SEC_ATTACHABLE_OPT}, + {"sk_skb/verdict", sys.BPF_PROG_TYPE_SK_SKB, sys.BPF_SK_SKB_VERDICT, _SEC_ATTACHABLE_OPT}, {"sk_skb", sys.BPF_PROG_TYPE_SK_SKB, 0, _SEC_NONE}, {"sk_msg", sys.BPF_PROG_TYPE_SK_MSG, sys.BPF_SK_MSG_VERDICT, _SEC_ATTACHABLE_OPT}, {"lirc_mode2", sys.BPF_PROG_TYPE_LIRC_MODE2, sys.BPF_LIRC_MODE2, _SEC_ATTACHABLE_OPT}, diff --git a/vendor/github.com/cilium/ebpf/features/prog.go b/vendor/github.com/cilium/ebpf/features/prog.go index 003bf006464..ee6f89c64d3 100644 --- a/vendor/github.com/cilium/ebpf/features/prog.go +++ b/vendor/github.com/cilium/ebpf/features/prog.go @@ -3,7 +3,8 @@ package features import ( "errors" "fmt" - "os" + "slices" + "strings" "github.com/cilium/ebpf" "github.com/cilium/ebpf/asm" @@ -229,10 +230,6 @@ var helperCache = internal.NewFeatureCache(func(key helperKey) *internal.Feature // // Probe results are cached and persist throughout any process capability changes. func HaveProgramHelper(pt ebpf.ProgramType, helper asm.BuiltinFunc) error { - if helper > helper.Max() { - return os.ErrInvalid - } - return helperCache.Result(helperKey{pt, helper}) } @@ -267,30 +264,59 @@ func haveProgramHelper(pt ebpf.ProgramType, helper asm.BuiltinFunc) error { } prog, err := ebpf.NewProgramWithOptions(spec, ebpf.ProgramOptions{ - LogDisabled: true, + LogLevel: 1, }) if err == nil { prog.Close() } + var verr *ebpf.VerifierError + if !errors.As(err, &verr) { + return err + } + + helperTag := fmt.Sprintf("#%d", helper) + switch { // EACCES occurs when attempting to create a program probe with a helper // while the register args when calling this helper aren't set up properly. // We interpret this as the helper being available, because the verifier // returns EINVAL if the helper is not supported by the running kernel. case errors.Is(err, unix.EACCES): - // TODO: possibly we need to check verifier output here to be sure err = nil // EINVAL occurs when attempting to create a program with an unknown helper. case errors.Is(err, unix.EINVAL): - // TODO: possibly we need to check verifier output here to be sure - err = ebpf.ErrNotSupported + // https://github.com/torvalds/linux/blob/09a0fa92e5b45e99cf435b2fbf5ebcf889cf8780/kernel/bpf/verifier.c#L10663 + if logContainsAll(verr.Log, "invalid func", helperTag) { + return ebpf.ErrNotSupported + } + + // https://github.com/torvalds/linux/blob/09a0fa92e5b45e99cf435b2fbf5ebcf889cf8780/kernel/bpf/verifier.c#L10668 + wrongProgramType := logContainsAll(verr.Log, "program of this type cannot use helper", helperTag) + // https://github.com/torvalds/linux/blob/59b418c7063d30e0a3e1f592d47df096db83185c/kernel/bpf/verifier.c#L10204 + // 4.9 doesn't include # in verifier output. + wrongProgramType = wrongProgramType || logContainsAll(verr.Log, "unknown func") + if wrongProgramType { + return fmt.Errorf("program of this type cannot use helper: %w", ebpf.ErrNotSupported) + } } return err } +func logContainsAll(log []string, needles ...string) bool { + first := max(len(log)-5, 0) // Check last 5 lines. + return slices.ContainsFunc(log[first:], func(line string) bool { + for _, needle := range needles { + if !strings.Contains(line, needle) { + return false + } + } + return true + }) +} + func helperProbeNotImplemented(pt ebpf.ProgramType) bool { switch pt { case ebpf.Extension, ebpf.LSM, ebpf.StructOps, ebpf.Tracing: diff --git a/vendor/github.com/cilium/ebpf/internal/sys/types.go b/vendor/github.com/cilium/ebpf/internal/sys/types.go index 88001c319eb..82f3492a83d 100644 --- a/vendor/github.com/cilium/ebpf/internal/sys/types.go +++ b/vendor/github.com/cilium/ebpf/internal/sys/types.go @@ -26,6 +26,7 @@ const ( BPF_FIB_LKUP_RET_UNREACHABLE = 2 BPF_FIB_LKUP_RET_UNSUPP_LWT = 6 BPF_FIB_LOOKUP_DIRECT = 1 + BPF_FIB_LOOKUP_MARK = 32 BPF_FIB_LOOKUP_OUTPUT = 2 BPF_FIB_LOOKUP_SKIP_NEIGH = 4 BPF_FIB_LOOKUP_SRC = 16 @@ -68,6 +69,7 @@ const ( BPF_F_NO_COMMON_LRU = 2 BPF_F_NO_PREALLOC = 1 BPF_F_NO_TUNNEL_KEY = 16 + BPF_F_NO_USER_CONV = 262144 BPF_F_NUMA_NODE = 4 BPF_F_PATH_FD = 16384 BPF_F_PEER = 4 @@ -77,17 +79,20 @@ const ( BPF_F_RDONLY_PROG = 128 BPF_F_RECOMPUTE_CSUM = 1 BPF_F_REUSE_STACKID = 1024 + BPF_F_SEGV_ON_FAULT = 131072 BPF_F_SEQ_NUMBER = 8 BPF_F_SKIP_FIELD_MASK = 255 BPF_F_STACK_BUILD_ID = 32 BPF_F_SYSCTL_BASE_NAME = 1 BPF_F_TIMER_ABS = 1 BPF_F_TIMER_CPU_PIN = 2 + BPF_F_TOKEN_FD = 65536 BPF_F_TUNINFO_FLAGS = 16 BPF_F_TUNINFO_IPV6 = 1 BPF_F_UPROBE_MULTI_RETURN = 1 BPF_F_USER_BUILD_ID = 2048 BPF_F_USER_STACK = 256 + BPF_F_VTYPE_BTF_OBJ_FD = 32768 BPF_F_WRONLY = 16 BPF_F_WRONLY_PROG = 256 BPF_F_ZERO_CSUM_TX = 2 @@ -117,6 +122,9 @@ const ( BPF_RINGBUF_BUSY_BIT = 2147483648 BPF_RINGBUF_DISCARD_BIT = 1073741824 BPF_RINGBUF_HDR_SZ = 8 + BPF_SKB_CLOCK_MONOTONIC = 1 + BPF_SKB_CLOCK_REALTIME = 0 + BPF_SKB_CLOCK_TAI = 2 BPF_SKB_TSTAMP_DELIVERY_MONO = 1 BPF_SKB_TSTAMP_UNSPEC = 0 BPF_SK_LOOKUP_F_NO_REUSEPORT = 2 @@ -146,8 +154,6 @@ const ( BPF_SOCK_OPS_VOID = 0 BPF_SOCK_OPS_WRITE_HDR_OPT_CB = 15 BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG = 64 - BPF_STRUCT_OPS_TYPE_bpf_dummy_ops = 0 - BPF_STRUCT_OPS_TYPE_tcp_congestion_ops = 1 BPF_TASK_ITER_ALL_PROCS = 0 BPF_TASK_ITER_ALL_THREADS = 1 BPF_TASK_ITER_PROC_THREADS = 2 @@ -236,7 +242,8 @@ const ( BPF_CGROUP_UNIX_GETSOCKNAME AttachType = 53 BPF_NETKIT_PRIMARY AttachType = 54 BPF_NETKIT_PEER AttachType = 55 - __MAX_BPF_ATTACH_TYPE AttachType = 56 + BPF_TRACE_KPROBE_SESSION AttachType = 56 + __MAX_BPF_ATTACH_TYPE AttachType = 57 ) type Cmd uint32 @@ -279,6 +286,8 @@ const ( BPF_ITER_CREATE Cmd = 33 BPF_LINK_DETACH Cmd = 34 BPF_PROG_BIND_MAP Cmd = 35 + BPF_TOKEN_CREATE Cmd = 36 + __MAX_BPF_CMD Cmd = 37 ) type FunctionId uint32 @@ -523,7 +532,8 @@ const ( BPF_LINK_TYPE_TCX LinkType = 11 BPF_LINK_TYPE_UPROBE_MULTI LinkType = 12 BPF_LINK_TYPE_NETKIT LinkType = 13 - __MAX_BPF_LINK_TYPE LinkType = 14 + BPF_LINK_TYPE_SOCKMAP LinkType = 14 + __MAX_BPF_LINK_TYPE LinkType = 15 ) type MapType uint32 @@ -564,6 +574,8 @@ const ( BPF_MAP_TYPE_BLOOM_FILTER MapType = 30 BPF_MAP_TYPE_USER_RINGBUF MapType = 31 BPF_MAP_TYPE_CGRP_STORAGE MapType = 32 + BPF_MAP_TYPE_ARENA MapType = 33 + __MAX_BPF_MAP_TYPE MapType = 34 ) type ObjType uint32 @@ -623,6 +635,7 @@ const ( BPF_PROG_TYPE_SK_LOOKUP ProgType = 30 BPF_PROG_TYPE_SYSCALL ProgType = 31 BPF_PROG_TYPE_NETFILTER ProgType = 32 + __MAX_BPF_PROG_TYPE ProgType = 33 ) type RetCode uint32 @@ -719,7 +732,7 @@ type MapInfo struct { BtfId uint32 BtfKeyTypeId TypeID BtfValueTypeId TypeID - _ [4]byte + BtfVmlinuxId uint32 MapExtra uint64 } @@ -816,6 +829,8 @@ type BtfLoadAttr struct { BtfLogSize uint32 BtfLogLevel uint32 BtfLogTrueSize uint32 + BtfFlags uint32 + BtfTokenFd int32 } func BtfLoad(attr *BtfLoadAttr) (*FD, error) { @@ -1069,6 +1084,8 @@ type MapCreateAttr struct { BtfValueTypeId TypeID BtfVmlinuxValueTypeId TypeID MapExtra uint64 + ValueTypeBtfObjFd int32 + MapTokenFd int32 } func MapCreate(attr *MapCreateAttr) (*FD, error) { @@ -1362,6 +1379,8 @@ type ProgLoadAttr struct { CoreRelos Pointer CoreReloRecSize uint32 LogTrueSize uint32 + ProgTokenFd int32 + _ [4]byte } func ProgLoad(attr *ProgLoadAttr) (*FD, error) { @@ -1419,6 +1438,7 @@ type RawTracepointOpenAttr struct { Name Pointer ProgFd uint32 _ [4]byte + Cookie uint64 } func RawTracepointOpen(attr *RawTracepointOpenAttr) (*FD, error) { @@ -1460,19 +1480,20 @@ type KprobeLinkInfo struct { Offset uint32 Addr uint64 Missed uint64 - _ [8]byte + Cookie uint64 } type KprobeMultiLinkInfo struct { - Type LinkType - Id LinkID - ProgId uint32 - _ [4]byte - Addrs Pointer - Count uint32 - Flags uint32 - Missed uint64 - _ [24]byte + Type LinkType + Id LinkID + ProgId uint32 + _ [4]byte + Addrs Pointer + Count uint32 + Flags uint32 + Missed uint64 + Cookies uint64 + _ [16]byte } type NetNsLinkInfo struct { diff --git a/vendor/github.com/cilium/ebpf/link/kprobe_multi.go b/vendor/github.com/cilium/ebpf/link/kprobe_multi.go index 094cb0538cb..f19f9f4c732 100644 --- a/vendor/github.com/cilium/ebpf/link/kprobe_multi.go +++ b/vendor/github.com/cilium/ebpf/link/kprobe_multi.go @@ -37,6 +37,14 @@ type KprobeMultiOptions struct { // Each Cookie is assigned to the Symbol or Address specified at the // corresponding slice index. Cookies []uint64 + + // Session must be true when attaching Programs with the + // [ebpf.AttachTraceKprobeSession] attach type. + // + // This makes a Kprobe execute on both function entry and return. The entry + // program can share a cookie value with the return program and can decide + // whether the return program gets executed. + Session bool } // KprobeMulti attaches the given eBPF program to the entry point of a given set @@ -82,9 +90,14 @@ func kprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions, flags uint32) (Lin return nil, fmt.Errorf("Cookies must be exactly Symbols or Addresses in length: %w", errInvalidInput) } + attachType := sys.BPF_TRACE_KPROBE_MULTI + if opts.Session { + attachType = sys.BPF_TRACE_KPROBE_SESSION + } + attr := &sys.LinkCreateKprobeMultiAttr{ ProgFd: uint32(prog.FD()), - AttachType: sys.BPF_TRACE_KPROBE_MULTI, + AttachType: attachType, KprobeMultiFlags: flags, } @@ -103,21 +116,31 @@ func kprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions, flags uint32) (Lin } fd, err := sys.LinkCreateKprobeMulti(attr) + if err == nil { + return &kprobeMultiLink{RawLink{fd, ""}}, nil + } + if errors.Is(err, unix.ESRCH) { return nil, fmt.Errorf("couldn't find one or more symbols: %w", os.ErrNotExist) } - if errors.Is(err, unix.EINVAL) { - return nil, fmt.Errorf("%w (missing kernel symbol or prog's AttachType not AttachTraceKprobeMulti?)", err) - } - if err != nil { + if opts.Session { + if haveFeatErr := haveBPFLinkKprobeSession(); haveFeatErr != nil { + return nil, haveFeatErr + } + } else { if haveFeatErr := haveBPFLinkKprobeMulti(); haveFeatErr != nil { return nil, haveFeatErr } - return nil, err } - return &kprobeMultiLink{RawLink{fd, ""}}, nil + // Check EINVAL after running feature probes, since it's also returned when + // the kernel doesn't support the multi/session attach types. + if errors.Is(err, unix.EINVAL) { + return nil, fmt.Errorf("%w (missing kernel symbol or prog's AttachType not %s?)", err, ebpf.AttachType(attachType)) + } + + return nil, err } type kprobeMultiLink struct { @@ -189,3 +212,44 @@ var haveBPFLinkKprobeMulti = internal.NewFeatureTest("bpf_link_kprobe_multi", fu return nil }, "5.18") + +var haveBPFLinkKprobeSession = internal.NewFeatureTest("bpf_link_kprobe_session", func() error { + prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ + Name: "probe_kps_link", + Type: ebpf.Kprobe, + Instructions: asm.Instructions{ + asm.Mov.Imm(asm.R0, 0), + asm.Return(), + }, + AttachType: ebpf.AttachTraceKprobeSession, + License: "MIT", + }) + if errors.Is(err, unix.E2BIG) { + // Kernel doesn't support AttachType field. + return internal.ErrNotSupported + } + if err != nil { + return err + } + defer prog.Close() + + fd, err := sys.LinkCreateKprobeMulti(&sys.LinkCreateKprobeMultiAttr{ + ProgFd: uint32(prog.FD()), + AttachType: sys.BPF_TRACE_KPROBE_SESSION, + Count: 1, + Syms: sys.NewStringSlicePointer([]string{"vprintk"}), + }) + switch { + case errors.Is(err, unix.EINVAL): + return internal.ErrNotSupported + // If CONFIG_FPROBE isn't set. + case errors.Is(err, unix.EOPNOTSUPP): + return internal.ErrNotSupported + case err != nil: + return err + } + + fd.Close() + + return nil +}, "6.10") diff --git a/vendor/github.com/cilium/ebpf/types.go b/vendor/github.com/cilium/ebpf/types.go index 211b308bbc7..d7fb00509de 100644 --- a/vendor/github.com/cilium/ebpf/types.go +++ b/vendor/github.com/cilium/ebpf/types.go @@ -236,6 +236,7 @@ const ( AttachSkReuseportSelectOrMigrate = AttachType(sys.BPF_SK_REUSEPORT_SELECT_OR_MIGRATE) AttachPerfEvent = AttachType(sys.BPF_PERF_EVENT) AttachTraceKprobeMulti = AttachType(sys.BPF_TRACE_KPROBE_MULTI) + AttachTraceKprobeSession = AttachType(sys.BPF_TRACE_KPROBE_SESSION) AttachLSMCgroup = AttachType(sys.BPF_LSM_CGROUP) AttachStructOps = AttachType(sys.BPF_STRUCT_OPS) AttachNetfilter = AttachType(sys.BPF_NETFILTER) diff --git a/vendor/modules.txt b/vendor/modules.txt index 7f7db5404cf..7dc4483e851 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -64,7 +64,7 @@ github.com/cilium/cilium/pkg/resiliency github.com/cilium/cilium/pkg/time github.com/cilium/cilium/pkg/version github.com/cilium/cilium/pkg/versioncheck -# github.com/cilium/ebpf v0.17.1 +# github.com/cilium/ebpf v0.17.2-0.20250113160858-6d6c5e322573 ## explicit; go 1.22 github.com/cilium/ebpf github.com/cilium/ebpf/asm From 611fdd6f6f10dfc670f6d194255a26176e22b07d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 23 Dec 2024 11:02:19 +0000 Subject: [PATCH 02/11] tetragon: Factor InitKernel/ReturnSelectorState functions Signed-off-by: Jiri Olsa --- pkg/selectors/kernel.go | 43 ++++++++++++------------ pkg/sensors/tracing/generickprobe.go | 11 +++--- pkg/sensors/tracing/genericlsm.go | 3 +- pkg/sensors/tracing/generictracepoint.go | 4 +-- pkg/sensors/tracing/genericuprobe.go | 4 +-- 5 files changed, 34 insertions(+), 31 deletions(-) diff --git a/pkg/selectors/kernel.go b/pkg/selectors/kernel.go index 7d4f02d8740..f5bbc6cdd66 100644 --- a/pkg/selectors/kernel.go +++ b/pkg/selectors/kernel.go @@ -1299,7 +1299,8 @@ func ParseMatchBinaries(k *KernelSelectorState, binarys []v1alpha1.BinarySelecto // // For some examples, see kernel_test.go func InitKernelSelectors(selectors []v1alpha1.KProbeSelector, args []v1alpha1.KProbeArg, actionArgTable *idtable.Table) ([4096]byte, error) { - state, err := InitKernelSelectorState(selectors, args, actionArgTable, nil, nil) + state := NewKernelSelectorState(nil, nil) + err := state.InitKernelSelector(selectors, args, actionArgTable) if err != nil { return [4096]byte{}, err } @@ -1307,37 +1308,37 @@ func InitKernelSelectors(selectors []v1alpha1.KProbeSelector, args []v1alpha1.KP } func InitKernelReturnSelectors(selectors []v1alpha1.KProbeSelector, returnArg *v1alpha1.KProbeArg, actionArgTable *idtable.Table) ([4096]byte, error) { - state, err := InitKernelReturnSelectorState(selectors, returnArg, actionArgTable, nil, nil) + state := NewKernelSelectorState(nil, nil) + err := state.InitKernelReturnSelector(selectors, returnArg, actionArgTable) if err != nil { return [4096]byte{}, err } return state.data.e, nil } -func createKernelSelectorState(selectors []v1alpha1.KProbeSelector, listReader ValueReader, maps *KernelSelectorMaps, - parseSelector func(k *KernelSelectorState, selectors *v1alpha1.KProbeSelector, selIdx int) error) (*KernelSelectorState, error) { - state := NewKernelSelectorState(listReader, maps) +func createKernelSelectorState(data *KernelSelectorData, selectors []v1alpha1.KProbeSelector, + parseSelector func(selectors *v1alpha1.KProbeSelector, selIdx int) error) error { - WriteSelectorUint32(&state.data, uint32(len(selectors))) + WriteSelectorUint32(data, uint32(len(selectors))) soff := make([]uint32, len(selectors)) for i := range selectors { - soff[i] = AdvanceSelectorLength(&state.data) + soff[i] = AdvanceSelectorLength(data) } for i, s := range selectors { - WriteSelectorLength(&state.data, soff[i]) - loff := AdvanceSelectorLength(&state.data) - if err := parseSelector(state, &s, i); err != nil { - return nil, err + WriteSelectorLength(data, soff[i]) + loff := AdvanceSelectorLength(data) + if err := parseSelector(&s, i); err != nil { + return err } - WriteSelectorLength(&state.data, loff) + WriteSelectorLength(data, loff) } - return state, nil + return nil } -func InitKernelSelectorState(selectors []v1alpha1.KProbeSelector, args []v1alpha1.KProbeArg, - actionArgTable *idtable.Table, listReader ValueReader, maps *KernelSelectorMaps) (*KernelSelectorState, error) { +func (k *KernelSelectorState) InitKernelSelector(selectors []v1alpha1.KProbeSelector, args []v1alpha1.KProbeArg, + actionArgTable *idtable.Table) error { - parse := func(k *KernelSelectorState, selectors *v1alpha1.KProbeSelector, selIdx int) error { + parse := func(selectors *v1alpha1.KProbeSelector, selIdx int) error { if err := ParseMatchPids(k, selectors.MatchPIDs); err != nil { return fmt.Errorf("parseMatchPids error: %w", err) } @@ -1365,13 +1366,13 @@ func InitKernelSelectorState(selectors []v1alpha1.KProbeSelector, args []v1alpha return nil } - return createKernelSelectorState(selectors, listReader, maps, parse) + return createKernelSelectorState(&k.data, selectors, parse) } -func InitKernelReturnSelectorState(selectors []v1alpha1.KProbeSelector, returnArg *v1alpha1.KProbeArg, - actionArgTable *idtable.Table, listReader ValueReader, maps *KernelSelectorMaps) (*KernelSelectorState, error) { +func (k *KernelSelectorState) InitKernelReturnSelector(selectors []v1alpha1.KProbeSelector, returnArg *v1alpha1.KProbeArg, + actionArgTable *idtable.Table) error { - parse := func(k *KernelSelectorState, selector *v1alpha1.KProbeSelector, _ int) error { + parse := func(selector *v1alpha1.KProbeSelector, _ int) error { if err := ParseMatchArgs(k, selector.MatchReturnArgs, []v1alpha1.KProbeArg{*returnArg}); err != nil { return fmt.Errorf("parseMatchArgs error: %w", err) } @@ -1381,7 +1382,7 @@ func InitKernelReturnSelectorState(selectors []v1alpha1.KProbeSelector, returnAr return nil } - return createKernelSelectorState(selectors, listReader, maps, parse) + return createKernelSelectorState(&k.data, selectors, parse) } func HasOverride(spec *v1alpha1.KProbeSpec) bool { diff --git a/pkg/sensors/tracing/generickprobe.go b/pkg/sensors/tracing/generickprobe.go index 0b7a7f97222..ee931038852 100644 --- a/pkg/sensors/tracing/generickprobe.go +++ b/pkg/sensors/tracing/generickprobe.go @@ -877,17 +877,18 @@ func addKprobe(funcName string, instance int, f *v1alpha1.KProbeSpec, in *addKpr } // Parse Filters into kernel filter logic - kprobeEntry.loadArgs.selectors.entry, err = selectors.InitKernelSelectorState(f.Selectors, f.Args, &kprobeEntry.actionArgs, nil, in.selMaps) - if err != nil { + state := selectors.NewKernelSelectorState(nil, in.selMaps) + if err := state.InitKernelSelector(f.Selectors, f.Args, &kprobeEntry.actionArgs); err != nil { return errFn(err) } + kprobeEntry.loadArgs.selectors.entry = state if f.Return { - kprobeEntry.loadArgs.selectors.retrn, err = selectors.InitKernelReturnSelectorState(f.Selectors, f.ReturnArg, - &kprobeEntry.actionArgs, nil, in.selMaps) - if err != nil { + state := selectors.NewKernelSelectorState(nil, in.selMaps) + if err := state.InitKernelReturnSelector(f.Selectors, f.ReturnArg, &kprobeEntry.actionArgs); err != nil { return errFn(err) } + kprobeEntry.loadArgs.selectors.retrn = state } kprobeEntry.pendingEvents, err = lru.New[pendingEventKey, pendingEvent](4096) diff --git a/pkg/sensors/tracing/genericlsm.go b/pkg/sensors/tracing/genericlsm.go index 699ba08b2ea..5f65c54f070 100644 --- a/pkg/sensors/tracing/genericlsm.go +++ b/pkg/sensors/tracing/genericlsm.go @@ -302,7 +302,8 @@ func addLsm(f *v1alpha1.LsmHookSpec, in *addLsmIn) (id idtable.EntryID, err erro } // Parse Filters into kernel filter logic - lsmEntry.selectors, err = selectors.InitKernelSelectorState(f.Selectors, f.Args, nil, nil, in.selMaps) + lsmEntry.selectors = selectors.NewKernelSelectorState(nil, in.selMaps) + err = lsmEntry.selectors.InitKernelSelector(f.Selectors, f.Args, nil) if err != nil { return errFn(err) } diff --git a/pkg/sensors/tracing/generictracepoint.go b/pkg/sensors/tracing/generictracepoint.go index 2ddab7967ea..e59c3fd1c4c 100644 --- a/pkg/sensors/tracing/generictracepoint.go +++ b/pkg/sensors/tracing/generictracepoint.go @@ -630,8 +630,8 @@ func (tp *genericTracepoint) InitKernelSelectors(lists []v1alpha1.ListSpec) erro } } - selectors, err := selectors.InitKernelSelectorState(selSelectors, selArgs, &tp.actionArgs, &listReader{lists}, nil) - if err != nil { + selectors := selectors.NewKernelSelectorState(&listReader{lists}, nil) + if err := selectors.InitKernelSelector(selSelectors, selArgs, &tp.actionArgs); err != nil { return err } tp.selectors = selectors diff --git a/pkg/sensors/tracing/genericuprobe.go b/pkg/sensors/tracing/genericuprobe.go index 3406ff772e7..c57619d2991 100644 --- a/pkg/sensors/tracing/genericuprobe.go +++ b/pkg/sensors/tracing/genericuprobe.go @@ -301,8 +301,8 @@ func addUprobe(spec *v1alpha1.UProbeSpec, ids []idtable.EntryID, in *addUprobeIn } // Parse Filters into kernel filter logic - uprobeSelectorState, err := selectors.InitKernelSelectorState(spec.Selectors, args, nil, nil, nil) - if err != nil { + uprobeSelectorState := selectors.NewKernelSelectorState(nil, nil) + if err := uprobeSelectorState.InitKernelSelector(spec.Selectors, args, nil); err != nil { return nil, err } From 64d42c04ac8485508a984eb62639631e6f57f046 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 23 Dec 2024 11:24:43 +0000 Subject: [PATCH 03/11] tetragon: Pass data argument to ParseMatchArgs Signed-off-by: Jiri Olsa --- pkg/selectors/kernel.go | 88 ++++++++++++++++++------------------ pkg/selectors/kernel_test.go | 14 +++--- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/pkg/selectors/kernel.go b/pkg/selectors/kernel.go index f5bbc6cdd66..f3137c8d761 100644 --- a/pkg/selectors/kernel.go +++ b/pkg/selectors/kernel.go @@ -446,7 +446,7 @@ func writeRangeInMap(v string, ty uint32, op uint32, m *ValueMap) error { return nil } -func writeMatchRangesInMap(k *KernelSelectorState, values []string, ty uint32, op uint32) error { +func writeMatchRangesInMap(k *KernelSelectorState, data *KernelSelectorData, values []string, ty uint32, op uint32) error { mid, m := k.newValueMap() for _, v := range values { err := writeRangeInMap(v, ty, op, &m) @@ -455,7 +455,7 @@ func writeMatchRangesInMap(k *KernelSelectorState, values []string, ty uint32, o } } // write the map id into the selector - WriteSelectorUint32(&k.data, mid) + WriteSelectorUint32(data, mid) return nil } @@ -483,7 +483,7 @@ func writeListValuesInMap(k *KernelSelectorState, v string, ty uint32, m *ValueM return nil } -func writeMatchValuesInMap(k *KernelSelectorState, values []string, ty uint32, op uint32) error { +func writeMatchValuesInMap(k *KernelSelectorState, data *KernelSelectorData, values []string, ty uint32, op uint32) error { mid, m := k.newValueMap() for _, v := range values { var val [8]byte @@ -522,11 +522,11 @@ func writeMatchValuesInMap(k *KernelSelectorState, values []string, ty uint32, o m.Data[val] = struct{}{} } // write the map id into the selector - WriteSelectorUint32(&k.data, mid) + WriteSelectorUint32(data, mid) return nil } -func writeMatchAddrsInMap(k *KernelSelectorState, values []string) error { +func writeMatchAddrsInMap(k *KernelSelectorState, data *KernelSelectorData, values []string) error { m4 := k.createAddr4Map() m6 := k.createAddr6Map() for _, v := range values { @@ -548,15 +548,15 @@ func writeMatchAddrsInMap(k *KernelSelectorState, values []string) error { // write the map ids into the selector if len(m4) != 0 { m4id := k.insertAddr4Map(m4) - WriteSelectorUint32(&k.data, m4id) + WriteSelectorUint32(data, m4id) } else { - WriteSelectorUint32(&k.data, 0xffffffff) + WriteSelectorUint32(data, 0xffffffff) } if len(m6) != 0 { m6id := k.insertAddr6Map(m6) - WriteSelectorUint32(&k.data, m6id) + WriteSelectorUint32(data, m6id) } else { - WriteSelectorUint32(&k.data, 0xffffffff) + WriteSelectorUint32(data, 0xffffffff) } return nil } @@ -613,7 +613,7 @@ func parseAddr(v string) ([]byte, uint32, error) { return nil, 0, fmt.Errorf("IP CIDR is not valid: address part does not parse") } -func writeMatchValues(k *KernelSelectorState, values []string, ty, op uint32) error { +func writeMatchValues(data *KernelSelectorData, values []string, ty, op uint32) error { for _, v := range values { base := getBase(v) switch ty { @@ -623,25 +623,25 @@ func writeMatchValues(k *KernelSelectorState, values []string, ty, op uint32) er if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) } - WriteSelectorInt32(&k.data, int32(i)) + WriteSelectorInt32(data, int32(i)) case gt.GenericU32Type: i, err := strconv.ParseUint(v, base, 32) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) } - WriteSelectorUint32(&k.data, uint32(i)) + WriteSelectorUint32(data, uint32(i)) case gt.GenericS64Type, gt.GenericSyscall64: i, err := strconv.ParseInt(v, base, 64) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) } - WriteSelectorInt64(&k.data, int64(i)) + WriteSelectorInt64(data, int64(i)) case gt.GenericU64Type: i, err := strconv.ParseUint(v, base, 64) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) } - WriteSelectorUint64(&k.data, uint64(i)) + WriteSelectorUint64(data, uint64(i)) case gt.GenericSockType, gt.GenericSkbType, gt.GenericNetDev: return fmt.Errorf("MatchArgs type sock, skb and net_device do not support operator %s", selectorOpStringTable[op]) case gt.GenericCharIovec: @@ -651,7 +651,7 @@ func writeMatchValues(k *KernelSelectorState, values []string, ty, op uint32) er return nil } -func writeMatchStrings(k *KernelSelectorState, values []string, ty uint32) error { +func writeMatchStrings(k *KernelSelectorState, data *KernelSelectorData, values []string, ty uint32) error { maps := k.createStringMaps() for _, v := range values { @@ -680,7 +680,7 @@ func writeMatchStrings(k *KernelSelectorState, values []string, ty uint32) error // write the map ids into the selector mapDetails := k.insertStringMaps(maps) for _, md := range mapDetails { - WriteSelectorUint32(&k.data, md) + WriteSelectorUint32(data, md) } return nil } @@ -705,12 +705,12 @@ func writePrefixBinaries(k *KernelSelectorState, values []string) (uint32, error return writePrefix(k, values, "MatchBinaries") } -func writePrefixStrings(k *KernelSelectorState, values []string) error { +func writePrefixStrings(k *KernelSelectorState, data *KernelSelectorData, values []string) error { mid, err := writePrefix(k, values, "MatchArgs") if err != nil { return err } - WriteSelectorUint32(&k.data, mid) + WriteSelectorUint32(data, mid) return nil } @@ -743,12 +743,12 @@ func writePostfixBinaries(k *KernelSelectorState, values []string) (uint32, erro return writePostfix(k, values, gt.GenericCharBuffer, "MatchBinaries") } -func writePostfixStrings(k *KernelSelectorState, values []string, ty uint32) error { +func writePostfixStrings(k *KernelSelectorState, data *KernelSelectorData, values []string, ty uint32) error { mid, err := writePostfix(k, values, ty, "MatchArgs") if err != nil { return err } - WriteSelectorUint32(&k.data, mid) + WriteSelectorUint32(data, mid) return nil } @@ -762,8 +762,8 @@ func checkOp(op uint32) error { return nil } -func ParseMatchArg(k *KernelSelectorState, arg *v1alpha1.ArgSelector, sig []v1alpha1.KProbeArg) error { - WriteSelectorUint32(&k.data, arg.Index) +func ParseMatchArg(k *KernelSelectorState, data *KernelSelectorData, arg *v1alpha1.ArgSelector, sig []v1alpha1.KProbeArg) error { + WriteSelectorUint32(data, arg.Index) op, err := SelectorOp(arg.Operator) if err != nil { @@ -773,39 +773,39 @@ func ParseMatchArg(k *KernelSelectorState, arg *v1alpha1.ArgSelector, sig []v1al if err != nil { return fmt.Errorf("matcharg error: %w", err) } - WriteSelectorUint32(&k.data, op) - moff := AdvanceSelectorLength(&k.data) + WriteSelectorUint32(data, op) + moff := AdvanceSelectorLength(data) ty, err := argSelectorType(arg, sig) if err != nil { return fmt.Errorf("argSelector error: %w", err) } - WriteSelectorUint32(&k.data, ty) + WriteSelectorUint32(data, ty) switch op { case SelectorInMap, SelectorNotInMap: - err := writeMatchValuesInMap(k, arg.Values, ty, op) + err := writeMatchValuesInMap(k, data, arg.Values, ty, op) if err != nil { return fmt.Errorf("writeMatchRangesInMap error: %w", err) } case SelectorOpEQ, SelectorOpNEQ: switch ty { case gt.GenericFdType, gt.GenericFileType, gt.GenericPathType, gt.GenericStringType, gt.GenericCharBuffer, gt.GenericLinuxBinprmType, gt.GenericDataLoc, gt.GenericNetDev: - err := writeMatchStrings(k, arg.Values, ty) + err := writeMatchStrings(k, data, arg.Values, ty) if err != nil { return fmt.Errorf("writeMatchStrings error: %w", err) } default: - err = writeMatchValues(k, arg.Values, ty, op) + err = writeMatchValues(data, arg.Values, ty, op) if err != nil { return fmt.Errorf("writeMatchValues error: %w", err) } } case SelectorOpPrefix, SelectorOpNotPrefix: - err := writePrefixStrings(k, arg.Values) + err := writePrefixStrings(k, data, arg.Values) if err != nil { return fmt.Errorf("writePrefixStrings error: %w", err) } case SelectorOpPostfix, SelectorOpNotPostfix: - err := writePostfixStrings(k, arg.Values, ty) + err := writePostfixStrings(k, data, arg.Values, ty) if err != nil { return fmt.Errorf("writePostfixStrings error: %w", err) } @@ -813,7 +813,7 @@ func ParseMatchArg(k *KernelSelectorState, arg *v1alpha1.ArgSelector, sig []v1al if ty != gt.GenericSockType && ty != gt.GenericSkbType { return fmt.Errorf("sock/skb operators specified for non-sock/skb type") } - err := writeMatchRangesInMap(k, arg.Values, gt.GenericU64Type, op) // force type for ports and protocols as ty is sock/skb + err := writeMatchRangesInMap(k, data, arg.Values, gt.GenericU64Type, op) // force type for ports and protocols as ty is sock/skb if err != nil { return fmt.Errorf("writeMatchRangesInMap error: %w", err) } @@ -821,7 +821,7 @@ func ParseMatchArg(k *KernelSelectorState, arg *v1alpha1.ArgSelector, sig []v1al if ty != gt.GenericSockType && ty != gt.GenericSkbType { return fmt.Errorf("sock/skb operators specified for non-sock/skb type") } - err := writeMatchAddrsInMap(k, arg.Values) + err := writeMatchAddrsInMap(k, data, arg.Values) if err != nil { return fmt.Errorf("writeMatchAddrsInMap error: %w", err) } @@ -831,17 +831,17 @@ func ParseMatchArg(k *KernelSelectorState, arg *v1alpha1.ArgSelector, sig []v1al return fmt.Errorf("sock/skb operators specified for non-sock/skb type") } default: - err = writeMatchValues(k, arg.Values, ty, op) + err = writeMatchValues(data, arg.Values, ty, op) if err != nil { return fmt.Errorf("writeMatchValues error: %w", err) } } - WriteSelectorLength(&k.data, moff) + WriteSelectorLength(data, moff) return nil } -func ParseMatchArgs(k *KernelSelectorState, args []v1alpha1.ArgSelector, sig []v1alpha1.KProbeArg) error { +func ParseMatchArgs(k *KernelSelectorState, data *KernelSelectorData, args []v1alpha1.ArgSelector, sig []v1alpha1.KProbeArg) error { max_args := 1 if kernels.EnableLargeProgs() { max_args = 5 // we support up 5 argument filters under matchArgs with kernels >= 5.3, otherwise 1 argument @@ -849,20 +849,20 @@ func ParseMatchArgs(k *KernelSelectorState, args []v1alpha1.ArgSelector, sig []v if len(args) > max_args { return fmt.Errorf("parseMatchArgs: supports up to %d filters (%d provided)", max_args, len(args)) } - actionOffset := GetCurrentOffset(&k.data) - loff := AdvanceSelectorLength(&k.data) + actionOffset := GetCurrentOffset(data) + loff := AdvanceSelectorLength(data) argOff := make([]uint32, 5) for i := 0; i < 5; i++ { - argOff[i] = AdvanceSelectorLength(&k.data) - WriteSelectorOffsetUint32(&k.data, argOff[i], 0) + argOff[i] = AdvanceSelectorLength(data) + WriteSelectorOffsetUint32(data, argOff[i], 0) } for i, a := range args { - WriteSelectorOffsetUint32(&k.data, argOff[i], GetCurrentOffset(&k.data)-actionOffset) - if err := ParseMatchArg(k, &a, sig); err != nil { + WriteSelectorOffsetUint32(data, argOff[i], GetCurrentOffset(data)-actionOffset) + if err := ParseMatchArg(k, data, &a, sig); err != nil { return err } } - WriteSelectorLength(&k.data, loff) + WriteSelectorLength(data, loff) return nil } @@ -1357,7 +1357,7 @@ func (k *KernelSelectorState) InitKernelSelector(selectors []v1alpha1.KProbeSele if err := ParseMatchBinaries(k, selectors.MatchBinaries, selIdx); err != nil { return fmt.Errorf("parseMatchBinaries error: %w", err) } - if err := ParseMatchArgs(k, selectors.MatchArgs, args); err != nil { + if err := ParseMatchArgs(k, &k.data, selectors.MatchArgs, args); err != nil { return fmt.Errorf("parseMatchArgs error: %w", err) } if err := ParseMatchActions(k, selectors.MatchActions, actionArgTable); err != nil { @@ -1373,7 +1373,7 @@ func (k *KernelSelectorState) InitKernelReturnSelector(selectors []v1alpha1.KPro actionArgTable *idtable.Table) error { parse := func(selector *v1alpha1.KProbeSelector, _ int) error { - if err := ParseMatchArgs(k, selector.MatchReturnArgs, []v1alpha1.KProbeArg{*returnArg}); err != nil { + if err := ParseMatchArgs(k, &k.data, selector.MatchReturnArgs, []v1alpha1.KProbeArg{*returnArg}); err != nil { return fmt.Errorf("parseMatchArgs error: %w", err) } if err := ParseMatchActions(k, selector.MatchReturnActions, actionArgTable); err != nil { diff --git a/pkg/selectors/kernel_test.go b/pkg/selectors/kernel_test.go index 057152dc35f..1365718b93f 100644 --- a/pkg/selectors/kernel_test.go +++ b/pkg/selectors/kernel_test.go @@ -246,7 +246,7 @@ func TestParseMatchArg(t *testing.T) { 0xff, 0xff, 0xff, 0xff, // map ID for strings 1025-2048 0xff, 0xff, 0xff, 0xff, // map ID for strings 2049-4096 } - if err := ParseMatchArg(k, arg1, sig); err != nil || bytes.Equal(expected1, d.e[0:d.off]) == false { + if err := ParseMatchArg(k, &k.data, arg1, sig); err != nil || bytes.Equal(expected1, d.e[0:d.off]) == false { t.Errorf("parseMatchArg: error %v expected:\n%v\nbytes:\n%v\nparsing %v\n", err, expected1, d.e[0:d.off], arg1) } @@ -260,7 +260,7 @@ func TestParseMatchArg(t *testing.T) { 0x01, 0x00, 0x00, 0x00, // value 1 0x02, 0x00, 0x00, 0x00, // value 2 } - if err := ParseMatchArg(k, arg2, sig); err != nil || bytes.Equal(expected2, d.e[nextArg:d.off]) == false { + if err := ParseMatchArg(k, &k.data, arg2, sig); err != nil || bytes.Equal(expected2, d.e[nextArg:d.off]) == false { t.Errorf("parseMatchArg: error %v expected %v bytes %v parsing %v\n", err, expected2, d.e[nextArg:d.off], arg2) } @@ -274,7 +274,7 @@ func TestParseMatchArg(t *testing.T) { 0x00, 0x00, 0x00, 0x00, // Addr4LPM mapid = 0 0xff, 0xff, 0xff, 0xff, // Addr6LPM no map } - if err := ParseMatchArg(k, arg3, sig); err != nil || bytes.Equal(expected3, d.e[nextArg:d.off]) == false { + if err := ParseMatchArg(k, &k.data, arg3, sig); err != nil || bytes.Equal(expected3, d.e[nextArg:d.off]) == false { t.Errorf("parseMatchArg: error %v expected %v bytes %v parsing %v\n", err, expected3, d.e[nextArg:d.off], arg3) } @@ -287,7 +287,7 @@ func TestParseMatchArg(t *testing.T) { 0x05, 0x00, 0x00, 0x00, // value type == skb 0x00, 0x00, 0x00, 0x00, // argfilter mapid = 0 } - if err := ParseMatchArg(k, arg4, sig); err != nil || bytes.Equal(expected4, d.e[nextArg:d.off]) == false { + if err := ParseMatchArg(k, &k.data, arg4, sig); err != nil || bytes.Equal(expected4, d.e[nextArg:d.off]) == false { t.Errorf("parseMatchArg: error %v expected %v bytes %v parsing %v\n", err, expected4, d.e[nextArg:d.off], arg4) } @@ -300,7 +300,7 @@ func TestParseMatchArg(t *testing.T) { 0x05, 0x00, 0x00, 0x00, // value type == skb 1, 0x00, 0x00, 0x00, // argfilter mapid = 1 } - if err := ParseMatchArg(k, arg5, sig); err != nil || bytes.Equal(expected5, d.e[nextArg:d.off]) == false { + if err := ParseMatchArg(k, &k.data, arg5, sig); err != nil || bytes.Equal(expected5, d.e[nextArg:d.off]) == false { t.Errorf("parseMatchArg: error %v expected %v bytes %v parsing %v\n", err, expected5, d.e[nextArg:d.off], arg5) } @@ -314,7 +314,7 @@ func TestParseMatchArg(t *testing.T) { 1, 0x00, 0x00, 0x00, // Addr4LPM mapid = 1 0x00, 0x00, 0x00, 0x00, // Addr6LPM mapid = 0 } - if err := ParseMatchArg(k, arg6, sig); err != nil || bytes.Equal(expected6, d.e[nextArg:d.off]) == false { + if err := ParseMatchArg(k, &k.data, arg6, sig); err != nil || bytes.Equal(expected6, d.e[nextArg:d.off]) == false { t.Errorf("parseMatchArg: error %v expected %v bytes %v parsing %v\n", err, expected6, d.e[nextArg:d.off], arg6) } @@ -332,7 +332,7 @@ func TestParseMatchArg(t *testing.T) { arg12 := []v1alpha1.ArgSelector{*arg1, *arg2} ks := NewKernelSelectorState(nil, nil) d = &ks.data - if err := ParseMatchArgs(ks, arg12, sig); err != nil || bytes.Equal(expected3, d.e[0:d.off]) == false { + if err := ParseMatchArgs(ks, &ks.data, arg12, sig); err != nil || bytes.Equal(expected3, d.e[0:d.off]) == false { t.Errorf("parseMatchArgs: error %v expected:\n%v\nbytes:\n%v\nparsing %v\n", err, expected3, d.e[0:d.off], arg3) } } From c26c5e2e6c0ead3377dc479f94b83f2e9c6080c0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 23 Dec 2024 11:29:01 +0000 Subject: [PATCH 04/11] tetragon: Pass data argument to ParseMatchActions Signed-off-by: Jiri Olsa --- pkg/selectors/kernel.go | 48 ++++++++++++++++++------------------ pkg/selectors/kernel_test.go | 6 ++--- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/pkg/selectors/kernel.go b/pkg/selectors/kernel.go index f3137c8d761..f1c4b26696e 100644 --- a/pkg/selectors/kernel.go +++ b/pkg/selectors/kernel.go @@ -907,12 +907,12 @@ func parseRateLimit(str string, scopeStr string) (uint32, uint32, error) { return uint32(rateLimit), scope, nil } -func ParseMatchAction(k *KernelSelectorState, action *v1alpha1.ActionSelector, actionArgTable *idtable.Table) error { +func ParseMatchAction(data *KernelSelectorData, action *v1alpha1.ActionSelector, actionArgTable *idtable.Table) error { act, ok := actionTypeTable[strings.ToLower(action.Action)] if !ok { return fmt.Errorf("parseMatchAction: ActionType %s unknown", action.Action) } - WriteSelectorUint32(&k.data, act) + WriteSelectorUint32(data, act) rateLimit := uint32(0) rateLimitScope := uint32(0) @@ -929,13 +929,13 @@ func ParseMatchAction(k *KernelSelectorState, action *v1alpha1.ActionSelector, a switch act { case ActionTypeFollowFd, ActionTypeCopyFd: - WriteSelectorUint32(&k.data, action.ArgFd) - WriteSelectorUint32(&k.data, action.ArgName) + WriteSelectorUint32(data, action.ArgFd) + WriteSelectorUint32(data, action.ArgName) case ActionTypeUnfollowFd: - WriteSelectorUint32(&k.data, action.ArgFd) - WriteSelectorUint32(&k.data, action.ArgName) + WriteSelectorUint32(data, action.ArgFd) + WriteSelectorUint32(data, action.ArgName) case ActionTypeOverride: - WriteSelectorInt32(&k.data, action.ArgError) + WriteSelectorInt32(data, action.ArgError) case ActionTypeGetUrl, ActionTypeDnsLookup: actionArg := ActionArgEntry{ tableId: idtable.UninitializedEntryID, @@ -947,42 +947,42 @@ func ParseMatchAction(k *KernelSelectorState, action *v1alpha1.ActionSelector, a actionArg.arg = action.ArgFqdn } actionArgTable.AddEntry(&actionArg) - WriteSelectorUint32(&k.data, uint32(actionArg.tableId.ID)) + WriteSelectorUint32(data, uint32(actionArg.tableId.ID)) case ActionTypeSignal: - WriteSelectorUint32(&k.data, action.ArgSig) + WriteSelectorUint32(data, action.ArgSig) case ActionTypeTrackSock, ActionTypeUntrackSock: - WriteSelectorUint32(&k.data, action.ArgSock) + WriteSelectorUint32(data, action.ArgSock) case ActionTypePost: - WriteSelectorUint32(&k.data, rateLimit) - WriteSelectorUint32(&k.data, rateLimitScope) + WriteSelectorUint32(data, rateLimit) + WriteSelectorUint32(data, rateLimitScope) kernelStackTrace := uint32(0) if action.KernelStackTrace { kernelStackTrace = 1 } - WriteSelectorUint32(&k.data, kernelStackTrace) + WriteSelectorUint32(data, kernelStackTrace) userStackTrace := uint32(0) if action.UserStackTrace { userStackTrace = 1 } - WriteSelectorUint32(&k.data, userStackTrace) + WriteSelectorUint32(data, userStackTrace) imaHash := uint32(0) if action.ImaHash { imaHash = 1 } - WriteSelectorUint32(&k.data, imaHash) + WriteSelectorUint32(data, imaHash) case ActionTypeNoPost: // no arguments case ActionTypeSigKill: // no arguments // NB: we should deprecate this action and just use ActionTypeSignal with SIGKILL case ActionTypeNotifyEnforcer: - WriteSelectorInt32(&k.data, action.ArgError) - WriteSelectorUint32(&k.data, action.ArgSig) + WriteSelectorInt32(data, action.ArgError) + WriteSelectorUint32(data, action.ArgSig) actionArgIndex := ^uint32(1) if action.EnforcerNotifyActionArgIndex != nil { actionArgIndex = *(action.EnforcerNotifyActionArgIndex) } - WriteSelectorUint32(&k.data, actionArgIndex) + WriteSelectorUint32(data, actionArgIndex) case ActionTypeCleanupEnforcerNotification: // no arguments default: @@ -991,19 +991,19 @@ func ParseMatchAction(k *KernelSelectorState, action *v1alpha1.ActionSelector, a return nil } -func ParseMatchActions(k *KernelSelectorState, actions []v1alpha1.ActionSelector, actionArgTable *idtable.Table) error { +func ParseMatchActions(data *KernelSelectorData, actions []v1alpha1.ActionSelector, actionArgTable *idtable.Table) error { if len(actions) > 3 { return fmt.Errorf("only %d actions are support for selector (current number of values is %d)", 3, len(actions)) } - loff := AdvanceSelectorLength(&k.data) + loff := AdvanceSelectorLength(data) for _, a := range actions { - if err := ParseMatchAction(k, &a, actionArgTable); err != nil { + if err := ParseMatchAction(data, &a, actionArgTable); err != nil { return err } } // No action (size value 4) defaults to post action. - WriteSelectorLength(&k.data, loff) + WriteSelectorLength(data, loff) return nil } @@ -1360,7 +1360,7 @@ func (k *KernelSelectorState) InitKernelSelector(selectors []v1alpha1.KProbeSele if err := ParseMatchArgs(k, &k.data, selectors.MatchArgs, args); err != nil { return fmt.Errorf("parseMatchArgs error: %w", err) } - if err := ParseMatchActions(k, selectors.MatchActions, actionArgTable); err != nil { + if err := ParseMatchActions(&k.data, selectors.MatchActions, actionArgTable); err != nil { return fmt.Errorf("parseMatchActions error: %w", err) } return nil @@ -1376,7 +1376,7 @@ func (k *KernelSelectorState) InitKernelReturnSelector(selectors []v1alpha1.KPro if err := ParseMatchArgs(k, &k.data, selector.MatchReturnArgs, []v1alpha1.KProbeArg{*returnArg}); err != nil { return fmt.Errorf("parseMatchArgs error: %w", err) } - if err := ParseMatchActions(k, selector.MatchReturnActions, actionArgTable); err != nil { + if err := ParseMatchActions(&k.data, selector.MatchReturnActions, actionArgTable); err != nil { return fmt.Errorf("parseMatchActions error: %w", err) } return nil diff --git a/pkg/selectors/kernel_test.go b/pkg/selectors/kernel_test.go index 1365718b93f..c0253e95dde 100644 --- a/pkg/selectors/kernel_test.go +++ b/pkg/selectors/kernel_test.go @@ -488,7 +488,7 @@ func TestParseMatchAction(t *testing.T) { 0x00, 0x00, 0x00, 0x00, // UserStackTrace = 0 0x00, 0x00, 0x00, 0x00, // ImaHash = 0 } - if err := ParseMatchAction(k, act1, &actionArgTable); err != nil || bytes.Equal(expected1, d.e[0:d.off]) == false { + if err := ParseMatchAction(&k.data, act1, &actionArgTable); err != nil || bytes.Equal(expected1, d.e[0:d.off]) == false { t.Errorf("parseMatchAction: error %v expected %v bytes %v parsing %v\n", err, expected1, d.e[0:d.off], act1) } // This is a bit contrived because we only have single action so far @@ -509,7 +509,7 @@ func TestParseMatchAction(t *testing.T) { act := []v1alpha1.ActionSelector{*act1, *act2} ks := &KernelSelectorState{data: KernelSelectorData{off: 0}} d = &ks.data - if err := ParseMatchActions(ks, act, &actionArgTable); err != nil || bytes.Equal(expected, d.e[0:d.off]) == false { + if err := ParseMatchActions(&ks.data, act, &actionArgTable); err != nil || bytes.Equal(expected, d.e[0:d.off]) == false { t.Errorf("parseMatchActions: error %v expected %v bytes %v parsing %v\n", err, expected, d.e[0:d.off], act) } } @@ -526,7 +526,7 @@ func TestParseMatchActionMax(t *testing.T) { k := &KernelSelectorState{data: KernelSelectorData{off: 0}} - err := ParseMatchActions(k, actions, &actionArgTable) + err := ParseMatchActions(&k.data, actions, &actionArgTable) if err == nil { t.Errorf("ParseMatchActions expected to fail") } From a8bf977863978db578f4fa559c4a87af44147e6d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 23 Dec 2024 11:51:05 +0000 Subject: [PATCH 05/11] tetragon: Move return filter to KernelSelectorState Signed-off-by: Jiri Olsa --- bpf/process/bpf_generic_kprobe.c | 2 +- bpf/process/bpf_generic_lsm_core.c | 2 +- bpf/process/bpf_generic_retkprobe.c | 2 +- bpf/process/bpf_generic_tracepoint.c | 2 +- bpf/process/bpf_generic_uprobe.c | 2 +- bpf/process/generic_calls.h | 23 +++++++++----- bpf/process/generic_maps.h | 10 +++++- pkg/selectors/kernel.go | 8 ++--- pkg/selectors/selectors.go | 8 +++-- pkg/sensors/tracing/generickprobe.go | 47 ++++++++-------------------- 10 files changed, 52 insertions(+), 54 deletions(-) diff --git a/bpf/process/bpf_generic_kprobe.c b/bpf/process/bpf_generic_kprobe.c index bf1ddb8d9d7..81127ff75d7 100644 --- a/bpf/process/bpf_generic_kprobe.c +++ b/bpf/process/bpf_generic_kprobe.c @@ -116,7 +116,7 @@ generic_kprobe_filter_arg(void *ctx) __attribute__((section("kprobe"), used)) int generic_kprobe_actions(void *ctx) { - generic_actions(ctx, (struct bpf_map_def *)&kprobe_calls); + generic_actions(ctx, (struct bpf_map_def *)&kprobe_calls, true); return 0; } diff --git a/bpf/process/bpf_generic_lsm_core.c b/bpf/process/bpf_generic_lsm_core.c index 9f8ffcf049e..65a09618e4f 100644 --- a/bpf/process/bpf_generic_lsm_core.c +++ b/bpf/process/bpf_generic_lsm_core.c @@ -84,7 +84,7 @@ generic_lsm_filter_arg(void *ctx) __attribute__((section("lsm"), used)) int generic_lsm_actions(void *ctx) { - bool postit = generic_actions(ctx, (struct bpf_map_def *)&lsm_calls); + bool postit = generic_actions(ctx, (struct bpf_map_def *)&lsm_calls, true); struct msg_generic_kprobe *e; int zero = 0; diff --git a/bpf/process/bpf_generic_retkprobe.c b/bpf/process/bpf_generic_retkprobe.c index 160639a9816..130e69040cd 100644 --- a/bpf/process/bpf_generic_retkprobe.c +++ b/bpf/process/bpf_generic_retkprobe.c @@ -58,7 +58,7 @@ BPF_KRETPROBE(generic_retkprobe_filter_arg) __attribute__((section("kprobe"), used)) int BPF_KRETPROBE(generic_retkprobe_actions) { - generic_actions(ctx, (struct bpf_map_def *)&retkprobe_calls); + generic_actions(ctx, (struct bpf_map_def *)&retkprobe_calls, false); return 0; } diff --git a/bpf/process/bpf_generic_tracepoint.c b/bpf/process/bpf_generic_tracepoint.c index a981998f9c8..ad512a4f2b8 100644 --- a/bpf/process/bpf_generic_tracepoint.c +++ b/bpf/process/bpf_generic_tracepoint.c @@ -247,7 +247,7 @@ generic_tracepoint_arg(void *ctx) __attribute__((section("tracepoint"), used)) int generic_tracepoint_actions(void *ctx) { - generic_actions(ctx, (struct bpf_map_def *)&tp_calls); + generic_actions(ctx, (struct bpf_map_def *)&tp_calls, true); return 0; } diff --git a/bpf/process/bpf_generic_uprobe.c b/bpf/process/bpf_generic_uprobe.c index 0a9d85bb280..5e346fd3a37 100644 --- a/bpf/process/bpf_generic_uprobe.c +++ b/bpf/process/bpf_generic_uprobe.c @@ -90,7 +90,7 @@ generic_uprobe_filter_arg(void *ctx) __attribute__((section("uprobe"), used)) int generic_uprobe_actions(void *ctx) { - generic_actions(ctx, (struct bpf_map_def *)&uprobe_calls); + generic_actions(ctx, (struct bpf_map_def *)&uprobe_calls, true); return 0; } diff --git a/bpf/process/generic_calls.h b/bpf/process/generic_calls.h index 5f0c5042abd..6af9b371b51 100644 --- a/bpf/process/generic_calls.h +++ b/bpf/process/generic_calls.h @@ -362,10 +362,11 @@ do_actions(void *ctx, struct selector_action *actions) } FUNC_INLINE long -generic_actions(void *ctx, struct bpf_map_def *calls) +generic_actions(void *ctx, struct bpf_map_def *calls, bool is_entry) { struct selector_arg_filters *arg; struct selector_action *actions; + struct filter_map_value *fval; struct msg_generic_kprobe *e; int actoff, pass, zero = 0; bool postit; @@ -379,10 +380,12 @@ generic_actions(void *ctx, struct bpf_map_def *calls) if (pass <= 1) return 0; - f = map_lookup_elem(&filter_map, &e->idx); - if (!f) + fval = map_lookup_elem(&filter_map, &e->idx); + if (!fval) return 0; + f = filter_map_ptr(fval, is_entry); + asm volatile("%[pass] &= 0x7ff;\n" : [pass] "+r"(pass) :); @@ -572,12 +575,15 @@ FUNC_INLINE int generic_process_filter(void) enter = event_find_curr(&ppid, &walker); if (enter) { + struct filter_map_value *fval; int selectors, pass; - __u32 *f = map_lookup_elem(&filter_map, &msg->idx); + __u32 *f; - if (!f) + fval = map_lookup_elem(&filter_map, &msg->idx); + if (!fval) return PFILTER_ERROR; + f = (__u32 *)filter_map_ptr(fval, true); sel = &msg->sel; current = &msg->current; @@ -615,11 +621,11 @@ FUNC_INLINE int generic_process_filter(void) FUNC_INLINE int filter_args(struct msg_generic_kprobe *e, int selidx, bool is_entry) { - __u8 *f; + struct filter_map_value *fval; /* No filters and no selectors so just accepts */ - f = map_lookup_elem(&filter_map, &e->idx); - if (!f) + fval = map_lookup_elem(&filter_map, &e->idx); + if (!fval) return 1; /* No selectors, accept by default */ @@ -634,6 +640,7 @@ FUNC_INLINE int filter_args(struct msg_generic_kprobe *e, int selidx, bool is_en return filter_args_reject(e->func_id); if (e->sel.active[selidx]) { + __u8 *f = filter_map_ptr(fval, is_entry); int pass = selector_arg_offset(f, e, selidx, is_entry); if (pass) diff --git a/bpf/process/generic_maps.h b/bpf/process/generic_maps.h index 193b177e68a..b32460a705a 100644 --- a/bpf/process/generic_maps.h +++ b/bpf/process/generic_maps.h @@ -4,6 +4,7 @@ #ifndef __GENERIC_MAPS_H__ #define __GENERIC_MAPS_H__ +#include #include "lib/data_msg.h" struct { @@ -37,9 +38,16 @@ struct { #endif struct filter_map_value { - unsigned char buf[FILTER_SIZE]; + __u8 entry[FILTER_SIZE]; + __u8 retrn[FILTER_SIZE]; }; +FUNC_INLINE __u8 * +filter_map_ptr(struct filter_map_value *fval, bool is_entry) +{ + return is_entry ? &fval->entry[0] : &fval->retrn[0]; +} + /* Arrays of size 1 will be rewritten to direct loads in verifier */ struct { __uint(type, BPF_MAP_TYPE_ARRAY); diff --git a/pkg/selectors/kernel.go b/pkg/selectors/kernel.go index f1c4b26696e..30cd76a6f14 100644 --- a/pkg/selectors/kernel.go +++ b/pkg/selectors/kernel.go @@ -1313,7 +1313,7 @@ func InitKernelReturnSelectors(selectors []v1alpha1.KProbeSelector, returnArg *v if err != nil { return [4096]byte{}, err } - return state.data.e, nil + return state.retn.e, nil } func createKernelSelectorState(data *KernelSelectorData, selectors []v1alpha1.KProbeSelector, @@ -1373,16 +1373,16 @@ func (k *KernelSelectorState) InitKernelReturnSelector(selectors []v1alpha1.KPro actionArgTable *idtable.Table) error { parse := func(selector *v1alpha1.KProbeSelector, _ int) error { - if err := ParseMatchArgs(k, &k.data, selector.MatchReturnArgs, []v1alpha1.KProbeArg{*returnArg}); err != nil { + if err := ParseMatchArgs(k, &k.retn, selector.MatchReturnArgs, []v1alpha1.KProbeArg{*returnArg}); err != nil { return fmt.Errorf("parseMatchArgs error: %w", err) } - if err := ParseMatchActions(&k.data, selector.MatchReturnActions, actionArgTable); err != nil { + if err := ParseMatchActions(&k.retn, selector.MatchReturnActions, actionArgTable); err != nil { return fmt.Errorf("parseMatchActions error: %w", err) } return nil } - return createKernelSelectorState(&k.data, selectors, parse) + return createKernelSelectorState(&k.retn, selectors, parse) } func HasOverride(spec *v1alpha1.KProbeSpec) bool { diff --git a/pkg/selectors/selectors.go b/pkg/selectors/selectors.go index 18b228a702b..1e0c4a71012 100644 --- a/pkg/selectors/selectors.go +++ b/pkg/selectors/selectors.go @@ -107,6 +107,7 @@ type KernelSelectorData struct { type KernelSelectorState struct { data KernelSelectorData + retn KernelSelectorData // valueMaps are used to populate value maps for InMap and NotInMap operators valueMaps []ValueMap @@ -166,8 +167,11 @@ func (k *KernelSelectorState) MatchBinariesPathsMaxEntries() int { return maxEntries } -func (k *KernelSelectorState) Buffer() [4096]byte { - return k.data.e +func (k *KernelSelectorState) Buffer() [8192]byte { + var ret [8192]byte + copy(ret[:], k.data.e[:]) + copy(ret[4096:], k.retn.e[:]) + return ret } func (k *KernelSelectorState) ValueMaps() []ValueMap { diff --git a/pkg/sensors/tracing/generickprobe.go b/pkg/sensors/tracing/generickprobe.go index ee931038852..bb9d3001d06 100644 --- a/pkg/sensors/tracing/generickprobe.go +++ b/pkg/sensors/tracing/generickprobe.go @@ -81,16 +81,11 @@ func kprobeCharBufErrorToString(e int32) string { return "CharBufErrorUnknown" } -type kprobeSelectors struct { - entry *selectors.KernelSelectorState - retrn *selectors.KernelSelectorState -} - type kprobeLoadArgs struct { - selectors kprobeSelectors - retprobe bool - syscall bool - config *api.EventConfig + selector *selectors.KernelSelectorState + retprobe bool + syscall bool + config *api.EventConfig } type pendingEventKey struct { @@ -185,25 +180,18 @@ var ( MaxFilterIntArgs = 8 ) -func getProgramSelector(load *program.Program, kprobeEntry *genericKprobe) *selectors.KernelSelectorState { - if kprobeEntry != nil { - if load.RetProbe { - return kprobeEntry.loadArgs.selectors.retrn - } - return kprobeEntry.loadArgs.selectors.entry - } - return nil -} - func filterMaps(load *program.Program, kprobeEntry *genericKprobe) []*program.Map { var maps []*program.Map + var state *selectors.KernelSelectorState /* * If we got passed genericKprobe != nil we can make selector map fixes * related to the kernel version. We pass nil for multi kprobes but as * they are added in later kernels than 5.9, there's no fixing needed. */ - state := getProgramSelector(load, kprobeEntry) + if kprobeEntry != nil { + state = kprobeEntry.loadArgs.selector + } argFilterMaps := program.MapBuilderProgram("argfilter_maps", load) if state != nil && !kernels.MinKernelVersion("5.9") { @@ -881,16 +869,15 @@ func addKprobe(funcName string, instance int, f *v1alpha1.KProbeSpec, in *addKpr if err := state.InitKernelSelector(f.Selectors, f.Args, &kprobeEntry.actionArgs); err != nil { return errFn(err) } - kprobeEntry.loadArgs.selectors.entry = state if f.Return { - state := selectors.NewKernelSelectorState(nil, in.selMaps) if err := state.InitKernelReturnSelector(f.Selectors, f.ReturnArg, &kprobeEntry.actionArgs); err != nil { return errFn(err) } - kprobeEntry.loadArgs.selectors.retrn = state } + kprobeEntry.loadArgs.selector = state + kprobeEntry.pendingEvents, err = lru.New[pendingEventKey, pendingEvent](4096) if err != nil { return errFn(err) @@ -963,7 +950,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ - matchBinariesPaths.SetInnerMaxEntries(kprobeEntry.loadArgs.selectors.entry.MatchBinariesPathsMaxEntries()) + matchBinariesPaths.SetInnerMaxEntries(kprobeEntry.loadArgs.selector.MatchBinariesPathsMaxEntries()) } maps = append(maps, matchBinariesPaths) @@ -1081,21 +1068,13 @@ func createSingleKprobeSensor(ids []idtable.EntryID, has hasMaps) ([]*program.Pr return progs, maps, nil } -func getMapLoad(load *program.Program, kprobeEntry *genericKprobe, index uint32) []*program.MapLoad { - state := getProgramSelector(load, kprobeEntry) - if state == nil { - return []*program.MapLoad{} - } - return selectorsMaploads(state, index) -} - func loadSingleKprobeSensor(id idtable.EntryID, bpfDir string, load *program.Program, verbose int) error { gk, err := genericKprobeTableGet(id) if err != nil { return err } - load.MapLoad = append(load.MapLoad, getMapLoad(load, gk, 0)...) + load.MapLoad = append(load.MapLoad, selectorsMaploads(gk.loadArgs.selector, 0)...) var configData bytes.Buffer binary.Write(&configData, binary.LittleEndian, gk.loadArgs.config) @@ -1128,7 +1107,7 @@ func loadMultiKprobeSensor(ids []idtable.EntryID, bpfDir string, load *program.P return err } - load.MapLoad = append(load.MapLoad, getMapLoad(load, gk, uint32(index))...) + load.MapLoad = append(load.MapLoad, selectorsMaploads(gk.loadArgs.selector, uint32(index))...) binary.Write(&bin_buf[index], binary.LittleEndian, gk.loadArgs.config) config := &program.MapLoad{ From b97fc37023eb50b68adfd1ea39eb43d2770513c2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 20 Dec 2024 14:19:55 +0000 Subject: [PATCH 06/11] tetragon: Add HasKprobeSession function Signed-off-by: Jiri Olsa --- pkg/bpf/detect.go | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/pkg/bpf/detect.go b/pkg/bpf/detect.go index 0a84f35ae06..6f76d14304a 100644 --- a/pkg/bpf/detect.go +++ b/pkg/bpf/detect.go @@ -32,6 +32,7 @@ type Feature struct { } var ( + kprobeSession Feature kprobeMulti Feature uprobeMulti Feature buildid Feature @@ -81,6 +82,35 @@ func HasKprobeMulti() bool { return kprobeMulti.detected } +func detectKprobeSession() bool { + prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ + Name: "probe_bpf_kprobe_multi_link", + Type: ebpf.Kprobe, + Instructions: asm.Instructions{ + asm.Mov.Imm(asm.R0, 0), + asm.Return(), + }, + AttachType: ebpf.AttachTraceKprobeSession, + License: "MIT", + }) + if err != nil { + return false + } + defer prog.Close() + + syms := []string{"vprintk"} + opts := link.KprobeMultiOptions{Symbols: syms, Session: true} + _, err = link.KprobeMulti(prog, opts) + return err == nil +} + +func HasKprobeSession() bool { + kprobeSession.init.Do(func() { + kprobeSession.detected = detectKprobeSession() + }) + return kprobeSession.detected +} + func detectUprobeMulti() bool { prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ Name: "probe_upm_link", @@ -426,8 +456,8 @@ func LogFeatures() string { // we cache all values so calling again a Has* function will // not load the BTF again defer ebtf.FlushKernelSpec() - return fmt.Sprintf("override_return: %t, buildid: %t, kprobe_multi: %t, uprobe_multi %t, fmodret: %t, fmodret_syscall: %t, signal: %t, large: %t, link_pin: %t, lsm: %t, missed_stats_kprobe_multi: %t, missed_stats_kprobe: %t", - HasOverrideHelper(), HasBuildId(), HasKprobeMulti(), HasUprobeMulti(), + return fmt.Sprintf("override_return: %t, buildid: %t, kprobe_multi: %t, kprobe_session %t, uprobe_multi %t, fmodret: %t, fmodret_syscall: %t, signal: %t, large: %t, link_pin: %t, lsm: %t, missed_stats_kprobe_multi: %t, missed_stats_kprobe: %t", + HasOverrideHelper(), HasBuildId(), HasKprobeMulti(), HasKprobeSession(), HasUprobeMulti(), HasModifyReturn(), HasModifyReturnSyscall(), HasSignalHelper(), HasProgramLargeSize(), HasLinkPin(), HasLSMPrograms(), HasMissedStatsKprobeMulti(), HasMissedStatsPerfEvent()) } From e34e5e2ea2f1dc90a016b577fe78d741c08a16c3 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 20 Dec 2024 23:15:17 +0000 Subject: [PATCH 07/11] tetragon: Add bpf_session_kprobe.c bpf object Signed-off-by: Jiri Olsa --- bpf/Makefile | 4 + bpf/include/api.h | 5 + bpf/lib/generic.h | 1 + bpf/process/bpf_session_kprobe.c | 153 +++++++++++++++++++++++++++++++ bpf/process/generic_calls.h | 1 + 5 files changed, 164 insertions(+) create mode 100644 bpf/process/bpf_session_kprobe.c diff --git a/bpf/Makefile b/bpf/Makefile index 778053579cf..f13b3da1694 100644 --- a/bpf/Makefile +++ b/bpf/Makefile @@ -75,6 +75,9 @@ PROCESS += bpf_generic_kprobe_v61.o bpf_generic_retkprobe_v61.o \ PROCESS += bpf_generic_lsm_core_v61.o bpf_generic_lsm_output_v61.o \ bpf_generic_lsm_ima_file_v61.o bpf_generic_lsm_ima_bprm_v61.o +# session +PROCESS += bpf_session_kprobe.o + CGROUP = bpf_cgroup_mkdir.o bpf_cgroup_rmdir.o bpf_cgroup_release.o bpf_cgtracker.o BPFTEST = bpf_lseek.o @@ -116,6 +119,7 @@ CFLAGS_bpf_enforcer.o = -D__BPF_OVERRIDE_RETURN CFLAGS_bpf_multi_enforcer.o = -D__BPF_OVERRIDE_RETURN -D__MULTI_KPROBE CFLAGS_bpf_generic_lsm_core.o = -D__LARGE_BPF_PROG CFLAGS_bpf_generic_lsm_output.o = -D__LARGE_BPF_PROG +CFLAGS_bpf_session_kprobe.o = -D__LARGE_BPF_PROG -D__LARGE_MAP_KEYS -D__V61_BPF_PROG -D__MULTI_KPROBE # Rules MTARGET_o = $(patsubst $(DEPSDIR)%.d,$(OBJSDIR)%.o,$@) diff --git a/bpf/include/api.h b/bpf/include/api.h index 82026545cdf..8ba4aecac62 100644 --- a/bpf/include/api.h +++ b/bpf/include/api.h @@ -303,4 +303,9 @@ static int BPF_FUNC(seq_write, struct seq_file *m, const void *data, uint32_t le #endif #endif +#define __ksym __attribute__((section(".ksyms"))) + +extern bool bpf_session_is_return(void) __ksym; +extern __u64 *bpf_session_cookie(void) __ksym; + #endif /* __BPF_API__ */ diff --git a/bpf/lib/generic.h b/bpf/lib/generic.h index bf785b11bdb..8d5bb197d82 100644 --- a/bpf/lib/generic.h +++ b/bpf/lib/generic.h @@ -62,6 +62,7 @@ struct msg_generic_kprobe { bool post; // true if event needs to be posted } lsm; }; + bool has_return; /* true if there's return probe defined */ }; FUNC_INLINE size_t generic_kprobe_common_size(void) diff --git a/bpf/process/bpf_session_kprobe.c b/bpf/process/bpf_session_kprobe.c new file mode 100644 index 00000000000..ec15a71b136 --- /dev/null +++ b/bpf/process/bpf_session_kprobe.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* Copyright Authors of Cilium */ + +#include "vmlinux.h" +#include "api.h" + +#define GENERIC_KPROBE + +#include "compiler.h" +#include "bpf_event.h" +#include "bpf_task.h" +#include "retprobe_map.h" +#include "types/operations.h" +#include "types/basic.h" +#include "pfilter.h" +#include "policy_filter.h" + +char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; + +int generic_kprobe_setup_event(void *ctx); +int generic_kprobe_process_event(void *ctx); +int generic_kprobe_process_filter(void *ctx); +int generic_kprobe_filter_arg(void *ctx); +int generic_kprobe_actions(void *ctx); +int generic_kprobe_output(void *ctx); + +struct { + __uint(type, BPF_MAP_TYPE_PROG_ARRAY); + __uint(max_entries, 13); + __uint(key_size, sizeof(__u32)); + __array(values, int(void *)); +} kprobe_calls SEC(".maps") = { + .values = { + [0] = (void *)&generic_kprobe_setup_event, + [1] = (void *)&generic_kprobe_process_event, + [2] = (void *)&generic_kprobe_process_filter, + [3] = (void *)&generic_kprobe_filter_arg, + [4] = (void *)&generic_kprobe_actions, + [5] = (void *)&generic_kprobe_output, + }, +}; + +int generic_retkprobe_filter_arg(void *ctx); +int generic_retkprobe_actions(void *ctx); +int generic_retkprobe_output(void *ctx); + +struct { + __uint(type, BPF_MAP_TYPE_PROG_ARRAY); + __uint(max_entries, 6); + __uint(key_size, sizeof(__u32)); + __array(values, int(void *)); +} retkprobe_calls SEC(".maps") = { + .values = { + [3] = (void *)&generic_retkprobe_filter_arg, + [4] = (void *)&generic_retkprobe_actions, + [5] = (void *)&generic_retkprobe_output, + }, +}; + +#include "generic_maps.h" +#include "generic_calls.h" + +__attribute__((section(("kprobe.session/generic_kprobe")), used)) int +generic_kprobe_event(struct pt_regs *ctx) +{ + if (bpf_session_is_return()) { + return generic_retkprobe(ctx, (struct bpf_map_def *)&retkprobe_calls, + PT_REGS_RC(ctx)); + } + + generic_start_process_filter(ctx, (struct bpf_map_def *)&kprobe_calls); + return 1; /* kill return probe */ +} + +__attribute__((section("kprobe.session"), used)) int +generic_kprobe_setup_event(void *ctx) +{ + generic_process_event_and_setup(ctx, (struct bpf_map_def *)&kprobe_calls); + return 1; /* kill return probe */ +} + +__attribute__((section("kprobe.session"), used)) int +generic_kprobe_process_event(void *ctx) +{ + generic_process_event(ctx, (struct bpf_map_def *)&kprobe_calls); + return 1; /* kill return probe */ +} + +__attribute__((section("kprobe.session"), used)) int +generic_kprobe_process_filter(void *ctx) +{ + int ret; + + ret = generic_process_filter(); + if (ret == PFILTER_CONTINUE) + tail_call(ctx, &kprobe_calls, TAIL_CALL_FILTER); + else if (ret == PFILTER_ACCEPT) + tail_call(ctx, &kprobe_calls, 0); + /* If filter does not accept drop it. Ideally we would + * log error codes for later review, TBD. + */ + return ret == PFILTER_REJECT ? 1 : 0; +} + +__attribute__((section("kprobe.session"), used)) int +generic_kprobe_filter_arg(void *ctx) +{ + generic_filter_arg(ctx, (struct bpf_map_def *)&kprobe_calls, true); + return 1; /* kill return probe */ +} + +__attribute__((section("kprobe.session"), used)) int +generic_kprobe_actions(void *ctx) +{ + generic_actions(ctx, (struct bpf_map_def *)&kprobe_calls, true); + return 1; /* kill return probe */ +} + +__attribute__((section("kprobe.session"), used)) int +generic_kprobe_output(void *ctx) +{ + return generic_output(ctx, MSG_OP_GENERIC_KPROBE); +} + +__attribute__((section("kprobe.session"), used)) int +generic_retkprobe_filter_arg(void *ctx) +{ + return generic_filter_arg(ctx, (struct bpf_map_def *)&retkprobe_calls, false); +} + +__attribute__((section("kprobe.session"), used)) int +generic_retkprobe_actions(void *ctx) +{ + generic_actions(ctx, (struct bpf_map_def *)&retkprobe_calls, false); + return 0; +} + +__attribute__((section("kprobe.session"), used)) int +generic_retkprobe_output(void *ctx) +{ + struct msg_generic_kprobe *msg; + int ret = 0, zero = 0; + + generic_output(ctx, MSG_OP_GENERIC_KPROBE); + + /* make sure we want to trigger return probe */ + msg = map_lookup_elem(&process_call_heap, &zero); + ret = msg && msg->has_return; + + asm volatile("%[ret] &= 0x1;\n" + : [ret] "+r"(ret)); + return ret; +} diff --git a/bpf/process/generic_calls.h b/bpf/process/generic_calls.h index 6af9b371b51..791d55bf7f2 100644 --- a/bpf/process/generic_calls.h +++ b/bpf/process/generic_calls.h @@ -33,6 +33,7 @@ generic_start_process_filter(void *ctx, struct bpf_map_def *calls) return 0; msg->func_id = config->func_id; msg->retprobe_id = 0; + msg->has_return = config->argreturn != 0; /* Initialize selector index to 0 */ msg->sel.curr = 0; From b0e57865b2b6f5dac3442000db8397f24c9e5a9d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 18 Dec 2024 20:30:27 +0000 Subject: [PATCH 08/11] tetragon: Add support to attach kprobe session program Signed-off-by: Jiri Olsa --- pkg/sensors/program/loader.go | 2 + pkg/sensors/program/program.go | 1 + pkg/sensors/tracing/generickprobe.go | 60 ++++++++++++++++++++++------ 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/pkg/sensors/program/loader.go b/pkg/sensors/program/loader.go index 01958701095..8778529fe97 100644 --- a/pkg/sensors/program/loader.go +++ b/pkg/sensors/program/loader.go @@ -509,6 +509,7 @@ func MultiKprobeAttach(load *Program, bpfDir string) AttachFunc { opts := link.KprobeMultiOptions{ Symbols: data.Overrides, + Session: data.Session, } load.unloaderOverride, err = multiKprobeAttach(load, progOverride, progOverrideSpec, opts, bpfDir, "override") @@ -520,6 +521,7 @@ func MultiKprobeAttach(load *Program, bpfDir string) AttachFunc { opts := link.KprobeMultiOptions{ Symbols: data.Symbols, Cookies: data.Cookies, + Session: data.Session, } return multiKprobeAttach(load, prog, spec, opts, bpfDir) diff --git a/pkg/sensors/program/program.go b/pkg/sensors/program/program.go index 4a84676e37f..00a02caf816 100644 --- a/pkg/sensors/program/program.go +++ b/pkg/sensors/program/program.go @@ -77,6 +77,7 @@ type MultiKprobeAttachData struct { Symbols []string Cookies []uint64 Overrides []string + Session bool } type UprobeAttachData struct { diff --git a/pkg/sensors/tracing/generickprobe.go b/pkg/sensors/tracing/generickprobe.go index bb9d3001d06..0c387a19279 100644 --- a/pkg/sensors/tracing/generickprobe.go +++ b/pkg/sensors/tracing/generickprobe.go @@ -93,6 +93,11 @@ type pendingEventKey struct { ktimeEnter uint64 } +type multiKprobeLoaderData struct { + ids []idtable.EntryID + session bool +} + type genericKprobeData struct { // stackTraceMap reference is needed when retrieving stack traces from // userspace when receiving events containing stacktrace IDs @@ -262,6 +267,7 @@ func createMultiKprobeSensor(policyName string, multiIDs []idtable.EntryID, has var multiRetIDs []idtable.EntryID var progs []*program.Program var maps []*program.Map + var load *program.Program data := &genericKprobeData{} @@ -290,14 +296,34 @@ func createMultiKprobeSensor(policyName string, multiIDs []idtable.EntryID, has loadProgRetName = "bpf_multi_retkprobe_v511.o" } - load := program.Builder( - path.Join(option.Config.HubbleLib, loadProgName), - fmt.Sprintf("kprobe_multi (%d functions)", len(multiIDs)), - "kprobe.multi/generic_kprobe", - "multi_kprobe", - "generic_kprobe"). - SetLoaderData(multiIDs). - SetPolicy(policyName) + useSession := bpf.HasKprobeSession() && !has.override + + if useSession { + load = program.Builder( + path.Join(option.Config.HubbleLib, "bpf_session_kprobe.o"), + fmt.Sprintf("kprobe_session (%d functions)", len(multiIDs)), + "kprobe.session/generic_kprobe", + "session_kprobe", + "generic_kprobe"). + SetLoaderData(multiKprobeLoaderData{ + ids: multiIDs, + session: useSession, + }). + SetPolicy(policyName) + } else { + load = program.Builder( + path.Join(option.Config.HubbleLib, loadProgName), + fmt.Sprintf("kprobe_multi (%d functions)", len(multiIDs)), + "kprobe.multi/generic_kprobe", + "multi_kprobe", + "generic_kprobe"). + SetLoaderData(multiIDs). + SetLoaderData(multiKprobeLoaderData{ + ids: multiIDs, + }). + SetPolicy(policyName) + } + progs = append(progs, load) fdinstall := program.MapBuilderSensor("fdinstall_map", load) @@ -367,6 +393,12 @@ func createMultiKprobeSensor(policyName string, multiIDs []idtable.EntryID, has } maps = append(maps, overrideTasksMap) + if useSession { + retTailCalls := program.MapBuilderProgram("retkprobe_calls", load) + maps = append(maps, retTailCalls) + return progs, maps, nil + } + if len(multiRetIDs) != 0 { loadret := program.Builder( path.Join(option.Config.HubbleLib, loadProgRetName), @@ -375,7 +407,9 @@ func createMultiKprobeSensor(policyName string, multiIDs []idtable.EntryID, has "multi_retkprobe", "generic_kprobe"). SetRetProbe(true). - SetLoaderData(multiRetIDs). + SetLoaderData(multiKprobeLoaderData{ + ids: multiRetIDs, + }). SetPolicy(policyName) progs = append(progs, loadret) @@ -1096,10 +1130,10 @@ func loadSingleKprobeSensor(id idtable.EntryID, bpfDir string, load *program.Pro return err } -func loadMultiKprobeSensor(ids []idtable.EntryID, bpfDir string, load *program.Program, verbose int) error { +func loadMultiKprobeSensor(ids []idtable.EntryID, session bool, bpfDir string, load *program.Program, verbose int) error { bin_buf := make([]bytes.Buffer, len(ids)) - data := &program.MultiKprobeAttachData{} + data := &program.MultiKprobeAttachData{Session: session} for index, id := range ids { gk, err := genericKprobeTableGet(id) @@ -1144,8 +1178,8 @@ func loadGenericKprobeSensor(bpfDir string, load *program.Program, verbose int) if id, ok := load.LoaderData.(idtable.EntryID); ok { return loadSingleKprobeSensor(id, bpfDir, load, verbose) } - if ids, ok := load.LoaderData.([]idtable.EntryID); ok { - return loadMultiKprobeSensor(ids, bpfDir, load, verbose) + if data, ok := load.LoaderData.(multiKprobeLoaderData); ok { + return loadMultiKprobeSensor(data.ids, data.session, bpfDir, load, verbose) } return fmt.Errorf("invalid loadData type: expecting idtable.EntryID/[] and got: %T (%v)", load.LoaderData, load.LoaderData) From 03b2997e4a4d474a18111105aa842deeb29c984d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 29 Dec 2024 10:49:54 +0000 Subject: [PATCH 09/11] tetragon: Skip kprobe session object in verify test Signed-off-by: Jiri Olsa --- contrib/verify/verify.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contrib/verify/verify.sh b/contrib/verify/verify.sh index b87be0556ee..b2ae000adda 100755 --- a/contrib/verify/verify.sh +++ b/contrib/verify/verify.sh @@ -64,6 +64,11 @@ for obj in "$TETRAGONDIR"/*.o; do continue fi + # Session kprobe support is still not widely around, skip the object + if [[ "$B" == bpf_session_* ]]; then + continue + fi + # Skip v6.1 objects check for kernel < 6.1 if [[ "$B" == *61.o && $(echo "$KERNEL < 6.1" | bc) == 1 ]]; then continue From e1e071e9be0eca271071ae2f86d36f87a74cd537 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 29 Dec 2024 20:15:10 +0000 Subject: [PATCH 10/11] tetragon: Add session specific setup to TestLoadKprobeSensor Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/kprobe_test.go | 146 ++++++++++++++++++++--------- 1 file changed, 101 insertions(+), 45 deletions(-) diff --git a/pkg/sensors/tracing/kprobe_test.go b/pkg/sensors/tracing/kprobe_test.go index 1822c482d77..ea8025cf10d 100644 --- a/pkg/sensors/tracing/kprobe_test.go +++ b/pkg/sensors/tracing/kprobe_test.go @@ -4327,64 +4327,120 @@ spec: } func TestLoadKprobeSensor(t *testing.T) { - var sensorProgs = []tus.SensorProg{ - // kprobe - 0: tus.SensorProg{Name: "generic_kprobe_event", Type: ebpf.Kprobe}, - 1: tus.SensorProg{Name: "generic_kprobe_setup_event", Type: ebpf.Kprobe}, - 2: tus.SensorProg{Name: "generic_kprobe_process_event", Type: ebpf.Kprobe}, - 3: tus.SensorProg{Name: "generic_kprobe_filter_arg", Type: ebpf.Kprobe}, - 4: tus.SensorProg{Name: "generic_kprobe_process_filter", Type: ebpf.Kprobe}, - 5: tus.SensorProg{Name: "generic_kprobe_actions", Type: ebpf.Kprobe}, - 6: tus.SensorProg{Name: "generic_kprobe_output", Type: ebpf.Kprobe}, - // retkprobe - 7: tus.SensorProg{Name: "generic_retkprobe_event", Type: ebpf.Kprobe}, - 8: tus.SensorProg{Name: "generic_retkprobe_filter_arg", Type: ebpf.Kprobe}, - 9: tus.SensorProg{Name: "generic_retkprobe_actions", Type: ebpf.Kprobe}, - 10: tus.SensorProg{Name: "generic_retkprobe_output", Type: ebpf.Kprobe}, - } + var ( + sensorProgs []tus.SensorProg + sensorMaps []tus.SensorMap + ) + + if bpf.HasKprobeSession() { + sensorProgs = []tus.SensorProg{ + 0: tus.SensorProg{Name: "generic_kprobe_event", Type: ebpf.Kprobe}, + 1: tus.SensorProg{Name: "generic_kprobe_setup_event", Type: ebpf.Kprobe}, + 2: tus.SensorProg{Name: "generic_kprobe_process_event", Type: ebpf.Kprobe}, + 3: tus.SensorProg{Name: "generic_kprobe_filter_arg", Type: ebpf.Kprobe}, + 4: tus.SensorProg{Name: "generic_kprobe_process_filter", Type: ebpf.Kprobe}, + 5: tus.SensorProg{Name: "generic_kprobe_actions", Type: ebpf.Kprobe}, + 6: tus.SensorProg{Name: "generic_kprobe_output", Type: ebpf.Kprobe}, + 7: tus.SensorProg{Name: "generic_retkprobe_filter_arg", Type: ebpf.Kprobe}, + 8: tus.SensorProg{Name: "generic_retkprobe_actions", Type: ebpf.Kprobe}, + 9: tus.SensorProg{Name: "generic_retkprobe_output", Type: ebpf.Kprobe}, + } - var sensorMaps = []tus.SensorMap{ - // all kprobe programs - tus.SensorMap{Name: "process_call_heap", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, + sensorMaps = []tus.SensorMap{ + // all kprobe programs + tus.SensorMap{Name: "process_call_heap", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}, - // all but generic_kprobe_output - tus.SensorMap{Name: "kprobe_calls", Progs: []uint{0, 1, 2, 3, 4, 5}}, + // all but generic_kprobe_output + tus.SensorMap{Name: "kprobe_calls", Progs: []uint{0, 1, 2, 3, 4, 5}}, - // generic_retkprobe_event - tus.SensorMap{Name: "retkprobe_calls", Progs: []uint{7, 8, 9}}, + // generic_retkprobe_event + tus.SensorMap{Name: "retkprobe_calls", Progs: []uint{0, 7, 8}}, - // generic_kprobe_process_filter,generic_kprobe_filter_arg, - // generic_kprobe_actions,generic_kprobe_output - tus.SensorMap{Name: "filter_map", Progs: []uint{3, 4, 5}}, + // generic_kprobe_process_filter,generic_kprobe_filter_arg, + // generic_kprobe_actions,generic_kprobe_output + tus.SensorMap{Name: "filter_map", Progs: []uint{3, 4, 5, 7, 8}}, - // generic_kprobe_actions - tus.SensorMap{Name: "override_tasks", Progs: []uint{5}}, + // generic_kprobe_actions + tus.SensorMap{Name: "override_tasks", Progs: []uint{5, 8}}, - // all kprobe but generic_kprobe_process_filter,generic_retkprobe_event - tus.SensorMap{Name: "config_map", Progs: []uint{0, 1, 2}}, + // all kprobe but generic_kprobe_process_filter,generic_retkprobe_event + tus.SensorMap{Name: "config_map", Progs: []uint{0, 1, 2}}, - // generic_kprobe_process_event*,generic_kprobe_actions,retkprobe - tus.SensorMap{Name: "fdinstall_map", Progs: []uint{1, 2, 5, 7, 9}}, + // generic_kprobe_process_event*,generic_kprobe_actions,retkprobe + tus.SensorMap{Name: "fdinstall_map", Progs: []uint{0, 1, 2, 5, 8}}, - // generic_kprobe_event - tus.SensorMap{Name: "tg_conf_map", Progs: []uint{0}}, - } + // generic_kprobe_event + tus.SensorMap{Name: "tg_conf_map", Progs: []uint{0}}, - if kernels.EnableLargeProgs() { - // shared with base sensor - sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4, 5, 6, 7, 9}}) + // shared with base sensor + tus.SensorMap{Name: "execve_map", Progs: []uint{0, 4, 5, 6, 8, 9}}, - // generic_kprobe_process_event*,generic_kprobe_output,generic_retkprobe_output - sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tcpmon_map", Progs: []uint{1, 2, 6, 10}}) + // generic_kprobe_process_event*,generic_kprobe_output,generic_retkprobe_output + tus.SensorMap{Name: "tcpmon_map", Progs: []uint{1, 2, 6, 9}}, - // generic_kprobe_process_event*,generic_kprobe_actions,retkprobe - sensorMaps = append(sensorMaps, tus.SensorMap{Name: "socktrack_map", Progs: []uint{1, 2, 5, 7, 9}}) + // generic_kprobe_process_event*,generic_kprobe_actions,retkprobe + tus.SensorMap{Name: "socktrack_map", Progs: []uint{0, 1, 2, 5, 8}}, + } } else { - // shared with base sensor - sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4, 7}}) + sensorProgs = []tus.SensorProg{ + // kprobe + 0: tus.SensorProg{Name: "generic_kprobe_event", Type: ebpf.Kprobe}, + 1: tus.SensorProg{Name: "generic_kprobe_setup_event", Type: ebpf.Kprobe}, + 2: tus.SensorProg{Name: "generic_kprobe_process_event", Type: ebpf.Kprobe}, + 3: tus.SensorProg{Name: "generic_kprobe_filter_arg", Type: ebpf.Kprobe}, + 4: tus.SensorProg{Name: "generic_kprobe_process_filter", Type: ebpf.Kprobe}, + 5: tus.SensorProg{Name: "generic_kprobe_actions", Type: ebpf.Kprobe}, + 6: tus.SensorProg{Name: "generic_kprobe_output", Type: ebpf.Kprobe}, + // retkprobe + 7: tus.SensorProg{Name: "generic_retkprobe_event", Type: ebpf.Kprobe}, + 8: tus.SensorProg{Name: "generic_retkprobe_filter_arg", Type: ebpf.Kprobe}, + 9: tus.SensorProg{Name: "generic_retkprobe_actions", Type: ebpf.Kprobe}, + 10: tus.SensorProg{Name: "generic_retkprobe_output", Type: ebpf.Kprobe}, + } + + sensorMaps = []tus.SensorMap{ + // all kprobe programs + tus.SensorMap{Name: "process_call_heap", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, + + // all but generic_kprobe_output + tus.SensorMap{Name: "kprobe_calls", Progs: []uint{0, 1, 2, 3, 4, 5}}, + + // generic_retkprobe_event + tus.SensorMap{Name: "retkprobe_calls", Progs: []uint{7, 8, 9}}, + + // generic_kprobe_process_filter,generic_kprobe_filter_arg, + // generic_kprobe_actions,generic_kprobe_output + tus.SensorMap{Name: "filter_map", Progs: []uint{3, 4, 5}}, - // generic_kprobe_output,generic_retkprobe_output - sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tcpmon_map", Progs: []uint{6, 10}}) + // generic_kprobe_actions + tus.SensorMap{Name: "override_tasks", Progs: []uint{5}}, + + // all kprobe but generic_kprobe_process_filter,generic_retkprobe_event + tus.SensorMap{Name: "config_map", Progs: []uint{0, 1, 2}}, + + // generic_kprobe_process_event*,generic_kprobe_actions,retkprobe + tus.SensorMap{Name: "fdinstall_map", Progs: []uint{1, 2, 5, 7, 9}}, + + // generic_kprobe_event + tus.SensorMap{Name: "tg_conf_map", Progs: []uint{0}}, + } + + if kernels.EnableLargeProgs() { + // shared with base sensor + sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4, 5, 6, 7, 9}}) + + // generic_kprobe_process_event*,generic_kprobe_output,generic_retkprobe_output + sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tcpmon_map", Progs: []uint{1, 2, 6, 10}}) + + // generic_kprobe_process_event*,generic_kprobe_actions,retkprobe + sensorMaps = append(sensorMaps, tus.SensorMap{Name: "socktrack_map", Progs: []uint{1, 2, 5, 7, 9}}) + } else { + // shared with base sensor + sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4, 7}}) + + // generic_kprobe_output,generic_retkprobe_output + sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tcpmon_map", Progs: []uint{6, 10}}) + } } readHook := ` From 8fcf4152090b95bb2a6fc9239e07ecb522c7fbac Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 29 Dec 2024 20:15:57 +0000 Subject: [PATCH 11/11] tetragon: Adjust TestMissedProgStatsKprobeMulti test for session Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/kprobe_test.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/pkg/sensors/tracing/kprobe_test.go b/pkg/sensors/tracing/kprobe_test.go index ea8025cf10d..3689160d025 100644 --- a/pkg/sensors/tracing/kprobe_test.go +++ b/pkg/sensors/tracing/kprobe_test.go @@ -7013,14 +7013,24 @@ spec: fmt.Printf("Failed to execute test binary: %s\n", err) } - expected := strings.NewReader(` # HELP tetragon_missed_prog_probes_total The total number of Tetragon probe missed by program. + s := ` # HELP tetragon_missed_prog_probes_total The total number of Tetragon probe missed by program. # TYPE tetragon_missed_prog_probes_total counter tetragon_missed_prog_probes_total{attach="acct_process",policy="__base__"} 0 -tetragon_missed_prog_probes_total{attach="kprobe_multi (2 functions)",policy="syswritefollowfdpsswd"} 1 +tetragon_missed_prog_probes_total{attach="%s (2 functions)",policy="syswritefollowfdpsswd"} %d tetragon_missed_prog_probes_total{attach="sched/sched_process_exec",policy="__base__"} 0 tetragon_missed_prog_probes_total{attach="security_bprm_committing_creds",policy="__base__"} 0 tetragon_missed_prog_probes_total{attach="wake_up_new_task",policy="__base__"} 0 -`) +` + + // Session programs get accounted missed counts also for return + // probe even if it's not executed (plus type name). + cnt := 1 + typ := "kprobe_multi" + if bpf.HasKprobeSession() { + cnt = 2 + typ = "kprobe_session" + } + expected := strings.NewReader(fmt.Sprintf(s, typ, cnt)) assert.NoError(t, testutil.GatherAndCompare(metricsconfig.GetRegistry(), expected, prometheus.BuildFQName(consts.MetricsNamespace, "", "missed_prog_probes_total")))