From 9c9cac47f97a793a6a870cf93324e22da0d84ca1 Mon Sep 17 00:00:00 2001 From: Mattia Meleleo Date: Fri, 1 Dec 2023 11:08:48 +0100 Subject: [PATCH] temporarily vendor ebpfevents --- .gitignore | 2 +- NOTICE.txt | 2 +- auditbeat/internal/tmpebpfevents/LICENSE.txt | 202 +++++ .../internal/tmpebpfevents/bpf_bpfel_arm64.go | 259 +++++++ .../internal/tmpebpfevents/bpf_bpfel_arm64.o | Bin 0 -> 256176 bytes .../internal/tmpebpfevents/bpf_bpfel_x86.go | 259 +++++++ .../internal/tmpebpfevents/bpf_bpfel_x86.o | Bin 0 -> 258528 bytes auditbeat/internal/tmpebpfevents/event.go | 730 ++++++++++++++++++ .../internal/tmpebpfevents/event_string.go | 127 +++ .../internal/tmpebpfevents/event_test.go | 387 ++++++++++ auditbeat/internal/tmpebpfevents/gen_amd64.go | 20 + auditbeat/internal/tmpebpfevents/gen_arm64.go | 20 + auditbeat/internal/tmpebpfevents/go.mod | 29 + auditbeat/internal/tmpebpfevents/go.sum | 90 +++ auditbeat/internal/tmpebpfevents/loader.go | 375 +++++++++ .../internal/tmpebpfevents/loader_test.go | 50 ++ .../tmpebpfevents/pkg/endian/endian.go | 34 + .../internal/tmpebpfevents/pkg/kernel/btf.go | 111 +++ .../tmpebpfevents/pkg/kernel/btf_test.go | 69 ++ .../tmpebpfevents/pkg/kernel/version.go | 170 ++++ .../tmpebpfevents/pkg/kernel/version_test.go | 65 ++ .../tmpebpfevents/pkg/testutils/varlen.go | 104 +++ .../tmpebpfevents/pkg/varlen/varlen.go | 217 ++++++ .../tmpebpfevents/pkg/varlen/varlen_test.go | 52 ++ go.mod | 3 +- go.sum | 2 - x-pack/auditbeat/auditbeat.reference.yml | 4 + 27 files changed, 3378 insertions(+), 5 deletions(-) create mode 100644 auditbeat/internal/tmpebpfevents/LICENSE.txt create mode 100644 auditbeat/internal/tmpebpfevents/bpf_bpfel_arm64.go create mode 100644 auditbeat/internal/tmpebpfevents/bpf_bpfel_arm64.o create mode 100644 auditbeat/internal/tmpebpfevents/bpf_bpfel_x86.go create mode 100644 auditbeat/internal/tmpebpfevents/bpf_bpfel_x86.o create mode 100644 auditbeat/internal/tmpebpfevents/event.go create mode 100644 auditbeat/internal/tmpebpfevents/event_string.go create mode 100644 auditbeat/internal/tmpebpfevents/event_test.go create mode 100644 auditbeat/internal/tmpebpfevents/gen_amd64.go create mode 100644 auditbeat/internal/tmpebpfevents/gen_arm64.go create mode 100644 auditbeat/internal/tmpebpfevents/go.mod create mode 100644 auditbeat/internal/tmpebpfevents/go.sum create mode 100644 auditbeat/internal/tmpebpfevents/loader.go create mode 100644 auditbeat/internal/tmpebpfevents/loader_test.go create mode 100644 auditbeat/internal/tmpebpfevents/pkg/endian/endian.go create mode 100644 auditbeat/internal/tmpebpfevents/pkg/kernel/btf.go create mode 100644 auditbeat/internal/tmpebpfevents/pkg/kernel/btf_test.go create mode 100644 auditbeat/internal/tmpebpfevents/pkg/kernel/version.go create mode 100644 auditbeat/internal/tmpebpfevents/pkg/kernel/version_test.go create mode 100644 auditbeat/internal/tmpebpfevents/pkg/testutils/varlen.go create mode 100644 auditbeat/internal/tmpebpfevents/pkg/varlen/varlen.go create mode 100644 auditbeat/internal/tmpebpfevents/pkg/varlen/varlen_test.go diff --git a/.gitignore b/.gitignore index 70941e281497..7052400157f2 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,7 @@ x-pack/dockerlogbeat/temproot.tar *.swn # Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o +#*.o TODO: remove comment *.a *.so *.exe diff --git a/NOTICE.txt b/NOTICE.txt index 0271bb812d07..8ad700b88c0f 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -12272,7 +12272,7 @@ Version: v0.0.0-20231129134946-a7e15f50b181 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/ebpfevents@v0.0.0-20231129134946-a7e15f50b181/LICENSE.txt: +Contents of probable licence file LICENSE.txt: Apache License diff --git a/auditbeat/internal/tmpebpfevents/LICENSE.txt b/auditbeat/internal/tmpebpfevents/LICENSE.txt new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/auditbeat/internal/tmpebpfevents/bpf_bpfel_arm64.go b/auditbeat/internal/tmpebpfevents/bpf_bpfel_arm64.go new file mode 100644 index 000000000000..42d7b345fea2 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/bpf_bpfel_arm64.go @@ -0,0 +1,259 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +// Code generated by bpf2go; DO NOT EDIT. +//go:build arm64 + +package ebpfevents + +import ( + "bytes" + _ "embed" + "fmt" + "io" + + "github.com/cilium/ebpf" +) + +// loadBpf returns the embedded CollectionSpec for bpf. +func loadBpf() (*ebpf.CollectionSpec, error) { + reader := bytes.NewReader(_BpfBytes) + spec, err := ebpf.LoadCollectionSpecFromReader(reader) + if err != nil { + return nil, fmt.Errorf("can't load bpf: %w", err) + } + + return spec, err +} + +// loadBpfObjects loads bpf and converts it into a struct. +// +// The following types are suitable as obj argument: +// +// *bpfObjects +// *bpfPrograms +// *bpfMaps +// +// See ebpf.CollectionSpec.LoadAndAssign documentation for details. +func loadBpfObjects(obj interface{}, opts *ebpf.CollectionOptions) error { + spec, err := loadBpf() + if err != nil { + return err + } + + return spec.LoadAndAssign(obj, opts) +} + +// bpfSpecs contains maps and programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfSpecs struct { + bpfProgramSpecs + bpfMapSpecs +} + +// bpfSpecs contains programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfProgramSpecs struct { + FentryCommitCreds *ebpf.ProgramSpec `ebpf:"fentry__commit_creds"` + FentryDoRenameat2 *ebpf.ProgramSpec `ebpf:"fentry__do_renameat2"` + FentryDoUnlinkat *ebpf.ProgramSpec `ebpf:"fentry__do_unlinkat"` + FentryMntWantWrite *ebpf.ProgramSpec `ebpf:"fentry__mnt_want_write"` + FentryTaskstatsExit *ebpf.ProgramSpec `ebpf:"fentry__taskstats_exit"` + FentryTcpClose *ebpf.ProgramSpec `ebpf:"fentry__tcp_close"` + FentryTtyWrite *ebpf.ProgramSpec `ebpf:"fentry__tty_write"` + FentryVfsRename *ebpf.ProgramSpec `ebpf:"fentry__vfs_rename"` + FentryVfsUnlink *ebpf.ProgramSpec `ebpf:"fentry__vfs_unlink"` + FexitDoFilpOpen *ebpf.ProgramSpec `ebpf:"fexit__do_filp_open"` + FexitInetCskAccept *ebpf.ProgramSpec `ebpf:"fexit__inet_csk_accept"` + FexitTcpV4Connect *ebpf.ProgramSpec `ebpf:"fexit__tcp_v4_connect"` + FexitTcpV6Connect *ebpf.ProgramSpec `ebpf:"fexit__tcp_v6_connect"` + FexitVfsRename *ebpf.ProgramSpec `ebpf:"fexit__vfs_rename"` + FexitVfsUnlink *ebpf.ProgramSpec `ebpf:"fexit__vfs_unlink"` + KprobeCommitCreds *ebpf.ProgramSpec `ebpf:"kprobe__commit_creds"` + KprobeDoRenameat2 *ebpf.ProgramSpec `ebpf:"kprobe__do_renameat2"` + KprobeDoUnlinkat *ebpf.ProgramSpec `ebpf:"kprobe__do_unlinkat"` + KprobeMntWantWrite *ebpf.ProgramSpec `ebpf:"kprobe__mnt_want_write"` + KprobeTaskstatsExit *ebpf.ProgramSpec `ebpf:"kprobe__taskstats_exit"` + KprobeTcpClose *ebpf.ProgramSpec `ebpf:"kprobe__tcp_close"` + KprobeTcpV4Connect *ebpf.ProgramSpec `ebpf:"kprobe__tcp_v4_connect"` + KprobeTcpV6Connect *ebpf.ProgramSpec `ebpf:"kprobe__tcp_v6_connect"` + KprobeTtyWrite *ebpf.ProgramSpec `ebpf:"kprobe__tty_write"` + KprobeVfsRename *ebpf.ProgramSpec `ebpf:"kprobe__vfs_rename"` + KprobeVfsUnlink *ebpf.ProgramSpec `ebpf:"kprobe__vfs_unlink"` + KretprobeDoFilpOpen *ebpf.ProgramSpec `ebpf:"kretprobe__do_filp_open"` + KretprobeInetCskAccept *ebpf.ProgramSpec `ebpf:"kretprobe__inet_csk_accept"` + KretprobeTcpV4Connect *ebpf.ProgramSpec `ebpf:"kretprobe__tcp_v4_connect"` + KretprobeTcpV6Connect *ebpf.ProgramSpec `ebpf:"kretprobe__tcp_v6_connect"` + KretprobeVfsRename *ebpf.ProgramSpec `ebpf:"kretprobe__vfs_rename"` + KretprobeVfsUnlink *ebpf.ProgramSpec `ebpf:"kretprobe__vfs_unlink"` + SchedProcessExec *ebpf.ProgramSpec `ebpf:"sched_process_exec"` + SchedProcessFork *ebpf.ProgramSpec `ebpf:"sched_process_fork"` + TracepointSyscallsSysExitSetsid *ebpf.ProgramSpec `ebpf:"tracepoint_syscalls_sys_exit_setsid"` +} + +// bpfMapSpecs contains maps before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfMapSpecs struct { + ElasticEbpfEventsInitBuffer *ebpf.MapSpec `ebpf:"elastic_ebpf_events_init_buffer"` + ElasticEbpfEventsScratchSpace *ebpf.MapSpec `ebpf:"elastic_ebpf_events_scratch_space"` + ElasticEbpfEventsState *ebpf.MapSpec `ebpf:"elastic_ebpf_events_state"` + ElasticEbpfEventsTrustedPids *ebpf.MapSpec `ebpf:"elastic_ebpf_events_trusted_pids"` + EventBufferMap *ebpf.MapSpec `ebpf:"event_buffer_map"` + PathResolverDentryScratchMap *ebpf.MapSpec `ebpf:"path_resolver_dentry_scratch_map"` + PathResolverKernfsNodeScratchMap *ebpf.MapSpec `ebpf:"path_resolver_kernfs_node_scratch_map"` + Ringbuf *ebpf.MapSpec `ebpf:"ringbuf"` +} + +// bpfObjects contains all objects after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfObjects struct { + bpfPrograms + bpfMaps +} + +func (o *bpfObjects) Close() error { + return _BpfClose( + &o.bpfPrograms, + &o.bpfMaps, + ) +} + +// bpfMaps contains all maps after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfMaps struct { + ElasticEbpfEventsInitBuffer *ebpf.Map `ebpf:"elastic_ebpf_events_init_buffer"` + ElasticEbpfEventsScratchSpace *ebpf.Map `ebpf:"elastic_ebpf_events_scratch_space"` + ElasticEbpfEventsState *ebpf.Map `ebpf:"elastic_ebpf_events_state"` + ElasticEbpfEventsTrustedPids *ebpf.Map `ebpf:"elastic_ebpf_events_trusted_pids"` + EventBufferMap *ebpf.Map `ebpf:"event_buffer_map"` + PathResolverDentryScratchMap *ebpf.Map `ebpf:"path_resolver_dentry_scratch_map"` + PathResolverKernfsNodeScratchMap *ebpf.Map `ebpf:"path_resolver_kernfs_node_scratch_map"` + Ringbuf *ebpf.Map `ebpf:"ringbuf"` +} + +func (m *bpfMaps) Close() error { + return _BpfClose( + m.ElasticEbpfEventsInitBuffer, + m.ElasticEbpfEventsScratchSpace, + m.ElasticEbpfEventsState, + m.ElasticEbpfEventsTrustedPids, + m.EventBufferMap, + m.PathResolverDentryScratchMap, + m.PathResolverKernfsNodeScratchMap, + m.Ringbuf, + ) +} + +// bpfPrograms contains all programs after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfPrograms struct { + FentryCommitCreds *ebpf.Program `ebpf:"fentry__commit_creds"` + FentryDoRenameat2 *ebpf.Program `ebpf:"fentry__do_renameat2"` + FentryDoUnlinkat *ebpf.Program `ebpf:"fentry__do_unlinkat"` + FentryMntWantWrite *ebpf.Program `ebpf:"fentry__mnt_want_write"` + FentryTaskstatsExit *ebpf.Program `ebpf:"fentry__taskstats_exit"` + FentryTcpClose *ebpf.Program `ebpf:"fentry__tcp_close"` + FentryTtyWrite *ebpf.Program `ebpf:"fentry__tty_write"` + FentryVfsRename *ebpf.Program `ebpf:"fentry__vfs_rename"` + FentryVfsUnlink *ebpf.Program `ebpf:"fentry__vfs_unlink"` + FexitDoFilpOpen *ebpf.Program `ebpf:"fexit__do_filp_open"` + FexitInetCskAccept *ebpf.Program `ebpf:"fexit__inet_csk_accept"` + FexitTcpV4Connect *ebpf.Program `ebpf:"fexit__tcp_v4_connect"` + FexitTcpV6Connect *ebpf.Program `ebpf:"fexit__tcp_v6_connect"` + FexitVfsRename *ebpf.Program `ebpf:"fexit__vfs_rename"` + FexitVfsUnlink *ebpf.Program `ebpf:"fexit__vfs_unlink"` + KprobeCommitCreds *ebpf.Program `ebpf:"kprobe__commit_creds"` + KprobeDoRenameat2 *ebpf.Program `ebpf:"kprobe__do_renameat2"` + KprobeDoUnlinkat *ebpf.Program `ebpf:"kprobe__do_unlinkat"` + KprobeMntWantWrite *ebpf.Program `ebpf:"kprobe__mnt_want_write"` + KprobeTaskstatsExit *ebpf.Program `ebpf:"kprobe__taskstats_exit"` + KprobeTcpClose *ebpf.Program `ebpf:"kprobe__tcp_close"` + KprobeTcpV4Connect *ebpf.Program `ebpf:"kprobe__tcp_v4_connect"` + KprobeTcpV6Connect *ebpf.Program `ebpf:"kprobe__tcp_v6_connect"` + KprobeTtyWrite *ebpf.Program `ebpf:"kprobe__tty_write"` + KprobeVfsRename *ebpf.Program `ebpf:"kprobe__vfs_rename"` + KprobeVfsUnlink *ebpf.Program `ebpf:"kprobe__vfs_unlink"` + KretprobeDoFilpOpen *ebpf.Program `ebpf:"kretprobe__do_filp_open"` + KretprobeInetCskAccept *ebpf.Program `ebpf:"kretprobe__inet_csk_accept"` + KretprobeTcpV4Connect *ebpf.Program `ebpf:"kretprobe__tcp_v4_connect"` + KretprobeTcpV6Connect *ebpf.Program `ebpf:"kretprobe__tcp_v6_connect"` + KretprobeVfsRename *ebpf.Program `ebpf:"kretprobe__vfs_rename"` + KretprobeVfsUnlink *ebpf.Program `ebpf:"kretprobe__vfs_unlink"` + SchedProcessExec *ebpf.Program `ebpf:"sched_process_exec"` + SchedProcessFork *ebpf.Program `ebpf:"sched_process_fork"` + TracepointSyscallsSysExitSetsid *ebpf.Program `ebpf:"tracepoint_syscalls_sys_exit_setsid"` +} + +func (p *bpfPrograms) Close() error { + return _BpfClose( + p.FentryCommitCreds, + p.FentryDoRenameat2, + p.FentryDoUnlinkat, + p.FentryMntWantWrite, + p.FentryTaskstatsExit, + p.FentryTcpClose, + p.FentryTtyWrite, + p.FentryVfsRename, + p.FentryVfsUnlink, + p.FexitDoFilpOpen, + p.FexitInetCskAccept, + p.FexitTcpV4Connect, + p.FexitTcpV6Connect, + p.FexitVfsRename, + p.FexitVfsUnlink, + p.KprobeCommitCreds, + p.KprobeDoRenameat2, + p.KprobeDoUnlinkat, + p.KprobeMntWantWrite, + p.KprobeTaskstatsExit, + p.KprobeTcpClose, + p.KprobeTcpV4Connect, + p.KprobeTcpV6Connect, + p.KprobeTtyWrite, + p.KprobeVfsRename, + p.KprobeVfsUnlink, + p.KretprobeDoFilpOpen, + p.KretprobeInetCskAccept, + p.KretprobeTcpV4Connect, + p.KretprobeTcpV6Connect, + p.KretprobeVfsRename, + p.KretprobeVfsUnlink, + p.SchedProcessExec, + p.SchedProcessFork, + p.TracepointSyscallsSysExitSetsid, + ) +} + +func _BpfClose(closers ...io.Closer) error { + for _, closer := range closers { + if err := closer.Close(); err != nil { + return err + } + } + return nil +} + +// Do not access this directly. +// +//go:embed bpf_bpfel_arm64.o +var _BpfBytes []byte diff --git a/auditbeat/internal/tmpebpfevents/bpf_bpfel_arm64.o b/auditbeat/internal/tmpebpfevents/bpf_bpfel_arm64.o new file mode 100644 index 0000000000000000000000000000000000000000..c26537bd5a83893450e2c29146e8b8d2fad464d5 GIT binary patch literal 256176 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 z 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 YFqyZ%qW`o?&~m>o4{Kllm(=io0ZDp_xc~qF literal 0 HcmV?d00001 diff --git a/auditbeat/internal/tmpebpfevents/bpf_bpfel_x86.go b/auditbeat/internal/tmpebpfevents/bpf_bpfel_x86.go new file mode 100644 index 000000000000..ab10e6b77bbe --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/bpf_bpfel_x86.go @@ -0,0 +1,259 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +// Code generated by bpf2go; DO NOT EDIT. +//go:build 386 || amd64 + +package ebpfevents + +import ( + "bytes" + _ "embed" + "fmt" + "io" + + "github.com/cilium/ebpf" +) + +// loadBpf returns the embedded CollectionSpec for bpf. +func loadBpf() (*ebpf.CollectionSpec, error) { + reader := bytes.NewReader(_BpfBytes) + spec, err := ebpf.LoadCollectionSpecFromReader(reader) + if err != nil { + return nil, fmt.Errorf("can't load bpf: %w", err) + } + + return spec, err +} + +// loadBpfObjects loads bpf and converts it into a struct. +// +// The following types are suitable as obj argument: +// +// *bpfObjects +// *bpfPrograms +// *bpfMaps +// +// See ebpf.CollectionSpec.LoadAndAssign documentation for details. +func loadBpfObjects(obj interface{}, opts *ebpf.CollectionOptions) error { + spec, err := loadBpf() + if err != nil { + return err + } + + return spec.LoadAndAssign(obj, opts) +} + +// bpfSpecs contains maps and programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfSpecs struct { + bpfProgramSpecs + bpfMapSpecs +} + +// bpfSpecs contains programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfProgramSpecs struct { + FentryCommitCreds *ebpf.ProgramSpec `ebpf:"fentry__commit_creds"` + FentryDoRenameat2 *ebpf.ProgramSpec `ebpf:"fentry__do_renameat2"` + FentryDoUnlinkat *ebpf.ProgramSpec `ebpf:"fentry__do_unlinkat"` + FentryMntWantWrite *ebpf.ProgramSpec `ebpf:"fentry__mnt_want_write"` + FentryTaskstatsExit *ebpf.ProgramSpec `ebpf:"fentry__taskstats_exit"` + FentryTcpClose *ebpf.ProgramSpec `ebpf:"fentry__tcp_close"` + FentryTtyWrite *ebpf.ProgramSpec `ebpf:"fentry__tty_write"` + FentryVfsRename *ebpf.ProgramSpec `ebpf:"fentry__vfs_rename"` + FentryVfsUnlink *ebpf.ProgramSpec `ebpf:"fentry__vfs_unlink"` + FexitDoFilpOpen *ebpf.ProgramSpec `ebpf:"fexit__do_filp_open"` + FexitInetCskAccept *ebpf.ProgramSpec `ebpf:"fexit__inet_csk_accept"` + FexitTcpV4Connect *ebpf.ProgramSpec `ebpf:"fexit__tcp_v4_connect"` + FexitTcpV6Connect *ebpf.ProgramSpec `ebpf:"fexit__tcp_v6_connect"` + FexitVfsRename *ebpf.ProgramSpec `ebpf:"fexit__vfs_rename"` + FexitVfsUnlink *ebpf.ProgramSpec `ebpf:"fexit__vfs_unlink"` + KprobeCommitCreds *ebpf.ProgramSpec `ebpf:"kprobe__commit_creds"` + KprobeDoRenameat2 *ebpf.ProgramSpec `ebpf:"kprobe__do_renameat2"` + KprobeDoUnlinkat *ebpf.ProgramSpec `ebpf:"kprobe__do_unlinkat"` + KprobeMntWantWrite *ebpf.ProgramSpec `ebpf:"kprobe__mnt_want_write"` + KprobeTaskstatsExit *ebpf.ProgramSpec `ebpf:"kprobe__taskstats_exit"` + KprobeTcpClose *ebpf.ProgramSpec `ebpf:"kprobe__tcp_close"` + KprobeTcpV4Connect *ebpf.ProgramSpec `ebpf:"kprobe__tcp_v4_connect"` + KprobeTcpV6Connect *ebpf.ProgramSpec `ebpf:"kprobe__tcp_v6_connect"` + KprobeTtyWrite *ebpf.ProgramSpec `ebpf:"kprobe__tty_write"` + KprobeVfsRename *ebpf.ProgramSpec `ebpf:"kprobe__vfs_rename"` + KprobeVfsUnlink *ebpf.ProgramSpec `ebpf:"kprobe__vfs_unlink"` + KretprobeDoFilpOpen *ebpf.ProgramSpec `ebpf:"kretprobe__do_filp_open"` + KretprobeInetCskAccept *ebpf.ProgramSpec `ebpf:"kretprobe__inet_csk_accept"` + KretprobeTcpV4Connect *ebpf.ProgramSpec `ebpf:"kretprobe__tcp_v4_connect"` + KretprobeTcpV6Connect *ebpf.ProgramSpec `ebpf:"kretprobe__tcp_v6_connect"` + KretprobeVfsRename *ebpf.ProgramSpec `ebpf:"kretprobe__vfs_rename"` + KretprobeVfsUnlink *ebpf.ProgramSpec `ebpf:"kretprobe__vfs_unlink"` + SchedProcessExec *ebpf.ProgramSpec `ebpf:"sched_process_exec"` + SchedProcessFork *ebpf.ProgramSpec `ebpf:"sched_process_fork"` + TracepointSyscallsSysExitSetsid *ebpf.ProgramSpec `ebpf:"tracepoint_syscalls_sys_exit_setsid"` +} + +// bpfMapSpecs contains maps before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfMapSpecs struct { + ElasticEbpfEventsInitBuffer *ebpf.MapSpec `ebpf:"elastic_ebpf_events_init_buffer"` + ElasticEbpfEventsScratchSpace *ebpf.MapSpec `ebpf:"elastic_ebpf_events_scratch_space"` + ElasticEbpfEventsState *ebpf.MapSpec `ebpf:"elastic_ebpf_events_state"` + ElasticEbpfEventsTrustedPids *ebpf.MapSpec `ebpf:"elastic_ebpf_events_trusted_pids"` + EventBufferMap *ebpf.MapSpec `ebpf:"event_buffer_map"` + PathResolverDentryScratchMap *ebpf.MapSpec `ebpf:"path_resolver_dentry_scratch_map"` + PathResolverKernfsNodeScratchMap *ebpf.MapSpec `ebpf:"path_resolver_kernfs_node_scratch_map"` + Ringbuf *ebpf.MapSpec `ebpf:"ringbuf"` +} + +// bpfObjects contains all objects after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfObjects struct { + bpfPrograms + bpfMaps +} + +func (o *bpfObjects) Close() error { + return _BpfClose( + &o.bpfPrograms, + &o.bpfMaps, + ) +} + +// bpfMaps contains all maps after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfMaps struct { + ElasticEbpfEventsInitBuffer *ebpf.Map `ebpf:"elastic_ebpf_events_init_buffer"` + ElasticEbpfEventsScratchSpace *ebpf.Map `ebpf:"elastic_ebpf_events_scratch_space"` + ElasticEbpfEventsState *ebpf.Map `ebpf:"elastic_ebpf_events_state"` + ElasticEbpfEventsTrustedPids *ebpf.Map `ebpf:"elastic_ebpf_events_trusted_pids"` + EventBufferMap *ebpf.Map `ebpf:"event_buffer_map"` + PathResolverDentryScratchMap *ebpf.Map `ebpf:"path_resolver_dentry_scratch_map"` + PathResolverKernfsNodeScratchMap *ebpf.Map `ebpf:"path_resolver_kernfs_node_scratch_map"` + Ringbuf *ebpf.Map `ebpf:"ringbuf"` +} + +func (m *bpfMaps) Close() error { + return _BpfClose( + m.ElasticEbpfEventsInitBuffer, + m.ElasticEbpfEventsScratchSpace, + m.ElasticEbpfEventsState, + m.ElasticEbpfEventsTrustedPids, + m.EventBufferMap, + m.PathResolverDentryScratchMap, + m.PathResolverKernfsNodeScratchMap, + m.Ringbuf, + ) +} + +// bpfPrograms contains all programs after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfPrograms struct { + FentryCommitCreds *ebpf.Program `ebpf:"fentry__commit_creds"` + FentryDoRenameat2 *ebpf.Program `ebpf:"fentry__do_renameat2"` + FentryDoUnlinkat *ebpf.Program `ebpf:"fentry__do_unlinkat"` + FentryMntWantWrite *ebpf.Program `ebpf:"fentry__mnt_want_write"` + FentryTaskstatsExit *ebpf.Program `ebpf:"fentry__taskstats_exit"` + FentryTcpClose *ebpf.Program `ebpf:"fentry__tcp_close"` + FentryTtyWrite *ebpf.Program `ebpf:"fentry__tty_write"` + FentryVfsRename *ebpf.Program `ebpf:"fentry__vfs_rename"` + FentryVfsUnlink *ebpf.Program `ebpf:"fentry__vfs_unlink"` + FexitDoFilpOpen *ebpf.Program `ebpf:"fexit__do_filp_open"` + FexitInetCskAccept *ebpf.Program `ebpf:"fexit__inet_csk_accept"` + FexitTcpV4Connect *ebpf.Program `ebpf:"fexit__tcp_v4_connect"` + FexitTcpV6Connect *ebpf.Program `ebpf:"fexit__tcp_v6_connect"` + FexitVfsRename *ebpf.Program `ebpf:"fexit__vfs_rename"` + FexitVfsUnlink *ebpf.Program `ebpf:"fexit__vfs_unlink"` + KprobeCommitCreds *ebpf.Program `ebpf:"kprobe__commit_creds"` + KprobeDoRenameat2 *ebpf.Program `ebpf:"kprobe__do_renameat2"` + KprobeDoUnlinkat *ebpf.Program `ebpf:"kprobe__do_unlinkat"` + KprobeMntWantWrite *ebpf.Program `ebpf:"kprobe__mnt_want_write"` + KprobeTaskstatsExit *ebpf.Program `ebpf:"kprobe__taskstats_exit"` + KprobeTcpClose *ebpf.Program `ebpf:"kprobe__tcp_close"` + KprobeTcpV4Connect *ebpf.Program `ebpf:"kprobe__tcp_v4_connect"` + KprobeTcpV6Connect *ebpf.Program `ebpf:"kprobe__tcp_v6_connect"` + KprobeTtyWrite *ebpf.Program `ebpf:"kprobe__tty_write"` + KprobeVfsRename *ebpf.Program `ebpf:"kprobe__vfs_rename"` + KprobeVfsUnlink *ebpf.Program `ebpf:"kprobe__vfs_unlink"` + KretprobeDoFilpOpen *ebpf.Program `ebpf:"kretprobe__do_filp_open"` + KretprobeInetCskAccept *ebpf.Program `ebpf:"kretprobe__inet_csk_accept"` + KretprobeTcpV4Connect *ebpf.Program `ebpf:"kretprobe__tcp_v4_connect"` + KretprobeTcpV6Connect *ebpf.Program `ebpf:"kretprobe__tcp_v6_connect"` + KretprobeVfsRename *ebpf.Program `ebpf:"kretprobe__vfs_rename"` + KretprobeVfsUnlink *ebpf.Program `ebpf:"kretprobe__vfs_unlink"` + SchedProcessExec *ebpf.Program `ebpf:"sched_process_exec"` + SchedProcessFork *ebpf.Program `ebpf:"sched_process_fork"` + TracepointSyscallsSysExitSetsid *ebpf.Program `ebpf:"tracepoint_syscalls_sys_exit_setsid"` +} + +func (p *bpfPrograms) Close() error { + return _BpfClose( + p.FentryCommitCreds, + p.FentryDoRenameat2, + p.FentryDoUnlinkat, + p.FentryMntWantWrite, + p.FentryTaskstatsExit, + p.FentryTcpClose, + p.FentryTtyWrite, + p.FentryVfsRename, + p.FentryVfsUnlink, + p.FexitDoFilpOpen, + p.FexitInetCskAccept, + p.FexitTcpV4Connect, + p.FexitTcpV6Connect, + p.FexitVfsRename, + p.FexitVfsUnlink, + p.KprobeCommitCreds, + p.KprobeDoRenameat2, + p.KprobeDoUnlinkat, + p.KprobeMntWantWrite, + p.KprobeTaskstatsExit, + p.KprobeTcpClose, + p.KprobeTcpV4Connect, + p.KprobeTcpV6Connect, + p.KprobeTtyWrite, + p.KprobeVfsRename, + p.KprobeVfsUnlink, + p.KretprobeDoFilpOpen, + p.KretprobeInetCskAccept, + p.KretprobeTcpV4Connect, + p.KretprobeTcpV6Connect, + p.KretprobeVfsRename, + p.KretprobeVfsUnlink, + p.SchedProcessExec, + p.SchedProcessFork, + p.TracepointSyscallsSysExitSetsid, + ) +} + +func _BpfClose(closers ...io.Closer) error { + for _, closer := range closers { + if err := closer.Close(); err != nil { + return err + } + } + return nil +} + +// Do not access this directly. +// +//go:embed bpf_bpfel_x86.o +var _BpfBytes []byte diff --git a/auditbeat/internal/tmpebpfevents/bpf_bpfel_x86.o b/auditbeat/internal/tmpebpfevents/bpf_bpfel_x86.o new file mode 100644 index 0000000000000000000000000000000000000000..cec67562687cd5aee1303b98b4e36d18efd0f8f4 GIT binary patch literal 258528 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

5Ok^jiZ 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 CVkZRv literal 0 HcmV?d00001 diff --git a/auditbeat/internal/tmpebpfevents/event.go b/auditbeat/internal/tmpebpfevents/event.go new file mode 100644 index 000000000000..526edc44dfa7 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/event.go @@ -0,0 +1,730 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package ebpfevents + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "fmt" + "net/netip" + "os" + "strings" + "time" + + "github.com/elastic/ebpfevents/pkg/endian" + "github.com/elastic/ebpfevents/pkg/varlen" +) + +//go:generate stringer -linecomment=true -type=EventType,Transport,Family,FileType -output=event_string.go + +type EventUnmarshaler interface { + Unmarshal(*bytes.Reader) error +} + +type EventType uint64 + +const ( + EventTypeProcessFork EventType = 1 << (iota + 1) // ProcessFork + EventTypeProcessExec // ProcessExec + EventTypeProcessExit // ProcessExit + EventTypeProcessSetsid // ProcessSetsid + EventTypeProcessSetuid // ProcessSetuid + EventTypeProcessSetgid // ProcessSetgid + EventTypeProcessTTYWrite // ProcessTTYWrite + EventTypeFileDelete // FileDelete + EventTypeFileCreate // FileCreate + EventTypeFileRename // FileRename + EventTypeNetworkConnectionAccepted // NetConnectionAccepted + EventTypeNetworkConnectionAttempted // NetConnectionAttempted + EventTypeNetworkConnectionClosed // NetConnectionClosed +) + +func (et EventType) MarshalJSON() ([]byte, error) { + return json.Marshal(et.String()) +} + +type Header struct { + NsSinceBoot uint64 `json:"ns_since_boot"` + Time time.Time `json:"time"` + Type EventType `json:"type"` +} + +type Event struct { + Header `json:",inline"` + Body any `json:"body"` +} + +type PidInfo struct { + StartTimeNs uint64 `json:"start_time_ns"` + Tid uint32 `json:"tid"` + Tgid uint32 `json:"tgid"` + Ppid uint32 `json:"ppid"` + Pgid uint32 `json:"pgid"` + Sid uint32 `json:"sid"` +} + +type CredInfo struct { + Ruid uint32 `json:"ruid"` + Rgid uint32 `json:"rgid"` + Euid uint32 `json:"euid"` + Egid uint32 `json:"egid"` + Suid uint32 `json:"suid"` + Sgid uint32 `json:"sgid"` + CapPermitted uint64 `json:"cap_permitted"` + CapEffective uint64 `json:"cap_effective"` +} + +type TTYWinsize struct { + Rows uint16 `json:"rows"` + Cols uint16 `json:"cols"` +} + +type TTYTermios struct { + Iflag uint32 `json:"iflag"` + Oflag uint32 `json:"oflag"` + Lflag uint32 `json:"lflag"` + Cflag uint32 `json:"cflag"` +} + +type TTYDev struct { + Minor uint16 `json:"minor"` + Major uint16 `json:"major"` + Winsize TTYWinsize `json:"winsize"` + Termios TTYTermios `json:"-"` +} + +type ProcessFork struct { + ParentPids PidInfo `json:"parent_pids"` + ChildPids PidInfo `json:"child_pids"` + Creds CredInfo `json:"creds"` + CgroupPath string `json:"cgroup_path"` +} + +const TaskCommLen = 16 + +func (e *ProcessFork) Unmarshal(r *bytes.Reader) error { + if err := binary.Read(r, endian.Native, &e.ParentPids); err != nil { + return fmt.Errorf("read parent pids: %v", err) + } + if err := binary.Read(r, endian.Native, &e.ChildPids); err != nil { + return fmt.Errorf("read child pids: %v", err) + } + if err := binary.Read(r, endian.Native, &e.Creds); err != nil { + return fmt.Errorf("read creds: %v", err) + } + + vlMap, err := varlen.DeserializeVarlenFields(r) + if err != nil { + return fmt.Errorf("deserialize varlen fields: %v", err) + } + if val, ok := vlMap[varlen.CgroupPath]; ok { + e.CgroupPath = val.(string) + } + + return nil +} + +type ProcessExec struct { + Pids PidInfo `json:"pids"` + Creds CredInfo `json:"creds"` + CTTY TTYDev `json:"ctty"` + Cwd string `json:"cwd"` + Argv []string `json:"argv"` + Env map[string]string `json:"env"` + Filename string `json:"filename"` + CgroupPath string `json:"cgroup_path"` +} + +func (e *ProcessExec) Unmarshal(r *bytes.Reader) error { + if err := binary.Read(r, endian.Native, &e.Pids); err != nil { + return fmt.Errorf("read pids: %v", err) + } + if err := binary.Read(r, endian.Native, &e.Creds); err != nil { + return fmt.Errorf("read creds: %v", err) + } + if err := binary.Read(r, endian.Native, &e.CTTY); err != nil { + return fmt.Errorf("read ctty: %v", err) + } + + vlMap, err := varlen.DeserializeVarlenFields(r) + if err != nil { + return fmt.Errorf("deserialize varlen fields: %v", err) + } + if val, ok := vlMap[varlen.Cwd]; ok { + e.Cwd = val.(string) + } + if val, ok := vlMap[varlen.Argv]; ok { + e.Argv = val.([]string) + } + if val, ok := vlMap[varlen.Env]; ok { + e.Env = val.(map[string]string) + } + if val, ok := vlMap[varlen.Filename]; ok { + e.Filename = val.(string) + } + if val, ok := vlMap[varlen.CgroupPath]; ok { + e.CgroupPath = val.(string) + } + + return nil +} + +type ProcessExit struct { + Pids PidInfo `json:"pids"` + ExitCode int32 `json:"exit_code"` + CgroupPath string `json:"cgroup_path"` +} + +func (e *ProcessExit) Unmarshal(r *bytes.Reader) error { + if err := binary.Read(r, endian.Native, &e.Pids); err != nil { + return fmt.Errorf("read pids: %v", err) + } + if err := binary.Read(r, endian.Native, &e.ExitCode); err != nil { + return fmt.Errorf("read exit code: %v", err) + } + + vlMap, err := varlen.DeserializeVarlenFields(r) + if err != nil { + return fmt.Errorf("deserialize varlen fields: %v", err) + } + if val, ok := vlMap[varlen.CgroupPath]; ok { + e.CgroupPath = val.(string) + } + + return nil +} + +type ProcessSetsid struct { + Pids PidInfo `json:"pids"` +} + +func (e *ProcessSetsid) Unmarshal(r *bytes.Reader) error { + if err := binary.Read(r, endian.Native, &e.Pids); err != nil { + return fmt.Errorf("read pids: %v", err) + } + return nil +} + +type ProcessSetuid struct { + Pids PidInfo `json:"pids"` + NewRuid uint32 `json:"new_ruid"` + NewEuid uint32 `json:"new_euid"` + NewRgid uint32 `json:"new_rgid"` + NewEgid uint32 `json:"new_egid"` +} + +func (e *ProcessSetuid) Unmarshal(r *bytes.Reader) error { + if err := binary.Read(r, endian.Native, &e.Pids); err != nil { + return fmt.Errorf("read pids: %v", err) + } + if err := binary.Read(r, endian.Native, &e.NewRuid); err != nil { + return fmt.Errorf("read new ruid: %v", err) + } + if err := binary.Read(r, endian.Native, &e.NewEuid); err != nil { + return fmt.Errorf("read new euid: %v", err) + } + if err := binary.Read(r, endian.Native, &e.NewRgid); err != nil { + return fmt.Errorf("read new rgid: %v", err) + } + if err := binary.Read(r, endian.Native, &e.NewEgid); err != nil { + return fmt.Errorf("read new egid: %v", err) + } + + return nil +} + +type ProcessSetgid struct { + Pids PidInfo `json:"pids"` + NewRgid uint32 `json:"new_rgid"` + NewEgid uint32 `json:"new_egid"` + NewRuid uint32 `json:"new_ruid"` + NewEuid uint32 `json:"new_euid"` +} + +func (e *ProcessSetgid) Unmarshal(r *bytes.Reader) error { + if err := binary.Read(r, endian.Native, &e.Pids); err != nil { + return fmt.Errorf("read pids: %v", err) + } + if err := binary.Read(r, endian.Native, &e.NewRgid); err != nil { + return fmt.Errorf("read new rgid: %v", err) + } + if err := binary.Read(r, endian.Native, &e.NewEgid); err != nil { + return fmt.Errorf("read new egid: %v", err) + } + if err := binary.Read(r, endian.Native, &e.NewRuid); err != nil { + return fmt.Errorf("read new ruid: %v", err) + } + if err := binary.Read(r, endian.Native, &e.NewEuid); err != nil { + return fmt.Errorf("read new euid: %v", err) + } + + return nil +} + +type ProcessTTYWrite struct { + Pids PidInfo `json:"pids"` + Truncated uint64 `json:"truncated"` + CTTY TTYDev `json:"ctty"` + TTY TTYDev `json:"tty"` + Comm string `json:"comm"` + Output string `json:"output"` +} + +func (e *ProcessTTYWrite) Unmarshal(r *bytes.Reader) error { + if err := binary.Read(r, endian.Native, &e.Pids); err != nil { + return fmt.Errorf("read pids: %v", err) + } + if err := binary.Read(r, endian.Native, &e.Truncated); err != nil { + return fmt.Errorf("read truncated: %v", err) + } + if err := binary.Read(r, endian.Native, &e.CTTY); err != nil { + return fmt.Errorf("read ctty: %v", err) + } + if err := binary.Read(r, endian.Native, &e.TTY); err != nil { + return fmt.Errorf("read tty: %v", err) + } + + comm, err := readTaskComm(r) + if err != nil { + return err + } + e.Comm = comm + + vlMap, err := varlen.DeserializeVarlenFields(r) + if err != nil { + return fmt.Errorf("deserialize varlen fields: %v", err) + } + if val, ok := vlMap[varlen.TTYOutput]; ok { + e.Output = val.(string) + } + + return nil +} + +type FileType uint32 + +const ( + FileTypeUnknown FileType = iota // Unknown + FileTypeFile // File + FileTypeDir // Dir + FileTypeSymlink // Symlink + FileTypeCharDevice // CharDevice + FileTypeBlockDevice // BlockDevice + FileTypeNamedPipe // NamedPipe + FileTypeSocket // Socket +) + +func (ft FileType) MarshalJSON() ([]byte, error) { + return json.Marshal(ft.String()) +} + +type FileInfo struct { + Type FileType `json:"type"` + Inode uint64 `json:"inode"` + Mode os.FileMode `json:"mode"` + Size uint64 `json:"size"` + Uid uint32 `json:"uid"` + Gid uint32 `json:"gid"` + Atime time.Time `json:"atime"` + Mtime time.Time `json:"mtime"` + Ctime time.Time `json:"ctime"` +} + +type FileCreate struct { + Pids PidInfo `json:"pids"` + Finfo FileInfo `json:"file_info"` + MountNs uint32 `json:"mount_ns"` + Comm string `json:"comm"` + Path string `json:"path"` + SymlinkTargetPath string `json:"symlink_target_path"` +} + +func (e *FileCreate) Unmarshal(r *bytes.Reader) error { + if err := binary.Read(r, endian.Native, &e.Pids); err != nil { + return fmt.Errorf("read pids: %v", err) + } + + fi, err := readFileInfo(r) + if err != nil { + return fmt.Errorf("read file info: %v", err) + } + e.Finfo = fi + + if err := binary.Read(r, endian.Native, &e.MountNs); err != nil { + return fmt.Errorf("read mount namespace: %v", err) + } + + comm, err := readTaskComm(r) + if err != nil { + return err + } + e.Comm = comm + + vlMap, err := varlen.DeserializeVarlenFields(r) + if err != nil { + return fmt.Errorf("deserialize varlen fields: %v", err) + } + if val, ok := vlMap[varlen.Path]; ok { + e.Path = val.(string) + } + if val, ok := vlMap[varlen.SymlinkTargetPath]; ok { + e.SymlinkTargetPath = val.(string) + } + + return nil +} + +type FileDelete struct { + Pids PidInfo `json:"pids"` + Finfo FileInfo `json:"file_info"` + MountNs uint32 `json:"mount_ns"` + Comm string `json:"comm"` + Path string `json:"path"` + SymlinkTargetPath string `json:"symlink_target_path"` +} + +func (e *FileDelete) Unmarshal(r *bytes.Reader) error { + if err := binary.Read(r, endian.Native, &e.Pids); err != nil { + return fmt.Errorf("read pids: %v", err) + } + + fi, err := readFileInfo(r) + if err != nil { + return fmt.Errorf("read file info: %v", err) + } + e.Finfo = fi + + if err := binary.Read(r, endian.Native, &e.MountNs); err != nil { + return fmt.Errorf("read mount namespace: %v", err) + } + + comm, err := readTaskComm(r) + if err != nil { + return err + } + e.Comm = comm + + vlMap, err := varlen.DeserializeVarlenFields(r) + if err != nil { + return fmt.Errorf("deserialize varlen fields: %v", err) + } + if val, ok := vlMap[varlen.Path]; ok { + e.Path = val.(string) + } + if val, ok := vlMap[varlen.SymlinkTargetPath]; ok { + e.SymlinkTargetPath = val.(string) + } + + return nil +} + +type FileRename struct { + Pids PidInfo `json:"pids"` + Finfo FileInfo `json:"file_info"` + MountNs uint32 `json:"mount_ns"` + Comm string `json:"comm"` + OldPath string `json:"old_path"` + NewPath string `json:"new_path"` + SymlinkTargetPath string `json:"symlink_target_path"` +} + +func (e *FileRename) Unmarshal(r *bytes.Reader) error { + if err := binary.Read(r, endian.Native, &e.Pids); err != nil { + return fmt.Errorf("read pids: %v", err) + } + + fi, err := readFileInfo(r) + if err != nil { + return fmt.Errorf("read file info: %v", err) + } + e.Finfo = fi + + if err := binary.Read(r, endian.Native, &e.MountNs); err != nil { + return fmt.Errorf("read mount namespace: %v", err) + } + + comm, err := readTaskComm(r) + if err != nil { + return err + } + e.Comm = comm + + vlMap, err := varlen.DeserializeVarlenFields(r) + if err != nil { + return fmt.Errorf("deserialize varlen fields: %v", err) + } + if val, ok := vlMap[varlen.OldPath]; ok { + e.OldPath = val.(string) + } + if val, ok := vlMap[varlen.NewPath]; ok { + e.NewPath = val.(string) + } + if val, ok := vlMap[varlen.SymlinkTargetPath]; ok { + e.SymlinkTargetPath = val.(string) + } + + return nil +} + +type Transport uint32 + +const ( + TransportTCP Transport = iota + 1 // TCP +) + +func (t Transport) MarshalJSON() ([]byte, error) { + return json.Marshal(t.String()) +} + +type Family uint32 + +const ( + AFInet Family = iota + 1 // Inet + AFInet6 // Inet6 +) + +func (f Family) MarshalJSON() ([]byte, error) { + return json.Marshal(f.String()) +} + +type NetInfo struct { + Transport Transport `json:"transport"` + Family Family `json:"family"` + SourceAddress netip.Addr `json:"source_address"` + DestinationAddress netip.Addr `json:"destination_address"` + SourcePort uint16 `json:"source_port"` + DestinationPort uint16 `json:"destination_port"` + NetNs uint32 `json:"net_ns"` + BytesSent uint64 `json:"bytes_sent"` + BytesReceived uint64 `json:"bytes_received"` +} + +type NetEvent struct { + Pids PidInfo `json:"pids"` + Net NetInfo `json:"net"` + Comm string `json:"comm"` +} + +func (e *NetEvent) Unmarshal(r *bytes.Reader) error { + if err := binary.Read(r, endian.Native, &e.Pids); err != nil { + return fmt.Errorf("read pids: %v", err) + } + + ni, err := readNetInfo(r) + if err != nil { + return fmt.Errorf("read net info: %v", err) + } + e.Net = ni + + comm, err := readTaskComm(r) + if err != nil { + return err + } + e.Comm = comm + + return nil +} + +func NewEvent(raw []byte) (*Event, error) { + var ( + err error + ev Event + r = bytes.NewReader(raw) + ) + + if err := readHeader(r, &ev); err != nil { + return nil, fmt.Errorf("read event header: %v", err) + } + + switch ev.Header.Type { + case EventTypeProcessFork: + err = readBody(r, &ProcessFork{}, &ev) + case EventTypeProcessExec: + err = readBody(r, &ProcessExec{}, &ev) + case EventTypeProcessExit: + err = readBody(r, &ProcessExit{}, &ev) + case EventTypeProcessSetsid: + err = readBody(r, &ProcessSetsid{}, &ev) + case EventTypeProcessSetuid: + err = readBody(r, &ProcessSetuid{}, &ev) + case EventTypeProcessSetgid: + err = readBody(r, &ProcessSetgid{}, &ev) + case EventTypeProcessTTYWrite: + err = readBody(r, &ProcessTTYWrite{}, &ev) + case EventTypeFileDelete: + err = readBody(r, &FileDelete{}, &ev) + case EventTypeFileCreate: + err = readBody(r, &FileCreate{}, &ev) + case EventTypeFileRename: + err = readBody(r, &FileRename{}, &ev) + case EventTypeNetworkConnectionAccepted, EventTypeNetworkConnectionAttempted, EventTypeNetworkConnectionClosed: + err = readBody(r, &NetEvent{}, &ev) + default: + return nil, fmt.Errorf("unknown event type %d", ev.Header.Type) + } + if err != nil { + return nil, fmt.Errorf("read event body (%s): %v", ev.Type.String(), err) + } + + return &ev, nil +} + +func readHeader(r *bytes.Reader, ev *Event) error { + var h Header + + if err := binary.Read(r, endian.Native, &h.NsSinceBoot); err != nil { + return fmt.Errorf("read ns since boot: %v", err) + } + if err := binary.Read(r, endian.Native, &h.Type); err != nil { + return fmt.Errorf("read type: %v", err) + } + h.Time = time.Now() + ev.Header = h + + return nil +} + +func readBody(r *bytes.Reader, e EventUnmarshaler, ev *Event) error { + if err := e.Unmarshal(r); err != nil { + return fmt.Errorf("unmarshal: %v", err) + } + ev.Body = e + return nil +} + +func readTaskComm(r *bytes.Reader) (string, error) { + var s strings.Builder + + for i := 0; i < TaskCommLen; i++ { + c, err := r.ReadByte() + if err != nil { + return "", fmt.Errorf("read comm: %v", err) + } + if c == 0 { + continue + } + if err := s.WriteByte(c); err != nil { + return "", fmt.Errorf("write comm: %v", err) + } + } + + return s.String(), nil +} + +func readNetInfo(r *bytes.Reader) (NetInfo, error) { + var ni NetInfo + + if err := binary.Read(r, endian.Native, &ni.Transport); err != nil { + return ni, fmt.Errorf("read transport: %v", err) + } + if err := binary.Read(r, endian.Native, &ni.Family); err != nil { + return ni, fmt.Errorf("read family: %v", err) + } + + switch ni.Family { + case AFInet: + var tmp [4]byte + + if err := binary.Read(r, endian.Native, &tmp); err != nil { + return ni, fmt.Errorf("read saddr: %v", err) + } + ni.SourceAddress = netip.AddrFrom4(tmp) + + if err := binary.Read(r, endian.Native, &tmp); err != nil { + return ni, fmt.Errorf("read daddr: %v", err) + } + ni.DestinationAddress = netip.AddrFrom4(tmp) + case AFInet6: + var tmp [16]byte + + if err := binary.Read(r, endian.Native, &tmp); err != nil { + return ni, fmt.Errorf("read saddr6: %v", err) + } + ni.SourceAddress = netip.AddrFrom16(tmp) + + if err := binary.Read(r, endian.Native, &tmp); err != nil { + return ni, fmt.Errorf("read daddr6: %v", err) + } + ni.DestinationAddress = netip.AddrFrom16(tmp) + } + + if err := binary.Read(r, endian.Native, &ni.SourcePort); err != nil { + return ni, fmt.Errorf("read sport: %v", err) + } + if err := binary.Read(r, endian.Native, &ni.DestinationPort); err != nil { + return ni, fmt.Errorf("read dport: %v", err) + } + if err := binary.Read(r, endian.Native, &ni.NetNs); err != nil { + return ni, fmt.Errorf("read net ns: %v", err) + } + if err := binary.Read(r, endian.Native, &ni.BytesSent); err != nil { + return ni, fmt.Errorf("read bytes sent: %v", err) + } + if err := binary.Read(r, endian.Native, &ni.BytesReceived); err != nil { + return ni, fmt.Errorf("read bytes received: %v", err) + } + + return ni, nil +} + +func readFileInfo(r *bytes.Reader) (FileInfo, error) { + var fi FileInfo + + if err := binary.Read(r, endian.Native, &fi.Type); err != nil { + return fi, fmt.Errorf("read type: %v", err) + } + if err := binary.Read(r, endian.Native, &fi.Inode); err != nil { + return fi, fmt.Errorf("read inode: %v", err) + } + + var m uint16 + if err := binary.Read(r, endian.Native, &m); err != nil { + return fi, fmt.Errorf("read mode: %v", err) + } + fi.Mode = os.FileMode(m) + + if err := binary.Read(r, endian.Native, &fi.Size); err != nil { + return fi, fmt.Errorf("read size: %v", err) + } + if err := binary.Read(r, endian.Native, &fi.Uid); err != nil { + return fi, fmt.Errorf("read uid: %v", err) + } + if err := binary.Read(r, endian.Native, &fi.Gid); err != nil { + return fi, fmt.Errorf("read gid: %v", err) + } + + var ts uint64 + + if err := binary.Read(r, endian.Native, &ts); err != nil { + return fi, fmt.Errorf("read atime: %v", err) + } + fi.Atime = time.Unix(0, int64(ts)) + + if err := binary.Read(r, endian.Native, &ts); err != nil { + return fi, fmt.Errorf("read mtime: %v", err) + } + fi.Mtime = time.Unix(0, int64(ts)) + + if err := binary.Read(r, endian.Native, &ts); err != nil { + return fi, fmt.Errorf("read ctime: %v", err) + } + fi.Ctime = time.Unix(0, int64(ts)) + + return fi, nil +} diff --git a/auditbeat/internal/tmpebpfevents/event_string.go b/auditbeat/internal/tmpebpfevents/event_string.go new file mode 100644 index 000000000000..0a9816710b62 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/event_string.go @@ -0,0 +1,127 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +// Code generated by "stringer -linecomment=true -type=EventType,Transport,Family,FileType -output=event_string.go"; DO NOT EDIT. + +package ebpfevents + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[EventTypeProcessFork-2] + _ = x[EventTypeProcessExec-4] + _ = x[EventTypeProcessExit-8] + _ = x[EventTypeProcessSetsid-16] + _ = x[EventTypeProcessSetuid-32] + _ = x[EventTypeProcessSetgid-64] + _ = x[EventTypeProcessTTYWrite-128] + _ = x[EventTypeFileDelete-256] + _ = x[EventTypeFileCreate-512] + _ = x[EventTypeFileRename-1024] + _ = x[EventTypeNetworkConnectionAccepted-2048] + _ = x[EventTypeNetworkConnectionAttempted-4096] + _ = x[EventTypeNetworkConnectionClosed-8192] +} + +const _EventType_name = "ProcessForkProcessExecProcessExitProcessSetsidProcessSetuidProcessSetgidProcessTTYWriteFileDeleteFileCreateFileRenameNetConnectionAcceptedNetConnectionAttemptedNetConnectionClosed" + +var _EventType_map = map[EventType]string{ + 2: _EventType_name[0:11], + 4: _EventType_name[11:22], + 8: _EventType_name[22:33], + 16: _EventType_name[33:46], + 32: _EventType_name[46:59], + 64: _EventType_name[59:72], + 128: _EventType_name[72:87], + 256: _EventType_name[87:97], + 512: _EventType_name[97:107], + 1024: _EventType_name[107:117], + 2048: _EventType_name[117:138], + 4096: _EventType_name[138:160], + 8192: _EventType_name[160:179], +} + +func (i EventType) String() string { + if str, ok := _EventType_map[i]; ok { + return str + } + return "EventType(" + strconv.FormatInt(int64(i), 10) + ")" +} +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[TransportTCP-1] +} + +const _Transport_name = "TCP" + +var _Transport_index = [...]uint8{0, 3} + +func (i Transport) String() string { + i -= 1 + if i >= Transport(len(_Transport_index)-1) { + return "Transport(" + strconv.FormatInt(int64(i+1), 10) + ")" + } + return _Transport_name[_Transport_index[i]:_Transport_index[i+1]] +} +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[AFInet-1] + _ = x[AFInet6-2] +} + +const _Family_name = "InetInet6" + +var _Family_index = [...]uint8{0, 4, 9} + +func (i Family) String() string { + i -= 1 + if i >= Family(len(_Family_index)-1) { + return "Family(" + strconv.FormatInt(int64(i+1), 10) + ")" + } + return _Family_name[_Family_index[i]:_Family_index[i+1]] +} +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[FileTypeUnknown-0] + _ = x[FileTypeFile-1] + _ = x[FileTypeDir-2] + _ = x[FileTypeSymlink-3] + _ = x[FileTypeCharDevice-4] + _ = x[FileTypeBlockDevice-5] + _ = x[FileTypeNamedPipe-6] + _ = x[FileTypeSocket-7] +} + +const _FileType_name = "UnknownFileDirSymlinkCharDeviceBlockDeviceNamedPipeSocket" + +var _FileType_index = [...]uint8{0, 7, 11, 14, 21, 31, 42, 51, 57} + +func (i FileType) String() string { + if i >= FileType(len(_FileType_index)-1) { + return "FileType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _FileType_name[_FileType_index[i]:_FileType_index[i+1]] +} diff --git a/auditbeat/internal/tmpebpfevents/event_test.go b/auditbeat/internal/tmpebpfevents/event_test.go new file mode 100644 index 000000000000..e2977cfbed64 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/event_test.go @@ -0,0 +1,387 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package ebpfevents_test + +import ( + "bufio" + "bytes" + "encoding/binary" + "net/netip" + "testing" + "time" + + "github.com/go-faker/faker/v4" + "github.com/stretchr/testify/assert" + + "github.com/elastic/ebpfevents" + "github.com/elastic/ebpfevents/pkg/endian" + "github.com/elastic/ebpfevents/pkg/testutils" + "github.com/elastic/ebpfevents/pkg/varlen" +) + +func writeProcessFork(t *testing.T, w *bufio.Writer, ev ebpfevents.ProcessFork) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, ev.ParentPids)) + assert.Nil(t, binary.Write(w, endian.Native, ev.ChildPids)) + assert.Nil(t, binary.Write(w, endian.Native, ev.Creds)) + testutils.WriteVarlenFields(t, w, varlen.Map{ + varlen.CgroupPath: ev.CgroupPath, + }) + + assert.Nil(t, w.Flush()) +} + +func TestProcessFork(t *testing.T) { + buf := bytes.NewBuffer(nil) + w := bufio.NewWriter(buf) + + var expectedEvent ebpfevents.ProcessFork + assert.Nil(t, faker.FakeData(&expectedEvent)) + writeProcessFork(t, w, expectedEvent) + + var newEvent ebpfevents.ProcessFork + assert.Nil(t, newEvent.Unmarshal(bytes.NewReader(buf.Bytes()))) + assert.Equal(t, expectedEvent, newEvent) +} + +func writeProcessExec(t *testing.T, w *bufio.Writer, ev ebpfevents.ProcessExec) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, ev.Pids)) + assert.Nil(t, binary.Write(w, endian.Native, ev.Creds)) + assert.Nil(t, binary.Write(w, endian.Native, ev.CTTY)) + testutils.WriteVarlenFields(t, w, varlen.Map{ + varlen.Cwd: ev.Cwd, + varlen.Argv: ev.Argv, + varlen.Env: ev.Env, + varlen.Filename: ev.Filename, + varlen.CgroupPath: ev.CgroupPath, + }) + + assert.Nil(t, w.Flush()) +} + +func TestProcessExec(t *testing.T) { + buf := bytes.NewBuffer(nil) + w := bufio.NewWriter(buf) + + var expectedEvent ebpfevents.ProcessExec + assert.Nil(t, faker.FakeData(&expectedEvent)) + writeProcessExec(t, w, expectedEvent) + + var newEvent ebpfevents.ProcessExec + assert.Nil(t, newEvent.Unmarshal(bytes.NewReader(buf.Bytes()))) + assert.Equal(t, expectedEvent, newEvent) +} + +func writeProcessExit(t *testing.T, w *bufio.Writer, ev ebpfevents.ProcessExit) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, ev.Pids)) + assert.Nil(t, binary.Write(w, endian.Native, ev.ExitCode)) + testutils.WriteVarlenFields(t, w, varlen.Map{ + varlen.CgroupPath: ev.CgroupPath, + }) + + assert.Nil(t, w.Flush()) +} + +func TestProcessExit(t *testing.T) { + buf := bytes.NewBuffer(nil) + w := bufio.NewWriter(buf) + + var expectedEvent ebpfevents.ProcessExit + assert.Nil(t, faker.FakeData(&expectedEvent)) + writeProcessExit(t, w, expectedEvent) + + var newEvent ebpfevents.ProcessExit + assert.Nil(t, newEvent.Unmarshal(bytes.NewReader(buf.Bytes()))) + assert.Equal(t, expectedEvent, newEvent) +} + +func writeProcessSetsid(t *testing.T, w *bufio.Writer, ev ebpfevents.ProcessSetsid) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, ev.Pids)) + + assert.Nil(t, w.Flush()) +} + +func TestProcessSetsid(t *testing.T) { + buf := bytes.NewBuffer(nil) + w := bufio.NewWriter(buf) + + var expectedEvent ebpfevents.ProcessSetsid + assert.Nil(t, faker.FakeData(&expectedEvent)) + writeProcessSetsid(t, w, expectedEvent) + + var newEvent ebpfevents.ProcessSetsid + assert.Nil(t, newEvent.Unmarshal(bytes.NewReader(buf.Bytes()))) + assert.Equal(t, expectedEvent, newEvent) +} + +func writeProcessSetuid(t *testing.T, w *bufio.Writer, ev ebpfevents.ProcessSetuid) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, ev.Pids)) + assert.Nil(t, binary.Write(w, endian.Native, ev.NewRuid)) + assert.Nil(t, binary.Write(w, endian.Native, ev.NewEuid)) + assert.Nil(t, binary.Write(w, endian.Native, ev.NewRgid)) + assert.Nil(t, binary.Write(w, endian.Native, ev.NewEgid)) + + assert.Nil(t, w.Flush()) +} + +func TestProcessSetuid(t *testing.T) { + buf := bytes.NewBuffer(nil) + w := bufio.NewWriter(buf) + + var expectedEvent ebpfevents.ProcessSetuid + assert.Nil(t, faker.FakeData(&expectedEvent)) + writeProcessSetuid(t, w, expectedEvent) + + var newEvent ebpfevents.ProcessSetuid + assert.Nil(t, newEvent.Unmarshal(bytes.NewReader(buf.Bytes()))) + assert.Equal(t, expectedEvent, newEvent) +} + +func writeProcessSetgid(t *testing.T, w *bufio.Writer, ev ebpfevents.ProcessSetgid) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, ev.Pids)) + assert.Nil(t, binary.Write(w, endian.Native, ev.NewRgid)) + assert.Nil(t, binary.Write(w, endian.Native, ev.NewEgid)) + assert.Nil(t, binary.Write(w, endian.Native, ev.NewRuid)) + assert.Nil(t, binary.Write(w, endian.Native, ev.NewEuid)) + + assert.Nil(t, w.Flush()) +} + +func TestProcessSetgid(t *testing.T) { + buf := bytes.NewBuffer(nil) + w := bufio.NewWriter(buf) + + var expectedEvent ebpfevents.ProcessSetgid + assert.Nil(t, faker.FakeData(&expectedEvent)) + writeProcessSetgid(t, w, expectedEvent) + + var newEvent ebpfevents.ProcessSetgid + assert.Nil(t, newEvent.Unmarshal(bytes.NewReader(buf.Bytes()))) + assert.Equal(t, expectedEvent, newEvent) +} + +func writeProcessTTYWrite(t *testing.T, w *bufio.Writer, ev ebpfevents.ProcessTTYWrite) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, ev.Pids)) + assert.Nil(t, binary.Write(w, endian.Native, ev.Truncated)) + assert.Nil(t, binary.Write(w, endian.Native, ev.CTTY)) + assert.Nil(t, binary.Write(w, endian.Native, ev.TTY)) + _, err := w.WriteString(ev.Comm) + assert.Nil(t, err) + assert.Nil(t, w.WriteByte(0)) + testutils.WriteVarlenFields(t, w, varlen.Map{ + varlen.TTYOutput: ev.Output, + }) + + assert.Nil(t, w.Flush()) +} + +func TestProcessTTYWrite(t *testing.T) { + buf := bytes.NewBuffer(nil) + w := bufio.NewWriter(buf) + + var expectedEvent ebpfevents.ProcessTTYWrite + assert.Nil(t, faker.FakeData(&expectedEvent)) + expectedEvent.Comm = expectedEvent.Comm[:ebpfevents.TaskCommLen-1] + writeProcessTTYWrite(t, w, expectedEvent) + + var newEvent ebpfevents.ProcessTTYWrite + assert.Nil(t, newEvent.Unmarshal(bytes.NewReader(buf.Bytes()))) + assert.Equal(t, expectedEvent, newEvent) +} + +func writeFileInfo(t *testing.T, w *bufio.Writer, fi ebpfevents.FileInfo) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, fi.Type)) + assert.Nil(t, binary.Write(w, endian.Native, fi.Inode)) + assert.Nil(t, binary.Write(w, endian.Native, uint16(fi.Mode))) + assert.Nil(t, binary.Write(w, endian.Native, fi.Size)) + assert.Nil(t, binary.Write(w, endian.Native, fi.Uid)) + assert.Nil(t, binary.Write(w, endian.Native, fi.Gid)) + assert.Nil(t, binary.Write(w, endian.Native, uint64(fi.Atime.Nanosecond()))) + assert.Nil(t, binary.Write(w, endian.Native, uint64(fi.Mtime.Nanosecond()))) + assert.Nil(t, binary.Write(w, endian.Native, uint64(fi.Ctime.Nanosecond()))) + + assert.Nil(t, w.Flush()) +} + +func writeFileCreate(t *testing.T, w *bufio.Writer, ev ebpfevents.FileCreate) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, ev.Pids)) + writeFileInfo(t, w, ev.Finfo) + assert.Nil(t, binary.Write(w, endian.Native, ev.MountNs)) + _, err := w.WriteString(ev.Comm) + assert.Nil(t, err) + assert.Nil(t, w.WriteByte(0)) + testutils.WriteVarlenFields(t, w, varlen.Map{ + varlen.Path: ev.Path, + varlen.SymlinkTargetPath: ev.SymlinkTargetPath, + }) + + assert.Nil(t, w.Flush()) +} + +func TestFileCreate(t *testing.T) { + buf := bytes.NewBuffer(nil) + w := bufio.NewWriter(buf) + + var expectedEvent ebpfevents.FileCreate + assert.Nil(t, faker.FakeData(&expectedEvent)) + expectedEvent.Comm = expectedEvent.Comm[:ebpfevents.TaskCommLen-1] + expectedEvent.Finfo.Atime = time.Unix(0, int64(1)) + expectedEvent.Finfo.Mtime = time.Unix(0, int64(2)) + expectedEvent.Finfo.Ctime = time.Unix(0, int64(3)) + writeFileCreate(t, w, expectedEvent) + + var newEvent ebpfevents.FileCreate + assert.Nil(t, newEvent.Unmarshal(bytes.NewReader(buf.Bytes()))) + assert.Equal(t, expectedEvent, newEvent) +} + +func writeFileRename(t *testing.T, w *bufio.Writer, ev ebpfevents.FileRename) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, ev.Pids)) + writeFileInfo(t, w, ev.Finfo) + assert.Nil(t, binary.Write(w, endian.Native, ev.MountNs)) + _, err := w.WriteString(ev.Comm) + assert.Nil(t, err) + assert.Nil(t, w.WriteByte(0)) + testutils.WriteVarlenFields(t, w, varlen.Map{ + varlen.OldPath: ev.OldPath, + varlen.NewPath: ev.NewPath, + varlen.SymlinkTargetPath: ev.SymlinkTargetPath, + }) + + assert.Nil(t, w.Flush()) +} + +func TestFileRename(t *testing.T) { + buf := bytes.NewBuffer(nil) + w := bufio.NewWriter(buf) + + var expectedEvent ebpfevents.FileRename + assert.Nil(t, faker.FakeData(&expectedEvent)) + expectedEvent.Comm = expectedEvent.Comm[:ebpfevents.TaskCommLen-1] + expectedEvent.Finfo.Atime = time.Unix(0, int64(1)) + expectedEvent.Finfo.Mtime = time.Unix(0, int64(2)) + expectedEvent.Finfo.Ctime = time.Unix(0, int64(3)) + writeFileRename(t, w, expectedEvent) + + var newEvent ebpfevents.FileRename + assert.Nil(t, newEvent.Unmarshal(bytes.NewReader(buf.Bytes()))) + assert.Equal(t, expectedEvent, newEvent) +} + +func writeFileDelete(t *testing.T, w *bufio.Writer, ev ebpfevents.FileDelete) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, ev.Pids)) + writeFileInfo(t, w, ev.Finfo) + assert.Nil(t, binary.Write(w, endian.Native, ev.MountNs)) + _, err := w.WriteString(ev.Comm) + assert.Nil(t, err) + assert.Nil(t, w.WriteByte(0)) + testutils.WriteVarlenFields(t, w, varlen.Map{ + varlen.Path: ev.Path, + varlen.SymlinkTargetPath: ev.SymlinkTargetPath, + }) + + assert.Nil(t, w.Flush()) +} + +func TestFileDelete(t *testing.T) { + buf := bytes.NewBuffer(nil) + w := bufio.NewWriter(buf) + + var expectedEvent ebpfevents.FileDelete + assert.Nil(t, faker.FakeData(&expectedEvent)) + expectedEvent.Comm = expectedEvent.Comm[:ebpfevents.TaskCommLen-1] + expectedEvent.Finfo.Atime = time.Unix(0, int64(1)) + expectedEvent.Finfo.Mtime = time.Unix(0, int64(2)) + expectedEvent.Finfo.Ctime = time.Unix(0, int64(3)) + writeFileDelete(t, w, expectedEvent) + + var newEvent ebpfevents.FileDelete + assert.Nil(t, newEvent.Unmarshal(bytes.NewReader(buf.Bytes()))) + assert.Equal(t, expectedEvent, newEvent) +} + +func writeNetInfo(t *testing.T, w *bufio.Writer, ni ebpfevents.NetInfo) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, uint32(ni.Transport))) + assert.Nil(t, binary.Write(w, endian.Native, uint32(ni.Family))) + assert.Nil(t, binary.Write(w, endian.Native, ni.SourceAddress.AsSlice())) + assert.Nil(t, binary.Write(w, endian.Native, ni.DestinationAddress.AsSlice())) + assert.Nil(t, binary.Write(w, endian.Native, ni.SourcePort)) + assert.Nil(t, binary.Write(w, endian.Native, ni.DestinationPort)) + assert.Nil(t, binary.Write(w, endian.Native, ni.NetNs)) + assert.Nil(t, binary.Write(w, endian.Native, ni.BytesSent)) + assert.Nil(t, binary.Write(w, endian.Native, ni.BytesReceived)) + + assert.Nil(t, w.Flush()) +} + +func writeNetEvent(t *testing.T, w *bufio.Writer, ev ebpfevents.NetEvent) { + t.Helper() + + assert.Nil(t, binary.Write(w, endian.Native, ev.Pids)) + writeNetInfo(t, w, ev.Net) + _, err := w.WriteString(ev.Comm) + assert.Nil(t, err) + assert.Nil(t, w.WriteByte(0)) + + assert.Nil(t, w.Flush()) +} + +func TestNetEvent(t *testing.T) { + buf := bytes.NewBuffer(nil) + w := bufio.NewWriter(buf) + + var expectedEvent ebpfevents.NetEvent + assert.Nil(t, faker.FakeData(&expectedEvent)) + expectedEvent.Comm = expectedEvent.Comm[:ebpfevents.TaskCommLen-1] + switch expectedEvent.Net.Family { + case ebpfevents.AFInet: + expectedEvent.Net.SourceAddress = netip.MustParseAddr("1.2.3.4") + expectedEvent.Net.DestinationAddress = netip.MustParseAddr("5.6.7.8") + case ebpfevents.AFInet6: + expectedEvent.Net.SourceAddress = netip.MustParseAddr("2001:0db8:85a3:0000:0000:8a2e:0370:7333") + expectedEvent.Net.DestinationAddress = netip.MustParseAddr("2001:0db8:85a3:0000:0000:8a2e:0370:7334") + } + writeNetEvent(t, w, expectedEvent) + + var newEvent ebpfevents.NetEvent + assert.Nil(t, newEvent.Unmarshal(bytes.NewReader(buf.Bytes()))) + assert.Equal(t, expectedEvent, newEvent) +} diff --git a/auditbeat/internal/tmpebpfevents/gen_amd64.go b/auditbeat/internal/tmpebpfevents/gen_amd64.go new file mode 100644 index 000000000000..df31595c1932 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/gen_amd64.go @@ -0,0 +1,20 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package ebpfevents + +//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc $BPF_CLANG -cflags $BPF_CFLAGS -target $BPF_TARGET -no-global-types bpf ./ebpf/GPL/Events/EventProbe.bpf.c -- -I./ebpf/GPL/Events/ -I./ebpf/contrib/vmlinux/x86_64/ -I./headers diff --git a/auditbeat/internal/tmpebpfevents/gen_arm64.go b/auditbeat/internal/tmpebpfevents/gen_arm64.go new file mode 100644 index 000000000000..c561a400b392 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/gen_arm64.go @@ -0,0 +1,20 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package ebpfevents + +//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc $BPF_CLANG -cflags $BPF_CFLAGS -target $BPF_TARGET -no-global-types bpf ./ebpf/GPL/Events/EventProbe.bpf.c -- -I./ebpf/GPL/Events/ -I./ebpf/contrib/vmlinux/aarch64/ -I./headers diff --git a/auditbeat/internal/tmpebpfevents/go.mod b/auditbeat/internal/tmpebpfevents/go.mod new file mode 100644 index 000000000000..dcd9bbee4bab --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/go.mod @@ -0,0 +1,29 @@ +module github.com/elastic/ebpfevents + +go 1.20 + +require ( + github.com/cilium/ebpf v0.12.3 + github.com/elastic/go-licenser v0.4.1 + github.com/go-faker/faker/v4 v4.2.0 + github.com/stretchr/testify v1.6.1 + go.elastic.co/go-licence-detector v0.6.0 + golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c +) + +require ( + github.com/cyphar/filepath-securejoin v0.2.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/gobuffalo/here v0.6.0 // indirect + github.com/google/licenseclassifier v0.0.0-20200402202327-879cb1424de0 // indirect + github.com/karrick/godirwalk v1.15.6 // indirect + github.com/markbates/pkger v0.17.0 // indirect + github.com/pkg/errors v0.8.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/sergi/go-diff v1.1.0 // indirect + golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 // indirect + golang.org/x/mod v0.6.0 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/text v0.3.7 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) diff --git a/auditbeat/internal/tmpebpfevents/go.sum b/auditbeat/internal/tmpebpfevents/go.sum new file mode 100644 index 000000000000..faec4a8091bd --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/go.sum @@ -0,0 +1,90 @@ +github.com/cilium/ebpf v0.12.3 h1:8ht6F9MquybnY97at+VDZb3eQQr8ev79RueWeVaEcG4= +github.com/cilium/ebpf v0.12.3/go.mod h1:TctK1ivibvI3znr66ljgi4hqOT8EYQjz1KWBfb1UVgM= +github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elastic/go-licenser v0.4.1 h1:1xDURsc8pL5zYT9R29425J3vkHdt4RT5TNEMeRN48x4= +github.com/elastic/go-licenser v0.4.1/go.mod h1:V56wHMpmdURfibNBggaSBfqgPxyT1Tldns1i87iTEvU= +github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= +github.com/go-faker/faker/v4 v4.2.0 h1:dGebOupKwssrODV51E0zbMrv5e2gO9VWSLNC1WDCpWg= +github.com/go-faker/faker/v4 v4.2.0/go.mod h1:F/bBy8GH9NxOxMInug5Gx4WYeG6fHJZ8Ol/dhcpRub4= +github.com/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI= +github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/licenseclassifier v0.0.0-20200402202327-879cb1424de0 h1:OggOMmdI0JLwg1FkOKH9S7fVHF0oEm8PX6S8kAdpOps= +github.com/google/licenseclassifier v0.0.0-20200402202327-879cb1424de0/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M= +github.com/karrick/godirwalk v1.15.6 h1:Yf2mmR8TJy+8Fa0SuQVto5SYap6IF7lNVX4Jdl8G1qA= +github.com/karrick/godirwalk v1.15.6/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/markbates/pkger v0.17.0 h1:RFfyBPufP2V6cddUyyEVSHBpaAnM1WzaMNyqomeT+iY= +github.com/markbates/pkger v0.17.0/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.elastic.co/go-licence-detector v0.6.0 h1:QJ+cUIHC0JpxEKgp5Bj0pabEiOOt9H1O9CCcUNe6yRQ= +go.elastic.co/go-licence-detector v0.6.0/go.mod h1:fSJQU8au4SAgDK+UQFbgUPsXKYNBDv4E/dwWevrMpXU= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= +golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c h1:3kC/TjQ+xzIblQv39bCOyRk8fbEeJcDHwbyxPUU2BpA= +golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/auditbeat/internal/tmpebpfevents/loader.go b/auditbeat/internal/tmpebpfevents/loader.go new file mode 100644 index 000000000000..d738e175b64f --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/loader.go @@ -0,0 +1,375 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package ebpfevents + +import ( + "context" + "errors" + "fmt" + "os" + "runtime" + + "github.com/cilium/ebpf" + "github.com/cilium/ebpf/btf" + "github.com/cilium/ebpf/features" + "github.com/cilium/ebpf/link" + "github.com/cilium/ebpf/ringbuf" + "github.com/cilium/ebpf/rlimit" + + "github.com/elastic/ebpfevents/pkg/kernel" +) + +type Loader struct { + // features + hasBpfTramp bool + + // bpf objects + kbtf *btf.Spec + objs bpfObjects + links []link.Link + reader *ringbuf.Reader + + // .rodata constants + constants map[string]any +} + +const ( + argIdxFmt = "arg__%s__%s__" // func, arg + retIdxFmt = "ret__%s__" // func + argExistsFmt = "exists__%s__%s__" // func, arg + fieldOffsetFmt = "off__%s__%s__" // struct, field +) + +func NewLoader() (*Loader, error) { + l := &Loader{ + constants: make(map[string]any), + links: make([]link.Link, 0), + } + l.constants["consumer_pid"] = uint32(os.Getpid()) + + if err := kernel.CheckSupported(); err != nil { + return nil, fmt.Errorf("check kernel version: %v", err) + } + + kbtf, err := btf.LoadKernelSpec() + if err != nil { + return nil, fmt.Errorf("load kernel btf: %v", err) + } + l.kbtf = kbtf + + if err = features.HaveProgramType(ebpf.Tracing); err == nil { + l.hasBpfTramp = true + } + + if err := l.fillIndexes(); err != nil { + return nil, fmt.Errorf("fill indexes: %v", err) + } + if err := l.loadBpf(); err != nil { + return nil, fmt.Errorf("load bpf: %v", err) + } + + return l, nil +} + +func (l *Loader) loadBpf() error { + if err := rlimit.RemoveMemlock(); err != nil { + return fmt.Errorf("rlimit remove memlock: %v", err) + } + + spec, err := loadBpf() + if err != nil { + return fmt.Errorf("load collection: %v", err) + } + if err := spec.RewriteConstants(l.constants); err != nil { + return fmt.Errorf("rewrite constants: %v", err) + } + spec.Maps["event_buffer_map"].MaxEntries = uint32(runtime.NumCPU()) + + var opts ebpf.CollectionOptions + opts.Programs.LogSize = 1 << 26 + opts.Programs.LogLevel = ebpf.LogLevelInstruction + + if err := spec.LoadAndAssign(&l.objs, &opts); err != nil { + var ve *ebpf.VerifierError + if errors.As(err, &ve) { + for _, line := range ve.Log { + fmt.Println(line) + } + return fmt.Errorf("verifier error: %w", err) + } + return fmt.Errorf("error loading bpf probes: %v", err) + } + defer func() { + btf.FlushKernelSpec() + runtime.GC() + }() + + rd, err := ringbuf.NewReader(l.objs.bpfMaps.Ringbuf) + if err != nil { + return fmt.Errorf("error opening ringbuf reader: %v", err) + } + l.reader = rd + + if err := l.attachBpfProgs(); err != nil { + return fmt.Errorf("error attaching bpf programs: %v", err) + } + + return nil +} + +func (l *Loader) attachBpfProgs() error { + attachTracing := func(at ebpf.AttachType, prog *ebpf.Program) error { + lnk, err := link.AttachTracing(link.TracingOptions{ + Program: prog, + AttachType: at, + }) + if err != nil { + return fmt.Errorf("attach tracing %q: %v", prog.String(), err) + } + l.links = append(l.links, lnk) + return nil + } + attachFentry := func(prog *ebpf.Program) error { + return attachTracing(ebpf.AttachTraceFEntry, prog) + } + attachFexit := func(prog *ebpf.Program) error { + return attachTracing(ebpf.AttachTraceFExit, prog) + } + attachRawTp := func(prog *ebpf.Program) error { + return attachTracing(ebpf.AttachTraceRawTp, prog) + } + attachKprobe := func(sym string, prog *ebpf.Program) error { + lnk, err := link.Kprobe(sym, prog, nil) + if err != nil { + return fmt.Errorf("attach kprobe %q: %v", prog.String(), err) + } + l.links = append(l.links, lnk) + return nil + } + attachKretprobe := func(sym string, prog *ebpf.Program) error { + lnk, err := link.Kretprobe(sym, prog, nil) + if err != nil { + return fmt.Errorf("attach kretprobe %q: %v", prog.String(), err) + } + l.links = append(l.links, lnk) + return nil + } + attachTracepoint := func(group, name string, prog *ebpf.Program) error { + lnk, err := link.Tracepoint(group, name, prog, nil) + if err != nil { + return fmt.Errorf("attach tracepoint '%s/%s': %v", group, name, err) + } + l.links = append(l.links, lnk) + return nil + } + + attach := func(errs *[]error, err error) { + if err != nil { + *errs = append(*errs, err) + } + } + var errs []error + + // do_renameat2 + if l.hasBpfTramp && kernel.FuncExists(l.kbtf, "do_renameat2") { + attach(&errs, attachFentry(l.objs.FentryDoRenameat2)) + } else { + attach(&errs, attachKprobe("do_renameat2", l.objs.KprobeDoRenameat2)) + } + + // tcp_v6_connect + if l.hasBpfTramp && kernel.FuncExists(l.kbtf, "tcp_v6_connect") { + attach(&errs, attachFexit(l.objs.FexitTcpV6Connect)) + } else { + attach(&errs, attachKprobe("tcp_v6_connect", l.objs.KprobeTcpV6Connect)) + attach(&errs, attachKretprobe("tcp_v6_connect", l.objs.KretprobeTcpV6Connect)) + } + + // tty_write + if l.hasBpfTramp && kernel.FuncExists(l.kbtf, "tty_write") { + attach(&errs, attachFentry(l.objs.FentryTtyWrite)) + } else { + attach(&errs, attachKprobe("tty_write", l.objs.KprobeTtyWrite)) + } + + // generic bpf trampoline + if l.hasBpfTramp { + attach(&errs, attachFentry(l.objs.FentryDoUnlinkat)) + attach(&errs, attachFentry(l.objs.FentryMntWantWrite)) + attach(&errs, attachFentry(l.objs.FentryVfsUnlink)) + attach(&errs, attachFexit(l.objs.FexitVfsUnlink)) + attach(&errs, attachFexit(l.objs.FexitDoFilpOpen)) + attach(&errs, attachFentry(l.objs.FentryVfsRename)) + attach(&errs, attachFexit(l.objs.FexitVfsRename)) + attach(&errs, attachFentry(l.objs.FentryTaskstatsExit)) + attach(&errs, attachFentry(l.objs.FentryCommitCreds)) + attach(&errs, attachFexit(l.objs.FexitInetCskAccept)) + attach(&errs, attachFexit(l.objs.FexitTcpV4Connect)) + attach(&errs, attachFentry(l.objs.FentryTcpClose)) + } else { + attach(&errs, attachKprobe("do_unlinkat", l.objs.KprobeDoUnlinkat)) + attach(&errs, attachKprobe("mnt_want_write", l.objs.KprobeMntWantWrite)) + attach(&errs, attachKprobe("vfs_unlink", l.objs.KprobeVfsUnlink)) + attach(&errs, attachKretprobe("vfs_unlink", l.objs.KretprobeVfsUnlink)) + attach(&errs, attachKretprobe("do_filp_open", l.objs.KretprobeDoFilpOpen)) + attach(&errs, attachKprobe("vfs_rename", l.objs.KprobeVfsRename)) + attach(&errs, attachKretprobe("vfs_rename", l.objs.KretprobeVfsRename)) + attach(&errs, attachKprobe("taskstats_exit", l.objs.KprobeTaskstatsExit)) + attach(&errs, attachKprobe("commit_creds", l.objs.KprobeCommitCreds)) + attach(&errs, attachKretprobe("inet_csk_accept", l.objs.KretprobeInetCskAccept)) + attach(&errs, attachKprobe("tcp_v4_connect", l.objs.KprobeTcpV4Connect)) + attach(&errs, attachKretprobe("tcp_v4_connect", l.objs.KretprobeTcpV4Connect)) + attach(&errs, attachKprobe("tcp_close", l.objs.KprobeTcpClose)) + } + + attach(&errs, attachRawTp(l.objs.SchedProcessExec)) + attach(&errs, attachRawTp(l.objs.SchedProcessFork)) + attach(&errs, attachTracepoint("syscalls", "sys_exit_setsid", l.objs.TracepointSyscallsSysExitSetsid)) + + if len(errs) != 0 { + msg := "bpf program(s) attach failed: " + for _, err := range errs { + msg += err.Error() + msg += ";" + } + return errors.New(msg) + } + + return nil +} + +func (l *Loader) EventLoop(ctx context.Context, out chan<- Event, errs chan<- error) { + in := make(chan ringbuf.Record) + + go func() { + for { + select { + case <-ctx.Done(): + return + default: + record, err := l.reader.Read() + if errors.Is(err, ringbuf.ErrClosed) { + break + } + if err != nil { + continue + } + in <- record + } + } + }() + + for { + select { + case <-ctx.Done(): + return + case record := <-in: + event, err := NewEvent(record.RawSample) + if err != nil { + errs <- err + continue + } + out <- *event + } + } +} + +func (l *Loader) Close() error { + if l.reader != nil { + l.reader.Close() + } + for _, lnk := range l.links { + lnk.Close() + } + return nil +} + +func (l *Loader) fillArgIndex(funcName, argName string) error { + name := fmt.Sprintf(argIdxFmt, funcName, argName) + + idx, err := kernel.ArgIdxByFunc(l.kbtf, funcName, argName) + if err != nil { + return fmt.Errorf("fill %s: %v", name, err) + } + l.constants[name] = idx + + return nil +} + +func (l *Loader) fillRetIndex(funcName string) error { + name := fmt.Sprintf(retIdxFmt, funcName) + + idx, err := kernel.RetIdxByFunc(l.kbtf, funcName) + if err != nil { + return fmt.Errorf("fill %s: %v", name, err) + } + l.constants[name] = idx + + return nil +} + +func (l *Loader) fillArgExists(funcName, argName string) error { + name := fmt.Sprintf(argExistsFmt, funcName, argName) + l.constants[name] = kernel.ArgExists(l.kbtf, funcName, argName) + return nil +} + +func (l *Loader) fillFieldOffset(structName, fieldName string) error { + name := fmt.Sprintf(fieldOffsetFmt, structName, fieldName) + + off, err := kernel.FieldOffset(l.kbtf, structName, fieldName) + if err != nil { + return fmt.Errorf("fill %s: %v", name, err) + } + l.constants[name] = off + + return nil +} + +func (l *Loader) fillIndexes() error { + if err := l.fillArgIndex("vfs_unlink", "dentry"); err != nil { + return fmt.Errorf("fill arg index: %v", err) + } + if err := l.fillRetIndex("vfs_unlink"); err != nil { + return fmt.Errorf("fill ret index: %v", err) + } + + if kernel.ArgExists(l.kbtf, "vfs_rename", "rd") { + if err := l.fillArgExists("vfs_rename", "rd"); err != nil { + return fmt.Errorf("fill arg exists: %v", err) + } + } else { + if err := l.fillArgIndex("vfs_rename", "old_dentry"); err != nil { + return fmt.Errorf("fill arg index: %v", err) + } + if err := l.fillArgIndex("vfs_rename", "new_dentry"); err != nil { + return fmt.Errorf("fill arg index: %v", err) + } + } + if err := l.fillRetIndex("vfs_rename"); err != nil { + return fmt.Errorf("fill ret index: %v", err) + } + + if kernel.FieldExists(l.kbtf, "iov_iter", "__iov") { + if err := l.fillFieldOffset("iov_iter", "__iov"); err != nil { + return fmt.Errorf("fill field offset: %v", err) + } + } + + return nil +} diff --git a/auditbeat/internal/tmpebpfevents/loader_test.go b/auditbeat/internal/tmpebpfevents/loader_test.go new file mode 100644 index 000000000000..d445d2f4f64b --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/loader_test.go @@ -0,0 +1,50 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package ebpfevents_test + +import ( + "context" + "os" + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/elastic/ebpfevents" +) + +func TestNewLoader(t *testing.T) { + l, err := ebpfevents.NewLoader() + assert.Nil(t, err) + defer l.Close() + + events := make(chan ebpfevents.Event, 3) + errors := make(chan error, 3) + go l.EventLoop(context.Background(), events, errors) + + // trigger an event + fname := "testloader" + _, err = os.Create(fname) + assert.Nil(t, err) + defer os.Remove(fname) + + time.Sleep(time.Second) + + assert.NotEmpty(t, events) + assert.Empty(t, errors) +} diff --git a/auditbeat/internal/tmpebpfevents/pkg/endian/endian.go b/auditbeat/internal/tmpebpfevents/pkg/endian/endian.go new file mode 100644 index 000000000000..681d71a89cc6 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/pkg/endian/endian.go @@ -0,0 +1,34 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package endian + +import ( + "encoding/binary" + + "golang.org/x/sys/cpu" +) + +var Native binary.ByteOrder + +func init() { + if cpu.IsBigEndian { + Native = binary.BigEndian + } else { + Native = binary.LittleEndian + } +} diff --git a/auditbeat/internal/tmpebpfevents/pkg/kernel/btf.go b/auditbeat/internal/tmpebpfevents/pkg/kernel/btf.go new file mode 100644 index 000000000000..9ec219c3c790 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/pkg/kernel/btf.go @@ -0,0 +1,111 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package kernel + +import ( + "fmt" + + "github.com/cilium/ebpf/btf" +) + +func FieldExists(kbtf *btf.Spec, structName, fieldName string) bool { + _, err := FieldOffset(kbtf, structName, fieldName) + return err == nil +} + +func FieldOffset(kbtf *btf.Spec, structName, fieldName string) (uint32, error) { + var s *btf.Struct + if err := kbtf.TypeByName(structName, &s); err != nil { + return 0, fmt.Errorf("find btf struct: %v", err) + } + + return fieldOffsetRecur(kbtf, 0, s, fieldName) +} + +func fieldOffsetRecur(kbtf *btf.Spec, base btf.Bits, typ btf.Type, fieldName string) (uint32, error) { + var members []btf.Member + + switch t := typ.(type) { + case *btf.Struct: + members = t.Members + case *btf.Union: + members = t.Members + } + + for _, m := range members { + if m.Name == fieldName { + return (base + m.Offset).Bytes(), nil + } + + switch m.Type.(type) { + case *btf.Struct, *btf.Union: + off, err := fieldOffsetRecur(kbtf, base+m.Offset, m.Type, fieldName) + if err != nil { + continue + } + return off, nil + default: + continue + } + } + + return 0, fmt.Errorf("field %s not found", fieldName) +} + +func ArgIdxByFunc(kbtf *btf.Spec, funcName, argName string) (uint32, error) { + funcProto, err := funcProtoByName(kbtf, funcName) + if err != nil { + return 0, fmt.Errorf("func proto by name: %v", err) + } + + for i, funcParam := range funcProto.Params { + if funcParam.Name == argName { + return uint32(i), nil + } + } + + return 0, fmt.Errorf("arg %s not found in %s proto", argName, funcName) +} + +func RetIdxByFunc(kbtf *btf.Spec, funcName string) (uint32, error) { + funcProto, err := funcProtoByName(kbtf, funcName) + if err != nil { + return 0, fmt.Errorf("func proto by name: %v", err) + } + + return uint32(len(funcProto.Params)), nil +} + +func ArgExists(kbtf *btf.Spec, funcName, argName string) bool { + _, err := ArgIdxByFunc(kbtf, funcName, argName) + return err == nil +} + +func FuncExists(kbtf *btf.Spec, funcName string) bool { + _, err := funcProtoByName(kbtf, funcName) + return err == nil +} + +func funcProtoByName(kbtf *btf.Spec, name string) (*btf.FuncProto, error) { + var f *btf.Func + if err := kbtf.TypeByName(name, &f); err != nil { + return nil, fmt.Errorf("find btf func: %v", err) + } + + return f.Type.(*btf.FuncProto), nil +} diff --git a/auditbeat/internal/tmpebpfevents/pkg/kernel/btf_test.go b/auditbeat/internal/tmpebpfevents/pkg/kernel/btf_test.go new file mode 100644 index 000000000000..135949f9bd21 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/pkg/kernel/btf_test.go @@ -0,0 +1,69 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package kernel + +import ( + "testing" + + "github.com/cilium/ebpf/btf" + "github.com/stretchr/testify/assert" +) + +func TestFieldExists(t *testing.T) { + spec, err := btf.LoadKernelSpec() + assert.Nil(t, err) + + assert.True(t, FieldExists(spec, "tty_struct", "link")) + assert.False(t, FieldExists(spec, "tty_struct", "qwerty")) +} + +func TestFuncExists(t *testing.T) { + spec, err := btf.LoadKernelSpec() + assert.Nil(t, err) + + assert.True(t, FuncExists(spec, "do_filp_open")) + assert.False(t, FuncExists(spec, "qwerty")) +} + +func TestArgExists(t *testing.T) { + spec, err := btf.LoadKernelSpec() + assert.Nil(t, err) + + assert.True(t, ArgExists(spec, "do_filp_open", "pathname")) + assert.False(t, ArgExists(spec, "do_filp_open", "qwerty")) +} + +func TestArgIdxByFunc(t *testing.T) { + spec, err := btf.LoadKernelSpec() + assert.Nil(t, err) + + expectedIdx := uint32(1) + idx, err := ArgIdxByFunc(spec, "do_filp_open", "pathname") + assert.Nil(t, err) + assert.Equal(t, expectedIdx, idx) +} + +func TestFieldOffset(t *testing.T) { + spec, err := btf.LoadKernelSpec() + assert.Nil(t, err) + + expectedOffset := uint32(17) // 4xint + 1xchar + off, err := FieldOffset(spec, "termios", "c_cc") + assert.Nil(t, err) + assert.Equal(t, expectedOffset, off) +} diff --git a/auditbeat/internal/tmpebpfevents/pkg/kernel/version.go b/auditbeat/internal/tmpebpfevents/pkg/kernel/version.go new file mode 100644 index 000000000000..dee869497456 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/pkg/kernel/version.go @@ -0,0 +1,170 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package kernel + +import ( + "fmt" + "os" + "strconv" + "strings" + "syscall" +) + +const ( + // We only support Linux 5.10.16+ + // + // Linux commit e114dd64c0071500345439fc79dd5e0f9d106ed (went in in + // 5.11/5.10.16) fixed a verifier bug that (as of 9/28/2022) causes our + // probes to fail to load. + minSupportedVersion = "5.10.16" + + procVersionSignature = "/proc/version_signature" +) + +type version struct { + maj, min, patch int +} + +func (v version) String() string { + return fmt.Sprintf("%d.%d.%d", v.maj, v.min, v.patch) +} + +func (v version) Less(other version) bool { + return v.maj < other.maj || + (v.maj == other.maj && v.min < other.min) || + (v.maj == other.maj && v.min == other.min && v.patch < other.patch) +} + +func new(s string) (version, error) { + var ( + v version + parts = strings.Split(s, ".") + ) + if len(parts) == 1 && parts[0] == "" { + return v, nil + } + + major, err := strconv.ParseUint(parts[0], 10, 0) + if err != nil { + return v, fmt.Errorf("parse version: bad major: %s", s) + } + v.maj = int(major) + if len(parts) == 1 { + return v, nil + } + + minor, err := strconv.ParseUint(parts[1], 10, 0) + if err != nil { + return v, fmt.Errorf("parse version: bad minor: %s", s) + } + v.min = int(minor) + if len(parts) == 2 { + return v, nil + } + + patch, err := strconv.ParseUint(parts[2], 10, 0) + if err != nil { + return v, fmt.Errorf("parse version: bad patch: %s", s) + } + v.patch = int(patch) + + return v, nil +} + +func CheckSupported() error { + currentVersion, err := kernelVersion() + if err != nil { + return fmt.Errorf("current version: %v", err) + } + + minVersion, err := new(minSupportedVersion) + if err != nil { + return fmt.Errorf("min version: %v", err) + } + + if !minVersion.Less(currentVersion) { + return fmt.Errorf("min kernel version (%s) is higher or equal than current kernel version (%s)", minVersion.String(), currentVersion.String()) + } + + return nil +} + +func kernelVersion() (version, error) { + var v version + + if _, err := os.Stat(procVersionSignature); err == nil { + // Ubuntu kernels do not report the true upstream kernel source version in + // utsname.release, they report the "ABI version", which is the upstream + // kernel major.minor with some extra ABI information, e.g.: + // 5.15.0-48-generic. The upstream patch version is always set to 0. + // + // Ubuntu provides a file under procfs that reports the actual upstream + // source version, so we use that instead if it exists. + content, err := os.ReadFile(procVersionSignature) + if err != nil { + return v, fmt.Errorf("read %s: %v", procVersionSignature, err) + } + + info := strings.Fields(string(content)) + v, err = new(strings.Split(info[2], "-")[0]) + if err != nil { + return v, fmt.Errorf("parse %s: %v", procVersionSignature, err) + } + + return v, nil + } + + var uname syscall.Utsname + if err := syscall.Uname(&uname); err != nil { + return v, fmt.Errorf("uname: %v", err) + } + release := make([]byte, 0, len(uname.Release)) + for _, v := range uname.Release { + if v == 0 { + break + } + release = append(release, byte(v)) + } + + if strings.Contains(string(release), "Debian") { + // Like Ubuntu, what Debian reports in the un.release buffer is the + // "ABI version", which is the major.minor of the upstream, with the + // patch always set to 0 (and some further ABI numbers). e.g.: + // 5.10.0-18-amd64 + // + // See the following docs for more info: + // https://kernel-team.pages.debian.net/kernel-handbook/ch-versions.html + // + // Unlike Ubuntu, Debian does not provide a special procfs file + // indicating the actual upstream source. Instead, it puts the actual + // upstream source version into the un.version field, after the string + // "Debian" + parts := strings.Split(string(release), "Debian ") + _, err := fmt.Sscanf(parts[1], "%d.%d.%d", &v.maj, &v.min, &v.patch) + if err != nil { + return v, fmt.Errorf("read debian release: %v", err) + } + } + + _, err := fmt.Sscanf(string(release), "%d.%d.%d", &v.maj, &v.min, &v.patch) + if err != nil { + return v, fmt.Errorf("read release: %v", err) + } + + return v, nil +} diff --git a/auditbeat/internal/tmpebpfevents/pkg/kernel/version_test.go b/auditbeat/internal/tmpebpfevents/pkg/kernel/version_test.go new file mode 100644 index 000000000000..f07b3f5878af --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/pkg/kernel/version_test.go @@ -0,0 +1,65 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package kernel + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewVersion(t *testing.T) { + tests := []struct { + vstring string + maj, min, patch int + }{ + {"1.0.0", 1, 0, 0}, + {"1.2.3", 1, 2, 3}, + {"0.0.0", 0, 0, 0}, + {"1.2", 1, 2, 0}, + {"1", 1, 0, 0}, + {"1.2.3.4.5", 1, 2, 3}, + {"", 0, 0, 0}, + } + + for i, tt := range tests { + t.Run(fmt.Sprintf("test new version #%d", i), func(t *testing.T) { + v, err := new(tt.vstring) + assert.NoError(t, err) + assert.Equal(t, v.maj, tt.maj) + assert.Equal(t, v.min, tt.min) + assert.Equal(t, v.patch, tt.patch) + }) + } +} + +func TestNewVersionError(t *testing.T) { + tests := []string{ + "1.-1.0", + ".1.0", + "1.1.", + } + + for i, s := range tests { + t.Run(fmt.Sprintf("test new version error #%d", i), func(t *testing.T) { + _, err := new(s) + assert.Error(t, err) + }) + } +} diff --git a/auditbeat/internal/tmpebpfevents/pkg/testutils/varlen.go b/auditbeat/internal/tmpebpfevents/pkg/testutils/varlen.go new file mode 100644 index 000000000000..57a183078484 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/pkg/testutils/varlen.go @@ -0,0 +1,104 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package testutils + +import ( + "bufio" + "encoding/binary" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/elastic/ebpfevents/pkg/endian" + "github.com/elastic/ebpfevents/pkg/varlen" +) + +func WriteVarlenFields(t *testing.T, w *bufio.Writer, m varlen.Map) { + t.Helper() + + var ( + size uint64 + nfields uint32 + fieldSizes = make(map[varlen.Field]uint32) + ) + + for k, v := range m { + size += 4 // `type` + size += 4 // varlen_field `size` + + fieldSizes[k] = 0 + switch k { + case varlen.Cwd, varlen.Filename, varlen.CgroupPath, + varlen.Path, varlen.OldPath, varlen.NewPath, varlen.TTYOutput, + varlen.SymlinkTargetPath: + fieldSizes[k] += uint32(len(v.(string))) + 1 // null terminator + case varlen.Argv: + for _, str := range v.([]string) { + fieldSizes[k] += uint32(len(str)) + 1 // null terminator + } + case varlen.Env: + for key, value := range v.(map[string]string) { + fieldSizes[k] += uint32(len(key)) + fieldSizes[k] += 1 // equal sign + fieldSizes[k] += uint32(len(value)) + fieldSizes[k] += 1 // null terminator + } + default: + t.Fatalf("unsupported varlen type: %d", k) + } + + size += uint64(fieldSizes[k]) + nfields++ + } + + assert.Nil(t, binary.Write(w, endian.Native, nfields)) + assert.Nil(t, binary.Write(w, endian.Native, size)) + + for k, v := range m { + assert.Nil(t, binary.Write(w, endian.Native, k)) + assert.Nil(t, binary.Write(w, endian.Native, fieldSizes[k])) + + switch k { + case varlen.Cwd, varlen.Filename, varlen.CgroupPath, + varlen.Path, varlen.OldPath, varlen.NewPath, varlen.TTYOutput, + varlen.SymlinkTargetPath: + _, err := w.WriteString(v.(string)) + assert.Nil(t, err) + assert.Nil(t, w.WriteByte(0)) + case varlen.Argv: + for _, str := range v.([]string) { + _, err := w.WriteString(str) + assert.Nil(t, err) + assert.Nil(t, w.WriteByte(0)) + } + case varlen.Env: + for key, value := range v.(map[string]string) { + _, err := w.WriteString(key) + assert.Nil(t, err) + assert.Nil(t, w.WriteByte('=')) + _, err = w.WriteString(value) + assert.Nil(t, err) + assert.Nil(t, w.WriteByte(0)) + } + default: + t.Fatalf("unsupported varlen type: %d", k) + } + } + + assert.Nil(t, w.Flush()) +} diff --git a/auditbeat/internal/tmpebpfevents/pkg/varlen/varlen.go b/auditbeat/internal/tmpebpfevents/pkg/varlen/varlen.go new file mode 100644 index 000000000000..74199c00b6a7 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/pkg/varlen/varlen.go @@ -0,0 +1,217 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package varlen + +import ( + "bytes" + "encoding/binary" + "fmt" + "strings" + + "github.com/elastic/ebpfevents/pkg/endian" +) + +type ( + Field uint32 + Map map[Field]any +) + +const ( + Cwd Field = iota + Argv + Env + Filename + Path + OldPath + NewPath + TTYOutput + CgroupPath + SymlinkTargetPath +) + +type varlenStart struct { + nfields uint32 + size uint64 +} + +type varlenField struct { + typ Field + size uint32 +} + +func DeserializeVarlenFields(r *bytes.Reader) (Map, error) { + start, err := deserializeVarlenStart(r) + if err != nil { + return nil, fmt.Errorf("deserialize varlen start: %v", err) + } + + ret := make(Map) + for i := uint32(0); i < start.nfields; i++ { + field, err := deserializeVarlenFieldHeader(r) + if err != nil { + return nil, fmt.Errorf("deserialize varlen header: %v", err) + } + + switch field.typ { + case Cwd, Filename, Path, OldPath, NewPath, TTYOutput, CgroupPath, SymlinkTargetPath: + str, err := deserializeVarlenString(r, field.size) + if err != nil { + return nil, fmt.Errorf("deserialize varlen string: %v", err) + } + ret[field.typ] = str + case Argv: + argv, err := deserializeVarlenArgv(r, field.size) + if err != nil { + return nil, fmt.Errorf("deserialize varlen argv: %v", err) + } + ret[field.typ] = argv + case Env: + env, err := deserializeVarlenEnv(r, field.size) + if err != nil { + return nil, fmt.Errorf("deserialize varlen env: %v", err) + } + ret[field.typ] = env + default: + return nil, fmt.Errorf("unsupported varlen type: %d", field.typ) + } + } + + if r.Len() != 0 { + return nil, fmt.Errorf("data left in reader: %v", r.Len()) + } + + return ret, nil +} + +func deserializeVarlenStart(r *bytes.Reader) (*varlenStart, error) { + var ret varlenStart + + if err := binary.Read(r, endian.Native, &ret.nfields); err != nil { + return nil, fmt.Errorf("read nfields: %v", err) + } + if err := binary.Read(r, endian.Native, &ret.size); err != nil { + return nil, fmt.Errorf("read size: %v", err) + } + + return &ret, nil +} + +func deserializeVarlenFieldHeader(r *bytes.Reader) (*varlenField, error) { + var ret varlenField + + if err := binary.Read(r, endian.Native, &ret.typ); err != nil { + return nil, fmt.Errorf("read typ: %v", err) + } + if err := binary.Read(r, endian.Native, &ret.size); err != nil { + return nil, fmt.Errorf("read size: %v", err) + } + + return &ret, nil +} + +func deserializeVarlenString(r *bytes.Reader, size uint32) (string, error) { + if size == 0 { + return "", nil + } + + var b strings.Builder + b.Grow(int(size - 1)) + + for i := uint32(0); i < size-1; i++ { + c, err := r.ReadByte() + if err != nil { + return "", err + } + + if err = b.WriteByte(c); err != nil { + return "", err + } + } + + // read null terminator + _, err := r.ReadByte() + if err != nil { + return "", err + } + + return b.String(), nil +} + +func deserializeVarlenArgv(r *bytes.Reader, size uint32) ([]string, error) { + var ( + b strings.Builder + ret = make([]string, 0) + ) + b.Grow(int(size)) + + for i := uint32(0); i < size; i++ { + c, err := r.ReadByte() + if err != nil { + return nil, err + } + + if c == 0 { + ret = append(ret, b.String()) + b.Reset() + continue + } + if err = b.WriteByte(c); err != nil { + return nil, err + } + } + + return ret, nil +} + +func deserializeVarlenEnv(r *bytes.Reader, size uint32) (map[string]string, error) { + var ( + key strings.Builder + value strings.Builder + parsingKey = true + ret = make(map[string]string) + ) + + for i := uint32(0); i < size; i++ { + c, err := r.ReadByte() + if err != nil { + return nil, err + } + + switch c { + case 0: + ret[key.String()] = value.String() + key.Reset() + value.Reset() + parsingKey = true + case '=': + parsingKey = false + default: + if parsingKey { + if err = key.WriteByte(c); err != nil { + return nil, err + } + } else { + if err = value.WriteByte(c); err != nil { + return nil, err + } + } + } + } + + return ret, nil +} diff --git a/auditbeat/internal/tmpebpfevents/pkg/varlen/varlen_test.go b/auditbeat/internal/tmpebpfevents/pkg/varlen/varlen_test.go new file mode 100644 index 000000000000..6243a6d09358 --- /dev/null +++ b/auditbeat/internal/tmpebpfevents/pkg/varlen/varlen_test.go @@ -0,0 +1,52 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package varlen_test + +import ( + "bufio" + "bytes" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/elastic/ebpfevents/pkg/testutils" + "github.com/elastic/ebpfevents/pkg/varlen" +) + +func TestDeserializeVarlenFields(t *testing.T) { + buf := bytes.NewBuffer(nil) + + expectedMap := varlen.Map{ + varlen.Cwd: "test_cwd", + varlen.Argv: []string{"a", "r", "g", "v"}, + varlen.Env: map[string]string{"a": "b", "c": "d"}, + varlen.Filename: "test_filename", + varlen.Path: "test_path", + varlen.OldPath: "test_oldpath", + varlen.NewPath: "test_newpath", + varlen.TTYOutput: "test_tty", + varlen.CgroupPath: "test_cgroup", + varlen.SymlinkTargetPath: "test_symlink", + } + testutils.WriteVarlenFields(t, bufio.NewWriter(buf), expectedMap) + + m, err := varlen.DeserializeVarlenFields(bytes.NewReader(buf.Bytes())) + assert.Nil(t, err) + + assert.Equal(t, expectedMap, m) +} diff --git a/go.mod b/go.mod index 9882dd5e6977..e2ec68450245 100644 --- a/go.mod +++ b/go.mod @@ -405,6 +405,8 @@ replace ( github.com/docker/go-plugins-helpers => github.com/elastic/go-plugins-helpers v0.0.0-20200207104224-bdf17607b79f github.com/dop251/goja => github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20 github.com/dop251/goja_nodejs => github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6 + + github.com/elastic/ebpfevents => ./auditbeat/internal/tmpebpfevents github.com/fsnotify/fsevents => github.com/elastic/fsevents v0.0.0-20181029231046-e1d381a4d270 github.com/fsnotify/fsnotify => github.com/adriansr/fsnotify v1.4.8-0.20211018144411-a81f2b630e7c github.com/godror/godror => github.com/godror/godror v0.33.2 // updating to v0.24.2 caused a breaking change @@ -414,7 +416,6 @@ replace ( github.com/snowflakedb/gosnowflake => github.com/snowflakedb/gosnowflake v1.6.19 github.com/tonistiigi/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c k8s.io/kubernetes v1.13.0 => k8s.io/kubernetes v1.24.15 - ) // Exclude this version because the version has an invalid checksum. diff --git a/go.sum b/go.sum index f80a85da581e..6e4e424c4936 100644 --- a/go.sum +++ b/go.sum @@ -652,8 +652,6 @@ github.com/elastic/bayeux v1.0.5 h1:UceFq01ipmT3S8DzFK+uVAkbCdiPR0Bqei8qIGmUeY0= github.com/elastic/bayeux v1.0.5/go.mod h1:CSI4iP7qeo5MMlkznGvYKftp8M7qqP/3nzmVZoXHY68= github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3 h1:lnDkqiRFKm0rxdljqrj3lotWinO9+jFmeDXIC4gvIQs= github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3/go.mod h1:aPqzac6AYkipvp4hufTyMj5PDIphF3+At8zr7r51xjY= -github.com/elastic/ebpfevents v0.0.0-20231129134946-a7e15f50b181 h1:/0SBxnH827/ZucMHcrMKwhiIpye1uDD2LKXUqOYNsEg= -github.com/elastic/ebpfevents v0.0.0-20231129134946-a7e15f50b181/go.mod h1:o21z5xup/9dK8u0Hg9bZRflSqqj1Zu5h2dg2hSTcUPQ= github.com/elastic/elastic-agent-autodiscover v0.6.4 h1:K+xC7OGgcy4fLXVuGgOGLs+eXCqRnRg2SQQinxP+KsA= github.com/elastic/elastic-agent-autodiscover v0.6.4/go.mod h1:5+7NIBAILc0GkgxYW3ckXncu5wRZfltZhTY4aZAYP4M= github.com/elastic/elastic-agent-client/v7 v7.5.0 h1:niI3WQ+01Lnp2r5LxK8SyNhrPJe13vBiOkqrDRK2oTA= diff --git a/x-pack/auditbeat/auditbeat.reference.yml b/x-pack/auditbeat/auditbeat.reference.yml index 09b343d8fe28..c46aa1815f92 100644 --- a/x-pack/auditbeat/auditbeat.reference.yml +++ b/x-pack/auditbeat/auditbeat.reference.yml @@ -92,6 +92,10 @@ auditbeat.modules: # Auditbeat will ignore files unless they match a pattern. #include_files: #- '/\.ssh($|/)' + # Select the backend which will be used to source events. + # Valid values: ebpf, fsnotify. + # Default: fsnotify. + force_backend: fsnotify # Scan over the configured file paths at startup and send events for new or # modified files since the last time Auditbeat was running.