Compare commits
54 Commits
Author | SHA1 | Date |
---|---|---|
|
d8d6d2bb45 | |
|
76fd297bea | |
|
e6a5c8e3e2 | |
|
12733f576f | |
|
29ec9e2c46 | |
|
3b1dc02551 | |
|
bdc2e3456f | |
|
3977c2d638 | |
|
a99b7e36d5 | |
|
8d93fd8f78 | |
|
58d9745723 | |
|
daa25c41b3 | |
|
10b2c10fc2 | |
|
5087729187 | |
|
7376d90024 | |
|
6c4222665f | |
|
807b57be99 | |
|
f6a8499542 | |
|
96cc888b6d | |
|
d13e89961b | |
|
6904e23a4f | |
|
c8dc49ff92 | |
|
5efa6ca6eb | |
|
8271dec87e | |
|
d4060b2011 | |
|
72a25d501a | |
|
d230606fb0 | |
|
0122aead06 | |
|
5860a5f8d9 | |
|
191a78bc5f | |
|
6b92800d59 | |
|
2aa6057c93 | |
|
eecb760909 | |
|
8958f00bfa | |
|
8d147677ac | |
|
4644924b53 | |
|
f9127f9b17 | |
|
196fd56ad6 | |
|
29bba20a52 | |
|
c9d2723d51 | |
|
68c4472981 | |
|
1a7864328e | |
|
a76366fe72 | |
|
7e017af2f4 | |
|
6c9bb76fba | |
|
c07e7823f6 | |
|
58c2e7acc3 | |
|
3cdca05e80 | |
|
05f013aa24 | |
|
a3fb7149b6 | |
|
b553485768 | |
|
11fdb6dcce | |
|
9575c45400 | |
|
b9a90fb643 |
|
@ -298,6 +298,43 @@ jobs:
|
|||
KERNELDIR=/lib/modules/$(ls /lib/modules)/build make scap-open driver bpf unit-test-libsinsp -j6
|
||||
./libsinsp/test/unit-test-libsinsp
|
||||
|
||||
# This job checks that a bundled deps of libs is as static as possible
|
||||
test-libs-static:
|
||||
name: test-libs-static (bundled_deps)
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout Libs ⤵️
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install deps ⛓️
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y --no-install-recommends ca-certificates cmake build-essential clang-14 llvm-14 git pkg-config autoconf automake libtool libelf-dev libcap-dev linux-headers-$(uname -r)
|
||||
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 90
|
||||
sudo update-alternatives --install /usr/bin/llvm-strip llvm-strip /usr/bin/llvm-strip-14 90
|
||||
sudo update-alternatives --install /usr/bin/llc llc /usr/bin/llc-14 90
|
||||
|
||||
- name: Build sinsp-example
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build && cmake -DUSE_BUNDLED_DEPS=On -DBUILD_DRIVER=ON -DBUILD_LIBSCAP_MODERN_BPF=ON -DBUILD_BPF=On -DBUILD_LIBSCAP_GVISOR=On -DCREATE_TEST_TARGETS=Off -DENABLE_LIBSCAP_TESTS=Off ../
|
||||
make -j$(nproc) sinsp-example
|
||||
|
||||
- name: Ensure that sinsp-example with bundled deps is as static as possible
|
||||
run: |
|
||||
ldd "build/libsinsp/examples/sinsp-example" | cut --fields=2 | cut --delimiter=' ' --fields=1 | rev | cut --delimiter='/' --fields=1 | rev | sort --unique --version-sort > ldd_out.txt
|
||||
cat > expected_ldd_out.txt <<EOF
|
||||
ld-linux-x86-64.so.2
|
||||
libc.so.6
|
||||
libgcc_s.so.1
|
||||
libm.so.6
|
||||
libstdc++.so.6
|
||||
linux-vdso.so.1
|
||||
EOF
|
||||
diff -u expected_ldd_out.txt ldd_out.txt
|
||||
|
||||
run-e2e-tests-amd64:
|
||||
name: run-e2e-tests-amd64
|
||||
strategy:
|
||||
|
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
name: check-insecure-api
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: returntocorp/semgrep
|
||||
image: returntocorp/semgrep:1.41.0
|
||||
steps:
|
||||
- name: Checkout Libs ⤵️
|
||||
uses: actions/checkout@v3
|
||||
|
|
|
@ -4,8 +4,8 @@ on:
|
|||
workflow_dispatch:
|
||||
inputs:
|
||||
linux-version:
|
||||
description: 'Archlinux kernel version to build a driver against, eg: 6.2.arch1-1'
|
||||
required: true
|
||||
description: 'Archlinux kernel version to build a driver against, eg: 6.2.arch1-1 or empty to build latest mainline'
|
||||
required: false
|
||||
type: string
|
||||
schedule:
|
||||
- cron: '0 8 * * *' # every day at 8am
|
||||
|
@ -59,7 +59,7 @@ jobs:
|
|||
|
||||
- name: Update README badge
|
||||
uses: schneegans/dynamic-badges-action@v1.6.0
|
||||
if: always() && inputs.linux-version == ''
|
||||
if: always() && github.event_name == 'schedule'
|
||||
with:
|
||||
auth: ${{ secrets.FEDEDP_GIST_SECRET }}
|
||||
gistID: 1cbc5d42edf8e3a02fb75e76625f1072
|
||||
|
|
|
@ -13,8 +13,11 @@ concurrency:
|
|||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
release-body:
|
||||
check-driver-tag:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
driver_tag: ${{ steps.regex-match.outputs.match }}
|
||||
|
||||
steps:
|
||||
# Note: there is no `tag` filter for `workflow_run`.
|
||||
# We need to manually check whether we are running on a tag.
|
||||
|
@ -25,9 +28,25 @@ jobs:
|
|||
text: ${{ github.event.workflow_run.head_branch }}
|
||||
regex: '[0-9]+.[0-9]+.[0-9]+\+driver$'
|
||||
|
||||
- name: Skip on non driver tag
|
||||
if: steps.regex-match.outputs.match == ''
|
||||
run: exit 0
|
||||
release-body:
|
||||
needs: check-driver-tag
|
||||
runs-on: ubuntu-latest
|
||||
if: needs.check-driver-tag.outputs.driver_tag != ''
|
||||
|
||||
steps:
|
||||
- name: Clone libs repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.workflow_run.head_branch }}
|
||||
|
||||
- name: Extract API and SCHEMA versions
|
||||
run: |
|
||||
touch release-body.md
|
||||
API_VERS=$(cat driver/API_VERSION)
|
||||
SCHEMA_VERS=$(cat driver/SCHEMA_VERSION)
|
||||
echo '!'"[API](https://img.shields.io/badge/API-${API_VERS}-yellow)" >> release-body.md
|
||||
echo '!'"[SCHEMA](https://img.shields.io/badge/SCHEMA-${SCHEMA_VERS}-yellow)" >> release-body.md
|
||||
echo "" >> release-body.md
|
||||
|
||||
- name: Download matrixes
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
|
@ -52,7 +71,7 @@ jobs:
|
|||
sed -i 's/\[\(.\)\]([^)]*)/\1/g' matrix_ARM64.md
|
||||
sed -i '1s/^/# Driver Testing Matrix amd64\n\n/' matrix_X64.md
|
||||
sed -i '1s/^/# Driver Testing Matrix arm64\n\n/' matrix_ARM64.md
|
||||
cat matrix_X64.md matrix_ARM64.md > release-body.md
|
||||
cat matrix_X64.md matrix_ARM64.md >> release-body.md
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
|
|
|
@ -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] The Falco Authors
|
||||
|
||||
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.
|
|
@ -43,8 +43,8 @@ else()
|
|||
curl
|
||||
PREFIX "${PROJECT_BINARY_DIR}/curl-prefix"
|
||||
DEPENDS openssl zlib
|
||||
URL "https://github.com/curl/curl/releases/download/curl-8_2_0/curl-8.2.0.tar.bz2"
|
||||
URL_HASH "SHA256=080aaa5bef29ab3f592101e7a95f32ddbe88b92125cb28dde479d5a104928ea4"
|
||||
URL "https://github.com/curl/curl/releases/download/curl-8_4_0/curl-8.4.0.tar.bz2"
|
||||
URL_HASH "SHA256=e5250581a9c032b1b6ed3cf2f9c114c811fc41881069e9892d115cc73f9e88c6"
|
||||
CONFIGURE_COMMAND
|
||||
./configure
|
||||
${CURL_SSL_OPTION}
|
||||
|
|
|
@ -34,9 +34,9 @@ else()
|
|||
libelf
|
||||
PREFIX "${PROJECT_BINARY_DIR}/libelf-prefix"
|
||||
DEPENDS zlib
|
||||
URL "https://sourceware.org/elfutils/ftp/0.187/elfutils-0.187.tar.bz2"
|
||||
URL_HASH "SHA256=e70b0dfbe610f90c4d1fe0d71af142a4e25c3c4ef9ebab8d2d72b65159d454c8"
|
||||
CONFIGURE_COMMAND ./configure LDFLAGS=-L${ZLIB_SRC} "CFLAGS=-I${ZLIB_INCLUDE}" --enable-deterministic-archives --disable-debuginfod --disable-libdebuginfod
|
||||
URL "https://sourceware.org/elfutils/ftp/0.189/elfutils-0.189.tar.bz2"
|
||||
URL_HASH "SHA256=39bd8f1a338e2b7cd4abc3ff11a0eddc6e690f69578a57478d8179b4148708c8"
|
||||
CONFIGURE_COMMAND ./configure LDFLAGS=-L${ZLIB_SRC} "CFLAGS=-I${ZLIB_INCLUDE}" --enable-deterministic-archives --disable-debuginfod --disable-libdebuginfod --without-zstd
|
||||
BUILD_IN_SOURCE 1
|
||||
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} -C lib libeu.a
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM} -C libelf libelf${LIBELF_LIB_SUFFIX}
|
||||
|
|
|
@ -28,8 +28,8 @@ else()
|
|||
|
||||
ExternalProject_Add(openssl
|
||||
PREFIX "${PROJECT_BINARY_DIR}/openssl-prefix"
|
||||
URL "https://github.com/openssl/openssl/releases/download/openssl-3.1.1/openssl-3.1.1.tar.gz"
|
||||
URL_HASH "SHA256=b3aa61334233b852b63ddb048df181177c2c659eb9d4376008118f9c08d07674"
|
||||
URL "https://github.com/openssl/openssl/releases/download/openssl-3.1.2/openssl-3.1.2.tar.gz"
|
||||
URL_HASH "SHA256=a0ce69b8b97ea6a35b96875235aa453b966ba3cba8af2de23657d8b6767d6539"
|
||||
CONFIGURE_COMMAND ./config ${OPENSSL_SHARED_OPTION} --prefix=${OPENSSL_INSTALL_DIR} --libdir=lib
|
||||
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||
BUILD_IN_SOURCE 1
|
||||
|
|
|
@ -46,8 +46,8 @@ else()
|
|||
|
||||
if(NOT TARGET tbb)
|
||||
message(STATUS "Using bundled tbb in '${TBB_SRC}'")
|
||||
set(TBB_SRC_URL "https://github.com/oneapi-src/oneTBB/archive/refs/tags/v2021.8.0.tar.gz")
|
||||
set(TBB_SRC_URL_HASH "SHA256=eee380323bb7ce864355ed9431f85c43955faaae9e9bce35c62b372d7ffd9f8b")
|
||||
set(TBB_SRC_URL "https://github.com/oneapi-src/oneTBB/archive/refs/tags/v2021.9.0.tar.gz")
|
||||
set(TBB_SRC_URL_HASH "SHA256=1ce48f34dada7837f510735ff1172f6e2c261b09460e3bf773b49791d247d24e")
|
||||
set(TBB_FLAGS "")
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
# latest TBB has issues with GCC >= 12
|
||||
|
|
|
@ -2839,7 +2839,12 @@ FILLER(execve_extra_tail_1, true)
|
|||
struct timespec64 time = {0};
|
||||
|
||||
/* Parameter 25: exe_file ctime (last status change time, epoch value in nanoseconds) (type: PT_ABSTIME) */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
|
||||
time = _READ(inode->__i_ctime);
|
||||
time.tv_nsec = time.tv_nsec & ~I_CTIME_QUERIED; // See https://elixir.bootlin.com/linux/v6.6-rc1/source/include/linux/fs.h#L1544
|
||||
#else
|
||||
time = _READ(inode->i_ctime);
|
||||
#endif
|
||||
res = bpf_push_u64_to_ring(data, bpf_epoch_ns_from_time(time));
|
||||
CHECK_RES(res);
|
||||
|
||||
|
@ -6694,7 +6699,12 @@ FILLER(sched_prog_exec_4, false)
|
|||
struct timespec64 time = {0};
|
||||
|
||||
/* Parameter 25: exe_file ctime (last status change time, epoch value in nanoseconds) (type: PT_ABSTIME) */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
|
||||
time = _READ(inode->__i_ctime);
|
||||
time.tv_nsec = time.tv_nsec & ~I_CTIME_QUERIED; // See https://elixir.bootlin.com/linux/v6.6-rc1/source/include/linux/fs.h#L1544
|
||||
#else
|
||||
time = _READ(inode->i_ctime);
|
||||
#endif
|
||||
res = bpf_push_u64_to_ring(data, bpf_epoch_ns_from_time(time));
|
||||
CHECK_RES(res);
|
||||
|
||||
|
|
|
@ -584,6 +584,13 @@
|
|||
|
||||
#define FMODE_CREATED (/*(__force fmode_t) */0x100000)
|
||||
|
||||
//////////////////////////
|
||||
// ctime flags
|
||||
//////////////////////////
|
||||
|
||||
/* `include/linux/fs.h` from kernel source tree. */
|
||||
#define I_CTIME_QUERIED (1L<<30)
|
||||
|
||||
//////////////////////////
|
||||
// flock flags
|
||||
//////////////////////////
|
||||
|
|
|
@ -36,6 +36,10 @@ struct task_struct___cos {
|
|||
struct audit_task_info *audit;
|
||||
};
|
||||
|
||||
struct inode___v6_6 {
|
||||
struct timespec64 __i_ctime;
|
||||
};
|
||||
|
||||
#ifndef BPF_NO_PRESERVE_ACCESS_INDEX
|
||||
#pragma clang attribute pop
|
||||
#endif
|
||||
|
|
|
@ -213,7 +213,16 @@ int BPF_PROG(t1_sched_p_exec,
|
|||
|
||||
/* Parameter 25: exe_file ctime (last status change time, epoch value in nanoseconds) (type: PT_ABSTIME) */
|
||||
struct timespec64 time = { 0, 0 };
|
||||
BPF_CORE_READ_INTO(&time, exe_inode, i_ctime);
|
||||
if(bpf_core_field_exists(exe_inode->i_ctime))
|
||||
{
|
||||
BPF_CORE_READ_INTO(&time, exe_inode, i_ctime);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct inode___v6_6 *exe_inode_v6_6 = (void *)exe_inode;
|
||||
BPF_CORE_READ_INTO(&time, exe_inode_v6_6, __i_ctime);
|
||||
time.tv_nsec = time.tv_nsec & ~I_CTIME_QUERIED;
|
||||
}
|
||||
auxmap__store_u64_param(auxmap, extract__epoch_ns_from_time(time));
|
||||
|
||||
/* Parameter 26: exe_file mtime (last modification time, epoch value in nanoseconds) (type: PT_ABSTIME) */
|
||||
|
|
|
@ -277,7 +277,16 @@ int BPF_PROG(t1_execve_x,
|
|||
|
||||
/* Parameter 25: exe_file ctime (last status change time, epoch value in nanoseconds) (type: PT_ABSTIME) */
|
||||
struct timespec64 time = { 0, 0 };
|
||||
BPF_CORE_READ_INTO(&time, exe_inode, i_ctime);
|
||||
if(bpf_core_field_exists(exe_inode->i_ctime))
|
||||
{
|
||||
BPF_CORE_READ_INTO(&time, exe_inode, i_ctime);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct inode___v6_6 *exe_inode_v6_6 = (void *)exe_inode;
|
||||
BPF_CORE_READ_INTO(&time, exe_inode_v6_6, __i_ctime);
|
||||
time.tv_nsec = time.tv_nsec & ~I_CTIME_QUERIED;
|
||||
}
|
||||
auxmap__store_u64_param(auxmap, extract__epoch_ns_from_time(time));
|
||||
|
||||
/* Parameter 26: exe_file mtime (last modification time, epoch value in nanoseconds) (type: PT_ABSTIME) */
|
||||
|
|
|
@ -293,7 +293,16 @@ int BPF_PROG(t1_execveat_x,
|
|||
|
||||
/* Parameter 25: exe_file ctime (last status change time, epoch value in nanoseconds) (type: PT_ABSTIME) */
|
||||
struct timespec64 time = { 0, 0 };
|
||||
BPF_CORE_READ_INTO(&time, exe_inode, i_ctime);
|
||||
if(bpf_core_field_exists(exe_inode->i_ctime))
|
||||
{
|
||||
BPF_CORE_READ_INTO(&time, exe_inode, i_ctime);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct inode___v6_6 *exe_inode_v6_6 = (void *)exe_inode;
|
||||
BPF_CORE_READ_INTO(&time, exe_inode_v6_6, __i_ctime);
|
||||
time.tv_nsec = time.tv_nsec & ~I_CTIME_QUERIED;
|
||||
}
|
||||
auxmap__store_u64_param(auxmap, extract__epoch_ns_from_time(time));
|
||||
|
||||
/* Parameter 26: exe_file mtime (last modification time, epoch value in nanoseconds) (type: PT_ABSTIME) */
|
||||
|
|
|
@ -579,12 +579,18 @@ int f_sys_write_x(struct event_filler_arguments *args)
|
|||
/*
|
||||
* get_mm_exe_file is only exported in some kernel versions
|
||||
*/
|
||||
|
||||
struct file *ppm_get_mm_exe_file(struct mm_struct *mm)
|
||||
{
|
||||
struct file *exe_file;
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
|
||||
/*
|
||||
* The following if/else preprocessor directive is to cover for that change:
|
||||
* https://github.com/torvalds/linux/commit/90f31d0ea88880f780574f3d0bb1a227c4c66ca3#diff-e37b5cb4c23f6ab27741c60ec48674eff0268624a228c9a1cddddb9e4ee2922dL709
|
||||
* That was introduced in linux 4.1, but it's backported in some distro kernels.
|
||||
* Luckily enough, `get_file_rcu` is a define, so we can check for it and use
|
||||
* the safer version.
|
||||
*/
|
||||
#if defined(get_file_rcu)
|
||||
rcu_read_lock();
|
||||
exe_file = rcu_dereference(mm->exe_file);
|
||||
if (exe_file && !get_file_rcu(exe_file))
|
||||
|
@ -1506,8 +1512,15 @@ cgroups_error:
|
|||
* During kernel versions `i_ctime` changed from `struct timespec` to `struct timespec64`
|
||||
* but fields names should be always the same.
|
||||
*/
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
|
||||
{
|
||||
struct timespec64 inode_ctime;
|
||||
inode_ctime = inode_get_ctime(file_inode(exe_file));
|
||||
ctime = inode_ctime.tv_sec * (uint64_t) 1000000000 + inode_ctime.tv_nsec;
|
||||
}
|
||||
#else
|
||||
ctime = file_inode(exe_file)->i_ctime.tv_sec * (uint64_t) 1000000000 + file_inode(exe_file)->i_ctime.tv_nsec;
|
||||
|
||||
#endif
|
||||
/* Support exe_file mtime
|
||||
* During kernel versions `i_mtime` changed from `struct timespec` to `struct timespec64`
|
||||
* but fields names should be always the same.
|
||||
|
@ -7769,7 +7782,15 @@ cgroups_error:
|
|||
* During kernel versions `i_ctime` changed from `struct timespec` to `struct timespec64`
|
||||
* but fields names should be always the same.
|
||||
*/
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
|
||||
{
|
||||
struct timespec64 inode_ctime;
|
||||
inode_ctime = inode_get_ctime(file_inode(exe_file));
|
||||
ctime = inode_ctime.tv_sec * (uint64_t) 1000000000 + inode_ctime.tv_nsec;
|
||||
}
|
||||
#else
|
||||
ctime = file_inode(exe_file)->i_ctime.tv_sec * (uint64_t) 1000000000 + file_inode(exe_file)->i_ctime.tv_nsec;
|
||||
#endif
|
||||
|
||||
/* Support exe_file mtime
|
||||
* During kernel versions `i_mtime` changed from `struct timespec` to `struct timespec64`
|
||||
|
|
|
@ -197,6 +197,10 @@ def parse_log(log: str) -> dict:
|
|||
Returns:
|
||||
A dictionary holding all the captured values for the event.
|
||||
"""
|
||||
if log.startswith('--'):
|
||||
# sinsp-example diagnostic messages
|
||||
print(log)
|
||||
return None
|
||||
try:
|
||||
return json.loads(log)
|
||||
except json.JSONDecodeError as e:
|
||||
|
|
|
@ -4,6 +4,7 @@ from sinspqa.sinsp import assert_events
|
|||
from sinspqa.docker import get_container_id
|
||||
|
||||
sinsp_args = [
|
||||
"-j",
|
||||
"-f", "evt.category=process and not container.id=host",
|
||||
"-o", "%container.id %evt.args %evt.category %evt.type %proc.cmdline %proc.exe %user.uid %user.name %user.homedir %group.gid %group.name"
|
||||
]
|
||||
|
|
|
@ -65,6 +65,12 @@ set(LIBSCAP_TESTS_SOURCES ${USERSPACE_TEST_SUITE})
|
|||
file(GLOB_RECURSE LIBSCAP_TESTS_UTILS_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/helpers/*cpp")
|
||||
list(APPEND LIBSCAP_TESTS_SOURCES ${LIBSCAP_TESTS_UTILS_SOURCES})
|
||||
|
||||
# Linux specific tests
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
file(GLOB_RECURSE LINUX_TEST_SUITE "${CMAKE_CURRENT_SOURCE_DIR}/test_suites/userspace/linux/*.cpp")
|
||||
list(APPEND LIBSCAP_TEST_SOURCES ${LINUX_TEST_SUITE})
|
||||
endif()
|
||||
|
||||
# Engine-specific tests
|
||||
if(BUILD_DRIVER)
|
||||
file(GLOB_RECURSE KMOD_TEST_SUITE "${CMAKE_CURRENT_SOURCE_DIR}/test_suites/engines/kmod/*.cpp")
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Copyright (C) 2023 The Falco Authors.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <linux/scap_cgroup.h>
|
||||
#include <linux/scap_cgroup.c>
|
||||
|
||||
TEST(cgroups, path_relative)
|
||||
{
|
||||
char final_path[4096];
|
||||
const char* prefix = "/1/2/3";
|
||||
const char* path = "/../../../init.scope";
|
||||
size_t prefix_len = 0;
|
||||
size_t path_strip_len = 0;
|
||||
ASSERT_EQ(scap_cgroup_prefix_path(prefix, path, &prefix_len, &path_strip_len), SCAP_SUCCESS);
|
||||
snprintf(final_path, sizeof(final_path), "%.*s%s", (int)prefix_len, prefix, path + path_strip_len);
|
||||
ASSERT_STREQ(final_path,"/init.scope");
|
||||
}
|
||||
|
||||
TEST(cgroups, path_relative_with_final_slash)
|
||||
{
|
||||
char final_path[4096];
|
||||
const char* prefix = "/1/2/3/";
|
||||
const char* path = "/../../../init.scope";
|
||||
size_t prefix_len = 0;
|
||||
size_t path_strip_len = 0;
|
||||
ASSERT_EQ(scap_cgroup_prefix_path(prefix, path, &prefix_len, &path_strip_len), SCAP_SUCCESS);
|
||||
snprintf(final_path, sizeof(final_path), "%.*s%s", (int)prefix_len, prefix, path + path_strip_len);
|
||||
ASSERT_STREQ(final_path,"/1/init.scope");
|
||||
}
|
||||
|
||||
TEST(cgroups, path_absolute)
|
||||
{
|
||||
char final_path[4096];
|
||||
const char* prefix = "/1/2/3";
|
||||
const char* path = "/absolute";
|
||||
size_t prefix_len = 0;
|
||||
size_t path_strip_len = 0;
|
||||
ASSERT_EQ(scap_cgroup_prefix_path(prefix, path, &prefix_len, &path_strip_len), SCAP_SUCCESS);
|
||||
snprintf(final_path, sizeof(final_path), "%.*s%s", (int)prefix_len, prefix, path + path_strip_len);
|
||||
ASSERT_STREQ(final_path,"/1/2/3/absolute");
|
||||
}
|
||||
|
||||
TEST(cgroups, prefix_empty)
|
||||
{
|
||||
const char* prefix = "";
|
||||
const char* path = "/../../absolute";
|
||||
size_t prefix_len = 0;
|
||||
size_t path_strip_len = 0;
|
||||
ASSERT_EQ(scap_cgroup_prefix_path(prefix, path, &prefix_len, &path_strip_len), SCAP_FAILURE);
|
||||
}
|
||||
|
||||
TEST(cgroups, path_empty)
|
||||
{
|
||||
char final_path[4096];
|
||||
const char* prefix = "/1/2/3";
|
||||
const char* path = "";
|
||||
size_t prefix_len = 0;
|
||||
size_t path_strip_len = 0;
|
||||
ASSERT_EQ(scap_cgroup_prefix_path(prefix, path, &prefix_len, &path_strip_len), SCAP_SUCCESS);
|
||||
snprintf(final_path, sizeof(final_path), "%.*s%s", (int)prefix_len, prefix, path + path_strip_len);
|
||||
ASSERT_STREQ(final_path,"/1/2/3");
|
||||
}
|
|
@ -17,6 +17,10 @@ limitations under the License.
|
|||
|
||||
#include "state.h"
|
||||
#include <sys/resource.h>
|
||||
#include <linux/limits.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <fcntl.h> /* Definition of AT_* constants */
|
||||
#include <unistd.h>
|
||||
|
||||
static int setup_libbpf_print_verbose(enum libbpf_print_level level, const char* format, va_list args)
|
||||
{
|
||||
|
@ -164,16 +168,139 @@ int pman_get_required_buffers()
|
|||
return g_state.n_required_buffers;
|
||||
}
|
||||
|
||||
bool check_location(const char* path)
|
||||
{
|
||||
static const char bpf_trace_raw_byte_array[] = "BPF_TRACE_RAW_TP";
|
||||
|
||||
bool res = false;
|
||||
|
||||
// On success `faccessat` returns 0.
|
||||
if(faccessat(0, path, R_OK, AT_EACCESS) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char *file_content = NULL;
|
||||
FILE *f = fopen(path, "r");
|
||||
if(!f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Seek to the end of file
|
||||
if(fseek(f, 0, SEEK_END))
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Return the dimension of the file
|
||||
long sz = ftell(f);
|
||||
if (sz < 0)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Seek again to the beginning of the file
|
||||
if(fseek(f, 0, SEEK_SET))
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// pre-alloc memory to read all of BTF data
|
||||
file_content = malloc(sz);
|
||||
if (!file_content)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// read all of BTF data
|
||||
if(fread(file_content, 1, sz, f) < sz)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Search 'BPF_TRACE_RAW_TP' byte array
|
||||
int z = 0;
|
||||
for(int j = 0; j< sz; j++)
|
||||
{
|
||||
if(file_content[j] == bpf_trace_raw_byte_array[z])
|
||||
{
|
||||
z++;
|
||||
if(z == sizeof(bpf_trace_raw_byte_array) / sizeof(*bpf_trace_raw_byte_array))
|
||||
{
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if(f)
|
||||
{
|
||||
fclose(f);
|
||||
}
|
||||
if(file_content)
|
||||
{
|
||||
free(file_content);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool probe_BPF_TRACE_RAW_TP_type(void)
|
||||
{
|
||||
// These locations are taken from libbpf library:
|
||||
// https://elixir.bootlin.com/linux/latest/source/tools/lib/bpf/btf.c#L4767
|
||||
const char *locations[] = {
|
||||
"/sys/kernel/btf/vmlinux",
|
||||
"/boot/vmlinux-%1$s",
|
||||
"/lib/modules/%1$s/vmlinux-%1$s",
|
||||
"/lib/modules/%1$s/build/vmlinux",
|
||||
"/usr/lib/modules/%1$s/kernel/vmlinux",
|
||||
"/usr/lib/debug/boot/vmlinux-%1$s",
|
||||
"/usr/lib/debug/boot/vmlinux-%1$s.debug",
|
||||
"/usr/lib/debug/lib/modules/%1$s/vmlinux",
|
||||
};
|
||||
|
||||
// Try canonical `vmlinux` BTF through `sysfs` first.
|
||||
if(check_location(locations[0]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fall back to trying to find `vmlinux` on disk otherwise
|
||||
struct utsname buf = {};
|
||||
if(uname(&buf) == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char path[PATH_MAX + 1];
|
||||
|
||||
// Skip vmlinux since we already tested it.
|
||||
for (int i = 1; i < sizeof(locations) / sizeof(*locations); i++)
|
||||
{
|
||||
snprintf(path, PATH_MAX, locations[i], buf.release);
|
||||
if(check_location(path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Probe the kernel for required dependencies, ring buffer maps and tracing
|
||||
* progs needs to be supported.
|
||||
*/
|
||||
bool pman_check_support()
|
||||
{
|
||||
bool res;
|
||||
|
||||
res = libbpf_probe_bpf_map_type(BPF_MAP_TYPE_RINGBUF, NULL) > 0;
|
||||
if (!res)
|
||||
bool res = libbpf_probe_bpf_map_type(BPF_MAP_TYPE_RINGBUF, NULL) > 0;
|
||||
if(!res)
|
||||
{
|
||||
pman_print_error("ring buffer map type is not supported");
|
||||
return res;
|
||||
|
@ -182,8 +309,18 @@ bool pman_check_support()
|
|||
res = libbpf_probe_bpf_prog_type(BPF_PROG_TYPE_TRACING, NULL) > 0;
|
||||
if (!res)
|
||||
{
|
||||
pman_print_error("tracing program type is not supported");
|
||||
return res;
|
||||
// The above function checks for the `BPF_TRACE_FENTRY` attach type presence, while we need
|
||||
// to check for the `BPF_TRACE_RAW_TP` one. If `BPF_TRACE_FENTRY` is defined we are
|
||||
// sure `BPF_TRACE_RAW_TP` is defined as well, in all other cases, we need to search
|
||||
// for it in the `vmlinux` file.
|
||||
res = probe_BPF_TRACE_RAW_TP_type();
|
||||
if(!res)
|
||||
{
|
||||
// Clear the errno for `pman_print_error`
|
||||
errno = 0;
|
||||
pman_print_error("prog 'BPF_TRACE_RAW_TP' is not supported");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/* Probe result depends on the success of map creation, no additional
|
||||
|
|
|
@ -201,6 +201,16 @@ int pman_finalize_ringbuf_array_after_loading()
|
|||
continue;
|
||||
}
|
||||
|
||||
if(ringbuf_id >= g_state.n_required_buffers)
|
||||
{
|
||||
/* If we arrive here it means that we have too many CPUs for our allocated ring buffers
|
||||
* so probably we faced a CPU hotplug.
|
||||
*/
|
||||
snprintf(error_message, MAX_ERROR_MESSAGE_LEN, "the actual system configuration requires more than '%d' ring buffers", g_state.n_required_buffers);
|
||||
pman_print_error((const char *)error_message);
|
||||
goto clean_percpu_ring_buffers;
|
||||
}
|
||||
|
||||
if(bpf_map_update_elem(ringubuf_array_fd, &i, &ringbufs_fds[ringbuf_id], BPF_ANY))
|
||||
{
|
||||
snprintf(error_message, MAX_ERROR_MESSAGE_LEN, "failed to add the ringbuf map for CPU '%d' to ringbuf '%d'", i, ringbuf_id);
|
||||
|
|
|
@ -73,16 +73,6 @@ add_library(scap
|
|||
scap_userlist.c
|
||||
scap_suppress.c)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
target_sources(scap PRIVATE linux/scap_machine_info.c)
|
||||
elseif(WIN32)
|
||||
target_sources(scap PRIVATE win32/scap_machine_info.c)
|
||||
elseif(APPLE)
|
||||
target_sources(scap PRIVATE macos/scap_machine_info.c)
|
||||
elseif(EMSCRIPTEN)
|
||||
target_sources(scap PRIVATE emscripten/scap_machine_info.c)
|
||||
endif()
|
||||
|
||||
set_scap_target_properties(scap)
|
||||
|
||||
add_library(scap_platform_util
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2023 The Falco Authors.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#include "scap_machine_info.h"
|
||||
#include "scap_os_machine_info.h"
|
||||
#include "scap_limits.h"
|
||||
#include "scap_assert.h"
|
||||
#include "scap.h"
|
||||
|
||||
#include "gettimeofday.h"
|
||||
#include <sys/utsname.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// note: in a webassembly module we have no notion of process or host from which
|
||||
// retrieving the boot time. As such, we just take a timestamp at which the
|
||||
// module is inited throgh a function noted as __attribute__((constructor)), which
|
||||
// should be supported by clang (emscripten's backend). We make no distiction
|
||||
// between the agent's boot time and the host boot time here.
|
||||
static uint64_t s_emscripten_boot_time_ns = 0;
|
||||
|
||||
static void retrieve_boot_time_ns() __attribute__((constructor));
|
||||
|
||||
static void retrieve_boot_time_ns()
|
||||
{
|
||||
s_emscripten_boot_time_ns = get_timestamp_ns();
|
||||
}
|
||||
|
||||
void scap_os_get_agent_info(scap_agent_info* agent_info)
|
||||
{
|
||||
agent_info->start_ts_epoch = 0;
|
||||
agent_info->start_time = 0;
|
||||
|
||||
/* Info 1:
|
||||
*
|
||||
* unix time in nsec of our startup time
|
||||
*/
|
||||
{
|
||||
// todo: this needs to be the process startup time
|
||||
agent_info->start_ts_epoch = s_emscripten_boot_time_ns;
|
||||
}
|
||||
|
||||
/* Info 2:
|
||||
*
|
||||
* our startup time in seconds since boot
|
||||
*/
|
||||
if(agent_info->start_ts_epoch != 0)
|
||||
{
|
||||
uint64_t boot_time_ns = s_emscripten_boot_time_ns;
|
||||
agent_info->start_time = (agent_info->start_ts_epoch - boot_time_ns) / (1.0 * SECOND_TO_NS);
|
||||
}
|
||||
|
||||
/* Info 3:
|
||||
*
|
||||
* Kernel release `uname -r` of the machine the agent is running on.
|
||||
*/
|
||||
|
||||
struct utsname uts;
|
||||
uname(&uts);
|
||||
snprintf(agent_info->uname_r, sizeof(agent_info->uname_r), "%s", uts.release);
|
||||
}
|
||||
|
||||
static void scap_gethostname(char* buf, size_t size)
|
||||
{
|
||||
char *env_hostname = getenv(SCAP_HOSTNAME_ENV_VAR);
|
||||
if(env_hostname != NULL)
|
||||
{
|
||||
snprintf(buf, size, "%s", env_hostname);
|
||||
}
|
||||
else
|
||||
{
|
||||
gethostname(buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t scap_os_get_machine_info(scap_machine_info* machine_info, char* lasterr)
|
||||
{
|
||||
machine_info->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
machine_info->memory_size_bytes = (uint64_t)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
|
||||
scap_gethostname(machine_info->hostname, sizeof(machine_info->hostname));
|
||||
machine_info->boot_ts_epoch = s_emscripten_boot_time_ns;
|
||||
if(machine_info->boot_ts_epoch == 0)
|
||||
{
|
||||
return SCAP_FAILURE;
|
||||
}
|
||||
|
||||
return SCAP_SUCCESS;
|
||||
}
|
|
@ -1465,8 +1465,6 @@ int32_t scap_bpf_load(
|
|||
const char *bpf_probe,
|
||||
scap_open_args *oargs)
|
||||
{
|
||||
int online_cpu;
|
||||
int j;
|
||||
struct scap_bpf_engine_params* bpf_args = oargs->engine_params;
|
||||
|
||||
if(set_runtime_params(handle) != SCAP_SUCCESS)
|
||||
|
@ -1521,26 +1519,28 @@ int32_t scap_bpf_load(
|
|||
//
|
||||
// Open and initialize all the devices
|
||||
//
|
||||
online_cpu = 0;
|
||||
for(j = 0; j < handle->m_ncpus; ++j)
|
||||
struct scap_device_set *devset = &handle->m_dev_set;
|
||||
uint32_t online_idx = 0;
|
||||
// devset->m_ndevs = online CPUs in the system.
|
||||
// handle->m_ncpus = available CPUs in the system.
|
||||
for(uint32_t cpu_idx = 0; online_idx < devset->m_ndevs && cpu_idx < handle->m_ncpus; ++cpu_idx)
|
||||
{
|
||||
struct perf_event_attr attr = {
|
||||
.sample_type = PERF_SAMPLE_RAW,
|
||||
.type = PERF_TYPE_SOFTWARE,
|
||||
.config = PERF_COUNT_SW_BPF_OUTPUT,
|
||||
};
|
||||
int pmu_fd;
|
||||
int ret;
|
||||
struct scap_device *dev;
|
||||
int pmu_fd = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* We suppose that CPU 0 is always online, so we only check for j > 0 */
|
||||
if(j > 0)
|
||||
/* We suppose that CPU 0 is always online, so we only check for cpu_idx > 0 */
|
||||
if(cpu_idx > 0)
|
||||
{
|
||||
char filename[SCAP_MAX_PATH_SIZE];
|
||||
int online;
|
||||
FILE *fp;
|
||||
int online = 0;
|
||||
|
||||
snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%d/online", j);
|
||||
snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%d/online", cpu_idx);
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if(fp == NULL)
|
||||
|
@ -1549,15 +1549,15 @@ int32_t scap_bpf_load(
|
|||
// Fallback at considering them online if we can at least reach their folder.
|
||||
// This is useful for example for raspPi devices.
|
||||
// See: https://github.com/kubernetes/kubernetes/issues/95039
|
||||
snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%d/", j);
|
||||
snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%d/", cpu_idx);
|
||||
if (access(filename, F_OK) == 0)
|
||||
{
|
||||
online = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, errno, "can't open %sonline", filename);
|
||||
}
|
||||
// If we can't access the cpu, count it as offline.
|
||||
// Some VMs or hyperthreading systems export an high number of configured CPUs,
|
||||
// even if they are not existing. See https://github.com/falcosecurity/falco/issues/2843 for example.
|
||||
// Skip them.
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1577,29 +1577,23 @@ int32_t scap_bpf_load(
|
|||
}
|
||||
}
|
||||
|
||||
if(online_cpu >= handle->m_dev_set.m_ndevs)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, 0, "too many online processors: %d, expected: %d", online_cpu, handle->m_dev_set.m_ndevs);
|
||||
}
|
||||
|
||||
dev = &handle->m_dev_set.m_devs[online_cpu];
|
||||
|
||||
pmu_fd = sys_perf_event_open(&attr, -1, j, -1, 0);
|
||||
pmu_fd = sys_perf_event_open(&attr, -1, cpu_idx, -1, 0);
|
||||
if(pmu_fd < 0)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, -pmu_fd, "unable to open the perf-buffer for cpu '%d'", j);
|
||||
return scap_errprintf(handle->m_lasterr, -pmu_fd, "unable to open the perf-buffer for cpu '%d'", cpu_idx);
|
||||
}
|
||||
|
||||
struct scap_device *dev = &devset->m_devs[online_idx];
|
||||
dev->m_fd = pmu_fd;
|
||||
|
||||
if((ret = bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_PERF_MAP], &j, &pmu_fd, BPF_ANY)) != 0)
|
||||
if((ret = bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_PERF_MAP], &cpu_idx, &pmu_fd, BPF_ANY)) != 0)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, -ret, "unable to update the SCAP_PERF_MAP map for cpu '%d'", j);
|
||||
return scap_errprintf(handle->m_lasterr, -ret, "unable to update the SCAP_PERF_MAP map for cpu '%d'", cpu_idx);
|
||||
}
|
||||
|
||||
if(ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0))
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, errno, "unable to call PERF_EVENT_IOC_ENABLE on the fd for cpu '%d'", j);
|
||||
return scap_errprintf(handle->m_lasterr, errno, "unable to call PERF_EVENT_IOC_ENABLE on the fd for cpu '%d'", cpu_idx);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1609,16 +1603,28 @@ int32_t scap_bpf_load(
|
|||
dev->m_buffer_size = bpf_args->buffer_bytes_dim;
|
||||
if(dev->m_buffer == MAP_FAILED)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, errno, "unable to mmap the perf-buffer for cpu '%d'", j);
|
||||
return scap_errprintf(handle->m_lasterr, errno, "unable to mmap the perf-buffer for cpu '%d'", cpu_idx);
|
||||
}
|
||||
|
||||
++online_cpu;
|
||||
online_idx++;
|
||||
}
|
||||
|
||||
if(online_cpu != handle->m_dev_set.m_ndevs)
|
||||
// Check that we parsed all online CPUs
|
||||
if(online_idx != devset->m_ndevs)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, 0, "processors online: %d, expected: %d", online_cpu, handle->m_dev_set.m_ndevs);
|
||||
return scap_errprintf(handle->m_lasterr, 0, "mismatch, processors online after the 'for' loop: %d, '_SC_NPROCESSORS_ONLN' before the 'for' loop: %d", online_idx, devset->m_ndevs);
|
||||
}
|
||||
|
||||
// Check that no CPUs were hotplugged during the for loop
|
||||
uint32_t final_ndevs = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if(final_ndevs == -1)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, errno, "cannot obtain the number of online CPUs from '_SC_NPROCESSORS_ONLN' to check against the previous value");
|
||||
}
|
||||
if (online_idx != final_ndevs)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, 0, "mismatch, processors online after the 'for' loop: %d, '_SC_NPROCESSORS_ONLN' after the 'for' loop: %d", online_idx, final_ndevs);
|
||||
}
|
||||
|
||||
|
||||
if(set_default_settings(handle) != SCAP_SUCCESS)
|
||||
{
|
||||
|
@ -1945,7 +1951,7 @@ static int32_t init(scap_t* handle, scap_open_args *oargs)
|
|||
ssize_t num_cpus = sysconf(_SC_NPROCESSORS_CONF);
|
||||
if(num_cpus == -1)
|
||||
{
|
||||
return scap_errprintf(engine.m_handle->m_lasterr, errno, "_SC_NPROCESSORS_CONF");
|
||||
return scap_errprintf(engine.m_handle->m_lasterr, errno, "cannot obtain the number of available CPUs from '_SC_NPROCESSORS_CONF'");
|
||||
}
|
||||
|
||||
engine.m_handle->m_ncpus = num_cpus;
|
||||
|
@ -1953,7 +1959,7 @@ static int32_t init(scap_t* handle, scap_open_args *oargs)
|
|||
ssize_t num_devs = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if(num_devs == -1)
|
||||
{
|
||||
return scap_errprintf(engine.m_handle->m_lasterr, errno, "_SC_NPROCESSORS_ONLN");
|
||||
return scap_errprintf(engine.m_handle->m_lasterr, errno, "cannot obtain the number of online CPUs from '_SC_NPROCESSORS_ONLN'");
|
||||
}
|
||||
|
||||
rc = devset_init(&engine.m_handle->m_dev_set, num_devs, engine.m_handle->m_lasterr);
|
||||
|
|
|
@ -336,7 +336,7 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs)
|
|||
ncpus = sysconf(_SC_NPROCESSORS_CONF);
|
||||
if(ncpus == -1)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, errno, "_SC_NPROCESSORS_CONF");
|
||||
return scap_errprintf(handle->m_lasterr, errno, "cannot obtain the number of available CPUs from '_SC_NPROCESSORS_CONF'");
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -345,7 +345,7 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs)
|
|||
ndevs = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if(ndevs == -1)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, errno, "_SC_NPROCESSORS_ONLN");
|
||||
return scap_errprintf(handle->m_lasterr, errno, "cannot obtain the number of online CPUs from '_SC_NPROCESSORS_ONLN'");
|
||||
}
|
||||
|
||||
rc = devset_init(&engine.m_handle->m_dev_set, ndevs, handle->m_lasterr);
|
||||
|
@ -360,14 +360,17 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs)
|
|||
mapped_len = single_buffer_dim * 2;
|
||||
|
||||
struct scap_device_set *devset = &engine.m_handle->m_dev_set;
|
||||
for(uint32_t j = 0, all_scanned_devs = 0; j < devset->m_ndevs && all_scanned_devs < ncpus; ++all_scanned_devs)
|
||||
uint32_t online_idx = 0;
|
||||
// devset->m_ndevs = online CPUs in the system.
|
||||
// ncpus = available CPUs in the system.
|
||||
for(uint32_t cpu_idx = 0; online_idx < devset->m_ndevs && cpu_idx < ncpus; ++cpu_idx)
|
||||
{
|
||||
struct scap_device *dev = &devset->m_devs[j];
|
||||
struct scap_device *dev = &devset->m_devs[online_idx];
|
||||
|
||||
//
|
||||
// Open the device
|
||||
//
|
||||
snprintf(filename, sizeof(filename), "%s/dev/" DRIVER_DEVICE_NAME "%d", scap_get_host_root(), all_scanned_devs);
|
||||
snprintf(filename, sizeof(filename), "%s/dev/" DRIVER_DEVICE_NAME "%d", scap_get_host_root(), cpu_idx);
|
||||
|
||||
if((dev->m_fd = open(filename, O_RDWR | O_SYNC)) < 0)
|
||||
{
|
||||
|
@ -489,7 +492,24 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs)
|
|||
}
|
||||
dev->m_bufinfo_size = sizeof(struct ppm_ring_buffer_info);
|
||||
|
||||
++j;
|
||||
++online_idx;
|
||||
}
|
||||
|
||||
// Check that we parsed all online CPUs
|
||||
if(online_idx != devset->m_ndevs)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, 0, "mismatch, processors online after the 'for' loop: %d, '_SC_NPROCESSORS_ONLN' before the 'for' loop: %d", online_idx, devset->m_ndevs);
|
||||
}
|
||||
|
||||
// Check that no CPUs were hotplugged during the for loop
|
||||
uint32_t final_ndevs = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if(final_ndevs == -1)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, errno, "cannot obtain the number of online CPUs from '_SC_NPROCESSORS_ONLN' to check against the previous value");
|
||||
}
|
||||
if (online_idx != final_ndevs)
|
||||
{
|
||||
return scap_errprintf(handle->m_lasterr, 0, "mismatch, processors online after the 'for' loop: %d, '_SC_NPROCESSORS_ONLN' after the 'for' loop: %d", online_idx, final_ndevs);
|
||||
}
|
||||
|
||||
/* Here we are covering the case in which some syscalls don't have an associated ppm_sc
|
||||
|
|
|
@ -1580,14 +1580,18 @@ static uint32_t scap_fd_read_from_disk(scap_fdinfo *fdi, size_t *nbytes, uint32_
|
|||
case SCAP_FD_BPF:
|
||||
case SCAP_FD_USERFAULTFD:
|
||||
case SCAP_FD_IOURING:
|
||||
case SCAP_FD_MEMFD:
|
||||
case SCAP_FD_PIDFD:
|
||||
res = scap_fd_read_fname_from_disk(fdi->info.fname, nbytes, r, error);
|
||||
break;
|
||||
case SCAP_FD_UNKNOWN:
|
||||
ASSERT(false);
|
||||
break;
|
||||
default:
|
||||
snprintf(error, SCAP_LASTERR_SIZE, "error reading the fd info from file, wrong fd type %u", (uint32_t)fdi->type);
|
||||
return SCAP_FAILURE;
|
||||
// unknown fd type, possibly coming from a newer library version
|
||||
fdi->type = SCAP_FD_UNSUPPORTED;
|
||||
snprintf(fdi->info.fname, sizeof(fdi->info.fname), "unknown-type:[%d]", (int)type);
|
||||
break;
|
||||
}
|
||||
|
||||
if(sub_len && *nbytes != sub_len)
|
||||
|
|
|
@ -145,8 +145,12 @@ static int close_engine(struct scap_engine_handle engine)
|
|||
{
|
||||
struct source_plugin_engine *handle = engine.m_handle;
|
||||
|
||||
handle->m_input_plugin->close(handle->m_input_plugin->state, handle->m_input_plugin->handle);
|
||||
handle->m_input_plugin->handle = NULL;
|
||||
// We could arrive here without having initialized 'm_input_plugin'.
|
||||
if(handle->m_input_plugin != NULL)
|
||||
{
|
||||
handle->m_input_plugin->close(handle->m_input_plugin->state, handle->m_input_plugin->handle);
|
||||
handle->m_input_plugin->handle = NULL;
|
||||
}
|
||||
return SCAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
add_library(scap_platform STATIC scap_linux_platform.c scap_procs.c scap_fds.c scap_userlist.c scap_iflist.c scap_cgroup.c)
|
||||
add_library(scap_platform STATIC scap_linux_platform.c scap_procs.c scap_fds.c scap_userlist.c scap_iflist.c scap_cgroup.c scap_machine_info.c)
|
||||
target_link_libraries(scap_platform scap_error scap_platform_util)
|
|
@ -259,11 +259,20 @@ static const char* scan_back(const char* start, const char* end)
|
|||
// slash so that we don't end up with doubled slashes (one from the prefix, one from the path)
|
||||
static int32_t scap_cgroup_prefix_path(const char* prefix, const char* path, size_t* prefix_len, size_t* path_strip_len)
|
||||
{
|
||||
ASSERT(prefix != NULL);
|
||||
ASSERT(path != NULL);
|
||||
|
||||
const char* prefix_p = prefix + strlen(prefix);
|
||||
const char* path_p = path;
|
||||
|
||||
while(strncmp(path_p, "/..", 3) == 0)
|
||||
{
|
||||
// If there's a trailing slash, remove it before scanning.
|
||||
if (*prefix_p == '/' && prefix_p != prefix)
|
||||
{
|
||||
prefix_p--;
|
||||
}
|
||||
|
||||
path_p += 3;
|
||||
prefix_p = scan_back(prefix, prefix_p);
|
||||
if(prefix_p == NULL)
|
||||
|
@ -527,7 +536,7 @@ static int32_t get_cgroup_subsystems_v2(struct scap_cgroup_interface* cgi, struc
|
|||
|
||||
if(cgi->m_use_cache)
|
||||
{
|
||||
struct scap_cgroup_cache* cached = malloc(sizeof(*cached));
|
||||
struct scap_cgroup_cache* cached = (struct scap_cgroup_cache*)malloc(sizeof(*cached));
|
||||
if(cached)
|
||||
{
|
||||
int uth_status = SCAP_SUCCESS;
|
||||
|
|
|
@ -323,6 +323,10 @@ int32_t scap_fd_handle_regular_file(struct scap_proclist *proclist, char *fname,
|
|||
{
|
||||
fdi->type = SCAP_FD_BPF;
|
||||
}
|
||||
else if (0 == strcmp(link_name, "anon_inode:[pidfd]"))
|
||||
{
|
||||
fdi->type = SCAP_FD_PIDFD;
|
||||
}
|
||||
|
||||
if(SCAP_FD_UNSUPPORTED == fdi->type)
|
||||
{
|
||||
|
@ -333,8 +337,16 @@ int32_t scap_fd_handle_regular_file(struct scap_proclist *proclist, char *fname,
|
|||
}
|
||||
else if(fdi->type == SCAP_FD_FILE_V2)
|
||||
{
|
||||
scap_fd_flags_file(fdi, procdir);
|
||||
strlcpy(fdi->info.regularinfo.fname, link_name, sizeof(fdi->info.regularinfo.fname));
|
||||
if (0 == strncmp(link_name, "/memfd:", strlen("/memfd:")))
|
||||
{
|
||||
fdi->type = SCAP_FD_MEMFD;
|
||||
strlcpy(fdi->info.fname, link_name, sizeof(fdi->info.fname));
|
||||
}
|
||||
else
|
||||
{
|
||||
scap_fd_flags_file(fdi, procdir);
|
||||
strlcpy(fdi->info.regularinfo.fname, link_name, sizeof(fdi->info.regularinfo.fname));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -37,6 +37,11 @@ struct scap_linux_platform;
|
|||
struct scap_proclist;
|
||||
typedef struct scap_threadinfo scap_threadinfo;
|
||||
|
||||
typedef struct _scap_agent_info scap_agent_info;
|
||||
typedef struct _scap_machine_info scap_machine_info;
|
||||
|
||||
void scap_os_get_agent_info(scap_agent_info* agent_info);
|
||||
int32_t scap_os_get_machine_info(scap_machine_info* machine_info, char* lasterr);
|
||||
int32_t scap_linux_create_iflist(struct scap_platform* platform);
|
||||
int32_t scap_linux_create_userlist(struct scap_platform* platform);
|
||||
|
||||
|
|
|
@ -62,6 +62,13 @@ int32_t scap_linux_init_platform(struct scap_platform* platform, char* lasterr,
|
|||
linux_platform->m_proc_scan_log_interval_ms = oargs->proc_scan_log_interval_ms;
|
||||
linux_platform->m_debug_log_fn = oargs->debug_log_fn;
|
||||
|
||||
if(scap_os_get_machine_info(&platform->m_machine_info, lasterr) != SCAP_SUCCESS)
|
||||
{
|
||||
return SCAP_FAILURE;
|
||||
}
|
||||
|
||||
scap_os_get_agent_info(&platform->m_agent_info);
|
||||
|
||||
rc = scap_linux_create_iflist(platform);
|
||||
if(rc != SCAP_SUCCESS)
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
#include "scap_machine_info.h"
|
||||
#include "scap_os_machine_info.h"
|
||||
#include "scap_linux_int.h"
|
||||
#include "scap_limits.h"
|
||||
#include "scap_assert.h"
|
||||
#include "scap.h"
|
||||
|
@ -106,7 +106,6 @@ static uint64_t scap_linux_get_host_boot_time_ns(char* last_err)
|
|||
FILE* f = fopen(proc_stat, "r");
|
||||
if (f == NULL)
|
||||
{
|
||||
ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -119,7 +118,6 @@ static uint64_t scap_linux_get_host_boot_time_ns(char* last_err)
|
|||
}
|
||||
}
|
||||
fclose(f);
|
||||
ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -156,6 +154,28 @@ static void scap_gethostname(char* buf, size_t size)
|
|||
|
||||
int32_t scap_os_get_machine_info(scap_machine_info* machine_info, char* lasterr)
|
||||
{
|
||||
// Check that we can read under '/proc'.
|
||||
// A wrong usage of the env variable 'HOST_ROOT' can be detected here.
|
||||
char filename[SCAP_MAX_PATH_SIZE] = {0};
|
||||
if(snprintf(filename, sizeof(filename), "%s/proc/", scap_get_host_root()) < 0)
|
||||
{
|
||||
if(lasterr != NULL)
|
||||
{
|
||||
snprintf(lasterr, SCAP_LASTERR_SIZE, "unable to build the `/proc` path with 'snprintf'\n");
|
||||
}
|
||||
return SCAP_FAILURE;
|
||||
}
|
||||
|
||||
struct stat targetstat = {0};
|
||||
if(stat(filename, &targetstat) != 0)
|
||||
{
|
||||
if(lasterr != NULL)
|
||||
{
|
||||
snprintf(lasterr, SCAP_LASTERR_SIZE, "the directory '%s' doesn't exist on the system. Check the usage of the 'HOST_ROOT' env variable.", filename);
|
||||
}
|
||||
return SCAP_FAILURE;
|
||||
}
|
||||
|
||||
machine_info->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
machine_info->memory_size_bytes = (uint64_t)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
|
||||
scap_gethostname(machine_info->hostname, sizeof(machine_info->hostname));
|
||||
|
@ -168,4 +188,3 @@ int32_t scap_os_get_machine_info(scap_machine_info* machine_info, char* lasterr)
|
|||
|
||||
return SCAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2023 The Falco Authors.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#include "scap_machine_info.h"
|
||||
#include "scap_os_machine_info.h"
|
||||
#include "scap_limits.h"
|
||||
#include "scap_assert.h"
|
||||
#include "scap.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define US_TO_NS 1000ULL
|
||||
|
||||
// https://stackoverflow.com/questions/3269321/osx-programmatically-get-uptime
|
||||
static uint64_t scap_macos_get_host_boot_time_ns()
|
||||
{
|
||||
struct timeval boottime;
|
||||
size_t len = sizeof(boottime);
|
||||
int mib[2] = { CTL_KERN, KERN_BOOTTIME };
|
||||
if(sysctl(mib, 2, &boottime, &len, NULL, 0) < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (boottime.tv_sec * SECOND_TO_NS) +
|
||||
(boottime.tv_usec * US_TO_NS);
|
||||
}
|
||||
|
||||
void scap_os_get_agent_info(scap_agent_info* agent_info)
|
||||
{
|
||||
agent_info->start_ts_epoch = 0;
|
||||
agent_info->start_time = 0;
|
||||
|
||||
/* Info 1:
|
||||
*
|
||||
* unix time in nsec of our startup time
|
||||
*/
|
||||
{
|
||||
// https://stackoverflow.com/questions/31603885/get-process-creation-date-time-in-osx-with-c-c/31605649
|
||||
struct kinfo_proc info;
|
||||
int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)getpid() };
|
||||
size_t len = sizeof info;
|
||||
memset(&info, 0, len);
|
||||
int rc = sysctl(mib, 4, &info, &len, NULL, 0);
|
||||
if(rc == 0)
|
||||
{
|
||||
struct timeval tv = info.kp_proc.p_starttime;
|
||||
if(tv.tv_sec != 0)
|
||||
{
|
||||
agent_info->start_ts_epoch = (tv.tv_sec * SECOND_TO_NS) +
|
||||
(tv.tv_usec * US_TO_NS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Info 2:
|
||||
*
|
||||
* our startup time in seconds since boot
|
||||
*/
|
||||
if(agent_info->start_ts_epoch != 0)
|
||||
{
|
||||
uint64_t boot_time_ns = scap_macos_get_host_boot_time_ns();
|
||||
agent_info->start_time = (agent_info->start_ts_epoch - boot_time_ns) / (1.0 * SECOND_TO_NS);
|
||||
}
|
||||
|
||||
/* Info 3:
|
||||
*
|
||||
* Kernel release `uname -r` of the machine the agent is running on.
|
||||
*/
|
||||
|
||||
struct utsname uts;
|
||||
uname(&uts);
|
||||
snprintf(agent_info->uname_r, sizeof(agent_info->uname_r), "%s", uts.release);
|
||||
}
|
||||
|
||||
static void scap_gethostname(char* buf, size_t size)
|
||||
{
|
||||
char *env_hostname = getenv(SCAP_HOSTNAME_ENV_VAR);
|
||||
if(env_hostname != NULL)
|
||||
{
|
||||
snprintf(buf, size, "%s", env_hostname);
|
||||
}
|
||||
else
|
||||
{
|
||||
gethostname(buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t scap_os_get_machine_info(scap_machine_info* machine_info, char* lasterr)
|
||||
{
|
||||
machine_info->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
machine_info->memory_size_bytes = (uint64_t)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
|
||||
scap_gethostname(machine_info->hostname, sizeof(machine_info->hostname));
|
||||
machine_info->boot_ts_epoch = scap_macos_get_host_boot_time_ns();
|
||||
if(machine_info->boot_ts_epoch == 0)
|
||||
{
|
||||
return SCAP_FAILURE;
|
||||
}
|
||||
|
||||
return SCAP_SUCCESS;
|
||||
}
|
||||
|
|
@ -175,10 +175,13 @@ int32_t scap_init(scap_t* handle, scap_open_args* oargs)
|
|||
platform = scap_linux_alloc_platform();
|
||||
struct scap_nodriver_engine_params* engine_params = oargs->engine_params;
|
||||
|
||||
if(platform && (!engine_params || !engine_params->full_proc_scan))
|
||||
if(platform)
|
||||
{
|
||||
((struct scap_linux_platform*)platform)->m_fd_lookup_limit = SCAP_NODRIVER_MAX_FD_LOOKUP;
|
||||
((struct scap_linux_platform*)platform)->m_minimal_scan = true;
|
||||
if(!engine_params || !engine_params->full_proc_scan)
|
||||
{
|
||||
((struct scap_linux_platform*)platform)->m_fd_lookup_limit = SCAP_NODRIVER_MAX_FD_LOOKUP;
|
||||
((struct scap_linux_platform*)platform)->m_minimal_scan = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2023 The Falco Authors.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _scap_agent_info scap_agent_info;
|
||||
typedef struct _scap_machine_info scap_machine_info;
|
||||
|
||||
void scap_os_get_agent_info(scap_agent_info* agent_info);
|
||||
int32_t scap_os_get_machine_info(scap_machine_info* machine_info, char* lasterr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -21,18 +21,11 @@ limitations under the License.
|
|||
|
||||
#include "scap.h"
|
||||
#include "scap-int.h"
|
||||
#include "scap_os_machine_info.h"
|
||||
|
||||
int32_t scap_generic_init_platform(struct scap_platform* platform, char* lasterr, struct scap_open_args* oargs)
|
||||
{
|
||||
memset(&platform->m_machine_info, 0, sizeof(platform->m_machine_info));
|
||||
if(scap_os_get_machine_info(&platform->m_machine_info, lasterr) != SCAP_SUCCESS)
|
||||
{
|
||||
return SCAP_FAILURE;
|
||||
}
|
||||
|
||||
scap_os_get_agent_info(&platform->m_agent_info);
|
||||
|
||||
memset(&platform->m_agent_info, 0, sizeof(platform->m_agent_info));
|
||||
platform->m_proclist.m_proc_callback = oargs->proc_callback;
|
||||
platform->m_proclist.m_proc_callback_context = oargs->proc_callback_context;
|
||||
platform->m_proclist.m_proclist = NULL;
|
||||
|
|
|
@ -198,6 +198,8 @@ static uint32_t scap_fd_info_len(scap_fdinfo *fdi)
|
|||
case SCAP_FD_BPF:
|
||||
case SCAP_FD_USERFAULTFD:
|
||||
case SCAP_FD_IOURING:
|
||||
case SCAP_FD_MEMFD:
|
||||
case SCAP_FD_PIDFD:
|
||||
res += (uint32_t)strnlen(fdi->info.fname, SCAP_MAX_PATH_SIZE) + 2; // 2 is the length field before the string
|
||||
break;
|
||||
default:
|
||||
|
@ -312,6 +314,8 @@ static int32_t scap_fd_write_to_disk(scap_dumper_t *d, scap_fdinfo *fdi, uint32_
|
|||
case SCAP_FD_BPF:
|
||||
case SCAP_FD_USERFAULTFD:
|
||||
case SCAP_FD_IOURING:
|
||||
case SCAP_FD_MEMFD:
|
||||
case SCAP_FD_PIDFD:
|
||||
stlen = (uint16_t)strnlen(fdi->info.fname, SCAP_MAX_PATH_SIZE);
|
||||
if(scap_dump_write(d, &stlen, sizeof(uint16_t)) != sizeof(uint16_t) ||
|
||||
(stlen > 0 && scap_dump_write(d, fdi->info.fname, stlen) != stlen))
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2023 The Falco Authors.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _UNICODE
|
||||
#define _UNICODE
|
||||
#endif
|
||||
|
||||
#include "scap_machine_info.h"
|
||||
#include "scap_os_machine_info.h"
|
||||
#include "scap_limits.h"
|
||||
#include "scap_assert.h"
|
||||
#include "scap.h"
|
||||
#include "gettimeofday.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#define MSEC_TO_NS 1000000
|
||||
|
||||
typedef LONG (WINAPI * RtlGetVersionProc) (OSVERSIONINFOEX *);
|
||||
#ifndef STATUS_SUCCESS
|
||||
#define STATUS_SUCCESS 0
|
||||
#endif
|
||||
|
||||
// https://stackoverflow.com/questions/10853985/programmatically-getting-system-boot-up-time-in-c-windows
|
||||
static uint64_t scap_windows_get_host_boot_time_ns()
|
||||
{
|
||||
return GetTickCount64() * MSEC_TO_NS;
|
||||
}
|
||||
|
||||
void scap_os_get_agent_info(scap_agent_info* agent_info)
|
||||
{
|
||||
agent_info->start_ts_epoch = 0;
|
||||
agent_info->start_time = 0;
|
||||
|
||||
/* Info 1:
|
||||
*
|
||||
* unix time in nsec of our startup time
|
||||
*/
|
||||
{
|
||||
FILETIME creation_time, exit_time, kernel_time, user_time;
|
||||
if(GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time, &kernel_time, &user_time))
|
||||
{
|
||||
agent_info->start_ts_epoch = ft_to_epoch_nsec(&creation_time);
|
||||
}
|
||||
}
|
||||
|
||||
/* Info 2:
|
||||
*
|
||||
* our startup time in seconds since boot
|
||||
*/
|
||||
if(agent_info->start_ts_epoch != 0)
|
||||
{
|
||||
uint64_t boot_time_ns = scap_windows_get_host_boot_time_ns();
|
||||
agent_info->start_time = (agent_info->start_ts_epoch - boot_time_ns) / (1.0 * SECOND_TO_NS);
|
||||
}
|
||||
|
||||
/* Info 3:
|
||||
*
|
||||
* Kernel release `uname -r` of the machine the agent is running on.
|
||||
*/
|
||||
{
|
||||
OSVERSIONINFOEX win_version_info = {0};
|
||||
RtlGetVersionProc RtlGetVersionP = 0;
|
||||
LONG version_status = -1; // Any nonzero value should work.
|
||||
|
||||
/*
|
||||
* We want the major and minor Windows version along with other
|
||||
* information. GetVersionEx provides this, but is deprecated.
|
||||
* We use RtlGetVersion instead, which requires a bit of extra
|
||||
* effort.
|
||||
*/
|
||||
|
||||
HMODULE ntdll_module = LoadLibrary(_T("ntdll.dll"));
|
||||
if(ntdll_module)
|
||||
{
|
||||
RtlGetVersionP = (RtlGetVersionProc) GetProcAddress(ntdll_module, "RtlGetVersion");
|
||||
win_version_info.dwOSVersionInfoSize = sizeof(win_version_info);
|
||||
version_status = RtlGetVersionP(&win_version_info);
|
||||
FreeLibrary(ntdll_module);
|
||||
}
|
||||
|
||||
if (version_status != STATUS_SUCCESS)
|
||||
{
|
||||
snprintf(agent_info->uname_r, sizeof(agent_info->uname_r), "Windows (unknown version)");
|
||||
}
|
||||
else
|
||||
{
|
||||
// more space than the absolute worst case of UTF16->UTF8 conversion
|
||||
char utf8_servicepack[sizeof(win_version_info.szCSDVersion) * 2] = {0};
|
||||
|
||||
// ... but if it still gets truncated, be sad for a while and move on
|
||||
// (our output buffer is finite, anyway)
|
||||
WideCharToMultiByte(CP_UTF8, 0, win_version_info.szCSDVersion, -1, utf8_servicepack, sizeof(utf8_servicepack), NULL, NULL);
|
||||
|
||||
snprintf(agent_info->uname_r, sizeof(agent_info->uname_r), "Windows %lu.%lu%s%s, build %lu",
|
||||
win_version_info.dwMajorVersion, win_version_info.dwMinorVersion,
|
||||
utf8_servicepack[0] != '\0' ? " " : "",
|
||||
utf8_servicepack,
|
||||
win_version_info.dwBuildNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void scap_gethostname(char* buf, size_t size)
|
||||
{
|
||||
char *env_hostname = getenv(SCAP_HOSTNAME_ENV_VAR);
|
||||
if(env_hostname != NULL)
|
||||
{
|
||||
snprintf(buf, size, "%s", env_hostname);
|
||||
}
|
||||
else
|
||||
{
|
||||
gethostname(buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t scap_os_get_machine_info(scap_machine_info* machine_info, char* lasterr)
|
||||
{
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
machine_info->num_cpus = si.dwNumberOfProcessors;
|
||||
|
||||
ULONGLONG mem_kb;
|
||||
GetPhysicallyInstalledSystemMemory(&mem_kb);
|
||||
machine_info->memory_size_bytes = mem_kb * 1024;
|
||||
|
||||
scap_gethostname(machine_info->hostname, sizeof(machine_info->hostname));
|
||||
machine_info->boot_ts_epoch = scap_windows_get_host_boot_time_ns();
|
||||
if(machine_info->boot_ts_epoch == 0)
|
||||
{
|
||||
return SCAP_FAILURE;
|
||||
}
|
||||
|
||||
return SCAP_SUCCESS;
|
||||
}
|
|
@ -672,6 +672,7 @@ bool docker_async_source::parse(const docker_lookup_request& request, sinsp_cont
|
|||
}
|
||||
/* FALLTHRU */
|
||||
case docker_connection::docker_response::RESP_ERROR:
|
||||
case docker_connection::docker_response::RESP_TIMEOUT:
|
||||
g_logger.format(sinsp_logger::SEV_DEBUG,
|
||||
"docker_async (%s): Url fetch failed, returning false",
|
||||
request.container_id.c_str());
|
||||
|
|
|
@ -18,7 +18,8 @@ public:
|
|||
enum docker_response {
|
||||
RESP_OK = 0,
|
||||
RESP_BAD_REQUEST = 1,
|
||||
RESP_ERROR = 2
|
||||
RESP_ERROR = 2,
|
||||
RESP_TIMEOUT = 3
|
||||
};
|
||||
|
||||
docker_connection();
|
||||
|
|
|
@ -20,6 +20,7 @@ limitations under the License.
|
|||
#include "sinsp_int.h"
|
||||
|
||||
namespace {
|
||||
const uint32_t max_allowed_timeouts = 5;
|
||||
|
||||
size_t docker_curl_write_callback(const char *ptr, size_t size, size_t nmemb, std::string *json)
|
||||
{
|
||||
|
@ -107,6 +108,7 @@ docker_connection::docker_response docker_connection::get_docker(const docker_lo
|
|||
return docker_response::RESP_ERROR;
|
||||
}
|
||||
|
||||
uint32_t num_timeouts = 0;
|
||||
while(true)
|
||||
{
|
||||
int still_running;
|
||||
|
@ -141,6 +143,21 @@ docker_connection::docker_response docker_connection::get_docker(const docker_lo
|
|||
ASSERT(false);
|
||||
return docker_response::RESP_ERROR;
|
||||
}
|
||||
if(numfds == 0)
|
||||
{
|
||||
// Operation timed out
|
||||
if(++num_timeouts >= max_allowed_timeouts)
|
||||
{
|
||||
g_logger.format(sinsp_logger::SEV_WARNING,
|
||||
"docker_async (%s): Max timeouts exceeded",
|
||||
url.c_str());
|
||||
return docker_response::RESP_TIMEOUT;
|
||||
}
|
||||
g_logger.format(sinsp_logger::SEV_DEBUG,
|
||||
"docker_async (%s): Operation timed out %d times",
|
||||
url.c_str(),
|
||||
num_timeouts);
|
||||
}
|
||||
}
|
||||
|
||||
if(curl_multi_remove_handle(m_curlm, curl) != CURLM_OK)
|
||||
|
|
|
@ -2656,6 +2656,8 @@ void sinsp_evt::get_category(OUT sinsp_evt::category* cat)
|
|||
case SCAP_FD_BPF:
|
||||
case SCAP_FD_IOURING:
|
||||
case SCAP_FD_NETLINK:
|
||||
case SCAP_FD_MEMFD:
|
||||
case SCAP_FD_PIDFD:
|
||||
cat->m_subcategory = SC_OTHER;
|
||||
break;
|
||||
case SCAP_FD_UNKNOWN:
|
||||
|
|
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#ifndef _WIN32
|
||||
|
@ -22,6 +23,7 @@ limitations under the License.
|
|||
#include <csignal>
|
||||
#include <sinsp.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "util.h"
|
||||
#include "filter/ppm_codes.h"
|
||||
#include <unordered_set>
|
||||
|
@ -40,13 +42,11 @@ using namespace std;
|
|||
|
||||
|
||||
// Functions used for dumping to stdout
|
||||
void plaintext_dump(sinsp& inspector);
|
||||
void json_dump(sinsp& inspector);
|
||||
void json_dump_init(sinsp& inspector);
|
||||
void json_dump_reinit_evt_formatter(sinsp& inspector);
|
||||
void raw_dump(sinsp&, sinsp_evt* ev);
|
||||
void formatted_dump(sinsp&, sinsp_evt* ev);
|
||||
|
||||
libsinsp::events::set<ppm_sc_code> extract_filter_sc_codes(sinsp& inspector);
|
||||
std::function<void(sinsp& inspector)> dump;
|
||||
std::function<void(sinsp&, sinsp_evt*)> dump = formatted_dump;
|
||||
static bool g_interrupted = false;
|
||||
static const uint8_t g_backoff_timeout_secs = 2;
|
||||
static bool g_all_threads = false;
|
||||
|
@ -54,20 +54,27 @@ static bool ppm_sc_modifies_state = false;
|
|||
static bool ppm_sc_repair_state = false;
|
||||
static bool ppm_sc_state_remove_io_sc = false;
|
||||
static bool enable_glogger = false;
|
||||
static bool json_dump_init_success = false;
|
||||
string engine_string = KMOD_ENGINE; /* Default for backward compatibility. */
|
||||
string filter_string = "";
|
||||
string file_path = "";
|
||||
string bpf_path = "";
|
||||
string output_fields_json = "";
|
||||
unsigned long buffer_bytes_dim = DEFAULT_DRIVER_BUFFER_BYTES_DIM;
|
||||
static uint64_t max_events = UINT64_MAX;
|
||||
|
||||
sinsp_evt* get_event(sinsp& inspector);
|
||||
sinsp_evt* get_event(sinsp& inspector, std::function<void(const std::string&)> handle_error);
|
||||
|
||||
#define PROCESS_DEFAULTS "*%evt.num %evt.time %evt.category %container.id %proc.ppid %proc.pid %evt.type %proc.exe %proc.cmdline %evt.args"
|
||||
#define EVENT_HEADER "%evt.num %evt.time cat=%evt.category container=%container.id proc=%proc.name(%proc.pid.%thread.tid) "
|
||||
#define EVENT_TRAILER "%evt.dir %evt.type %evt.args"
|
||||
|
||||
#define EVENT_DEFAULTS EVENT_HEADER EVENT_TRAILER
|
||||
#define PROCESS_DEFAULTS EVENT_HEADER "ppid=%proc.ppid exe=%proc.exe args=[%proc.cmdline] " EVENT_TRAILER
|
||||
|
||||
#define JSON_PROCESS_DEFAULTS "*%evt.num %evt.time %evt.category %container.id %proc.ppid %proc.pid %evt.type %proc.exe %proc.cmdline %evt.args"
|
||||
|
||||
std::string default_output = EVENT_DEFAULTS;
|
||||
std::string process_output = PROCESS_DEFAULTS;
|
||||
std::string net_output = PROCESS_DEFAULTS " %fd.name";
|
||||
|
||||
// Formatters used with JSON output
|
||||
static std::unique_ptr<sinsp_evt_formatter> default_formatter = nullptr;
|
||||
static std::unique_ptr<sinsp_evt_formatter> process_formatter = nullptr;
|
||||
static std::unique_ptr<sinsp_evt_formatter> net_formatter = nullptr;
|
||||
|
@ -93,13 +100,14 @@ Options:
|
|||
-k, --kmod Kernel module
|
||||
-s <path>, --scap_file <path> Scap file
|
||||
-d <dim>, --buffer_dim <dim> Dimension in bytes that every per-CPU buffer will have.
|
||||
-o <fields>, --output-fields-json <fields> [JSON support only, can also use without -j] Output fields string (see <filter> for supported display fields) that overwrites JSON default output fields for all events. * at the beginning prints JSON keys with null values, else no null fields are printed.
|
||||
-o <fields>, --output-fields <fields> Output fields string (see <filter> for supported display fields) that overwrites default output fields for all events. * at the beginning prints JSON keys with null values, else no null fields are printed.
|
||||
-E, --exclude-users Don't create the user/group tables
|
||||
-n, --num-events Number of events to be retrieved (no limit by default)
|
||||
-z, --ppm-sc-modifies-state Select ppm sc codes from filter AST plus enforce sinsp state ppm sc codes via `sinsp_state_sc_set`, requires valid filter expression.
|
||||
-x, --ppm-sc-repair-state Select ppm sc codes from filter AST plus enforce sinsp state ppm sc codes via `sinsp_repair_state_sc_set`, requires valid filter expression.
|
||||
-q, --remove-io-sc-state Remove ppm sc codes belonging to `io_sc_set` from `sinsp_state_sc_set` sinsp state enforcement, defaults to false and only applies when choosing `-z` option, used for e2e testing of sinsp state.
|
||||
-g, --enable-glogger Enable libs g_logger, set to SEV_DEBUG. For a different severity adjust the test binary source and re-compile.
|
||||
-r, --raw raw event ouput
|
||||
)";
|
||||
cout << usage << endl;
|
||||
}
|
||||
|
@ -118,19 +126,21 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv)
|
|||
{"kmod", no_argument, 0, 'k'},
|
||||
{"scap_file", required_argument, 0, 's'},
|
||||
{"buffer_dim", required_argument, 0, 'd'},
|
||||
{"output-fields-json", required_argument, 0, 'o'},
|
||||
{"output-fields", required_argument, 0, 'o'},
|
||||
{"exclude-users", no_argument, 0, 'E'},
|
||||
{"num-events", required_argument, 0, 'n'},
|
||||
{"ppm-sc-modifies-state", no_argument, 0, 'z'},
|
||||
{"ppm-sc-repair-state", no_argument, 0, 'x'},
|
||||
{"remove-io-sc-state", no_argument, 0, 'q'},
|
||||
{"enable-glogger", no_argument, 0, 'g'},
|
||||
{"raw", no_argument, 0, 'r'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
bool format_set = false;
|
||||
int op;
|
||||
int long_index = 0;
|
||||
while((op = getopt_long(argc, argv,
|
||||
"hf:jab:mks:d:o:En:zxqg",
|
||||
"hf:jab:mks:d:o:En:zxqgr",
|
||||
long_options, &long_index)) != -1)
|
||||
{
|
||||
switch(op)
|
||||
|
@ -142,7 +152,14 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv)
|
|||
filter_string = optarg;
|
||||
break;
|
||||
case 'j':
|
||||
json_dump_init(inspector);
|
||||
dump = formatted_dump;
|
||||
if(!format_set)
|
||||
{
|
||||
default_output = DEFAULT_OUTPUT_STR;
|
||||
process_output = JSON_PROCESS_DEFAULTS;
|
||||
net_output = JSON_PROCESS_DEFAULTS " %fd.name";
|
||||
}
|
||||
inspector.set_buffer_format(sinsp_evt::PF_JSON);
|
||||
break;
|
||||
case 'a':
|
||||
g_all_threads = true;
|
||||
|
@ -165,9 +182,10 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv)
|
|||
buffer_bytes_dim = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'o':
|
||||
output_fields_json = optarg;
|
||||
json_dump_init(inspector);
|
||||
json_dump_reinit_evt_formatter(inspector);
|
||||
default_output = optarg;
|
||||
process_output = optarg;
|
||||
net_output = optarg;
|
||||
format_set = true;
|
||||
break;
|
||||
case 'E':
|
||||
inspector.set_import_users(false);
|
||||
|
@ -187,6 +205,8 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv)
|
|||
case 'g':
|
||||
enable_glogger = true;
|
||||
break;
|
||||
case 'r':
|
||||
dump = raw_dump;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -341,7 +361,6 @@ error:
|
|||
int main(int argc, char** argv)
|
||||
{
|
||||
sinsp inspector;
|
||||
dump = plaintext_dump;
|
||||
|
||||
#ifndef _WIN32
|
||||
parse_CLI_options(inspector, argc, argv);
|
||||
|
@ -393,12 +412,25 @@ int main(int argc, char** argv)
|
|||
|
||||
inspector.start_capture();
|
||||
|
||||
default_formatter = std::make_unique<sinsp_evt_formatter>(&inspector, default_output);
|
||||
process_formatter = std::make_unique<sinsp_evt_formatter>(&inspector, process_output);
|
||||
net_formatter = std::make_unique<sinsp_evt_formatter>(&inspector, net_output);
|
||||
|
||||
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
|
||||
uint64_t num_events = 0;
|
||||
while(!g_interrupted && num_events < max_events)
|
||||
{
|
||||
dump(inspector);
|
||||
num_events++;
|
||||
sinsp_evt* ev = get_event(inspector, [](const std::string& error_msg)
|
||||
{ cout << "[ERROR] " << error_msg << endl; });
|
||||
if(ev != nullptr)
|
||||
{
|
||||
sinsp_threadinfo* thread = ev->get_thread_info();
|
||||
if(!thread || g_all_threads || thread->is_main_thread())
|
||||
{
|
||||
dump(inspector, ev);
|
||||
num_events++;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
|
||||
const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
|
||||
|
@ -442,146 +474,16 @@ sinsp_evt* get_event(sinsp& inspector, std::function<void(const std::string&)> h
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void plaintext_dump(sinsp& inspector)
|
||||
void formatted_dump(sinsp&, sinsp_evt* ev)
|
||||
{
|
||||
|
||||
sinsp_evt* ev = get_event(inspector, [](const std::string& error_msg)
|
||||
{ cout << "[ERROR] " << error_msg << endl; });
|
||||
|
||||
if(ev == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sinsp_threadinfo* thread = ev->get_thread_info();
|
||||
if(thread)
|
||||
{
|
||||
string cmdline;
|
||||
sinsp_threadinfo::populate_cmdline(cmdline, thread);
|
||||
|
||||
if(g_all_threads || thread->is_main_thread())
|
||||
{
|
||||
string date_time;
|
||||
sinsp_utils::ts_to_iso_8601(ev->get_ts(), &date_time);
|
||||
|
||||
bool is_host_proc = thread->m_container_id.empty();
|
||||
cout << "[" << date_time << "]:["
|
||||
<< (is_host_proc ? "HOST" : thread->m_container_id) << "]:";
|
||||
|
||||
cout << "[CAT=";
|
||||
|
||||
if(ev->get_category() == EC_PROCESS)
|
||||
{
|
||||
cout << "PROCESS]:";
|
||||
}
|
||||
else if(ev->get_category() == EC_NET)
|
||||
{
|
||||
cout << get_event_category_name(ev->get_category()) << "]:";
|
||||
sinsp_fdinfo_t* fd_info = ev->get_fd_info();
|
||||
|
||||
// event subcategory should contain SC_NET if ipv4/ipv6
|
||||
if(nullptr != fd_info && (fd_info->get_l4proto() != SCAP_L4_UNKNOWN && fd_info->get_l4proto() != SCAP_L4_NA))
|
||||
{
|
||||
cout << "[" << fd_info->tostring() << "]:";
|
||||
}
|
||||
}
|
||||
else if(ev->get_category() == EC_IO_READ || ev->get_category() == EC_IO_WRITE)
|
||||
{
|
||||
cout << get_event_category_name(ev->get_category()) << "]:";
|
||||
|
||||
sinsp_fdinfo_t* fd_info = ev->get_fd_info();
|
||||
if(nullptr != fd_info && (fd_info->get_l4proto() != SCAP_L4_UNKNOWN && fd_info->get_l4proto() != SCAP_L4_NA))
|
||||
{
|
||||
cout << "[" << fd_info->tostring() << "]:";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << get_event_category_name(ev->get_category()) << "]:";
|
||||
}
|
||||
|
||||
sinsp_threadinfo* p_thr = thread->get_parent_thread();
|
||||
int64_t parent_pid = -1;
|
||||
if(nullptr != p_thr)
|
||||
{
|
||||
parent_pid = p_thr->m_pid;
|
||||
}
|
||||
|
||||
cout << "[PPID=" << parent_pid << "]:"
|
||||
<< "[PID=" << thread->m_pid << "]:"
|
||||
<< "[TYPE=" << get_event_type_name(inspector, ev) << "]:"
|
||||
<< "[EXE=" << thread->get_exepath() << "]:"
|
||||
<< "[CMD=" << cmdline << "]"
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "[EVENT]:[" << get_event_category_name(ev->get_category()) << "]:"
|
||||
<< ev->get_name() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void json_dump_init(sinsp& inspector)
|
||||
{
|
||||
if (!json_dump_init_success)
|
||||
{
|
||||
dump = json_dump;
|
||||
inspector.set_buffer_format(sinsp_evt::PF_JSON);
|
||||
// Initialize JSON formatters
|
||||
default_formatter.reset(new sinsp_evt_formatter(&inspector, DEFAULT_OUTPUT_STR));
|
||||
process_formatter.reset(new sinsp_evt_formatter(&inspector, PROCESS_DEFAULTS));
|
||||
net_formatter.reset(new sinsp_evt_formatter(&inspector, PROCESS_DEFAULTS " %fd.name"));
|
||||
json_dump_init_success = true;
|
||||
}
|
||||
}
|
||||
|
||||
void json_dump_reinit_evt_formatter(sinsp& inspector)
|
||||
{
|
||||
if (!output_fields_json.empty() && json_dump_init_success)
|
||||
{
|
||||
default_formatter.reset(new sinsp_evt_formatter(&inspector, output_fields_json));
|
||||
process_formatter.reset(new sinsp_evt_formatter(&inspector, output_fields_json));
|
||||
net_formatter.reset(new sinsp_evt_formatter(&inspector, output_fields_json));
|
||||
}
|
||||
}
|
||||
|
||||
void json_dump(sinsp& inspector)
|
||||
{
|
||||
|
||||
sinsp_evt* ev = get_event(inspector, [](const std::string& error_msg)
|
||||
{ cout << R"({"error": ")" << error_msg << R"("})" << endl; });
|
||||
|
||||
if(ev == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string output;
|
||||
sinsp_threadinfo* thread = ev->get_thread_info();
|
||||
|
||||
if(thread)
|
||||
if(ev->get_category() == EC_PROCESS)
|
||||
{
|
||||
if(g_all_threads || thread->is_main_thread())
|
||||
{
|
||||
if(ev->get_category() == EC_PROCESS)
|
||||
{
|
||||
process_formatter->tostring(ev, output);
|
||||
}
|
||||
else if(ev->get_category() == EC_NET || ev->get_category() == EC_IO_READ || ev->get_category() == EC_IO_WRITE)
|
||||
{
|
||||
net_formatter->tostring(ev, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
default_formatter->tostring(ev, output);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Prevent empty lines from being printed
|
||||
return;
|
||||
}
|
||||
process_formatter->tostring(ev, output);
|
||||
}
|
||||
else if(ev->get_category() == EC_NET || ev->get_category() == EC_IO_READ || ev->get_category() == EC_IO_WRITE)
|
||||
{
|
||||
net_formatter->tostring(ev, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -590,3 +492,67 @@ void json_dump(sinsp& inspector)
|
|||
|
||||
cout << output << std::endl;
|
||||
}
|
||||
|
||||
static void hexdump(const unsigned char* buf, size_t len)
|
||||
{
|
||||
bool in_ascii = false;
|
||||
|
||||
putc('[', stdout);
|
||||
for(size_t i = 0; i < len; ++i)
|
||||
{
|
||||
if(isprint(buf[i]))
|
||||
{
|
||||
if(!in_ascii)
|
||||
{
|
||||
in_ascii = true;
|
||||
if(i > 0)
|
||||
{
|
||||
putc(' ', stdout);
|
||||
}
|
||||
putc('"', stdout);
|
||||
}
|
||||
putc(buf[i], stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(in_ascii)
|
||||
{
|
||||
in_ascii = false;
|
||||
fputs("\" ", stdout);
|
||||
}
|
||||
else if(i > 0)
|
||||
{
|
||||
putc(' ', stdout);
|
||||
}
|
||||
printf("%02x", buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if(in_ascii)
|
||||
{
|
||||
putc('"', stdout);
|
||||
}
|
||||
putc(']', stdout);
|
||||
}
|
||||
|
||||
void raw_dump(sinsp& inspector, sinsp_evt* ev)
|
||||
{
|
||||
string date_time;
|
||||
sinsp_utils::ts_to_iso_8601(ev->get_ts(), &date_time);
|
||||
|
||||
cout << "ts=" << date_time;
|
||||
cout << " tid=" << ev->get_tid();
|
||||
cout << " type=" << (ev->get_direction() == SCAP_ED_IN ? '>' : '<') << get_event_type_name(ev);
|
||||
cout << " category=" << get_event_category_name(ev->get_category());
|
||||
cout << " nparams=" << ev->get_num_params();
|
||||
|
||||
for(size_t i = 0; i < ev->get_num_params(); ++i)
|
||||
{
|
||||
const sinsp_evt_param *p = ev->get_param(i);
|
||||
const struct ppm_param_info *pi = ev->get_param_info(i);
|
||||
cout << ' ' << i << ':' << pi->name << '=';
|
||||
hexdump((const unsigned char*)p->m_val, p->m_len);
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ std::string get_event_category_name(ppm_event_category category)
|
|||
//
|
||||
// Get the string representation of a ppm_event_type
|
||||
//
|
||||
std::string get_event_type_name(sinsp& inspector, sinsp_evt* ev)
|
||||
std::string get_event_type_name(sinsp_evt *ev)
|
||||
{
|
||||
uint16_t type = ev->get_type();
|
||||
if (type >= PPM_EVENT_MAX)
|
||||
|
|
|
@ -25,4 +25,4 @@ std::string get_event_category_name(ppm_event_category category);
|
|||
//
|
||||
// Get the string representation of a ppm_event_type
|
||||
//
|
||||
std::string get_event_type_name(sinsp& inspector, sinsp_evt* ev);
|
||||
std::string get_event_type_name(sinsp_evt *ev);
|
|
@ -428,6 +428,11 @@ uint8_t* sinsp_filter_check_fspath::extract(sinsp_evt* evt, OUT uint32_t* len, b
|
|||
{
|
||||
sinsp_threadinfo* tinfo = evt->get_thread_info();
|
||||
|
||||
if(tinfo == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::filesystem::path tstr = tinfo->get_cwd() + m_tstr;
|
||||
m_tstr = std::filesystem::absolute(tstr).lexically_normal().string();
|
||||
}
|
||||
|
@ -4489,6 +4494,7 @@ int32_t sinsp_filter_check_event::parse_field_name(const char* str, bool alloc_s
|
|||
res = extract_arg("evt.rawarg", val, &m_arginfo);
|
||||
|
||||
m_customfield.m_type = m_arginfo->type;
|
||||
m_customfield.m_print_format = m_arginfo->fmt;
|
||||
}
|
||||
else if(STR_MATCH("evt.around"))
|
||||
{
|
||||
|
@ -5287,6 +5293,21 @@ uint8_t* sinsp_filter_check_event::extract(sinsp_evt *evt, OUT uint32_t* len, bo
|
|||
case EC_SCHEDULER:
|
||||
m_strstorage = "scheduler";
|
||||
break;
|
||||
case EC_INTERNAL:
|
||||
m_strstorage = "internal";
|
||||
break;
|
||||
case EC_SYSCALL:
|
||||
m_strstorage = "syscall";
|
||||
break;
|
||||
case EC_TRACEPOINT:
|
||||
m_strstorage = "tracepoint";
|
||||
break;
|
||||
case EC_PLUGIN:
|
||||
m_strstorage = "plugin";
|
||||
break;
|
||||
case EC_METAEVENT:
|
||||
m_strstorage = "meta";
|
||||
break;
|
||||
default:
|
||||
m_strstorage = "unknown";
|
||||
break;
|
||||
|
@ -8563,7 +8584,7 @@ uint8_t* sinsp_filter_check_fdlist::extract(sinsp_evt *evt, OUT uint32_t* len, b
|
|||
bool add_comma = true;
|
||||
int64_t fd = *(int64_t *)(payload + pos);
|
||||
|
||||
sinsp_fdinfo_t *fdinfo = tinfo->get_fd(fd);
|
||||
sinsp_fdinfo_t *fdinfo = tinfo ? tinfo->get_fd(fd) : NULL;
|
||||
|
||||
switch(m_field_id)
|
||||
{
|
||||
|
|
|
@ -2806,7 +2806,15 @@ void sinsp_parser::parse_dirfd(sinsp_evt *evt, char* name, int64_t dirfd, OUT st
|
|||
}
|
||||
else if(dirfd == PPM_AT_FDCWD)
|
||||
{
|
||||
*sdir = evt->m_tinfo->get_cwd();
|
||||
if(evt->m_tinfo != NULL)
|
||||
{
|
||||
*sdir = evt->m_tinfo->get_cwd();
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(false);
|
||||
*sdir = "<UNKNOWN>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -6658,7 +6666,7 @@ void sinsp_parser::parse_pidfd_open_exit(sinsp_evt *evt)
|
|||
/* pid (fd) */
|
||||
parinfo = evt->get_param(1);
|
||||
ASSERT(parinfo->m_len == sizeof(int64_t));
|
||||
ASSERT(evt->get_param_info(0)->type == PT_PID);
|
||||
ASSERT(evt->get_param_info(1)->type == PT_PID);
|
||||
pid = *(int64_t *)parinfo->m_val;
|
||||
|
||||
/* flags */
|
||||
|
|
|
@ -494,6 +494,10 @@ void sinsp::open_common(scap_open_args* oargs)
|
|||
std::string error = scap_getlasterr(m_h);
|
||||
scap_close(m_h);
|
||||
m_h = NULL;
|
||||
if(error.empty())
|
||||
{
|
||||
error = "Initialization issues during scap_init";
|
||||
}
|
||||
throw scap_open_exception(error, scap_rc);
|
||||
}
|
||||
|
||||
|
@ -1216,6 +1220,8 @@ int32_t sinsp::next(OUT sinsp_evt **puevt)
|
|||
sinsp_evt* evt;
|
||||
int32_t res;
|
||||
|
||||
*puevt = NULL;
|
||||
|
||||
//
|
||||
// Check if there are fake cpu events to events
|
||||
//
|
||||
|
@ -1289,8 +1295,6 @@ int32_t sinsp::next(OUT sinsp_evt **puevt)
|
|||
{
|
||||
m_external_event_processor->process_event(NULL, libsinsp::EVENT_RETURN_TIMEOUT);
|
||||
}
|
||||
*puevt = NULL;
|
||||
return res;
|
||||
}
|
||||
else if(res == SCAP_EOF)
|
||||
{
|
||||
|
@ -1306,8 +1310,7 @@ int32_t sinsp::next(OUT sinsp_evt **puevt)
|
|||
// In this case, we restart the capture so that the internal states gets reset
|
||||
// and the blocks coming from the next appended file get consumed.
|
||||
restart_capture();
|
||||
return SCAP_TIMEOUT;
|
||||
|
||||
res = SCAP_TIMEOUT;
|
||||
}
|
||||
else if(res == SCAP_FILTERED_EVENT)
|
||||
{
|
||||
|
@ -1319,8 +1322,6 @@ int32_t sinsp::next(OUT sinsp_evt **puevt)
|
|||
if(m_external_event_processor)
|
||||
{
|
||||
m_external_event_processor->process_event(NULL, libsinsp::EVENT_RETURN_FILTERED);
|
||||
*puevt = NULL;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1418,24 +1419,19 @@ int32_t sinsp::next(OUT sinsp_evt **puevt)
|
|||
// things like exit() or close() can be parsed.
|
||||
//
|
||||
uint32_t nfdr = (uint32_t)m_fds_to_remove->size();
|
||||
|
||||
if(nfdr != 0)
|
||||
{
|
||||
/* This is a removal logic we shouldn't scan /proc. If we don't have the thread
|
||||
* to remove we are fine.
|
||||
*/
|
||||
sinsp_threadinfo* ptinfo = get_thread_ref(m_tid_of_fd_to_remove, false).get();
|
||||
if(!ptinfo)
|
||||
if(ptinfo)
|
||||
{
|
||||
ASSERT(false);
|
||||
return res;
|
||||
for(uint32_t j = 0; j < nfdr; j++)
|
||||
{
|
||||
ptinfo->remove_fd(m_fds_to_remove->at(j));
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t j = 0; j < nfdr; j++)
|
||||
{
|
||||
ptinfo->remove_fd(m_fds_to_remove->at(j));
|
||||
}
|
||||
|
||||
m_fds_to_remove->clear();
|
||||
}
|
||||
|
||||
|
@ -1508,6 +1504,9 @@ int32_t sinsp::next(OUT sinsp_evt **puevt)
|
|||
m_dumper->dump(evt);
|
||||
}
|
||||
|
||||
// Finally set output evt;
|
||||
// From now on, any return must have the correct output being set.
|
||||
*puevt = evt;
|
||||
if(evt->m_filtered_out)
|
||||
{
|
||||
ppm_event_category cat = evt->get_category();
|
||||
|
@ -1516,7 +1515,6 @@ int32_t sinsp::next(OUT sinsp_evt **puevt)
|
|||
// mode and the category of this event is internal.
|
||||
if(!(m_isinternal_events_enabled && (cat & EC_INTERNAL)))
|
||||
{
|
||||
*puevt = evt;
|
||||
return SCAP_FILTERED_EVENT;
|
||||
}
|
||||
}
|
||||
|
@ -1546,7 +1544,6 @@ int32_t sinsp::next(OUT sinsp_evt **puevt)
|
|||
//
|
||||
// Done
|
||||
//
|
||||
*puevt = evt;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -234,6 +234,11 @@ public:
|
|||
virtual void open_modern_bpf(unsigned long driver_buffer_bytes_dim = DEFAULT_DRIVER_BUFFER_BYTES_DIM, uint16_t cpus_for_each_buffer = DEFAULT_CPU_FOR_EACH_BUFFER, bool online_only = true, const libsinsp::events::set<ppm_sc_code> &ppm_sc_of_interest = {});
|
||||
virtual void open_test_input(scap_test_input_data* data, scap_mode_t mode = SCAP_MODE_TEST);
|
||||
|
||||
void fseek(uint64_t filepos)
|
||||
{
|
||||
scap_fseek(m_h, filepos);
|
||||
}
|
||||
|
||||
scap_open_args factory_open_args(const char* engine_name, scap_mode_t scap_mode);
|
||||
|
||||
std::string generate_gvisor_config(std::string socket_path);
|
||||
|
@ -1080,11 +1085,6 @@ private:
|
|||
|
||||
void restart_capture();
|
||||
|
||||
void fseek(uint64_t filepos)
|
||||
{
|
||||
scap_fseek(m_h, filepos);
|
||||
}
|
||||
|
||||
void add_suppressed_comms(scap_open_args *oargs);
|
||||
|
||||
bool increased_snaplen_port_range_set() const
|
||||
|
|
|
@ -69,7 +69,7 @@ TEST_F(sinsp_with_test_input, event_hostname)
|
|||
|
||||
add_default_init_thread();
|
||||
|
||||
open_inspector();
|
||||
open_inspector(SCAP_MODE_LIVE);
|
||||
sinsp_evt *evt = NULL;
|
||||
|
||||
/* Toy event example from a previous test. */
|
||||
|
|
|
@ -389,6 +389,8 @@ void sinsp_threadinfo::add_fd_from_scap(scap_fdinfo *fdi, OUT sinsp_fdinfo_t *re
|
|||
case SCAP_FD_BPF:
|
||||
case SCAP_FD_USERFAULTFD:
|
||||
case SCAP_FD_IOURING:
|
||||
case SCAP_FD_MEMFD:
|
||||
case SCAP_FD_PIDFD:
|
||||
newfdi->m_name = fdi->info.fname;
|
||||
|
||||
if(newfdi->m_name == USER_EVT_DEVICE_NAME)
|
||||
|
@ -953,9 +955,6 @@ std::string sinsp_threadinfo::get_cwd()
|
|||
else
|
||||
{
|
||||
///todo(@Andreagit97) not sure we want to return "./" it seems like a valid path
|
||||
#if defined(__linux__)
|
||||
ASSERT(false);
|
||||
#endif //__linux__
|
||||
return "./";
|
||||
}
|
||||
}
|
||||
|
@ -1416,6 +1415,8 @@ void sinsp_threadinfo::fd_to_scap(scap_fdinfo *dst, sinsp_fdinfo_t* src)
|
|||
case SCAP_FD_BPF:
|
||||
case SCAP_FD_USERFAULTFD:
|
||||
case SCAP_FD_IOURING:
|
||||
case SCAP_FD_MEMFD:
|
||||
case SCAP_FD_PIDFD:
|
||||
strlcpy(dst->info.fname, src->m_name.c_str(), sizeof(dst->info.fname));
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue