Compare commits
94 Commits
319368f1ad
...
b7eb0dd652
Author | SHA1 | Date |
---|---|---|
|
b7eb0dd652 | |
|
2bc27c049c | |
|
7e7a5129b6 | |
|
86d06a8e91 | |
|
11c8096fc5 | |
|
e71045b29d | |
|
f05aaecd11 | |
|
7ffd922614 | |
|
33b7ce9124 | |
|
0765e5de62 | |
|
65784c2e94 | |
|
e821bb23a6 | |
|
04fe1a6563 | |
|
6280aaaca6 | |
|
271c8f71ac | |
|
c0c04e75eb | |
|
dcf1dc9d34 | |
|
c2ec5dca61 | |
|
109398a09a | |
|
4f4c882d3e | |
|
39e05ab79c | |
|
c260765511 | |
|
97dd002dfc | |
|
388011895c | |
|
f05af8ac65 | |
|
de964b79c7 | |
|
4232351731 | |
|
8e2a574bce | |
|
1ea8a662a6 | |
|
57c076266f | |
|
1b612964a8 | |
|
f144d588df | |
|
76fef4e57e | |
|
93dad63469 | |
|
5b4fad5cbb | |
|
e473353cf6 | |
|
f92018e1b4 | |
|
27ea5bcb0b | |
|
431f65f1dc | |
|
f21502ed92 | |
|
25afadce41 | |
|
045f38284a | |
|
53039b6a3c | |
|
93f897de7c | |
|
02a3712b06 | |
|
50d21d1dc3 | |
|
4f177295c3 | |
|
ccadd6884c | |
|
7227177d4b | |
|
0bc1b30852 | |
|
663e607eed | |
|
b864389510 | |
|
cc821199ca | |
|
4722ec6da3 | |
|
688fcebb59 | |
|
cba4af082a | |
|
a14f7d883f | |
|
a4174d8090 | |
|
6f6d296395 | |
|
6b1b9c0dcf | |
|
85f898e7af | |
|
cc42b767e8 | |
|
a34513703d | |
|
7f3ee83f64 | |
|
50b6f03ae5 | |
|
2c080edf47 | |
|
0b5d160896 | |
|
7d5af8bbc2 | |
|
5ef0ad690a | |
|
8596512f11 | |
|
b2b4fe86b0 | |
|
96add173cf | |
|
60434ce291 | |
|
9f372d0e50 | |
|
033c4b9f28 | |
|
bb2e13f499 | |
|
ba8d76e194 | |
|
44418e930d | |
|
dfaff4e4af | |
|
c19fe029ec | |
|
73e0b8f008 | |
|
d1a2bb749f | |
|
12406fc9fd | |
|
3745949eeb | |
|
2750b8893b | |
|
50aa758594 | |
|
fa1e72b0cd | |
|
87ea250323 | |
|
4df7717bff | |
|
ad771ad8a0 | |
|
5f0ebecb47 | |
|
71b6cfd7ad | |
|
c87aee07ee | |
|
2374ead905 |
140
README.md
140
README.md
|
@ -1,3 +1,141 @@
|
||||||
# falcosecurity/libs
|
# falcosecurity/libs
|
||||||
|
|
||||||
As per the [OSS Libraries Contribution Plan](https://github.com/falcosecurity/falco/blob/master/proposals/20210119-libraries-contribution.md), this repository has been chosen to be the new home for **libsinsp**, **libscap**, the **kernel module driver** and the **eBPF driver sources**.
|
As per the [OSS Libraries Contribution Plan](https://github.com/falcosecurity/falco/blob/master/proposals/20210119-libraries-contribution.md), this repository has been chosen to be the new home for **libsinsp**, **libscap**, the **kernel module** and the **eBPF probe** sources.
|
||||||
|
Refer to https://falco.org/blog/contribution-drivers-kmod-ebpf-libraries/ for more informations.
|
||||||
|
|
||||||
|
These components are at the foundation of [Falco](https://github.com/falcosecurity/falco) and other projects that work with the same kind of data.
|
||||||
|
|
||||||
|
This component stack mainly operates on a data source: system calls. This data source is collected using either a kernel module or an eBPF probe, which we call *drivers*. On top of the drivers, libscap manages the data capture process, libsinsp enriches the data, and provides a rich set of API to consume the data. Furthermore, these two libraries also implement a [plugin](https://github.com/falcosecurity/plugins) framework that extends this stack to potentially any other data sources.
|
||||||
|
|
||||||
|
An image is worth a thousand words, they say:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Project Layout
|
||||||
|
|
||||||
|
* [_driver/_](./driver) contains kernel module and eBPF probe source code,
|
||||||
|
so-called **drivers**.
|
||||||
|
* [_userspace/_](./userspace) contains libscap and libsinsp libraries code,
|
||||||
|
plus chisels related code and common utilities.
|
||||||
|
* **libscap** (aka lib for *System CAPture*) is the userspace library
|
||||||
|
that directly communicates with the drivers, reading syscall events from
|
||||||
|
the ring buffer (where drivers place them), and forwarding them
|
||||||
|
up to libsinsp. Moreover, libscap implements OS state collection and
|
||||||
|
supports reading/writing to scap files.
|
||||||
|
* **libsinsp** (aka lib for *System INSPection*) receives events from
|
||||||
|
libscap and enriches them with machine state: moreover, it performs
|
||||||
|
events filtering with rule evaluation through its internal rule engine.
|
||||||
|
Finally, it manages outputs.
|
||||||
|
* **chisels** are just little Lua scripts to analyze an event stream
|
||||||
|
and perform useful actions. In this subfolder, the backend code for
|
||||||
|
chisels support can be found.
|
||||||
|
* [_proposals/_](./proposals) unexpectedly contains the list of proposals.
|
||||||
|
* [_cmake/modules/_](./cmake/modules) contains modules to build
|
||||||
|
external dependencies, plus the libscap and libsinsp ones; consumers
|
||||||
|
(like Falco) use those modules to build the libs in their projects.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Libs relies upon `cmake` build system.
|
||||||
|
Lots of `make` targets will be available; the most important ones are:
|
||||||
|
* `driver` -> to build the kmod
|
||||||
|
* `bpf` -> to build the eBPF probe
|
||||||
|
* `scap` -> to build libscap
|
||||||
|
* `sinsp` -> to build libsinsp (depends upon `scap` target)
|
||||||
|
* `scap-open` -> to build a small libscap example to quickly test drivers (depends upon `scap`)
|
||||||
|
|
||||||
|
To start, first create and move inside `build/` folder:
|
||||||
|
```bash
|
||||||
|
mkdir build && cd build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bundled deps
|
||||||
|
|
||||||
|
Easiest way to build the project is to use BUNDLED_DEPS option,
|
||||||
|
meaning that most of the dependencies will be fetched and compiled during the process:
|
||||||
|
```bash
|
||||||
|
cmake -DUSE_BUNDLED_DEPS=true ../
|
||||||
|
make sinsp
|
||||||
|
```
|
||||||
|
> **NOTE:** take a break as this will take quite a bit of time (around 15 mins, dependent on the hardware obviously).
|
||||||
|
|
||||||
|
### System deps
|
||||||
|
|
||||||
|
To build using the system deps instead, first make sure to have all the needed packages installed.
|
||||||
|
Refer to https://falco.org/docs/getting-started/source/ for the list of dependencies.
|
||||||
|
|
||||||
|
Then, simply issue:
|
||||||
|
```bash
|
||||||
|
cmake ../
|
||||||
|
make sinsp
|
||||||
|
```
|
||||||
|
|
||||||
|
> **NOTE:** using system libraries is useful to cut compile times down, as this way it will only build libs, and not all deps.
|
||||||
|
> On the other hand, system deps version may have an impact, and we cannot guarantee everything goes smoothly while using them.
|
||||||
|
|
||||||
|
### Build kmod
|
||||||
|
|
||||||
|
To build the kmod driver, you need your kernel headers installed. Again, checkout the Falco documentation for this step.
|
||||||
|
Then it will be just a matter of running:
|
||||||
|
```bash
|
||||||
|
make driver
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build eBPF probe
|
||||||
|
|
||||||
|
To build the eBPF probe, you need `clang` and `llvm` packages.
|
||||||
|
Then, issue:
|
||||||
|
```bash
|
||||||
|
cmake -DBUILD_BPF=true ../
|
||||||
|
make bpf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test drivers
|
||||||
|
|
||||||
|
Libscap ships a small example that is quite handy to quickly check that drivers are working fine.
|
||||||
|
To build it, issue:
|
||||||
|
```bash
|
||||||
|
make scap-open
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, to execute it with the eBPF probe, issue:
|
||||||
|
```bash
|
||||||
|
sudo BPF_PROBE=driver/bpf/probe.o ./libscap/examples/01-open/scap-open
|
||||||
|
```
|
||||||
|
|
||||||
|
To execute it with the kmod instead issue:
|
||||||
|
```bash
|
||||||
|
sudo insmod driver/scap.ko
|
||||||
|
sudo ./libscap/examples/01-open/scap-open
|
||||||
|
sudo rmmod scap
|
||||||
|
```
|
||||||
|
|
||||||
|
As soon as you quit (ctrl-C) the scap-open program, you will be prompted with detailed informations on the capture:
|
||||||
|
```bash
|
||||||
|
events captured: 39460
|
||||||
|
seen by driver: 39912
|
||||||
|
Number of dropped events: 0
|
||||||
|
Number of dropped events caused by full buffer: 0
|
||||||
|
Number of dropped events caused by invalid memory access: 0
|
||||||
|
Number of dropped events caused by an invalid condition in the kernel instrumentation: 0
|
||||||
|
Number of preemptions: 0
|
||||||
|
Number of events skipped due to the tid being in a set of suppressed tids: 0
|
||||||
|
Number of threads currently being suppressed: 0
|
||||||
|
```
|
||||||
|
therefore confirming that the drivers are indeed working fine!
|
||||||
|
|
||||||
|
## Contribute
|
||||||
|
|
||||||
|
Any contribution is incredibly helpful and **warmly** accepted; be it code, documentation, or just ideas, please feel free to share it!
|
||||||
|
For a contribution guideline, refer to: https://github.com/falcosecurity/.github/blob/master/CONTRIBUTING.md.
|
||||||
|
|
||||||
|
### Adding syscalls
|
||||||
|
|
||||||
|
Implementing new syscalls is surely one of the highest frequency request.
|
||||||
|
While it is indeed important for libs to support as many syscalls as possible, most of the time it is not a high priority task.
|
||||||
|
But **you** can speed up things by opening a PR for it!
|
||||||
|
Luckily enough, a Falco blog post explains the process very thoroughly: https://falco.org/blog/falco-monitoring-new-syscalls/.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed to you under the [Apache 2.0](./COPYING) open source license. Some subcomponents might be licensed separately. You can find licensing notices [here](./NOTICES).
|
|
@ -83,13 +83,14 @@ else()
|
||||||
"${GRPC_SRC}/libupb.a"
|
"${GRPC_SRC}/libupb.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/hash/libabsl_hash.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/hash/libabsl_hash.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/hash/libabsl_city.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/hash/libabsl_city.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/hash/libabsl_wyhash.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/hash/libabsl_low_level_hash.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/container/libabsl_raw_hash_set.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/container/libabsl_raw_hash_set.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/container/libabsl_hashtablez_sampler.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/container/libabsl_hashtablez_sampler.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/base/libabsl_exponential_biased.a"
|
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/status/libabsl_statusor.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/status/libabsl_statusor.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/status/libabsl_status.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/status/libabsl_status.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_cord.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_cord.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_cordz_functions.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/profiling/libabsl_exponential_biased.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/types/libabsl_bad_optional_access.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/types/libabsl_bad_optional_access.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/types/libabsl_bad_variant_access.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/types/libabsl_bad_variant_access.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_str_format_internal.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_str_format_internal.a"
|
||||||
|
@ -111,13 +112,24 @@ else()
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/base/libabsl_raw_logging_internal.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/base/libabsl_raw_logging_internal.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/base/libabsl_log_severity.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/base/libabsl_log_severity.a"
|
||||||
"${GRPC_SRC}/third_party/abseil-cpp/absl/time/libabsl_time_zone.a"
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/time/libabsl_time_zone.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_cord_internal.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_cordz_info.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_cordz_handle.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_pool_urbg.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_randen.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_randen_hwaes.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_randen_hwaes_impl.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_platform.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_randen_slow.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_seed_material.a"
|
||||||
|
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_seed_gen_exception.a"
|
||||||
)
|
)
|
||||||
|
|
||||||
ExternalProject_Add(grpc
|
ExternalProject_Add(grpc
|
||||||
PREFIX "${PROJECT_BINARY_DIR}/grpc-prefix"
|
PREFIX "${PROJECT_BINARY_DIR}/grpc-prefix"
|
||||||
DEPENDS openssl protobuf c-ares zlib
|
DEPENDS openssl protobuf c-ares zlib
|
||||||
GIT_REPOSITORY https://github.com/grpc/grpc.git
|
GIT_REPOSITORY https://github.com/grpc/grpc.git
|
||||||
GIT_TAG v1.38.1
|
GIT_TAG v1.44.0
|
||||||
GIT_SUBMODULES "third_party/abseil-cpp third_party/re2"
|
GIT_SUBMODULES "third_party/abseil-cpp third_party/re2"
|
||||||
CMAKE_CACHE_ARGS
|
CMAKE_CACHE_ARGS
|
||||||
-DCMAKE_INSTALL_PREFIX:PATH=${GRPC_INSTALL_DIR}
|
-DCMAKE_INSTALL_PREFIX:PATH=${GRPC_INSTALL_DIR}
|
||||||
|
@ -156,6 +168,7 @@ else()
|
||||||
BUILD_BYPRODUCTS ${GRPC_LIB} ${GRPCPP_LIB} ${GPR_LIB} ${GRPC_LIBRARIES}
|
BUILD_BYPRODUCTS ${GRPC_LIB} ${GRPCPP_LIB} ${GPR_LIB} ${GRPC_LIBRARIES}
|
||||||
# Keep installation files into the local ${GRPC_INSTALL_DIR}
|
# Keep installation files into the local ${GRPC_INSTALL_DIR}
|
||||||
# since here is the case when we are embedding gRPC
|
# since here is the case when we are embedding gRPC
|
||||||
|
UPDATE_COMMAND ""
|
||||||
INSTALL_COMMAND DESTDIR= ${CMD_MAKE} install
|
INSTALL_COMMAND DESTDIR= ${CMD_MAKE} install
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -6,7 +6,7 @@ option(USE_BUNDLED_LUAJIT "Enable building of the bundled LuaJIT" ${USE_BUNDLED_
|
||||||
if(LUAJIT_INCLUDE)
|
if(LUAJIT_INCLUDE)
|
||||||
# we already have luajit
|
# we already have luajit
|
||||||
elseif(NOT USE_BUNDLED_LUAJIT)
|
elseif(NOT USE_BUNDLED_LUAJIT)
|
||||||
find_path(LUAJIT_INCLUDE luajit.h PATH_SUFFIXES luajit-2.0 luajit)
|
find_path(LUAJIT_INCLUDE luajit.h PATH_SUFFIXES luajit-2.0 luajit-2.1 luajit)
|
||||||
find_library(LUAJIT_LIB NAMES luajit luajit-5.1)
|
find_library(LUAJIT_LIB NAMES luajit luajit-5.1)
|
||||||
if(LUAJIT_INCLUDE AND LUAJIT_LIB)
|
if(LUAJIT_INCLUDE AND LUAJIT_LIB)
|
||||||
message(STATUS "Found LuaJIT: include: ${LUAJIT_INCLUDE}, lib: ${LUAJIT_LIB}")
|
message(STATUS "Found LuaJIT: include: ${LUAJIT_INCLUDE}, lib: ${LUAJIT_LIB}")
|
||||||
|
@ -42,6 +42,7 @@ else()
|
||||||
BUILD_COMMAND ${CMD_MAKE}
|
BUILD_COMMAND ${CMD_MAKE}
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
BUILD_BYPRODUCTS ${LUAJIT_LIB}
|
BUILD_BYPRODUCTS ${LUAJIT_LIB}
|
||||||
|
UPDATE_COMMAND ""
|
||||||
INSTALL_COMMAND "")
|
INSTALL_COMMAND "")
|
||||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "s390x")
|
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "s390x")
|
||||||
ExternalProject_Add(luajit
|
ExternalProject_Add(luajit
|
||||||
|
@ -52,6 +53,7 @@ else()
|
||||||
BUILD_COMMAND ${CMD_MAKE}
|
BUILD_COMMAND ${CMD_MAKE}
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
BUILD_BYPRODUCTS ${LUAJIT_LIB}
|
BUILD_BYPRODUCTS ${LUAJIT_LIB}
|
||||||
|
UPDATE_COMMAND ""
|
||||||
INSTALL_COMMAND "")
|
INSTALL_COMMAND "")
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
ExternalProject_Add(luajit
|
ExternalProject_Add(luajit
|
||||||
|
@ -72,6 +74,7 @@ else()
|
||||||
BUILD_COMMAND ${CMD_MAKE}
|
BUILD_COMMAND ${CMD_MAKE}
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
BUILD_BYPRODUCTS ${LUAJIT_LIB}
|
BUILD_BYPRODUCTS ${LUAJIT_LIB}
|
||||||
|
UPDATE_COMMAND ""
|
||||||
INSTALL_COMMAND "")
|
INSTALL_COMMAND "")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
1.0.0
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (C) 2021 The Falco Authors.
|
# Copyright (C) 2022 The Falco Authors.
|
||||||
#
|
#
|
||||||
# This file is dual licensed under either the MIT or GPL 2. See
|
# This file is dual licensed under either the MIT or GPL 2. See
|
||||||
# MIT.txt or GPL.txt for full copies of the license.
|
# MIT.txt or GPL.txt for full copies of the license.
|
||||||
|
@ -39,6 +39,23 @@ endif()
|
||||||
# after the build we copy the compiled module one directory up,
|
# after the build we copy the compiled module one directory up,
|
||||||
# to ${CMAKE_CURRENT_BINARY_DIR}.
|
# to ${CMAKE_CURRENT_BINARY_DIR}.
|
||||||
|
|
||||||
|
file(STRINGS API_VERSION DRIVER_API_VERSION LIMIT_COUNT 1)
|
||||||
|
string(REGEX MATCHALL "[0-9]+" DRIVER_API_COMPONENTS "${DRIVER_API_VERSION}")
|
||||||
|
list(GET DRIVER_API_COMPONENTS 0 PPM_API_CURRENT_VERSION_MAJOR)
|
||||||
|
list(GET DRIVER_API_COMPONENTS 1 PPM_API_CURRENT_VERSION_MINOR)
|
||||||
|
list(GET DRIVER_API_COMPONENTS 2 PPM_API_CURRENT_VERSION_PATCH)
|
||||||
|
message(STATUS "Driver API version ${PPM_API_CURRENT_VERSION_MAJOR}.${PPM_API_CURRENT_VERSION_MINOR}.${PPM_API_CURRENT_VERSION_PATCH}")
|
||||||
|
|
||||||
|
file(STRINGS SCHEMA_VERSION DRIVER_SCHEMA_VERSION LIMIT_COUNT 1)
|
||||||
|
string(REGEX MATCHALL "[0-9]+" DRIVER_SCHEMA_COMPONENTS "${DRIVER_SCHEMA_VERSION}")
|
||||||
|
list(GET DRIVER_SCHEMA_COMPONENTS 0 PPM_SCHEMA_CURRENT_VERSION_MAJOR)
|
||||||
|
list(GET DRIVER_SCHEMA_COMPONENTS 1 PPM_SCHEMA_CURRENT_VERSION_MINOR)
|
||||||
|
list(GET DRIVER_SCHEMA_COMPONENTS 2 PPM_SCHEMA_CURRENT_VERSION_PATCH)
|
||||||
|
message(STATUS "Driver schema version ${PPM_SCHEMA_CURRENT_VERSION_MAJOR}.${PPM_SCHEMA_CURRENT_VERSION_MINOR}.${PPM_SCHEMA_CURRENT_VERSION_PATCH}")
|
||||||
|
|
||||||
|
execute_process(COMMAND git rev-parse HEAD OUTPUT_VARIABLE GIT_COMMIT ERROR_QUIET WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
string(STRIP "${GIT_COMMIT}" GIT_COMMIT)
|
||||||
|
|
||||||
configure_file(dkms.conf.in src/dkms.conf)
|
configure_file(dkms.conf.in src/dkms.conf)
|
||||||
configure_file(Makefile.in src/Makefile)
|
configure_file(Makefile.in src/Makefile)
|
||||||
configure_file(driver_config.h.in src/driver_config.h)
|
configure_file(driver_config.h.in src/driver_config.h)
|
||||||
|
@ -51,6 +68,7 @@ set(DRIVER_SOURCES
|
||||||
kernel_hacks.h
|
kernel_hacks.h
|
||||||
main.c
|
main.c
|
||||||
ppm.h
|
ppm.h
|
||||||
|
ppm_api_version.h
|
||||||
ppm_events.c
|
ppm_events.c
|
||||||
ppm_events.h
|
ppm_events.h
|
||||||
ppm_events_public.h
|
ppm_events_public.h
|
||||||
|
@ -84,13 +102,13 @@ endif()
|
||||||
if(BUILD_DRIVER)
|
if(BUILD_DRIVER)
|
||||||
add_custom_target(driver ALL
|
add_custom_target(driver ALL
|
||||||
COMMAND ${MAKE_COMMAND}
|
COMMAND ${MAKE_COMMAND}
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${PROBE_NAME}.ko "${CMAKE_CURRENT_BINARY_DIR}"
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${DRIVER_NAME}.ko "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
WORKING_DIRECTORY src
|
WORKING_DIRECTORY src
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
else()
|
else()
|
||||||
add_custom_target(driver
|
add_custom_target(driver
|
||||||
COMMAND ${MAKE_COMMAND}
|
COMMAND ${MAKE_COMMAND}
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${PROBE_NAME}.ko "${CMAKE_CURRENT_BINARY_DIR}"
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${DRIVER_NAME}.ko "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
WORKING_DIRECTORY src
|
WORKING_DIRECTORY src
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
endif()
|
endif()
|
||||||
|
@ -106,7 +124,7 @@ if(ENABLE_DKMS)
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/src/dkms.conf
|
${CMAKE_CURRENT_BINARY_DIR}/src/dkms.conf
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/src/driver_config.h
|
${CMAKE_CURRENT_BINARY_DIR}/src/driver_config.h
|
||||||
${DRIVER_SOURCES}
|
${DRIVER_SOURCES}
|
||||||
DESTINATION "src/${DRIVER_PACKAGE_NAME}-${PROBE_VERSION}"
|
DESTINATION "src/${DRIVER_PACKAGE_NAME}-${DRIVER_VERSION}"
|
||||||
COMPONENT ${DRIVER_COMPONENT_NAME})
|
COMPONENT ${DRIVER_COMPONENT_NAME})
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#
|
#
|
||||||
# Copyright (C) 2021 The Falco Authors.
|
# Copyright (C) 2022 The Falco Authors.
|
||||||
#
|
#
|
||||||
# This file is dual licensed under either the MIT or GPL 2. See
|
# This file is dual licensed under either the MIT or GPL 2. See
|
||||||
# MIT.txt or GPL.txt for full copies of the license.
|
# MIT.txt or GPL.txt for full copies of the license.
|
||||||
#
|
#
|
||||||
|
|
||||||
@PROBE_NAME@-y += main.o dynamic_params_table.o fillers_table.o flags_table.o ppm_events.o ppm_fillers.o event_table.o syscall_table.o ppm_cputime.o
|
@DRIVER_NAME@-y += main.o dynamic_params_table.o fillers_table.o flags_table.o ppm_events.o ppm_fillers.o event_table.o syscall_table.o ppm_cputime.o
|
||||||
obj-m += @PROBE_NAME@.o
|
obj-m += @DRIVER_NAME@.o
|
||||||
ccflags-y := @KBUILD_FLAGS@
|
ccflags-y := @KBUILD_FLAGS@
|
||||||
|
|
||||||
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
|
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
# API version number
|
||||||
|
|
||||||
|
The file API_VERSION must contain a semver-like version number of the userspace<->kernel API. All other lines are ignored.
|
||||||
|
|
||||||
|
## When to increment
|
||||||
|
|
||||||
|
**major version**: increment when the driver API becomes incompatible with previous userspace versions
|
||||||
|
|
||||||
|
**minor version**: increment when new features are added but existing features remain compatible
|
||||||
|
|
||||||
|
**patch version**: increment when code changes don't break compatibility (e.g. bug fixes)
|
||||||
|
|
||||||
|
Do *not* increment for patches that only add support for new kernels, without affecting already supported ones.
|
||||||
|
|
||||||
|
# Schema version number
|
||||||
|
|
||||||
|
The file SCHEMA_VERSION must contain a semver-like version number of the event schema. All other lines are ignored.
|
||||||
|
|
||||||
|
## When to increment
|
||||||
|
|
||||||
|
**major version**: increment when the schema becomes incompatible with previous userspace versions
|
||||||
|
|
||||||
|
**minor version**: increment when new features are added but existing features remain compatible (e.g. new event fields or new events)
|
||||||
|
|
||||||
|
**patch version**: increment when code changes don't break compatibility (e.g. bug fixes in filler code)
|
|
@ -0,0 +1 @@
|
||||||
|
1.0.0
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (C) 2021 The Falco Authors.
|
# Copyright (C) 2022 The Falco Authors.
|
||||||
#
|
#
|
||||||
# This file is dual licensed under either the MIT or GPL 2. See
|
# This file is dual licensed under either the MIT or GPL 2. See
|
||||||
# MIT.txt or GPL.txt for full copies of the license.
|
# MIT.txt or GPL.txt for full copies of the license.
|
||||||
|
@ -29,5 +29,5 @@ install(FILES
|
||||||
quirks.h
|
quirks.h
|
||||||
ring_helpers.h
|
ring_helpers.h
|
||||||
types.h
|
types.h
|
||||||
DESTINATION "src/${DRIVER_PACKAGE_NAME}-${PROBE_VERSION}/bpf"
|
DESTINATION "src/${DRIVER_PACKAGE_NAME}-${DRIVER_VERSION}/bpf"
|
||||||
COMPONENT ${DRIVER_COMPONENT_NAME})
|
COMPONENT ${DRIVER_COMPONENT_NAME})
|
||||||
|
|
|
@ -9,6 +9,7 @@ or GPL2.txt for full copies of the license.
|
||||||
#ifndef __SYSDIGBPF_HELPERS_H
|
#ifndef __SYSDIGBPF_HELPERS_H
|
||||||
#define __SYSDIGBPF_HELPERS_H
|
#define __SYSDIGBPF_HELPERS_H
|
||||||
|
|
||||||
|
#include <linux/compat.h>
|
||||||
#include <net/compat.h>
|
#include <net/compat.h>
|
||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
#include <net/inet_sock.h>
|
#include <net/inet_sock.h>
|
||||||
|
@ -745,7 +746,10 @@ static __always_inline int __bpf_val_to_ring(struct filler_data *data,
|
||||||
|
|
||||||
curoff_bounded = data->state->tail_ctx.curoff & SCRATCH_SIZE_HALF;
|
curoff_bounded = data->state->tail_ctx.curoff & SCRATCH_SIZE_HALF;
|
||||||
if (data->state->tail_ctx.curoff > SCRATCH_SIZE_HALF)
|
if (data->state->tail_ctx.curoff > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (dyn_idx != (u8)-1) {
|
if (dyn_idx != (u8)-1) {
|
||||||
*((u8 *)&data->buf[curoff_bounded]) = dyn_idx;
|
*((u8 *)&data->buf[curoff_bounded]) = dyn_idx;
|
||||||
len_dyn = sizeof(u8);
|
len_dyn = sizeof(u8);
|
||||||
|
@ -755,7 +759,9 @@ static __always_inline int __bpf_val_to_ring(struct filler_data *data,
|
||||||
|
|
||||||
curoff_bounded = data->state->tail_ctx.curoff & SCRATCH_SIZE_HALF;
|
curoff_bounded = data->state->tail_ctx.curoff & SCRATCH_SIZE_HALF;
|
||||||
if (data->state->tail_ctx.curoff > SCRATCH_SIZE_HALF)
|
if (data->state->tail_ctx.curoff > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PT_CHARBUF:
|
case PT_CHARBUF:
|
||||||
|
@ -815,7 +821,9 @@ static __always_inline int __bpf_val_to_ring(struct filler_data *data,
|
||||||
|
|
||||||
curoff_bounded = data->state->tail_ctx.curoff & SCRATCH_SIZE_HALF;
|
curoff_bounded = data->state->tail_ctx.curoff & SCRATCH_SIZE_HALF;
|
||||||
if (data->state->tail_ctx.curoff > SCRATCH_SIZE_HALF)
|
if (data->state->tail_ctx.curoff > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BPF_FORBIDS_ZERO_ACCESS
|
#ifdef BPF_FORBIDS_ZERO_ACCESS
|
||||||
if (read_size)
|
if (read_size)
|
||||||
|
@ -900,7 +908,9 @@ static __always_inline int __bpf_val_to_ring(struct filler_data *data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (len_dyn + len > PPM_MAX_ARG_SIZE)
|
if (len_dyn + len > PPM_MAX_ARG_SIZE)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
fixup_evt_arg_len(data->buf, data->state->tail_ctx.curarg, len_dyn + len);
|
fixup_evt_arg_len(data->buf, data->state->tail_ctx.curarg, len_dyn + len);
|
||||||
data->state->tail_ctx.curoff += len;
|
data->state->tail_ctx.curoff += len;
|
||||||
|
|
|
@ -95,7 +95,7 @@ static __always_inline int __bpf_##x(struct filler_data *data) \
|
||||||
|
|
||||||
FILLER_RAW(terminate_filler)
|
FILLER_RAW(terminate_filler)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_per_cpu_state *state;
|
struct scap_bpf_per_cpu_state *state;
|
||||||
|
|
||||||
state = get_local_state(bpf_get_smp_processor_id());
|
state = get_local_state(bpf_get_smp_processor_id());
|
||||||
if (!state)
|
if (!state)
|
||||||
|
@ -130,6 +130,14 @@ FILLER_RAW(terminate_filler)
|
||||||
break;
|
break;
|
||||||
case PPM_SKIP_EVENT:
|
case PPM_SKIP_EVENT:
|
||||||
break;
|
break;
|
||||||
|
case PPM_FAILURE_FRAME_SCRATCH_MAP_FULL:
|
||||||
|
bpf_printk("PPM_FAILURE_FRAME_SCRATCH_MAP_FULL event=%d curarg=%d\n",
|
||||||
|
state->tail_ctx.evt_type,
|
||||||
|
state->tail_ctx.curarg);
|
||||||
|
if (state->n_drops_scratch_map != ULLONG_MAX) {
|
||||||
|
++state->n_drops_scratch_map;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
bpf_printk("Unknown filler res=%d event=%d curarg=%d\n",
|
bpf_printk("Unknown filler res=%d event=%d curarg=%d\n",
|
||||||
state->tail_ctx.prev_res,
|
state->tail_ctx.prev_res,
|
||||||
|
@ -169,6 +177,43 @@ FILLER(sys_single_x, true)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILLER(sys_open_e, true)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long val;
|
||||||
|
unsigned long mode;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* name
|
||||||
|
*/
|
||||||
|
val = bpf_syscall_get_argument(data, 0);
|
||||||
|
res = bpf_val_to_ring(data, val);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flags
|
||||||
|
* Note that we convert them into the ppm portable representation before pushing them to the ring
|
||||||
|
*/
|
||||||
|
val = bpf_syscall_get_argument(data, 1);
|
||||||
|
flags = open_flags_to_scap(val);
|
||||||
|
res = bpf_val_to_ring(data, flags);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mode
|
||||||
|
*/
|
||||||
|
mode = bpf_syscall_get_argument(data, 2);
|
||||||
|
mode = open_modes_to_scap(val, mode);
|
||||||
|
res = bpf_val_to_ring(data, mode);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
FILLER(sys_open_x, true)
|
FILLER(sys_open_x, true)
|
||||||
{
|
{
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
@ -301,7 +346,9 @@ static __always_inline int bpf_poll_parse_fds(struct filler_data *data,
|
||||||
fds = (struct pollfd *)data->tmp_scratch;
|
fds = (struct pollfd *)data->tmp_scratch;
|
||||||
read_size = nfds * sizeof(struct pollfd);
|
read_size = nfds * sizeof(struct pollfd);
|
||||||
if (read_size > SCRATCH_SIZE_MAX)
|
if (read_size > SCRATCH_SIZE_MAX)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
val = bpf_syscall_get_argument(data, 0);
|
val = bpf_syscall_get_argument(data, 0);
|
||||||
#ifdef BPF_FORBIDS_ZERO_ACCESS
|
#ifdef BPF_FORBIDS_ZERO_ACCESS
|
||||||
|
@ -315,7 +362,9 @@ static __always_inline int bpf_poll_parse_fds(struct filler_data *data,
|
||||||
return PPM_FAILURE_INVALID_USER_MEMORY;
|
return PPM_FAILURE_INVALID_USER_MEMORY;
|
||||||
|
|
||||||
if (data->state->tail_ctx.curoff > SCRATCH_SIZE_HALF)
|
if (data->state->tail_ctx.curoff > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
off = data->state->tail_ctx.curoff + sizeof(u16);
|
off = data->state->tail_ctx.curoff + sizeof(u16);
|
||||||
fds_count = 0;
|
fds_count = 0;
|
||||||
|
@ -323,7 +372,9 @@ static __always_inline int bpf_poll_parse_fds(struct filler_data *data,
|
||||||
#pragma unroll
|
#pragma unroll
|
||||||
for (j = 0; j < POLL_MAXFDS; ++j) {
|
for (j = 0; j < POLL_MAXFDS; ++j) {
|
||||||
if (off > SCRATCH_SIZE_HALF)
|
if (off > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (j == nfds)
|
if (j == nfds)
|
||||||
break;
|
break;
|
||||||
|
@ -338,7 +389,9 @@ static __always_inline int bpf_poll_parse_fds(struct filler_data *data,
|
||||||
*(s64 *)&data->buf[off & SCRATCH_SIZE_HALF] = fds[j].fd;
|
*(s64 *)&data->buf[off & SCRATCH_SIZE_HALF] = fds[j].fd;
|
||||||
off += sizeof(s64);
|
off += sizeof(s64);
|
||||||
if (off > SCRATCH_SIZE_HALF)
|
if (off > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
*(s16 *)&data->buf[off & SCRATCH_SIZE_HALF] = flags;
|
*(s16 *)&data->buf[off & SCRATCH_SIZE_HALF] = flags;
|
||||||
off += sizeof(s16);
|
off += sizeof(s16);
|
||||||
|
@ -410,7 +463,9 @@ static __always_inline int bpf_parse_readv_writev_bufs(struct filler_data *data,
|
||||||
iov = (const struct iovec *)data->tmp_scratch;
|
iov = (const struct iovec *)data->tmp_scratch;
|
||||||
|
|
||||||
if (copylen > SCRATCH_SIZE_MAX)
|
if (copylen > SCRATCH_SIZE_MAX)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BPF_FORBIDS_ZERO_ACCESS
|
#ifdef BPF_FORBIDS_ZERO_ACCESS
|
||||||
if (copylen)
|
if (copylen)
|
||||||
|
@ -907,6 +962,51 @@ FILLER(sys_getrlimit_setrlrimit_x, true)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILLER(sys_connect_e, true)
|
||||||
|
{
|
||||||
|
struct sockaddr *usrsockaddr;
|
||||||
|
unsigned long val;
|
||||||
|
long size = 0;
|
||||||
|
long retval;
|
||||||
|
int err;
|
||||||
|
int res;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = bpf_syscall_get_argument(data, 0);
|
||||||
|
res = bpf_val_to_ring_type(data, fd, PT_FD);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
if (fd >= 0) {
|
||||||
|
usrsockaddr = (struct sockaddr *)bpf_syscall_get_argument(data, 1);
|
||||||
|
val = bpf_syscall_get_argument(data, 2);
|
||||||
|
|
||||||
|
if (usrsockaddr && val != 0) {
|
||||||
|
/*
|
||||||
|
* Copy the address
|
||||||
|
*/
|
||||||
|
err = bpf_addr_to_kernel(usrsockaddr, val,
|
||||||
|
(struct sockaddr *)data->tmp_scratch);
|
||||||
|
if (err >= 0) {
|
||||||
|
/*
|
||||||
|
* Convert the fd into socket endpoint information
|
||||||
|
*/
|
||||||
|
size = bpf_pack_addr(data,
|
||||||
|
(struct sockaddr *)data->tmp_scratch,
|
||||||
|
val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the endpoint info into the ring
|
||||||
|
*/
|
||||||
|
data->curarg_already_on_frame = true;
|
||||||
|
res = bpf_val_to_ring_len(data, 0, size);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
FILLER(sys_connect_x, true)
|
FILLER(sys_connect_x, true)
|
||||||
{
|
{
|
||||||
struct sockaddr *usrsockaddr;
|
struct sockaddr *usrsockaddr;
|
||||||
|
@ -1623,7 +1723,9 @@ static __always_inline int __bpf_append_cgroup(struct css_set *cgroups,
|
||||||
|
|
||||||
off_bounded = off & SCRATCH_SIZE_HALF;
|
off_bounded = off & SCRATCH_SIZE_HALF;
|
||||||
if (off > SCRATCH_SIZE_HALF)
|
if (off > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
int res = bpf_probe_read_str(&buf[off_bounded],
|
int res = bpf_probe_read_str(&buf[off_bounded],
|
||||||
SCRATCH_SIZE_HALF,
|
SCRATCH_SIZE_HALF,
|
||||||
|
@ -1635,7 +1737,9 @@ static __always_inline int __bpf_append_cgroup(struct css_set *cgroups,
|
||||||
|
|
||||||
off_bounded = off & SCRATCH_SIZE_HALF;
|
off_bounded = off & SCRATCH_SIZE_HALF;
|
||||||
if (off > SCRATCH_SIZE_HALF)
|
if (off > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
buf[off_bounded] = '=';
|
buf[off_bounded] = '=';
|
||||||
++off;
|
++off;
|
||||||
|
@ -1656,7 +1760,9 @@ static __always_inline int __bpf_append_cgroup(struct css_set *cgroups,
|
||||||
if (cgroup_path[k]) {
|
if (cgroup_path[k]) {
|
||||||
if (!prev_empty) {
|
if (!prev_empty) {
|
||||||
if (off > SCRATCH_SIZE_HALF)
|
if (off > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
buf[off_bounded] = '/';
|
buf[off_bounded] = '/';
|
||||||
++off;
|
++off;
|
||||||
|
@ -1666,7 +1772,9 @@ static __always_inline int __bpf_append_cgroup(struct css_set *cgroups,
|
||||||
prev_empty = false;
|
prev_empty = false;
|
||||||
|
|
||||||
if (off > SCRATCH_SIZE_HALF)
|
if (off > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
res = bpf_probe_read_str(&buf[off_bounded],
|
res = bpf_probe_read_str(&buf[off_bounded],
|
||||||
SCRATCH_SIZE_HALF,
|
SCRATCH_SIZE_HALF,
|
||||||
|
@ -1684,7 +1792,9 @@ static __always_inline int __bpf_append_cgroup(struct css_set *cgroups,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (off > SCRATCH_SIZE_HALF)
|
if (off > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
buf[off_bounded] = 0;
|
buf[off_bounded] = 0;
|
||||||
++off;
|
++off;
|
||||||
|
@ -1755,7 +1865,9 @@ static __always_inline int bpf_accumulate_argv_or_env(struct filler_data *data,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (off > SCRATCH_SIZE_HALF)
|
if (off > SCRATCH_SIZE_HALF)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
len = bpf_probe_read_str(&data->buf[off & SCRATCH_SIZE_HALF], SCRATCH_SIZE_HALF, arg);
|
len = bpf_probe_read_str(&data->buf[off & SCRATCH_SIZE_HALF], SCRATCH_SIZE_HALF, arg);
|
||||||
if (len == -EFAULT)
|
if (len == -EFAULT)
|
||||||
|
@ -2253,6 +2365,10 @@ FILLER(proc_startupdate_3, true)
|
||||||
long retval;
|
long retval;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
#ifdef __NR_clone3
|
||||||
|
struct clone_args cl_args;
|
||||||
|
#endif
|
||||||
|
|
||||||
retval = bpf_syscall_get_retval(data->ctx);
|
retval = bpf_syscall_get_retval(data->ctx);
|
||||||
|
|
||||||
task = (struct task_struct *)bpf_get_current_task();
|
task = (struct task_struct *)bpf_get_current_task();
|
||||||
|
@ -2262,7 +2378,9 @@ FILLER(proc_startupdate_3, true)
|
||||||
|
|
||||||
if (data->state->tail_ctx.evt_type == PPME_SYSCALL_CLONE_20_X ||
|
if (data->state->tail_ctx.evt_type == PPME_SYSCALL_CLONE_20_X ||
|
||||||
data->state->tail_ctx.evt_type == PPME_SYSCALL_FORK_20_X ||
|
data->state->tail_ctx.evt_type == PPME_SYSCALL_FORK_20_X ||
|
||||||
data->state->tail_ctx.evt_type == PPME_SYSCALL_VFORK_20_X) {
|
data->state->tail_ctx.evt_type == PPME_SYSCALL_VFORK_20_X ||
|
||||||
|
data->state->tail_ctx.evt_type == PPME_SYSCALL_CLONE3_X)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* clone-only parameters
|
* clone-only parameters
|
||||||
*/
|
*/
|
||||||
|
@ -2278,10 +2396,29 @@ FILLER(proc_startupdate_3, true)
|
||||||
/*
|
/*
|
||||||
* flags
|
* flags
|
||||||
*/
|
*/
|
||||||
if (data->state->tail_ctx.evt_type == PPME_SYSCALL_CLONE_20_X)
|
switch (data->state->tail_ctx.evt_type)
|
||||||
|
{
|
||||||
|
case PPME_SYSCALL_CLONE_20_X:
|
||||||
flags = bpf_syscall_get_argument(data, 0);
|
flags = bpf_syscall_get_argument(data, 0);
|
||||||
else
|
break;
|
||||||
|
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
|
#ifdef __NR_clone3
|
||||||
|
flags = bpf_syscall_get_argument(data, 0);
|
||||||
|
if (bpf_probe_read(&cl_args, sizeof(struct clone_args), (void *)flags))
|
||||||
|
{
|
||||||
|
return PPM_FAILURE_INVALID_USER_MEMORY;
|
||||||
|
}
|
||||||
|
flags = cl_args.flags;
|
||||||
|
#else
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
flags = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
flags = clone_flags_to_scap(flags);
|
flags = clone_flags_to_scap(flags);
|
||||||
|
|
||||||
|
@ -2344,7 +2481,7 @@ FILLER(proc_startupdate_3, true)
|
||||||
} else if (data->state->tail_ctx.evt_type == PPME_SYSCALL_EXECVE_19_X ||
|
} else if (data->state->tail_ctx.evt_type == PPME_SYSCALL_EXECVE_19_X ||
|
||||||
data->state->tail_ctx.evt_type == PPME_SYSCALL_EXECVEAT_X) {
|
data->state->tail_ctx.evt_type == PPME_SYSCALL_EXECVEAT_X) {
|
||||||
/*
|
/*
|
||||||
* execve-only parameters
|
* execve family parameters.
|
||||||
*/
|
*/
|
||||||
long env_len = 0;
|
long env_len = 0;
|
||||||
kuid_t loginuid;
|
kuid_t loginuid;
|
||||||
|
@ -2598,24 +2735,24 @@ FILLER(sys_unshare_e, true)
|
||||||
|
|
||||||
FILLER(sys_generic, true)
|
FILLER(sys_generic, true)
|
||||||
{
|
{
|
||||||
long *sysdig_id;
|
long *scap_id;
|
||||||
int native_id;
|
int native_id;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
native_id = bpf_syscall_get_nr(data->ctx);
|
native_id = bpf_syscall_get_nr(data->ctx);
|
||||||
sysdig_id = bpf_map_lookup_elem(&syscall_code_routing_table, &native_id);
|
scap_id = bpf_map_lookup_elem(&syscall_code_routing_table, &native_id);
|
||||||
if (!sysdig_id) {
|
if (!scap_id) {
|
||||||
bpf_printk("no routing for syscall %d\n", native_id);
|
bpf_printk("no routing for syscall %d\n", native_id);
|
||||||
return PPM_FAILURE_BUG;
|
return PPM_FAILURE_BUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*sysdig_id == PPM_SC_UNKNOWN)
|
if (*scap_id == PPM_SC_UNKNOWN)
|
||||||
bpf_printk("no syscall for id %d\n", native_id);
|
bpf_printk("no syscall for id %d\n", native_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* id
|
* id
|
||||||
*/
|
*/
|
||||||
res = bpf_val_to_ring(data, *sysdig_id);
|
res = bpf_val_to_ring(data, *scap_id);
|
||||||
if (res != PPM_SUCCESS)
|
if (res != PPM_SUCCESS)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
@ -2629,6 +2766,54 @@ FILLER(sys_generic, true)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILLER(sys_openat_e, true)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long val;
|
||||||
|
unsigned long mode;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dirfd
|
||||||
|
*/
|
||||||
|
val = bpf_syscall_get_argument(data, 0);
|
||||||
|
if ((int)val == AT_FDCWD)
|
||||||
|
val = PPM_AT_FDCWD;
|
||||||
|
|
||||||
|
res = bpf_val_to_ring(data, val);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* name
|
||||||
|
*/
|
||||||
|
val = bpf_syscall_get_argument(data, 1);
|
||||||
|
res = bpf_val_to_ring(data, val);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flags
|
||||||
|
* Note that we convert them into the ppm portable representation before pushing them to the ring
|
||||||
|
*/
|
||||||
|
val = bpf_syscall_get_argument(data, 2);
|
||||||
|
flags = open_flags_to_scap(val);
|
||||||
|
res = bpf_val_to_ring(data, flags);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mode
|
||||||
|
*/
|
||||||
|
mode = bpf_syscall_get_argument(data, 3);
|
||||||
|
mode = open_modes_to_scap(val, mode);
|
||||||
|
res = bpf_val_to_ring(data, mode);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
FILLER(sys_openat_x, true)
|
FILLER(sys_openat_x, true)
|
||||||
{
|
{
|
||||||
unsigned long dev;
|
unsigned long dev;
|
||||||
|
@ -2692,6 +2877,77 @@ FILLER(sys_openat_x, true)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILLER(sys_openat2_e, true)
|
||||||
|
{
|
||||||
|
unsigned long resolve;
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long val;
|
||||||
|
unsigned long mode;
|
||||||
|
int res;
|
||||||
|
#ifdef __NR_openat2
|
||||||
|
struct open_how how;
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* dirfd
|
||||||
|
*/
|
||||||
|
val = bpf_syscall_get_argument(data, 0);
|
||||||
|
if ((int)val == AT_FDCWD)
|
||||||
|
val = PPM_AT_FDCWD;
|
||||||
|
|
||||||
|
res = bpf_val_to_ring(data, val);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* name
|
||||||
|
*/
|
||||||
|
val = bpf_syscall_get_argument(data, 1);
|
||||||
|
res = bpf_val_to_ring(data, val);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
#ifdef __NR_openat2
|
||||||
|
/*
|
||||||
|
* how: we get the data structure, and put its fields in the buffer one by one
|
||||||
|
*/
|
||||||
|
val = bpf_syscall_get_argument(data, 2);
|
||||||
|
if (bpf_probe_read(&how, sizeof(struct open_how), (void *)val)) {
|
||||||
|
return PPM_FAILURE_INVALID_USER_MEMORY;
|
||||||
|
}
|
||||||
|
flags = open_flags_to_scap(how.flags);
|
||||||
|
mode = open_modes_to_scap(how.flags, how.mode);
|
||||||
|
resolve = openat2_resolve_to_scap(how.resolve);
|
||||||
|
#else
|
||||||
|
flags = 0;
|
||||||
|
mode = 0;
|
||||||
|
resolve = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flags (extracted from open_how structure)
|
||||||
|
* Note that we convert them into the ppm portable representation before pushing them to the ring
|
||||||
|
*/
|
||||||
|
res = bpf_val_to_ring(data, flags);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mode (extracted from open_how structure)
|
||||||
|
* Note that we convert them into the ppm portable representation before pushing them to the ring
|
||||||
|
*/
|
||||||
|
res = bpf_val_to_ring(data, mode);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* resolve (extracted from open_how structure)
|
||||||
|
* Note that we convert them into the ppm portable representation before pushing them to the ring
|
||||||
|
*/
|
||||||
|
res = bpf_val_to_ring(data, resolve);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FILLER(sys_openat2_x, true)
|
FILLER(sys_openat2_x, true)
|
||||||
{
|
{
|
||||||
unsigned long resolve;
|
unsigned long resolve;
|
||||||
|
@ -3404,6 +3660,32 @@ FILLER(sys_sendmsg_x, true)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILLER(sys_creat_e, true)
|
||||||
|
{
|
||||||
|
unsigned long val;
|
||||||
|
unsigned long mode;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* name
|
||||||
|
*/
|
||||||
|
val = bpf_syscall_get_argument(data, 0);
|
||||||
|
res = bpf_val_to_ring(data, val);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mode
|
||||||
|
*/
|
||||||
|
mode = bpf_syscall_get_argument(data, 1);
|
||||||
|
mode = open_modes_to_scap(O_CREAT, mode);
|
||||||
|
res = bpf_val_to_ring(data, mode);
|
||||||
|
if (res != PPM_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
FILLER(sys_creat_x, true)
|
FILLER(sys_creat_x, true)
|
||||||
{
|
{
|
||||||
unsigned long dev;
|
unsigned long dev;
|
||||||
|
@ -4872,4 +5154,67 @@ FILLER(sys_fchmod_x, true)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILLER(sys_copy_file_range_e, true)
|
||||||
|
{
|
||||||
|
int fdin;
|
||||||
|
unsigned long offin;
|
||||||
|
unsigned long len;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fdin
|
||||||
|
*/
|
||||||
|
fdin = bpf_syscall_get_argument(data, 0);
|
||||||
|
res = bpf_val_to_ring(data, fdin);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* offin
|
||||||
|
*/
|
||||||
|
offin = bpf_syscall_get_argument(data, 1);
|
||||||
|
res = bpf_val_to_ring(data, offin);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* len
|
||||||
|
*/
|
||||||
|
len = bpf_syscall_get_argument(data, 4);
|
||||||
|
res = bpf_val_to_ring(data, len);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILLER(sys_copy_file_range_x, true)
|
||||||
|
{
|
||||||
|
int fdout;
|
||||||
|
unsigned long offout;
|
||||||
|
long retval;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
retval = bpf_syscall_get_retval(data->ctx);
|
||||||
|
res = bpf_val_to_ring(data, retval);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fdout
|
||||||
|
*/
|
||||||
|
fdout = bpf_syscall_get_argument(data, 2);
|
||||||
|
res = bpf_val_to_ring(data, fdout);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* offout
|
||||||
|
*/
|
||||||
|
offout = bpf_syscall_get_argument(data, 3);
|
||||||
|
res = bpf_val_to_ring(data, offout);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -79,14 +79,14 @@ struct bpf_map_def __bpf_section("maps") tmp_scratch_map = {
|
||||||
struct bpf_map_def __bpf_section("maps") settings_map = {
|
struct bpf_map_def __bpf_section("maps") settings_map = {
|
||||||
.type = BPF_MAP_TYPE_ARRAY,
|
.type = BPF_MAP_TYPE_ARRAY,
|
||||||
.key_size = sizeof(u32),
|
.key_size = sizeof(u32),
|
||||||
.value_size = sizeof(struct sysdig_bpf_settings),
|
.value_size = sizeof(struct scap_bpf_settings),
|
||||||
.max_entries = 1,
|
.max_entries = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bpf_map_def __bpf_section("maps") local_state_map = {
|
struct bpf_map_def __bpf_section("maps") local_state_map = {
|
||||||
.type = BPF_MAP_TYPE_ARRAY,
|
.type = BPF_MAP_TYPE_ARRAY,
|
||||||
.key_size = sizeof(u32),
|
.key_size = sizeof(u32),
|
||||||
.value_size = sizeof(struct sysdig_bpf_per_cpu_state),
|
.value_size = sizeof(struct scap_bpf_per_cpu_state),
|
||||||
.max_entries = 0,
|
.max_entries = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -228,9 +228,9 @@ static __always_inline const struct ppm_event_entry *get_event_filler_info(enum
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline struct sysdig_bpf_settings *get_bpf_settings(void)
|
static __always_inline struct scap_bpf_settings *get_bpf_settings(void)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings *settings;
|
struct scap_bpf_settings *settings;
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
|
||||||
settings = bpf_map_lookup_elem(&settings_map, &id);
|
settings = bpf_map_lookup_elem(&settings_map, &id);
|
||||||
|
@ -240,9 +240,9 @@ static __always_inline struct sysdig_bpf_settings *get_bpf_settings(void)
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline struct sysdig_bpf_per_cpu_state *get_local_state(unsigned int cpu)
|
static __always_inline struct scap_bpf_per_cpu_state *get_local_state(unsigned int cpu)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_per_cpu_state *state;
|
struct scap_bpf_per_cpu_state *state;
|
||||||
|
|
||||||
state = bpf_map_lookup_elem(&local_state_map, &cpu);
|
state = bpf_map_lookup_elem(&local_state_map, &cpu);
|
||||||
if (!state)
|
if (!state)
|
||||||
|
@ -251,7 +251,7 @@ static __always_inline struct sysdig_bpf_per_cpu_state *get_local_state(unsigned
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline bool acquire_local_state(struct sysdig_bpf_per_cpu_state *state)
|
static __always_inline bool acquire_local_state(struct scap_bpf_per_cpu_state *state)
|
||||||
{
|
{
|
||||||
if (state->in_use) {
|
if (state->in_use) {
|
||||||
bpf_printk("acquire_local_state: already in use\n");
|
bpf_printk("acquire_local_state: already in use\n");
|
||||||
|
@ -262,7 +262,7 @@ static __always_inline bool acquire_local_state(struct sysdig_bpf_per_cpu_state
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline bool release_local_state(struct sysdig_bpf_per_cpu_state *state)
|
static __always_inline bool release_local_state(struct scap_bpf_per_cpu_state *state)
|
||||||
{
|
{
|
||||||
if (!state->in_use) {
|
if (!state->in_use) {
|
||||||
bpf_printk("release_local_state: already not in use\n");
|
bpf_printk("release_local_state: already not in use\n");
|
||||||
|
@ -327,9 +327,9 @@ static __always_inline int bpf_test_bit(int nr, unsigned long *addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline bool drop_event(void *ctx,
|
static __always_inline bool drop_event(void *ctx,
|
||||||
struct sysdig_bpf_per_cpu_state *state,
|
struct scap_bpf_per_cpu_state *state,
|
||||||
enum ppm_event_type evt_type,
|
enum ppm_event_type evt_type,
|
||||||
struct sysdig_bpf_settings *settings,
|
struct scap_bpf_settings *settings,
|
||||||
enum syscall_flags drop_flags)
|
enum syscall_flags drop_flags)
|
||||||
{
|
{
|
||||||
if (!settings->dropping_mode)
|
if (!settings->dropping_mode)
|
||||||
|
@ -422,7 +422,7 @@ static __always_inline bool drop_event(void *ctx,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline void reset_tail_ctx(struct sysdig_bpf_per_cpu_state *state,
|
static __always_inline void reset_tail_ctx(struct scap_bpf_per_cpu_state *state,
|
||||||
enum ppm_event_type evt_type,
|
enum ppm_event_type evt_type,
|
||||||
unsigned long long ts)
|
unsigned long long ts)
|
||||||
{
|
{
|
||||||
|
@ -437,11 +437,11 @@ static __always_inline void reset_tail_ctx(struct sysdig_bpf_per_cpu_state *stat
|
||||||
static __always_inline void call_filler(void *ctx,
|
static __always_inline void call_filler(void *ctx,
|
||||||
void *stack_ctx,
|
void *stack_ctx,
|
||||||
enum ppm_event_type evt_type,
|
enum ppm_event_type evt_type,
|
||||||
struct sysdig_bpf_settings *settings,
|
struct scap_bpf_settings *settings,
|
||||||
enum syscall_flags drop_flags)
|
enum syscall_flags drop_flags)
|
||||||
{
|
{
|
||||||
const struct ppm_event_entry *filler_info;
|
const struct ppm_event_entry *filler_info;
|
||||||
struct sysdig_bpf_per_cpu_state *state;
|
struct scap_bpf_per_cpu_state *state;
|
||||||
unsigned long long pid;
|
unsigned long long pid;
|
||||||
unsigned long long ts;
|
unsigned long long ts;
|
||||||
unsigned int cpu;
|
unsigned int cpu;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Copyright (C) 2021 The Falco Authors.
|
Copyright (C) 2022 The Falco Authors.
|
||||||
|
|
||||||
This file is dual licensed under either the MIT or GPL 2. See MIT.txt
|
This file is dual licensed under either the MIT or GPL 2. See MIT.txt
|
||||||
or GPL2.txt for full copies of the license.
|
or GPL2.txt for full copies of the license.
|
||||||
|
@ -36,7 +36,7 @@ int bpf_##event(struct type *ctx)
|
||||||
BPF_PROBE("raw_syscalls/", sys_enter, sys_enter_args)
|
BPF_PROBE("raw_syscalls/", sys_enter, sys_enter_args)
|
||||||
{
|
{
|
||||||
const struct syscall_evt_pair *sc_evt;
|
const struct syscall_evt_pair *sc_evt;
|
||||||
struct sysdig_bpf_settings *settings;
|
struct scap_bpf_settings *settings;
|
||||||
enum ppm_event_type evt_type;
|
enum ppm_event_type evt_type;
|
||||||
int drop_flags;
|
int drop_flags;
|
||||||
long id;
|
long id;
|
||||||
|
@ -88,7 +88,7 @@ BPF_PROBE("raw_syscalls/", sys_enter, sys_enter_args)
|
||||||
BPF_PROBE("raw_syscalls/", sys_exit, sys_exit_args)
|
BPF_PROBE("raw_syscalls/", sys_exit, sys_exit_args)
|
||||||
{
|
{
|
||||||
const struct syscall_evt_pair *sc_evt;
|
const struct syscall_evt_pair *sc_evt;
|
||||||
struct sysdig_bpf_settings *settings;
|
struct scap_bpf_settings *settings;
|
||||||
enum ppm_event_type evt_type;
|
enum ppm_event_type evt_type;
|
||||||
int drop_flags;
|
int drop_flags;
|
||||||
long id;
|
long id;
|
||||||
|
@ -128,7 +128,7 @@ BPF_PROBE("raw_syscalls/", sys_exit, sys_exit_args)
|
||||||
|
|
||||||
BPF_PROBE("sched/", sched_process_exit, sched_process_exit_args)
|
BPF_PROBE("sched/", sched_process_exit, sched_process_exit_args)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings *settings;
|
struct scap_bpf_settings *settings;
|
||||||
enum ppm_event_type evt_type;
|
enum ppm_event_type evt_type;
|
||||||
struct task_struct *task;
|
struct task_struct *task;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
@ -154,7 +154,7 @@ BPF_PROBE("sched/", sched_process_exit, sched_process_exit_args)
|
||||||
|
|
||||||
BPF_PROBE("sched/", sched_switch, sched_switch_args)
|
BPF_PROBE("sched/", sched_switch, sched_switch_args)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings *settings;
|
struct scap_bpf_settings *settings;
|
||||||
enum ppm_event_type evt_type;
|
enum ppm_event_type evt_type;
|
||||||
|
|
||||||
settings = get_bpf_settings();
|
settings = get_bpf_settings();
|
||||||
|
@ -172,7 +172,7 @@ BPF_PROBE("sched/", sched_switch, sched_switch_args)
|
||||||
|
|
||||||
static __always_inline int bpf_page_fault(struct page_fault_args *ctx)
|
static __always_inline int bpf_page_fault(struct page_fault_args *ctx)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings *settings;
|
struct scap_bpf_settings *settings;
|
||||||
enum ppm_event_type evt_type;
|
enum ppm_event_type evt_type;
|
||||||
|
|
||||||
settings = get_bpf_settings();
|
settings = get_bpf_settings();
|
||||||
|
@ -203,7 +203,7 @@ BPF_PROBE("exceptions/", page_fault_kernel, page_fault_args)
|
||||||
|
|
||||||
BPF_PROBE("signal/", signal_deliver, signal_deliver_args)
|
BPF_PROBE("signal/", signal_deliver, signal_deliver_args)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings *settings;
|
struct scap_bpf_settings *settings;
|
||||||
enum ppm_event_type evt_type;
|
enum ppm_event_type evt_type;
|
||||||
|
|
||||||
settings = get_bpf_settings();
|
settings = get_bpf_settings();
|
||||||
|
@ -223,7 +223,7 @@ BPF_PROBE("signal/", signal_deliver, signal_deliver_args)
|
||||||
__bpf_section(TP_NAME "sched/sched_process_fork")
|
__bpf_section(TP_NAME "sched/sched_process_fork")
|
||||||
int bpf_sched_process_fork(struct sched_process_fork_args *ctx)
|
int bpf_sched_process_fork(struct sched_process_fork_args *ctx)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings *settings;
|
struct scap_bpf_settings *settings;
|
||||||
enum ppm_event_type evt_type;
|
enum ppm_event_type evt_type;
|
||||||
struct sys_stash_args args;
|
struct sys_stash_args args;
|
||||||
unsigned long *argsp;
|
unsigned long *argsp;
|
||||||
|
@ -251,4 +251,10 @@ char kernel_ver[] __bpf_section("kernel_version") = UTS_RELEASE;
|
||||||
|
|
||||||
char __license[] __bpf_section("license") = "GPL";
|
char __license[] __bpf_section("license") = "GPL";
|
||||||
|
|
||||||
char probe_ver[] __bpf_section("probe_version") = PROBE_VERSION;
|
char probe_ver[] __bpf_section("probe_version") = DRIVER_VERSION;
|
||||||
|
|
||||||
|
char probe_commit[] __bpf_section("build_commit") = DRIVER_COMMIT;
|
||||||
|
|
||||||
|
uint64_t probe_api_ver __bpf_section("api_version") = PPM_API_CURRENT_VERSION;
|
||||||
|
|
||||||
|
uint64_t probe_schema_ver __bpf_section("schema_version") = PPM_SCHEMA_CURRENT_VERSION;
|
||||||
|
|
|
@ -54,7 +54,9 @@ static __always_inline int push_evt_frame(void *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->state->tail_ctx.len > PERF_EVENT_MAX_SIZE)
|
if (data->state->tail_ctx.len > PERF_EVENT_MAX_SIZE)
|
||||||
return PPM_FAILURE_BUFFER_FULL;
|
{
|
||||||
|
return PPM_FAILURE_FRAME_SCRATCH_MAP_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
fixup_evt_len(data->buf, data->state->tail_ctx.len);
|
fixup_evt_len(data->buf, data->state->tail_ctx.len);
|
||||||
|
|
||||||
|
@ -81,13 +83,16 @@ static __always_inline int push_evt_frame(void *ctx,
|
||||||
*
|
*
|
||||||
* Schedule a hotplug event on CPU 0
|
* Schedule a hotplug event on CPU 0
|
||||||
*/
|
*/
|
||||||
struct sysdig_bpf_per_cpu_state *state = get_local_state(0);
|
struct scap_bpf_per_cpu_state *state = get_local_state(0);
|
||||||
|
|
||||||
if (!state)
|
if (!state)
|
||||||
return PPM_FAILURE_BUG;
|
return PPM_FAILURE_BUG;
|
||||||
|
|
||||||
state->hotplug_cpu = bpf_get_smp_processor_id();
|
state->hotplug_cpu = bpf_get_smp_processor_id();
|
||||||
bpf_printk("detected hotplug event, cpu=%d\n", state->hotplug_cpu);
|
bpf_printk("detected hotplug event, cpu=%d\n", state->hotplug_cpu);
|
||||||
|
} else if (res == -ENOSPC) {
|
||||||
|
bpf_printk("bpf_perf_buffer full\n");
|
||||||
|
return PPM_FAILURE_BUFFER_FULL;
|
||||||
} else if (res) {
|
} else if (res) {
|
||||||
bpf_printk("bpf_perf_event_output failed, res=%d\n", res);
|
bpf_printk("bpf_perf_event_output failed, res=%d\n", res);
|
||||||
return PPM_FAILURE_BUG;
|
return PPM_FAILURE_BUG;
|
||||||
|
|
|
@ -131,8 +131,8 @@ struct sys_stash_args {
|
||||||
|
|
||||||
struct filler_data {
|
struct filler_data {
|
||||||
void *ctx;
|
void *ctx;
|
||||||
struct sysdig_bpf_settings *settings;
|
struct scap_bpf_settings *settings;
|
||||||
struct sysdig_bpf_per_cpu_state *state;
|
struct scap_bpf_per_cpu_state *state;
|
||||||
char *tmp_scratch;
|
char *tmp_scratch;
|
||||||
const struct ppm_event_info *evt;
|
const struct ppm_event_info *evt;
|
||||||
const struct ppm_event_entry *filler_info;
|
const struct ppm_event_entry *filler_info;
|
||||||
|
@ -171,23 +171,23 @@ struct perf_event_sample {
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
enum sysdig_map_types {
|
enum scap_map_types {
|
||||||
SYSDIG_PERF_MAP = 0,
|
SCAP_PERF_MAP = 0,
|
||||||
SYSDIG_TAIL_MAP = 1,
|
SCAP_TAIL_MAP = 1,
|
||||||
SYSDIG_SYSCALL_CODE_ROUTING_TABLE = 2,
|
SCAP_SYSCALL_CODE_ROUTING_TABLE = 2,
|
||||||
SYSDIG_SYSCALL_TABLE = 3,
|
SCAP_SYSCALL_TABLE = 3,
|
||||||
SYSDIG_EVENT_INFO_TABLE = 4,
|
SCAP_EVENT_INFO_TABLE = 4,
|
||||||
SYSDIG_FILLERS_TABLE = 5,
|
SCAP_FILLERS_TABLE = 5,
|
||||||
SYSDIG_FRAME_SCRATCH_MAP = 6,
|
SCAP_FRAME_SCRATCH_MAP = 6,
|
||||||
SYSDIG_TMP_SCRATCH_MAP = 7,
|
SCAP_TMP_SCRATCH_MAP = 7,
|
||||||
SYSDIG_SETTINGS_MAP = 8,
|
SCAP_SETTINGS_MAP = 8,
|
||||||
SYSDIG_LOCAL_STATE_MAP = 9,
|
SCAP_LOCAL_STATE_MAP = 9,
|
||||||
#ifndef BPF_SUPPORTS_RAW_TRACEPOINTS
|
#ifndef BPF_SUPPORTS_RAW_TRACEPOINTS
|
||||||
SYSDIG_STASH_MAP = 10,
|
SCAP_STASH_MAP = 10,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sysdig_bpf_settings {
|
struct scap_bpf_settings {
|
||||||
uint64_t boot_time;
|
uint64_t boot_time;
|
||||||
void *socket_file_ops;
|
void *socket_file_ops;
|
||||||
uint32_t snaplen;
|
uint32_t snaplen;
|
||||||
|
@ -212,10 +212,11 @@ struct tail_context {
|
||||||
int prev_res;
|
int prev_res;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct sysdig_bpf_per_cpu_state {
|
struct scap_bpf_per_cpu_state {
|
||||||
struct tail_context tail_ctx;
|
struct tail_context tail_ctx;
|
||||||
unsigned long long n_evts;
|
unsigned long long n_evts;
|
||||||
unsigned long long n_drops_buffer;
|
unsigned long long n_drops_buffer;
|
||||||
|
unsigned long long n_drops_scratch_map;
|
||||||
unsigned long long n_drops_pf;
|
unsigned long long n_drops_pf;
|
||||||
unsigned long long n_drops_bug;
|
unsigned long long n_drops_bug;
|
||||||
unsigned int hotplug_cpu;
|
unsigned int hotplug_cpu;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
PACKAGE_NAME="@DRIVER_PACKAGE_NAME@"
|
PACKAGE_NAME="@DRIVER_PACKAGE_NAME@"
|
||||||
PACKAGE_VERSION="@PROBE_VERSION@"
|
PACKAGE_VERSION="@DRIVER_VERSION@"
|
||||||
BUILT_MODULE_NAME[0]="@PROBE_NAME@"
|
BUILT_MODULE_NAME[0]="@DRIVER_NAME@"
|
||||||
DEST_MODULE_LOCATION[0]="/kernel/extra"
|
DEST_MODULE_LOCATION[0]="/kernel/extra"
|
||||||
AUTOINSTALL="yes"
|
AUTOINSTALL="yes"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Copyright (C) 2021 The Falco Authors.
|
Copyright (C) 2022 The Falco Authors.
|
||||||
|
|
||||||
This file is dual licensed under either the MIT or GPL 2. See MIT.txt
|
This file is dual licensed under either the MIT or GPL 2. See MIT.txt
|
||||||
or GPL2.txt for full copies of the license.
|
or GPL2.txt for full copies of the license.
|
||||||
|
@ -8,12 +8,26 @@ or GPL2.txt for full copies of the license.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define PROBE_VERSION "${PROBE_VERSION}"
|
/* taken from driver/API_VERSION */
|
||||||
|
#define PPM_API_CURRENT_VERSION_MAJOR ${PPM_API_CURRENT_VERSION_MAJOR}
|
||||||
|
#define PPM_API_CURRENT_VERSION_MINOR ${PPM_API_CURRENT_VERSION_MINOR}
|
||||||
|
#define PPM_API_CURRENT_VERSION_PATCH ${PPM_API_CURRENT_VERSION_PATCH}
|
||||||
|
|
||||||
#define PROBE_NAME "${PROBE_NAME}"
|
/* taken from driver/SCHEMA_VERSION */
|
||||||
|
#define PPM_SCHEMA_CURRENT_VERSION_MAJOR ${PPM_SCHEMA_CURRENT_VERSION_MAJOR}
|
||||||
|
#define PPM_SCHEMA_CURRENT_VERSION_MINOR ${PPM_SCHEMA_CURRENT_VERSION_MINOR}
|
||||||
|
#define PPM_SCHEMA_CURRENT_VERSION_PATCH ${PPM_SCHEMA_CURRENT_VERSION_PATCH}
|
||||||
|
|
||||||
#define PROBE_DEVICE_NAME "${PROBE_DEVICE_NAME}"
|
#include "ppm_api_version.h"
|
||||||
|
|
||||||
|
#define DRIVER_VERSION "${DRIVER_VERSION}"
|
||||||
|
|
||||||
|
#define DRIVER_NAME "${DRIVER_NAME}"
|
||||||
|
|
||||||
|
#define DRIVER_DEVICE_NAME "${DRIVER_DEVICE_NAME}"
|
||||||
|
|
||||||
|
#define DRIVER_COMMIT "${GIT_COMMIT}"
|
||||||
|
|
||||||
#ifndef KBUILD_MODNAME
|
#ifndef KBUILD_MODNAME
|
||||||
#define KBUILD_MODNAME PROBE_NAME
|
#define KBUILD_MODNAME DRIVER_NAME
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,7 +12,7 @@ or GPL2.txt for full copies of the license.
|
||||||
const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = {
|
const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = {
|
||||||
/* PPME_GENERIC_E */{"syscall", EC_OTHER, EF_NONE, 2, {{"ID", PT_SYSCALLID, PF_DEC}, {"nativeID", PT_UINT16, PF_DEC} } },
|
/* PPME_GENERIC_E */{"syscall", EC_OTHER, EF_NONE, 2, {{"ID", PT_SYSCALLID, PF_DEC}, {"nativeID", PT_UINT16, PF_DEC} } },
|
||||||
/* PPME_GENERIC_X */{"syscall", EC_OTHER, EF_NONE, 1, {{"ID", PT_SYSCALLID, PF_DEC} } },
|
/* PPME_GENERIC_X */{"syscall", EC_OTHER, EF_NONE, 1, {{"ID", PT_SYSCALLID, PF_DEC} } },
|
||||||
/* PPME_SYSCALL_OPEN_E */{"open", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 0},
|
/* PPME_SYSCALL_OPEN_E */{"open", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 3, {{"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT} } },
|
||||||
/* PPME_SYSCALL_OPEN_X */{"open", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX} } },
|
/* PPME_SYSCALL_OPEN_X */{"open", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX} } },
|
||||||
/* PPME_SYSCALL_CLOSE_E */{"close", EC_IO_OTHER, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 1, {{"fd", PT_FD, PF_DEC} } },
|
/* PPME_SYSCALL_CLOSE_E */{"close", EC_IO_OTHER, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 1, {{"fd", PT_FD, PF_DEC} } },
|
||||||
/* PPME_SYSCALL_CLOSE_X */{"close", EC_IO_OTHER, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } },
|
/* PPME_SYSCALL_CLOSE_X */{"close", EC_IO_OTHER, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } },
|
||||||
|
@ -24,15 +24,15 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = {
|
||||||
/* PPME_SYSCALL_BRK_1_X */{"brk", EC_MEMORY, EF_OLD_VERSION, 1, {{"res", PT_UINT64, PF_HEX} } },
|
/* PPME_SYSCALL_BRK_1_X */{"brk", EC_MEMORY, EF_OLD_VERSION, 1, {{"res", PT_UINT64, PF_HEX} } },
|
||||||
/* PPME_SYSCALL_EXECVE_8_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
/* PPME_SYSCALL_EXECVE_8_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
||||||
/* PPME_SYSCALL_EXECVE_8_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 8, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, PF_DEC} } },
|
/* PPME_SYSCALL_EXECVE_8_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 8, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, PF_DEC} } },
|
||||||
/* PPME_CLONE_11_E */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
/* PPME_SYSCALL_CLONE_11_E */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
||||||
/* PPME_CLONE_11_X */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 11, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } },
|
/* PPME_SYSCALL_CLONE_11_X */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 11, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } },
|
||||||
/* PPME_PROCEXIT_E */{"procexit", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
/* PPME_PROCEXIT_E */{"procexit", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
||||||
/* PPME_NA1 */{"NA1", EC_PROCESS, EF_UNUSED, 0},
|
/* PPME_NA1 */{"NA1", EC_PROCESS, EF_UNUSED, 0},
|
||||||
/* PPME_SOCKET_SOCKET_E */{"socket", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE, 3, {{"domain", PT_FLAGS32, PF_DEC, socket_families}, {"type", PT_UINT32, PF_DEC}, {"proto", PT_UINT32, PF_DEC} } },
|
/* PPME_SOCKET_SOCKET_E */{"socket", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE, 3, {{"domain", PT_FLAGS32, PF_DEC, socket_families}, {"type", PT_UINT32, PF_DEC}, {"proto", PT_UINT32, PF_DEC} } },
|
||||||
/* PPME_SOCKET_SOCKET_X */{"socket", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } },
|
/* PPME_SOCKET_SOCKET_X */{"socket", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } },
|
||||||
/* PPME_SOCKET_BIND_E */{"bind", EC_NET, EF_USES_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } },
|
/* PPME_SOCKET_BIND_E */{"bind", EC_NET, EF_USES_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } },
|
||||||
/* PPME_SOCKET_BIND_X */{"bind", EC_NET, EF_USES_FD | EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"addr", PT_SOCKADDR, PF_NA} } },
|
/* PPME_SOCKET_BIND_X */{"bind", EC_NET, EF_USES_FD | EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"addr", PT_SOCKADDR, PF_NA} } },
|
||||||
/* PPME_SOCKET_CONNECT_E */{"connect", EC_NET, EF_USES_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } },
|
/* PPME_SOCKET_CONNECT_E */{"connect", EC_NET, EF_USES_FD | EF_MODIFIES_STATE, 2, {{"fd", PT_FD, PF_DEC}, {"addr", PT_SOCKADDR, PF_NA} } },
|
||||||
/* PPME_SOCKET_CONNECT_X */{"connect", EC_NET, EF_USES_FD | EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA} } },
|
/* PPME_SOCKET_CONNECT_X */{"connect", EC_NET, EF_USES_FD | EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA} } },
|
||||||
/* PPME_SOCKET_LISTEN_E */{"listen", EC_NET, EF_USES_FD, 2, {{"fd", PT_FD, PF_DEC}, {"backlog", PT_UINT32, PF_DEC} } },
|
/* PPME_SOCKET_LISTEN_E */{"listen", EC_NET, EF_USES_FD, 2, {{"fd", PT_FD, PF_DEC}, {"backlog", PT_UINT32, PF_DEC} } },
|
||||||
/* PPME_SOCKET_LISTEN_X */{"listen", EC_NET, EF_USES_FD, 1, {{"res", PT_ERRNO, PF_DEC} } },
|
/* PPME_SOCKET_LISTEN_X */{"listen", EC_NET, EF_USES_FD, 1, {{"res", PT_ERRNO, PF_DEC} } },
|
||||||
|
@ -68,7 +68,7 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = {
|
||||||
/* PPME_SOCKET_RECVMMSG_X */{"recvmmsg", EC_IO_READ, EF_DROP_SIMPLE_CONS, 0},
|
/* PPME_SOCKET_RECVMMSG_X */{"recvmmsg", EC_IO_READ, EF_DROP_SIMPLE_CONS, 0},
|
||||||
/* PPME_SOCKET_ACCEPT4_E */{"accept", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 1, {{"flags", PT_INT32, PF_HEX} } },
|
/* PPME_SOCKET_ACCEPT4_E */{"accept", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 1, {{"flags", PT_INT32, PF_HEX} } },
|
||||||
/* PPME_SOCKET_ACCEPT4_X */{"accept", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 3, {{"fd", PT_FD, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA}, {"queuepct", PT_UINT8, PF_DEC} } },
|
/* PPME_SOCKET_ACCEPT4_X */{"accept", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 3, {{"fd", PT_FD, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA}, {"queuepct", PT_UINT8, PF_DEC} } },
|
||||||
/* PPME_SYSCALL_CREAT_E */{"creat", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 0},
|
/* PPME_SYSCALL_CREAT_E */{"creat", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 2, {{"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT} } },
|
||||||
/* PPME_SYSCALL_CREAT_X */{"creat", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX} } },
|
/* PPME_SYSCALL_CREAT_X */{"creat", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX} } },
|
||||||
/* PPME_SOCKET_PIPE_E */{"pipe", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 0},
|
/* PPME_SOCKET_PIPE_E */{"pipe", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 0},
|
||||||
/* PPME_SOCKET_PIPE_X */{"pipe", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"res", PT_ERRNO, PF_DEC}, {"fd1", PT_FD, PF_DEC}, {"fd2", PT_FD, PF_DEC}, {"ino", PT_UINT64, PF_DEC} } },
|
/* PPME_SOCKET_PIPE_X */{"pipe", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"res", PT_ERRNO, PF_DEC}, {"fd1", PT_FD, PF_DEC}, {"fd2", PT_FD, PF_DEC}, {"ino", PT_UINT64, PF_DEC} } },
|
||||||
|
@ -168,8 +168,8 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = {
|
||||||
/* PPME_SCHEDSWITCH_6_X */{"NA2", EC_SCHEDULER, EF_UNUSED, 0},
|
/* PPME_SCHEDSWITCH_6_X */{"NA2", EC_SCHEDULER, EF_UNUSED, 0},
|
||||||
/* PPME_SYSCALL_EXECVE_13_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
/* PPME_SYSCALL_EXECVE_13_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
||||||
/* PPME_SYSCALL_EXECVE_13_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 13, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } },
|
/* PPME_SYSCALL_EXECVE_13_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 13, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } },
|
||||||
/* PPME_CLONE_16_E */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
/* PPME_SYSCALL_CLONE_16_E */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
||||||
/* PPME_CLONE_16_X */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 16, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } },
|
/* PPME_SYSCALL_CLONE_16_X */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 16, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } },
|
||||||
/* PPME_SYSCALL_BRK_4_E */{"brk", EC_MEMORY, EF_DROP_SIMPLE_CONS, 1, {{"addr", PT_UINT64, PF_HEX} } },
|
/* PPME_SYSCALL_BRK_4_E */{"brk", EC_MEMORY, EF_DROP_SIMPLE_CONS, 1, {{"addr", PT_UINT64, PF_HEX} } },
|
||||||
/* PPME_SYSCALL_BRK_4_X */{"brk", EC_MEMORY, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_UINT64, PF_HEX}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } },
|
/* PPME_SYSCALL_BRK_4_X */{"brk", EC_MEMORY, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_UINT64, PF_HEX}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } },
|
||||||
/* PPME_SYSCALL_MMAP_E */{"mmap", EC_MEMORY, EF_DROP_SIMPLE_CONS, 6, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags}, {"flags", PT_FLAGS32, PF_HEX, mmap_flags}, {"fd", PT_FD, PF_DEC}, {"offset", PT_UINT64, PF_DEC} } },
|
/* PPME_SYSCALL_MMAP_E */{"mmap", EC_MEMORY, EF_DROP_SIMPLE_CONS, 6, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags}, {"flags", PT_FLAGS32, PF_HEX, mmap_flags}, {"fd", PT_FD, PF_DEC}, {"offset", PT_UINT64, PF_DEC} } },
|
||||||
|
@ -228,14 +228,14 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = {
|
||||||
/* PPME_SYSCALL_GETRESGID_X */ {"getresgid", EC_USER, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_ERRNO, PF_DEC}, {"rgid", PT_GID, PF_DEC }, {"egid", PT_GID, PF_DEC }, {"sgid", PT_GID, PF_DEC } } },
|
/* PPME_SYSCALL_GETRESGID_X */ {"getresgid", EC_USER, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_ERRNO, PF_DEC}, {"rgid", PT_GID, PF_DEC }, {"egid", PT_GID, PF_DEC }, {"sgid", PT_GID, PF_DEC } } },
|
||||||
/* PPME_SYSCALL_EXECVE_15_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
/* PPME_SYSCALL_EXECVE_15_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
||||||
/* PPME_SYSCALL_EXECVE_15_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 15, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"env", PT_BYTEBUF, PF_NA} } },
|
/* PPME_SYSCALL_EXECVE_15_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 15, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"env", PT_BYTEBUF, PF_NA} } },
|
||||||
/* PPME_CLONE_17_E */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
/* PPME_SYSCALL_CLONE_17_E */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
||||||
/* PPME_CLONE_17_X */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 17, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } },
|
/* PPME_SYSCALL_CLONE_17_X */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 17, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } },
|
||||||
/* PPME_SYSCALL_FORK_17_E */{"fork", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
/* PPME_SYSCALL_FORK_17_E */{"fork", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
||||||
/* PPME_SYSCALL_FORK_17_X */{"fork", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 17, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } },
|
/* PPME_SYSCALL_FORK_17_X */{"fork", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 17, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } },
|
||||||
/* PPME_SYSCALL_VFORK_17_E */{"vfork", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
/* PPME_SYSCALL_VFORK_17_E */{"vfork", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0},
|
||||||
/* PPME_SYSCALL_VFORK_17_X */{"vfork", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 17, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } },
|
/* PPME_SYSCALL_VFORK_17_X */{"vfork", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 17, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } },
|
||||||
/* PPME_CLONE_20_E */{"clone", EC_PROCESS, EF_MODIFIES_STATE, 0},
|
/* PPME_SYSCALL_CLONE_20_E */{"clone", EC_PROCESS, EF_MODIFIES_STATE, 0},
|
||||||
/* PPME_CLONE_20_X */{"clone", EC_PROCESS, EF_MODIFIES_STATE, 20, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC}, {"vtid", PT_PID, PF_DEC}, {"vpid", PT_PID, PF_DEC} } },
|
/* PPME_SYSCALL_CLONE_20_X */{"clone", EC_PROCESS, EF_MODIFIES_STATE, 20, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC}, {"vtid", PT_PID, PF_DEC}, {"vpid", PT_PID, PF_DEC} } },
|
||||||
/* PPME_SYSCALL_FORK_20_E */{"fork", EC_PROCESS, EF_MODIFIES_STATE, 0},
|
/* PPME_SYSCALL_FORK_20_E */{"fork", EC_PROCESS, EF_MODIFIES_STATE, 0},
|
||||||
/* PPME_SYSCALL_FORK_20_X */{"fork", EC_PROCESS, EF_MODIFIES_STATE, 20, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC}, {"vtid", PT_PID, PF_DEC}, {"vpid", PT_PID, PF_DEC} } },
|
/* PPME_SYSCALL_FORK_20_X */{"fork", EC_PROCESS, EF_MODIFIES_STATE, 20, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC}, {"vtid", PT_PID, PF_DEC}, {"vpid", PT_PID, PF_DEC} } },
|
||||||
/* PPME_SYSCALL_VFORK_20_E */{"vfork", EC_PROCESS, EF_MODIFIES_STATE, 0},
|
/* PPME_SYSCALL_VFORK_20_E */{"vfork", EC_PROCESS, EF_MODIFIES_STATE, 0},
|
||||||
|
@ -318,7 +318,7 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = {
|
||||||
/* PPME_SYSCALL_UNLINKAT_2_X */{"unlinkat", EC_FILE, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, unlinkat_flags} } },
|
/* PPME_SYSCALL_UNLINKAT_2_X */{"unlinkat", EC_FILE, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, unlinkat_flags} } },
|
||||||
/* PPME_SYSCALL_MKDIRAT_E */{"mkdirat", EC_FILE, EF_NONE, 0},
|
/* PPME_SYSCALL_MKDIRAT_E */{"mkdirat", EC_FILE, EF_NONE, 0},
|
||||||
/* PPME_SYSCALL_MKDIRAT_X */{"mkdirat", EC_FILE, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"path", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"mode", PT_UINT32, PF_HEX} } },
|
/* PPME_SYSCALL_MKDIRAT_X */{"mkdirat", EC_FILE, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"path", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"mode", PT_UINT32, PF_HEX} } },
|
||||||
/* PPME_SYSCALL_OPENAT_2_E */{"openat", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 0},
|
/* PPME_SYSCALL_OPENAT_2_E */{"openat", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT} } },
|
||||||
/* PPME_SYSCALL_OPENAT_2_X */{"openat", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX} } },
|
/* PPME_SYSCALL_OPENAT_2_X */{"openat", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX} } },
|
||||||
/* PPME_SYSCALL_LINK_2_E */{"link", EC_FILE, EF_NONE, 0},
|
/* PPME_SYSCALL_LINK_2_E */{"link", EC_FILE, EF_NONE, 0},
|
||||||
/* PPME_SYSCALL_LINK_2_X */{"link", EC_FILE, EF_NONE, 3, {{"res", PT_ERRNO, PF_DEC}, {"oldpath", PT_FSPATH, PF_NA}, {"newpath", PT_FSPATH, PF_NA} } },
|
/* PPME_SYSCALL_LINK_2_X */{"link", EC_FILE, EF_NONE, 3, {{"res", PT_ERRNO, PF_DEC}, {"oldpath", PT_FSPATH, PF_NA}, {"newpath", PT_FSPATH, PF_NA} } },
|
||||||
|
@ -338,12 +338,16 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = {
|
||||||
/* PPME_NA1 */{"pluginevent", EC_OTHER, EF_UNUSED, 0},
|
/* PPME_NA1 */{"pluginevent", EC_OTHER, EF_UNUSED, 0},
|
||||||
/* PPME_CONTAINER_JSON_2_E */{"container", EC_PROCESS, EF_MODIFIES_STATE | EF_LARGE_PAYLOAD, 1, {{"json", PT_CHARBUF, PF_NA} } },
|
/* PPME_CONTAINER_JSON_2_E */{"container", EC_PROCESS, EF_MODIFIES_STATE | EF_LARGE_PAYLOAD, 1, {{"json", PT_CHARBUF, PF_NA} } },
|
||||||
/* PPME_CONTAINER_JSON_2_X */{"container", EC_PROCESS, EF_UNUSED, 0},
|
/* PPME_CONTAINER_JSON_2_X */{"container", EC_PROCESS, EF_UNUSED, 0},
|
||||||
/* PPME_SYSCALL_OPENAT2_E */{"openat2", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 0},
|
/* PPME_SYSCALL_OPENAT2_E */{"openat2", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags} } },
|
||||||
/* PPME_SYSCALL_OPENAT2_X */{"openat2", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags} } },
|
/* PPME_SYSCALL_OPENAT2_X */{"openat2", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags} } },
|
||||||
/* PPME_SYSCALL_MPROTECT_E */{"mprotect", EC_MEMORY, EF_DROP_SIMPLE_CONS, 3, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags} } },
|
/* PPME_SYSCALL_MPROTECT_E */{"mprotect", EC_MEMORY, EF_DROP_SIMPLE_CONS, 3, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags} } },
|
||||||
/* PPME_SYSCALL_MPROTECT_X */{"mprotect", EC_MEMORY, EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } },
|
/* PPME_SYSCALL_MPROTECT_X */{"mprotect", EC_MEMORY, EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } },
|
||||||
/* PPME_SYSCALL_EXECVEAT_E */{"execveat", EC_PROCESS, EF_MODIFIES_STATE, 3, {{"dirfd", PT_FD, PF_DEC}, {"pathname", PT_FSRELPATH, PF_NA, DIRFD_PARAM(0)}, {"flags", PT_FLAGS32, PF_HEX, execveat_flags} } },
|
/* PPME_SYSCALL_EXECVEAT_E */{"execveat", EC_PROCESS, EF_MODIFIES_STATE, 3, {{"dirfd", PT_FD, PF_DEC}, {"pathname", PT_FSRELPATH, PF_NA, DIRFD_PARAM(0)}, {"flags", PT_FLAGS32, PF_HEX, execveat_flags} } },
|
||||||
/* PPME_SYSCALL_EXECVEAT_X */{"execveat", EC_PROCESS, EF_MODIFIES_STATE, 19, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"env", PT_BYTEBUF, PF_NA}, {"tty", PT_INT32, PF_DEC}, {"pgid", PT_PID, PF_DEC}, {"loginuid", PT_INT32, PF_DEC} } },
|
/* PPME_SYSCALL_EXECVEAT_X */{"execveat", EC_PROCESS, EF_MODIFIES_STATE, 20, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"env", PT_BYTEBUF, PF_NA}, {"tty", PT_INT32, PF_DEC}, {"pgid", PT_PID, PF_DEC}, {"loginuid", PT_INT32, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, execve_flags} } },
|
||||||
|
/* PPME_SYSCALL_COPY_FILE_RANGE_E */{"copy_file_range", EC_FILE, EF_USES_FD | EF_READS_FROM_FD | EF_WRITES_TO_FD, 3, {{"fdin", PT_FD, PF_DEC}, {"offin", PT_UINT64, PF_DEC}, {"len", PT_UINT64, PF_DEC} } },
|
||||||
|
/* PPME_SYSCALL_COPY_FILE_RANGE_X */{"copy_file_range", EC_FILE, EF_USES_FD | EF_READS_FROM_FD | EF_WRITES_TO_FD, 3, {{"res", PT_ERRNO, PF_DEC}, {"fdout", PT_FD, PF_DEC}, {"offout", PT_UINT64, PF_DEC} } },
|
||||||
|
/* PPME_SYSCALL_CLONE3_E */{"clone3", EC_PROCESS, EF_MODIFIES_STATE, 0},
|
||||||
|
/* PPME_SYSCALL_CLONE3_X */{"clone3", EC_PROCESS, EF_MODIFIES_STATE, 20, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC}, {"vtid", PT_PID, PF_DEC}, {"vpid", PT_PID, PF_DEC} } },
|
||||||
/* NB: Starting from scap version 1.2, event types will no longer be changed when an event is modified, and the only kind of change permitted for pre-existent events is adding parameters.
|
/* NB: Starting from scap version 1.2, event types will no longer be changed when an event is modified, and the only kind of change permitted for pre-existent events is adding parameters.
|
||||||
* New event types are allowed only for new syscalls or new internal events.
|
* New event types are allowed only for new syscalls or new internal events.
|
||||||
* The number of parameters can be used to differentiate between event versions.
|
* The number of parameters can be used to differentiate between event versions.
|
||||||
|
|
|
@ -30,7 +30,7 @@ or GPL2.txt for full copies of the license.
|
||||||
const struct ppm_event_entry g_ppm_events[PPM_EVENT_MAX] = {
|
const struct ppm_event_entry g_ppm_events[PPM_EVENT_MAX] = {
|
||||||
[PPME_GENERIC_E] = {FILLER_REF(sys_generic)},
|
[PPME_GENERIC_E] = {FILLER_REF(sys_generic)},
|
||||||
[PPME_GENERIC_X] = {FILLER_REF(sys_generic)},
|
[PPME_GENERIC_X] = {FILLER_REF(sys_generic)},
|
||||||
[PPME_SYSCALL_OPEN_E] = {FILLER_REF(sys_empty)},
|
[PPME_SYSCALL_OPEN_E] = {FILLER_REF(sys_open_e)},
|
||||||
[PPME_SYSCALL_OPEN_X] = {FILLER_REF(sys_open_x)},
|
[PPME_SYSCALL_OPEN_X] = {FILLER_REF(sys_open_x)},
|
||||||
[PPME_SYSCALL_CLOSE_E] = {FILLER_REF(sys_single)},
|
[PPME_SYSCALL_CLOSE_E] = {FILLER_REF(sys_single)},
|
||||||
[PPME_SYSCALL_CLOSE_X] = {FILLER_REF(sys_single_x)},
|
[PPME_SYSCALL_CLOSE_X] = {FILLER_REF(sys_single_x)},
|
||||||
|
@ -43,7 +43,7 @@ const struct ppm_event_entry g_ppm_events[PPM_EVENT_MAX] = {
|
||||||
[PPME_SOCKET_SOCKET_X] = {FILLER_REF(sys_socket_x)},
|
[PPME_SOCKET_SOCKET_X] = {FILLER_REF(sys_socket_x)},
|
||||||
[PPME_SOCKET_BIND_E] = {FILLER_REF(sys_autofill), 1, APT_SOCK, {{0} } },
|
[PPME_SOCKET_BIND_E] = {FILLER_REF(sys_autofill), 1, APT_SOCK, {{0} } },
|
||||||
[PPME_SOCKET_BIND_X] = {FILLER_REF(sys_socket_bind_x)},
|
[PPME_SOCKET_BIND_X] = {FILLER_REF(sys_socket_bind_x)},
|
||||||
[PPME_SOCKET_CONNECT_E] = {FILLER_REF(sys_autofill), 1, APT_SOCK, {{0} } },
|
[PPME_SOCKET_CONNECT_E] = {FILLER_REF(sys_connect_e)},
|
||||||
[PPME_SOCKET_CONNECT_X] = {FILLER_REF(sys_connect_x)},
|
[PPME_SOCKET_CONNECT_X] = {FILLER_REF(sys_connect_x)},
|
||||||
[PPME_SOCKET_LISTEN_E] = {FILLER_REF(sys_autofill), 2, APT_SOCK, {{0}, {1} } },
|
[PPME_SOCKET_LISTEN_E] = {FILLER_REF(sys_autofill), 2, APT_SOCK, {{0}, {1} } },
|
||||||
[PPME_SOCKET_LISTEN_X] = {FILLER_REF(sys_single_x)},
|
[PPME_SOCKET_LISTEN_X] = {FILLER_REF(sys_single_x)},
|
||||||
|
@ -78,7 +78,7 @@ const struct ppm_event_entry g_ppm_events[PPM_EVENT_MAX] = {
|
||||||
[PPME_SOCKET_RECVMSG_X] = {FILLER_REF(sys_recvmsg_x)},
|
[PPME_SOCKET_RECVMSG_X] = {FILLER_REF(sys_recvmsg_x)},
|
||||||
[PPME_SOCKET_RECVMMSG_E] = {FILLER_REF(sys_empty)},
|
[PPME_SOCKET_RECVMMSG_E] = {FILLER_REF(sys_empty)},
|
||||||
[PPME_SOCKET_RECVMMSG_X] = {FILLER_REF(sys_empty)},
|
[PPME_SOCKET_RECVMMSG_X] = {FILLER_REF(sys_empty)},
|
||||||
[PPME_SYSCALL_CREAT_E] = {FILLER_REF(sys_empty)},
|
[PPME_SYSCALL_CREAT_E] = {FILLER_REF(sys_creat_e)},
|
||||||
[PPME_SYSCALL_CREAT_X] = {FILLER_REF(sys_creat_x)},
|
[PPME_SYSCALL_CREAT_X] = {FILLER_REF(sys_creat_x)},
|
||||||
[PPME_SYSCALL_PIPE_E] = {FILLER_REF(sys_empty)},
|
[PPME_SYSCALL_PIPE_E] = {FILLER_REF(sys_empty)},
|
||||||
[PPME_SYSCALL_PIPE_X] = {FILLER_REF(sys_pipe_x)},
|
[PPME_SYSCALL_PIPE_X] = {FILLER_REF(sys_pipe_x)},
|
||||||
|
@ -291,7 +291,7 @@ const struct ppm_event_entry g_ppm_events[PPM_EVENT_MAX] = {
|
||||||
[PPME_SYSCALL_UNLINKAT_2_X] = {FILLER_REF(sys_unlinkat_x)},
|
[PPME_SYSCALL_UNLINKAT_2_X] = {FILLER_REF(sys_unlinkat_x)},
|
||||||
[PPME_SYSCALL_MKDIRAT_E] = {FILLER_REF(sys_empty)},
|
[PPME_SYSCALL_MKDIRAT_E] = {FILLER_REF(sys_empty)},
|
||||||
[PPME_SYSCALL_MKDIRAT_X] = {FILLER_REF(sys_mkdirat_x)},
|
[PPME_SYSCALL_MKDIRAT_X] = {FILLER_REF(sys_mkdirat_x)},
|
||||||
[PPME_SYSCALL_OPENAT_2_E] = {FILLER_REF(sys_empty)},
|
[PPME_SYSCALL_OPENAT_2_E] = {FILLER_REF(sys_openat_e)},
|
||||||
[PPME_SYSCALL_OPENAT_2_X] = {FILLER_REF(sys_openat_x)},
|
[PPME_SYSCALL_OPENAT_2_X] = {FILLER_REF(sys_openat_x)},
|
||||||
[PPME_SYSCALL_LINK_2_E] = {FILLER_REF(sys_empty)},
|
[PPME_SYSCALL_LINK_2_E] = {FILLER_REF(sys_empty)},
|
||||||
[PPME_SYSCALL_LINK_2_X] = {FILLER_REF(sys_autofill), 3, APT_REG, {{AF_ID_RETVAL}, {0}, {1} } },
|
[PPME_SYSCALL_LINK_2_X] = {FILLER_REF(sys_autofill), 3, APT_REG, {{AF_ID_RETVAL}, {0}, {1} } },
|
||||||
|
@ -307,11 +307,15 @@ const struct ppm_event_entry g_ppm_events[PPM_EVENT_MAX] = {
|
||||||
[PPME_SYSCALL_RENAMEAT2_X] = {FILLER_REF(sys_renameat2_x)},
|
[PPME_SYSCALL_RENAMEAT2_X] = {FILLER_REF(sys_renameat2_x)},
|
||||||
[PPME_SYSCALL_USERFAULTFD_E] = {FILLER_REF(sys_empty)},
|
[PPME_SYSCALL_USERFAULTFD_E] = {FILLER_REF(sys_empty)},
|
||||||
[PPME_SYSCALL_USERFAULTFD_X] = {FILLER_REF(sys_autofill), 2, APT_REG, {{AF_ID_RETVAL}, {0} } },
|
[PPME_SYSCALL_USERFAULTFD_X] = {FILLER_REF(sys_autofill), 2, APT_REG, {{AF_ID_RETVAL}, {0} } },
|
||||||
[PPME_SYSCALL_OPENAT2_E] = {FILLER_REF(sys_empty)},
|
[PPME_SYSCALL_OPENAT2_E] = {FILLER_REF(sys_openat2_e)},
|
||||||
[PPME_SYSCALL_OPENAT2_X] = {FILLER_REF(sys_openat2_x)},
|
[PPME_SYSCALL_OPENAT2_X] = {FILLER_REF(sys_openat2_x)},
|
||||||
[PPME_SYSCALL_MPROTECT_E] = {FILLER_REF(sys_mprotect_e)},
|
[PPME_SYSCALL_MPROTECT_E] = {FILLER_REF(sys_mprotect_e)},
|
||||||
[PPME_SYSCALL_MPROTECT_X] = {FILLER_REF(sys_mprotect_x)},
|
[PPME_SYSCALL_MPROTECT_X] = {FILLER_REF(sys_mprotect_x)},
|
||||||
[PPME_SYSCALL_EXECVEAT_E] = {FILLER_REF(sys_execveat_e)},
|
[PPME_SYSCALL_EXECVEAT_E] = {FILLER_REF(sys_execveat_e)},
|
||||||
[PPME_SYSCALL_EXECVEAT_X] = {FILLER_REF(proc_startupdate)},
|
[PPME_SYSCALL_EXECVEAT_X] = {FILLER_REF(proc_startupdate)},
|
||||||
|
[PPME_SYSCALL_COPY_FILE_RANGE_E] = {FILLER_REF(sys_copy_file_range_e)},
|
||||||
|
[PPME_SYSCALL_COPY_FILE_RANGE_X] = {FILLER_REF(sys_copy_file_range_x)},
|
||||||
|
[PPME_SYSCALL_CLONE3_E] = {FILLER_REF(sys_empty)},
|
||||||
|
[PPME_SYSCALL_CLONE3_X] = {FILLER_REF(proc_startupdate)},
|
||||||
#endif /* WDIG */
|
#endif /* WDIG */
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Copyright (C) 2021 The Falco Authors.
|
Copyright (C) 2022 The Falco Authors.
|
||||||
|
|
||||||
This file is dual licensed under either the MIT or GPL 2. See MIT.txt
|
This file is dual licensed under either the MIT or GPL 2. See MIT.txt
|
||||||
or GPL2.txt for full copies of the license.
|
or GPL2.txt for full copies of the license.
|
||||||
|
@ -775,13 +775,25 @@ cleanup_ioctl_procinfo:
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto cleanup_ioctl_nolock;
|
goto cleanup_ioctl_nolock;
|
||||||
} else if (cmd == PPM_IOCTL_GET_PROBE_VERSION) {
|
} else if (cmd == PPM_IOCTL_GET_DRIVER_VERSION) {
|
||||||
if (copy_to_user((void *)arg, PROBE_VERSION, sizeof(PROBE_VERSION))) {
|
if (copy_to_user((void *)arg, DRIVER_VERSION, sizeof(DRIVER_VERSION))) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto cleanup_ioctl_nolock;
|
goto cleanup_ioctl_nolock;
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto cleanup_ioctl_nolock;
|
goto cleanup_ioctl_nolock;
|
||||||
|
} else if (cmd == PPM_IOCTL_GET_API_VERSION) {
|
||||||
|
unsigned long long __user *out = (unsigned long long __user *) arg;
|
||||||
|
ret = 0;
|
||||||
|
if(put_user(PPM_API_CURRENT_VERSION, out))
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto cleanup_ioctl_nolock;
|
||||||
|
} else if (cmd == PPM_IOCTL_GET_SCHEMA_VERSION) {
|
||||||
|
unsigned long long __user *out = (unsigned long long __user *) arg;
|
||||||
|
ret = 0;
|
||||||
|
if(put_user(PPM_SCHEMA_CURRENT_VERSION, out))
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto cleanup_ioctl_nolock;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&g_consumer_mutex);
|
mutex_lock(&g_consumer_mutex);
|
||||||
|
@ -2385,15 +2397,15 @@ static int do_cpu_callback(unsigned long cpu, long sd_action)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
|
||||||
static int sysdig_cpu_online(unsigned int cpu)
|
static int scap_cpu_online(unsigned int cpu)
|
||||||
{
|
{
|
||||||
vpr_info("sysdig_cpu_online on cpu %d\n", cpu);
|
vpr_info("scap_cpu_online on cpu %d\n", cpu);
|
||||||
return do_cpu_callback(cpu, 1);
|
return do_cpu_callback(cpu, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sysdig_cpu_offline(unsigned int cpu)
|
static int scap_cpu_offline(unsigned int cpu)
|
||||||
{
|
{
|
||||||
vpr_info("sysdig_cpu_offline on cpu %d\n", cpu);
|
vpr_info("scap_cpu_offline on cpu %d\n", cpu);
|
||||||
return do_cpu_callback(cpu, 2);
|
return do_cpu_callback(cpu, 2);
|
||||||
}
|
}
|
||||||
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) */
|
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) */
|
||||||
|
@ -2435,7 +2447,7 @@ static struct notifier_block cpu_notifier = {
|
||||||
};
|
};
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) */
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) */
|
||||||
|
|
||||||
int sysdig_init(void)
|
int scap_init(void)
|
||||||
{
|
{
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
unsigned int cpu;
|
unsigned int cpu;
|
||||||
|
@ -2452,7 +2464,7 @@ int sysdig_init(void)
|
||||||
#else
|
#else
|
||||||
struct class_device *device = NULL;
|
struct class_device *device = NULL;
|
||||||
#endif
|
#endif
|
||||||
pr_info("driver loading, " PROBE_NAME " " PROBE_VERSION "\n");
|
pr_info("driver loading, " DRIVER_NAME " " DRIVER_VERSION "\n");
|
||||||
|
|
||||||
ret = get_tracepoint_handles();
|
ret = get_tracepoint_handles();
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -2467,14 +2479,14 @@ int sysdig_init(void)
|
||||||
* Initialize the user I/O
|
* Initialize the user I/O
|
||||||
* ( + 1 for sysdig-events)
|
* ( + 1 for sysdig-events)
|
||||||
*/
|
*/
|
||||||
acrret = alloc_chrdev_region(&dev, 0, num_cpus + 1, PROBE_DEVICE_NAME);
|
acrret = alloc_chrdev_region(&dev, 0, num_cpus + 1, DRIVER_DEVICE_NAME);
|
||||||
if (acrret < 0) {
|
if (acrret < 0) {
|
||||||
pr_err("could not allocate major number for %s\n", PROBE_DEVICE_NAME);
|
pr_err("could not allocate major number for %s\n", DRIVER_DEVICE_NAME);
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto init_module_err;
|
goto init_module_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ppm_class = class_create(THIS_MODULE, PROBE_DEVICE_NAME);
|
g_ppm_class = class_create(THIS_MODULE, DRIVER_DEVICE_NAME);
|
||||||
if (IS_ERR(g_ppm_class)) {
|
if (IS_ERR(g_ppm_class)) {
|
||||||
pr_err("can't allocate device class\n");
|
pr_err("can't allocate device class\n");
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
|
@ -2506,7 +2518,7 @@ int sysdig_init(void)
|
||||||
g_ppm_devs[j].dev = MKDEV(g_ppm_major, j);
|
g_ppm_devs[j].dev = MKDEV(g_ppm_major, j);
|
||||||
|
|
||||||
if (cdev_add(&g_ppm_devs[j].cdev, g_ppm_devs[j].dev, 1) < 0) {
|
if (cdev_add(&g_ppm_devs[j].cdev, g_ppm_devs[j].dev, 1) < 0) {
|
||||||
pr_err("could not allocate chrdev for %s\n", PROBE_DEVICE_NAME);
|
pr_err("could not allocate chrdev for %s\n", DRIVER_DEVICE_NAME);
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto init_module_err;
|
goto init_module_err;
|
||||||
}
|
}
|
||||||
|
@ -2519,11 +2531,11 @@ int sysdig_init(void)
|
||||||
g_ppm_class, NULL, /* no parent device */
|
g_ppm_class, NULL, /* no parent device */
|
||||||
g_ppm_devs[j].dev,
|
g_ppm_devs[j].dev,
|
||||||
NULL, /* no additional data */
|
NULL, /* no additional data */
|
||||||
PROBE_DEVICE_NAME "%d",
|
DRIVER_DEVICE_NAME "%d",
|
||||||
j);
|
j);
|
||||||
|
|
||||||
if (IS_ERR(device)) {
|
if (IS_ERR(device)) {
|
||||||
pr_err("error creating the device for %s\n", PROBE_DEVICE_NAME);
|
pr_err("error creating the device for %s\n", DRIVER_DEVICE_NAME);
|
||||||
cdev_del(&g_ppm_devs[j].cdev);
|
cdev_del(&g_ppm_devs[j].cdev);
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto init_module_err;
|
goto init_module_err;
|
||||||
|
@ -2550,9 +2562,9 @@ int sysdig_init(void)
|
||||||
*/
|
*/
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
|
||||||
hp_ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
|
hp_ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
|
||||||
"sysdig/probe:online",
|
DRIVER_NAME "/driver:online",
|
||||||
sysdig_cpu_online,
|
scap_cpu_online,
|
||||||
sysdig_cpu_offline);
|
scap_cpu_offline);
|
||||||
if (hp_ret <= 0) {
|
if (hp_ret <= 0) {
|
||||||
pr_err("error registering cpu hotplug callback\n");
|
pr_err("error registering cpu hotplug callback\n");
|
||||||
ret = hp_ret;
|
ret = hp_ret;
|
||||||
|
@ -2593,7 +2605,7 @@ init_module_err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sysdig_exit(void)
|
void scap_exit(void)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
|
@ -2629,9 +2641,12 @@ void sysdig_exit(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(sysdig_init);
|
module_init(scap_init);
|
||||||
module_exit(sysdig_exit);
|
module_exit(scap_exit);
|
||||||
MODULE_VERSION(PROBE_VERSION);
|
MODULE_VERSION(DRIVER_VERSION);
|
||||||
|
MODULE_INFO(build_commit, DRIVER_COMMIT);
|
||||||
|
MODULE_INFO(api_version, PPM_API_CURRENT_VERSION_STRING);
|
||||||
|
MODULE_INFO(schema_version, PPM_SCHEMA_CURRENT_VERSION_STRING);
|
||||||
|
|
||||||
module_param(max_consumers, uint, 0444);
|
module_param(max_consumers, uint, 0444);
|
||||||
MODULE_PARM_DESC(max_consumers, "Maximum number of consumers that can simultaneously open the devices");
|
MODULE_PARM_DESC(max_consumers, "Maximum number of consumers that can simultaneously open the devices");
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef PPM_API_VERSION_H
|
||||||
|
#define PPM_API_VERSION_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* API version component macros
|
||||||
|
*
|
||||||
|
* The version is a single uint64_t, structured as follows:
|
||||||
|
* bit 63: unused (so the version number is always positive)
|
||||||
|
* bits 44-62: major version
|
||||||
|
* bits 24-43: minor version
|
||||||
|
* bits 0-23: patch version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PPM_VERSION_PACK(val, bits, shift) ((((unsigned long long)(val)) & ((1ULL << (bits)) - 1)) << (shift))
|
||||||
|
#define PPM_VERSION_UNPACK(val, bits, shift) ((((unsigned long long)(val)) >> (shift)) & ((1ULL << (bits)) - 1))
|
||||||
|
|
||||||
|
/* extract components from an API version number */
|
||||||
|
#define PPM_API_VERSION_MAJOR(ver) PPM_VERSION_UNPACK(ver, 19, 44)
|
||||||
|
#define PPM_API_VERSION_MINOR(ver) PPM_VERSION_UNPACK(ver, 20, 24)
|
||||||
|
#define PPM_API_VERSION_PATCH(ver) PPM_VERSION_UNPACK(ver, 24, 0)
|
||||||
|
|
||||||
|
/* build an API version number from components */
|
||||||
|
#define PPM_API_VERSION(major, minor, patch) \
|
||||||
|
PPM_VERSION_PACK(major, 19, 44) | \
|
||||||
|
PPM_VERSION_PACK(minor, 20, 24) | \
|
||||||
|
PPM_VERSION_PACK(patch, 24, 0)
|
||||||
|
|
||||||
|
#define PPM_API_CURRENT_VERSION PPM_API_VERSION( \
|
||||||
|
PPM_API_CURRENT_VERSION_MAJOR, \
|
||||||
|
PPM_API_CURRENT_VERSION_MINOR, \
|
||||||
|
PPM_API_CURRENT_VERSION_PATCH)
|
||||||
|
|
||||||
|
#define PPM_SCHEMA_CURRENT_VERSION PPM_API_VERSION( \
|
||||||
|
PPM_SCHEMA_CURRENT_VERSION_MAJOR, \
|
||||||
|
PPM_SCHEMA_CURRENT_VERSION_MINOR, \
|
||||||
|
PPM_SCHEMA_CURRENT_VERSION_PATCH)
|
||||||
|
|
||||||
|
#define __PPM_STRINGIFY1(x) #x
|
||||||
|
#define __PPM_STRINGIFY(x) __PPM_STRINGIFY1(x)
|
||||||
|
|
||||||
|
#define PPM_API_CURRENT_VERSION_STRING \
|
||||||
|
__PPM_STRINGIFY(PPM_API_CURRENT_VERSION_MAJOR) "." \
|
||||||
|
__PPM_STRINGIFY(PPM_API_CURRENT_VERSION_MINOR) "." \
|
||||||
|
__PPM_STRINGIFY(PPM_API_CURRENT_VERSION_PATCH)
|
||||||
|
|
||||||
|
#define PPM_SCHEMA_CURRENT_VERSION_STRING \
|
||||||
|
__PPM_STRINGIFY(PPM_SCHEMA_CURRENT_VERSION_MAJOR) "." \
|
||||||
|
__PPM_STRINGIFY(PPM_SCHEMA_CURRENT_VERSION_MINOR) "." \
|
||||||
|
__PPM_STRINGIFY(PPM_SCHEMA_CURRENT_VERSION_PATCH)
|
||||||
|
|
||||||
|
#endif
|
|
@ -358,10 +358,12 @@
|
||||||
#define __NR_ia32_userfaultfd 350
|
#define __NR_ia32_userfaultfd 350
|
||||||
#define __NR_ia32_openat2 351
|
#define __NR_ia32_openat2 351
|
||||||
#define __NR_ia32_execveat 352
|
#define __NR_ia32_execveat 352
|
||||||
|
#define __NR_ia32_copy_file_range 353
|
||||||
|
#define __NR_ia32_clone3 354
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#define NR_ia32_syscalls 353
|
#define NR_ia32_syscalls 355
|
||||||
|
|
||||||
#define __ARCH_WANT_IPC_PARSE_VERSION
|
#define __ARCH_WANT_IPC_PARSE_VERSION
|
||||||
#define __ARCH_WANT_OLD_READDIR
|
#define __ARCH_WANT_OLD_READDIR
|
||||||
|
|
|
@ -606,7 +606,7 @@ or GPL2.txt for full copies of the license.
|
||||||
#define PPM_RESOLVE_CACHED (1 << 5)
|
#define PPM_RESOLVE_CACHED (1 << 5)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execve additional flags
|
* Execve family additional flags.
|
||||||
*/
|
*/
|
||||||
#define PPM_EXE_WRITABLE (1 << 0)
|
#define PPM_EXE_WRITABLE (1 << 0)
|
||||||
|
|
||||||
|
@ -992,7 +992,11 @@ enum ppm_event_type {
|
||||||
PPME_SYSCALL_MPROTECT_X = 329,
|
PPME_SYSCALL_MPROTECT_X = 329,
|
||||||
PPME_SYSCALL_EXECVEAT_E = 330,
|
PPME_SYSCALL_EXECVEAT_E = 330,
|
||||||
PPME_SYSCALL_EXECVEAT_X = 331,
|
PPME_SYSCALL_EXECVEAT_X = 331,
|
||||||
PPM_EVENT_MAX = 332
|
PPME_SYSCALL_COPY_FILE_RANGE_E = 332,
|
||||||
|
PPME_SYSCALL_COPY_FILE_RANGE_X = 333,
|
||||||
|
PPME_SYSCALL_CLONE3_E = 334,
|
||||||
|
PPME_SYSCALL_CLONE3_X = 335,
|
||||||
|
PPM_EVENT_MAX = 336
|
||||||
};
|
};
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
@ -1326,7 +1330,10 @@ enum ppm_syscall_code {
|
||||||
PPM_SC_UMOUNT2 = 323,
|
PPM_SC_UMOUNT2 = 323,
|
||||||
PPM_SC_EXECVE = 324,
|
PPM_SC_EXECVE = 324,
|
||||||
PPM_SC_EXECVEAT = 325,
|
PPM_SC_EXECVEAT = 325,
|
||||||
PPM_SC_MAX = 326,
|
PPM_SC_COPY_FILE_RANGE = 326,
|
||||||
|
PPM_SC_CLONE = 327,
|
||||||
|
PPM_SC_CLONE3 = 328,
|
||||||
|
PPM_SC_MAX = 329,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1518,9 +1525,11 @@ struct ppm_evt_hdr {
|
||||||
#define PPM_IOCTL_SET_SIMPLE_MODE _IO(PPM_IOCTL_MAGIC, 18)
|
#define PPM_IOCTL_SET_SIMPLE_MODE _IO(PPM_IOCTL_MAGIC, 18)
|
||||||
#define PPM_IOCTL_ENABLE_PAGE_FAULTS _IO(PPM_IOCTL_MAGIC, 19)
|
#define PPM_IOCTL_ENABLE_PAGE_FAULTS _IO(PPM_IOCTL_MAGIC, 19)
|
||||||
#define PPM_IOCTL_GET_N_TRACEPOINT_HIT _IO(PPM_IOCTL_MAGIC, 20)
|
#define PPM_IOCTL_GET_N_TRACEPOINT_HIT _IO(PPM_IOCTL_MAGIC, 20)
|
||||||
#define PPM_IOCTL_GET_PROBE_VERSION _IO(PPM_IOCTL_MAGIC, 21)
|
#define PPM_IOCTL_GET_DRIVER_VERSION _IO(PPM_IOCTL_MAGIC, 21)
|
||||||
#define PPM_IOCTL_SET_FULLCAPTURE_PORT_RANGE _IO(PPM_IOCTL_MAGIC, 22)
|
#define PPM_IOCTL_SET_FULLCAPTURE_PORT_RANGE _IO(PPM_IOCTL_MAGIC, 22)
|
||||||
#define PPM_IOCTL_SET_STATSD_PORT _IO(PPM_IOCTL_MAGIC, 23)
|
#define PPM_IOCTL_SET_STATSD_PORT _IO(PPM_IOCTL_MAGIC, 23)
|
||||||
|
#define PPM_IOCTL_GET_API_VERSION _IO(PPM_IOCTL_MAGIC, 24)
|
||||||
|
#define PPM_IOCTL_GET_SCHEMA_VERSION _IO(PPM_IOCTL_MAGIC, 25)
|
||||||
#endif // CYGWING_AGENT
|
#endif // CYGWING_AGENT
|
||||||
|
|
||||||
extern const struct ppm_name_value socket_families[];
|
extern const struct ppm_name_value socket_families[];
|
||||||
|
@ -1663,6 +1672,7 @@ struct ppm_event_entry {
|
||||||
#define PPM_FAILURE_INVALID_USER_MEMORY -2
|
#define PPM_FAILURE_INVALID_USER_MEMORY -2
|
||||||
#define PPM_FAILURE_BUG -3
|
#define PPM_FAILURE_BUG -3
|
||||||
#define PPM_SKIP_EVENT -4
|
#define PPM_SKIP_EVENT -4
|
||||||
|
#define PPM_FAILURE_FRAME_SCRATCH_MAP_FULL -5 /* this is used only inside bpf, kernel module does not have a frame scratch map*/
|
||||||
|
|
||||||
#define RW_SNAPLEN 80
|
#define RW_SNAPLEN 80
|
||||||
#define RW_MAX_SNAPLEN PPM_MAX_ARG_SIZE
|
#define RW_MAX_SNAPLEN PPM_MAX_ARG_SIZE
|
||||||
|
|
|
@ -236,6 +236,47 @@ out_unlock:
|
||||||
#endif /* UDIG */
|
#endif /* UDIG */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int f_sys_open_e(struct event_filler_arguments *args)
|
||||||
|
{
|
||||||
|
syscall_arg_t val;
|
||||||
|
syscall_arg_t flags;
|
||||||
|
syscall_arg_t modes;
|
||||||
|
char *name = NULL;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* name
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 0, 1, &val);
|
||||||
|
if(likely(ppm_strncpy_from_user(args->str_storage, (const void __user *)val, PPM_MAX_PATH_SIZE) >= 0))
|
||||||
|
{
|
||||||
|
name = args->str_storage;
|
||||||
|
name[PPM_MAX_PATH_SIZE - 1] = '\0';
|
||||||
|
}
|
||||||
|
res = val_to_ring(args, (int64_t)(long)name, 0, false, 0);
|
||||||
|
if(unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flags
|
||||||
|
* Note that we convert them into the ppm portable representation before pushing them to the ring
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 1, 1, &flags);
|
||||||
|
res = val_to_ring(args, open_flags_to_scap(flags), 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mode
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 2, 1, &modes);
|
||||||
|
res = val_to_ring(args, open_modes_to_scap(flags, modes), 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return add_sentinel(args);
|
||||||
|
}
|
||||||
|
|
||||||
int f_sys_open_x(struct event_filler_arguments *args)
|
int f_sys_open_x(struct event_filler_arguments *args)
|
||||||
{
|
{
|
||||||
syscall_arg_t val;
|
syscall_arg_t val;
|
||||||
|
@ -759,6 +800,10 @@ int f_proc_startupdate(struct event_filler_arguments *args)
|
||||||
long swap = 0;
|
long swap = 0;
|
||||||
int available = STR_STORAGE_SIZE;
|
int available = STR_STORAGE_SIZE;
|
||||||
|
|
||||||
|
#ifdef __NR_clone3
|
||||||
|
struct clone_args cl_args;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure the operation was successful
|
* Make sure the operation was successful
|
||||||
*/
|
*/
|
||||||
|
@ -837,6 +882,7 @@ int f_proc_startupdate(struct event_filler_arguments *args)
|
||||||
|
|
||||||
case PPME_SYSCALL_EXECVEAT_X:
|
case PPME_SYSCALL_EXECVEAT_X:
|
||||||
syscall_get_arguments_deprecated(current, args->regs, 2, 1, &val);
|
syscall_get_arguments_deprecated(current, args->regs, 2, 1, &val);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
val = 0;
|
val = 0;
|
||||||
|
@ -993,7 +1039,9 @@ cgroups_error:
|
||||||
|
|
||||||
if (args->event_type == PPME_SYSCALL_CLONE_20_X ||
|
if (args->event_type == PPME_SYSCALL_CLONE_20_X ||
|
||||||
args->event_type == PPME_SYSCALL_FORK_20_X ||
|
args->event_type == PPME_SYSCALL_FORK_20_X ||
|
||||||
args->event_type == PPME_SYSCALL_VFORK_20_X) {
|
args->event_type == PPME_SYSCALL_VFORK_20_X ||
|
||||||
|
args->event_type == PPME_SYSCALL_CLONE3_X)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* clone-only parameters
|
* clone-only parameters
|
||||||
*/
|
*/
|
||||||
|
@ -1015,14 +1063,34 @@ cgroups_error:
|
||||||
/*
|
/*
|
||||||
* flags
|
* flags
|
||||||
*/
|
*/
|
||||||
if (args->event_type == PPME_SYSCALL_CLONE_20_X) {
|
switch (args->event_type)
|
||||||
|
{
|
||||||
|
case PPME_SYSCALL_CLONE_20_X:
|
||||||
#ifdef CONFIG_S390
|
#ifdef CONFIG_S390
|
||||||
syscall_get_arguments_deprecated(current, args->regs, 1, 1, &val);
|
syscall_get_arguments_deprecated(current, args->regs, 1, 1, &val);
|
||||||
#else
|
#else
|
||||||
syscall_get_arguments_deprecated(current, args->regs, 0, 1, &val);
|
syscall_get_arguments_deprecated(current, args->regs, 0, 1, &val);
|
||||||
#endif
|
#endif
|
||||||
} else
|
break;
|
||||||
|
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
|
#ifdef __NR_clone3
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 0, 1, &val);
|
||||||
|
res = ppm_copy_from_user(&cl_args, (void *)val, sizeof(struct clone_args));
|
||||||
|
if (unlikely(res != 0))
|
||||||
|
{
|
||||||
|
return PPM_FAILURE_INVALID_USER_MEMORY;
|
||||||
|
}
|
||||||
|
val = cl_args.flags;
|
||||||
|
#else
|
||||||
val = 0;
|
val = 0;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
val = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20)
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20)
|
||||||
if(pidns != &init_pid_ns || pid_ns_for_children(current) != pidns)
|
if(pidns != &init_pid_ns || pid_ns_for_children(current) != pidns)
|
||||||
|
@ -1073,7 +1141,7 @@ cgroups_error:
|
||||||
} else if (args->event_type == PPME_SYSCALL_EXECVE_19_X ||
|
} else if (args->event_type == PPME_SYSCALL_EXECVE_19_X ||
|
||||||
args->event_type == PPME_SYSCALL_EXECVEAT_X) {
|
args->event_type == PPME_SYSCALL_EXECVEAT_X) {
|
||||||
/*
|
/*
|
||||||
* execve-only parameters
|
* execve family parameters.
|
||||||
*/
|
*/
|
||||||
long env_len = 0;
|
long env_len = 0;
|
||||||
int tty_nr = 0;
|
int tty_nr = 0;
|
||||||
|
@ -1193,9 +1261,10 @@ cgroups_error:
|
||||||
flags |= PPM_EXE_WRITABLE;
|
flags |= PPM_EXE_WRITABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write all the additional flags for execve family here...
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* flags
|
* flags
|
||||||
* Write all the additional flags for execve
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
res = val_to_ring(args, flags, 0, false, 0);
|
res = val_to_ring(args, flags, 0, false, 0);
|
||||||
|
@ -1347,6 +1416,84 @@ int f_sys_socket_bind_x(struct event_filler_arguments *args)
|
||||||
return add_sentinel(args);
|
return add_sentinel(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int f_sys_connect_e(struct event_filler_arguments *args)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
int err = 0;
|
||||||
|
int fd;
|
||||||
|
struct sockaddr __user *usrsockaddr;
|
||||||
|
u16 size = 0;
|
||||||
|
char *targetbuf = args->str_storage;
|
||||||
|
struct sockaddr_storage address;
|
||||||
|
syscall_arg_t val;
|
||||||
|
|
||||||
|
if (!args->is_socketcall) {
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 0, 1, &val);
|
||||||
|
fd = (int)val;
|
||||||
|
}
|
||||||
|
#ifndef UDIG
|
||||||
|
else
|
||||||
|
fd = (int)args->socketcall_args[0];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
res = val_to_ring(args, fd, 0, true, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
if (fd >= 0) {
|
||||||
|
/*
|
||||||
|
* Get the address
|
||||||
|
*/
|
||||||
|
if (!args->is_socketcall)
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 1, 1, &val);
|
||||||
|
#ifndef UDIG
|
||||||
|
else
|
||||||
|
val = args->socketcall_args[1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
usrsockaddr = (struct sockaddr __user *)val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the address len
|
||||||
|
*/
|
||||||
|
if (!args->is_socketcall)
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 2, 1, &val);
|
||||||
|
#ifndef UDIG
|
||||||
|
else
|
||||||
|
val = args->socketcall_args[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (usrsockaddr != NULL && val != 0) {
|
||||||
|
/*
|
||||||
|
* Copy the address
|
||||||
|
*/
|
||||||
|
err = addr_to_kernel(usrsockaddr, val, (struct sockaddr *)&address);
|
||||||
|
if (likely(err >= 0)) {
|
||||||
|
/*
|
||||||
|
* Convert the fd into socket endpoint information
|
||||||
|
*/
|
||||||
|
size = pack_addr((struct sockaddr *)&address,
|
||||||
|
val,
|
||||||
|
targetbuf,
|
||||||
|
STR_STORAGE_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the endpoint info into the ring
|
||||||
|
*/
|
||||||
|
res = val_to_ring(args,
|
||||||
|
(uint64_t)targetbuf,
|
||||||
|
size,
|
||||||
|
false,
|
||||||
|
0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return add_sentinel(args);
|
||||||
|
}
|
||||||
|
|
||||||
int f_sys_connect_x(struct event_filler_arguments *args)
|
int f_sys_connect_x(struct event_filler_arguments *args)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
@ -2585,6 +2732,37 @@ int f_sys_recvmsg_x(struct event_filler_arguments *args)
|
||||||
return add_sentinel(args);
|
return add_sentinel(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int f_sys_creat_e(struct event_filler_arguments *args)
|
||||||
|
{
|
||||||
|
unsigned long val;
|
||||||
|
unsigned long modes;
|
||||||
|
char *name = NULL;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* name
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 0, 1, &val);
|
||||||
|
if(likely(ppm_strncpy_from_user(args->str_storage, (const void __user *)val, PPM_MAX_PATH_SIZE) >= 0))
|
||||||
|
{
|
||||||
|
name = args->str_storage;
|
||||||
|
name[PPM_MAX_PATH_SIZE - 1] = '\0';
|
||||||
|
}
|
||||||
|
res = val_to_ring(args, (int64_t)(long)name, 0, false, 0);
|
||||||
|
if(unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mode
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 1, 1, &modes);
|
||||||
|
res = val_to_ring(args, open_modes_to_scap(O_CREAT, modes), 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return add_sentinel(args);
|
||||||
|
}
|
||||||
|
|
||||||
int f_sys_creat_x(struct event_filler_arguments *args)
|
int f_sys_creat_x(struct event_filler_arguments *args)
|
||||||
{
|
{
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
|
@ -3057,6 +3235,59 @@ int f_sys_mount_e(struct event_filler_arguments *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WDIG
|
#ifndef WDIG
|
||||||
|
int f_sys_openat_e(struct event_filler_arguments *args)
|
||||||
|
{
|
||||||
|
unsigned long val;
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long modes;
|
||||||
|
char *name = NULL;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dirfd
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 0, 1, &val);
|
||||||
|
|
||||||
|
if ((int)val == AT_FDCWD)
|
||||||
|
val = PPM_AT_FDCWD;
|
||||||
|
|
||||||
|
res = val_to_ring(args, val, 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* name
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 1, 1, &val);
|
||||||
|
if(likely(ppm_strncpy_from_user(args->str_storage, (const void __user *)val, PPM_MAX_PATH_SIZE) >= 0))
|
||||||
|
{
|
||||||
|
name = args->str_storage;
|
||||||
|
name[PPM_MAX_PATH_SIZE - 1] = '\0';
|
||||||
|
}
|
||||||
|
res = val_to_ring(args, (int64_t)(long)name, 0, false, 0);
|
||||||
|
if(unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flags
|
||||||
|
* Note that we convert them into the ppm portable representation before pushing them to the ring
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 2, 1, &flags);
|
||||||
|
res = val_to_ring(args, open_flags_to_scap(flags), 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mode
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 3, 1, &modes);
|
||||||
|
res = val_to_ring(args, open_modes_to_scap(flags, modes), 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return add_sentinel(args);
|
||||||
|
}
|
||||||
|
|
||||||
int f_sys_openat_x(struct event_filler_arguments *args)
|
int f_sys_openat_x(struct event_filler_arguments *args)
|
||||||
{
|
{
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
|
@ -4373,6 +4604,88 @@ int f_sys_symlinkat_x(struct event_filler_arguments *args)
|
||||||
return add_sentinel(args);
|
return add_sentinel(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int f_sys_openat2_e(struct event_filler_arguments *args)
|
||||||
|
{
|
||||||
|
unsigned long resolve;
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long val;
|
||||||
|
unsigned long mode;
|
||||||
|
char *name = NULL;
|
||||||
|
int res;
|
||||||
|
#ifdef __NR_openat2
|
||||||
|
struct open_how how;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dirfd
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 0, 1, &val);
|
||||||
|
|
||||||
|
if ((int)val == AT_FDCWD)
|
||||||
|
val = PPM_AT_FDCWD;
|
||||||
|
|
||||||
|
res = val_to_ring(args, val, 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* name
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 1, 1, &val);
|
||||||
|
if(likely(ppm_strncpy_from_user(args->str_storage, (const void __user *)val, PPM_MAX_PATH_SIZE) >= 0))
|
||||||
|
{
|
||||||
|
name = args->str_storage;
|
||||||
|
name[PPM_MAX_PATH_SIZE - 1] = '\0';
|
||||||
|
}
|
||||||
|
res = val_to_ring(args, (int64_t)(long)name, 0, false, 0);
|
||||||
|
if(unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NR_openat2
|
||||||
|
/*
|
||||||
|
* how: we get the data structure, and put its fields in the buffer one by one
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 2, 1, &val);
|
||||||
|
res = ppm_copy_from_user(&how, (void *)val, sizeof(struct open_how));
|
||||||
|
if (unlikely(res != 0))
|
||||||
|
return PPM_FAILURE_INVALID_USER_MEMORY;
|
||||||
|
|
||||||
|
flags = open_flags_to_scap(how.flags);
|
||||||
|
mode = open_modes_to_scap(how.flags, how.mode);
|
||||||
|
resolve = openat2_resolve_to_scap(how.resolve);
|
||||||
|
#else
|
||||||
|
flags = 0;
|
||||||
|
mode = 0;
|
||||||
|
resolve = 0;
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* flags (extracted from open_how structure)
|
||||||
|
* Note that we convert them into the ppm portable representation before pushing them to the ring
|
||||||
|
*/
|
||||||
|
res = val_to_ring(args, flags, 0, true, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mode (extracted from open_how structure)
|
||||||
|
* Note that we convert them into the ppm portable representation before pushing them to the ring
|
||||||
|
*/
|
||||||
|
res = val_to_ring(args, mode, 0, true, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* resolve (extracted from open_how structure)
|
||||||
|
* Note that we convert them into the ppm portable representation before pushing them to the ring
|
||||||
|
*/
|
||||||
|
res = val_to_ring(args, resolve, 0, true, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return add_sentinel(args);
|
||||||
|
}
|
||||||
|
|
||||||
int f_sys_openat2_x(struct event_filler_arguments *args)
|
int f_sys_openat2_x(struct event_filler_arguments *args)
|
||||||
{
|
{
|
||||||
unsigned long resolve;
|
unsigned long resolve;
|
||||||
|
@ -4454,6 +4767,71 @@ int f_sys_openat2_x(struct event_filler_arguments *args)
|
||||||
|
|
||||||
return add_sentinel(args);
|
return add_sentinel(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int f_sys_copy_file_range_e(struct event_filler_arguments *args)
|
||||||
|
{
|
||||||
|
unsigned long fdin;
|
||||||
|
unsigned long offin;
|
||||||
|
unsigned long len;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fdin
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 0, 1, &fdin);
|
||||||
|
res = val_to_ring(args, fdin, 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* offin
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 1, 1, &offin);
|
||||||
|
res = val_to_ring(args, offin, 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* len
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 4, 1, &len);
|
||||||
|
res = val_to_ring(args, len, 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return add_sentinel(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
int f_sys_copy_file_range_x(struct event_filler_arguments *args)
|
||||||
|
{
|
||||||
|
unsigned long fdout;
|
||||||
|
unsigned long offout;
|
||||||
|
int64_t retval;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
retval = (int64_t)syscall_get_return_value(current, args->regs);
|
||||||
|
res = val_to_ring(args, retval, 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fdout
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 2, 1, &fdout);
|
||||||
|
res = val_to_ring(args, fdout, 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* offout
|
||||||
|
*/
|
||||||
|
syscall_get_arguments_deprecated(current, args->regs, 3, 1, &offout);
|
||||||
|
res = val_to_ring(args, offout, 0, false, 0);
|
||||||
|
if (unlikely(res != PPM_SUCCESS))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return add_sentinel(args);
|
||||||
|
}
|
||||||
#endif /* WDIG */
|
#endif /* WDIG */
|
||||||
|
|
||||||
int f_sys_procexit_e(struct event_filler_arguments *args)
|
int f_sys_procexit_e(struct event_filler_arguments *args)
|
||||||
|
|
|
@ -33,6 +33,7 @@ or GPL2.txt for full copies of the license.
|
||||||
FN(sys_empty) \
|
FN(sys_empty) \
|
||||||
FN(sys_single) \
|
FN(sys_single) \
|
||||||
FN(sys_single_x) \
|
FN(sys_single_x) \
|
||||||
|
FN(sys_open_e) \
|
||||||
FN(sys_open_x) \
|
FN(sys_open_x) \
|
||||||
FN(sys_read_x) \
|
FN(sys_read_x) \
|
||||||
FN(sys_write_x) \
|
FN(sys_write_x) \
|
||||||
|
@ -56,6 +57,7 @@ or GPL2.txt for full copies of the license.
|
||||||
FN(sys_recvmsg_x) \
|
FN(sys_recvmsg_x) \
|
||||||
FN(sys_recvmsg_x_2) \
|
FN(sys_recvmsg_x_2) \
|
||||||
FN(sys_shutdown_e) \
|
FN(sys_shutdown_e) \
|
||||||
|
FN(sys_creat_e) \
|
||||||
FN(sys_creat_x) \
|
FN(sys_creat_x) \
|
||||||
FN(sys_pipe_x) \
|
FN(sys_pipe_x) \
|
||||||
FN(sys_eventfd_e) \
|
FN(sys_eventfd_e) \
|
||||||
|
@ -113,13 +115,18 @@ or GPL2.txt for full copies of the license.
|
||||||
FN(sys_chmod_x) \
|
FN(sys_chmod_x) \
|
||||||
FN(sys_fchmod_x) \
|
FN(sys_fchmod_x) \
|
||||||
FN(sys_mkdirat_x) \
|
FN(sys_mkdirat_x) \
|
||||||
|
FN(sys_openat_e) \
|
||||||
FN(sys_openat_x) \
|
FN(sys_openat_x) \
|
||||||
|
FN(sys_openat2_e) \
|
||||||
FN(sys_openat2_x) \
|
FN(sys_openat2_x) \
|
||||||
FN(sys_linkat_x) \
|
FN(sys_linkat_x) \
|
||||||
FN(sys_mprotect_e) \
|
FN(sys_mprotect_e) \
|
||||||
FN(sys_mprotect_x) \
|
FN(sys_mprotect_x) \
|
||||||
FN(sys_execveat_e) \
|
FN(sys_execveat_e) \
|
||||||
FN(execve_family_flags) \
|
FN(execve_family_flags) \
|
||||||
|
FN(sys_copy_file_range_e) \
|
||||||
|
FN(sys_copy_file_range_x) \
|
||||||
|
FN(sys_connect_e) \
|
||||||
FN(terminate_filler)
|
FN(terminate_filler)
|
||||||
|
|
||||||
#define FILLER_ENUM_FN(x) PPM_FILLER_##x,
|
#define FILLER_ENUM_FN(x) PPM_FILLER_##x,
|
||||||
|
|
|
@ -361,12 +361,18 @@ const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE] = {
|
||||||
#ifdef __NR_openat2
|
#ifdef __NR_openat2
|
||||||
[__NR_openat2 - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_OPENAT2_E, PPME_SYSCALL_OPENAT2_X},
|
[__NR_openat2 - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_OPENAT2_E, PPME_SYSCALL_OPENAT2_X},
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __NR_clone3
|
||||||
|
[__NR_clone3 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_CLONE3_E, PPME_SYSCALL_CLONE3_X},
|
||||||
|
#endif
|
||||||
#ifdef __NR_mprotect
|
#ifdef __NR_mprotect
|
||||||
[__NR_mprotect - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MPROTECT_E, PPME_SYSCALL_MPROTECT_X},
|
[__NR_mprotect - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MPROTECT_E, PPME_SYSCALL_MPROTECT_X},
|
||||||
#endif
|
#endif
|
||||||
#ifdef __NR_execveat
|
#ifdef __NR_execveat
|
||||||
[__NR_execveat - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_EXECVEAT_E, PPME_SYSCALL_EXECVEAT_X},
|
[__NR_execveat - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_EXECVEAT_E, PPME_SYSCALL_EXECVEAT_X},
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __NR_copy_file_range
|
||||||
|
[__NR_copy_file_range - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_COPY_FILE_RANGE_E, PPME_SYSCALL_COPY_FILE_RANGE_X},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -994,6 +1000,13 @@ const enum ppm_syscall_code g_syscall_code_routing_table[SYSCALL_TABLE_SIZE] = {
|
||||||
#ifdef __NR_execveat
|
#ifdef __NR_execveat
|
||||||
[__NR_execveat - SYSCALL_TABLE_ID0] = PPM_SC_EXECVEAT,
|
[__NR_execveat - SYSCALL_TABLE_ID0] = PPM_SC_EXECVEAT,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __NR_copy_file_range
|
||||||
|
[__NR_copy_file_range - SYSCALL_TABLE_ID0] = PPM_SC_COPY_FILE_RANGE,
|
||||||
|
#endif
|
||||||
|
[__NR_clone - SYSCALL_TABLE_ID0] = PPM_SC_CLONE,
|
||||||
|
#ifdef __NR_clone3
|
||||||
|
[__NR_clone3 - SYSCALL_TABLE_ID0] = PPM_SC_CLONE3,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_IA32_EMULATION
|
#ifdef CONFIG_IA32_EMULATION
|
||||||
|
@ -1236,12 +1249,18 @@ const struct syscall_evt_pair g_syscall_ia32_table[SYSCALL_TABLE_SIZE] = {
|
||||||
#ifdef __NR_ia32_openat2
|
#ifdef __NR_ia32_openat2
|
||||||
[__NR_ia32_openat2 - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_OPENAT2_E, PPME_SYSCALL_OPENAT2_X},
|
[__NR_ia32_openat2 - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_OPENAT2_E, PPME_SYSCALL_OPENAT2_X},
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __NR_ia32_clone3
|
||||||
|
[__NR_ia32_clone3 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_CLONE3_E, PPME_SYSCALL_CLONE3_X},
|
||||||
|
#endif
|
||||||
#ifdef __NR_ia32_mprotect
|
#ifdef __NR_ia32_mprotect
|
||||||
[__NR_ia32_mprotect - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MPROTECT_E, PPME_SYSCALL_MPROTECT_X},
|
[__NR_ia32_mprotect - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MPROTECT_E, PPME_SYSCALL_MPROTECT_X},
|
||||||
#endif
|
#endif
|
||||||
#ifdef __NR_ia32_execveat
|
#ifdef __NR_ia32_execveat
|
||||||
[__NR_ia32_execveat - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_EXECVEAT_E, PPME_SYSCALL_EXECVEAT_X},
|
[__NR_ia32_execveat - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_EXECVEAT_E, PPME_SYSCALL_EXECVEAT_X},
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __NR_ia32_copy_file_range
|
||||||
|
[__NR_ia32_copy_file_range - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_COPY_FILE_RANGE_E, PPME_SYSCALL_COPY_FILE_RANGE_X},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1804,6 +1823,13 @@ const enum ppm_syscall_code g_syscall_ia32_code_routing_table[SYSCALL_TABLE_SIZE
|
||||||
#ifdef __NR_ia32_execveat
|
#ifdef __NR_ia32_execveat
|
||||||
[__NR_ia32_execveat - SYSCALL_TABLE_ID0] = PPM_SC_EXECVEAT,
|
[__NR_ia32_execveat - SYSCALL_TABLE_ID0] = PPM_SC_EXECVEAT,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __NR_ia32_copy_file_range
|
||||||
|
[__NR_ia32_copy_file_range - SYSCALL_TABLE_ID0] = PPM_SC_COPY_FILE_RANGE,
|
||||||
|
#endif
|
||||||
|
[__NR_ia32_clone - SYSCALL_TABLE_ID0] = PPM_SC_CLONE,
|
||||||
|
#ifdef __NR_ia32_clone3
|
||||||
|
[__NR_ia32_clone3 - SYSCALL_TABLE_ID0] = PPM_SC_CLONE3,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CONFIG_IA32_EMULATION */
|
#endif /* CONFIG_IA32_EMULATION */
|
||||||
|
|
|
@ -40,6 +40,8 @@ This proposal intends to extend on points 10-12 for the libsinsp and libscap pla
|
||||||
|
|
||||||
### Versioning Scheme
|
### Versioning Scheme
|
||||||
|
|
||||||
|
**Superseeded by**: [versioning-schema-amendment proposal](20220203-versioning-schema-amendment.md).
|
||||||
|
|
||||||
This document proposes to version libscap, libsinsp, and the Falco drivers - all residing in `falcosecurity/libs` - with a single [SemVer 2.0](https://semver.org/spec/v2.0.0.html) string.
|
This document proposes to version libscap, libsinsp, and the Falco drivers - all residing in `falcosecurity/libs` - with a single [SemVer 2.0](https://semver.org/spec/v2.0.0.html) string.
|
||||||
|
|
||||||
While libscap and libsinsp - to do not mention the drivers - have different API surfaces, this document proposes to version them as one single machinery to avoid further maintenance burdens and version compatibility matrices (read dependency hell) between all the floating pieces.
|
While libscap and libsinsp - to do not mention the drivers - have different API surfaces, this document proposes to version them as one single machinery to avoid further maintenance burdens and version compatibility matrices (read dependency hell) between all the floating pieces.
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
# Versioning schema
|
||||||
|
|
||||||
|
**Supersedes**: [20210524-versioning-and-release-of-the-libs-artifacts.md#versioning-scheme](20210524-versioning-and-release-of-the-libs-artifacts.md#versioning-scheme)
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
This proposal extends and improves the two previous proposals regarding the versioning and the release process of the `falcosecurity/libs` repository (which includes libscap, libsinsp, and the two drivers).
|
||||||
|
|
||||||
|
In particular, the [20210524-versioning-and-release-of-the-libs-artifacts.md#versioning-scheme](20210524-versioning-and-release-of-the-libs-artifacts.md#versioning-scheme) proposal mandated to version all the artifacts as one single machinery with the spirit of simplicity. Although that was a good idea at the time of the first proposal, the new [20210818-driver-semver.md](20210818-driver-semver.md) proposal introduced an effective API versioning solution for the user/kernel boundary in order to make the drivers reusable across libscap consumers and their versions (when version compatibility allows).
|
||||||
|
|
||||||
|
This amendment introduces two different version numbers for releasing artifacts (instead of one single version number):
|
||||||
|
|
||||||
|
- The **libs version number** which represents the build version of the user-space libraries (i.e., libscap, libsinsp, and possibly any other further user-space library)
|
||||||
|
- The **driver version number** which represents the build version of kernel-space drivers (i.e., the kernel module, the eBPF probe, and possibly any other kernel-space driver)
|
||||||
|
|
||||||
|
This proposal does not aim to introduce changes other than using two different version numbers. Moreover, this proposal is only about the versions string used at build time, so no code changes are expected outside the build system context.
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
The [20210818-driver-semver.md](20210818-driver-semver.md#motivation) proposal is already fully implemented. The advantages introduced by that proposal would be lost if we used a single versioning number for all the artifacts as mandated by [20210524-versioning-and-release-of-the-libs-artifacts.md#versioning-scheme](20210524-versioning-and-release-of-the-libs-artifacts.md#versioning-scheme). Furthermore, that proposal is only about versioning the APIs that sits between the kernel and the user-space components. It does not mandate any specification regarding the versioning of artifacts.
|
||||||
|
|
||||||
|
This amendment is required to fill the gap between the two proposals and allow our users to reuse the same driver version across a range of compatible consumers.
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
* Document the two versioning schemes (one for the libs and another for the drivers)
|
||||||
|
* Allow releasing libs and drivers separately (different timing and versioning)
|
||||||
|
* Make the drivers reusable across libscap consumers and their versions
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
|
||||||
|
* Introduce code changes other than in the build system and in the documentation
|
||||||
|
* Indicate how the distribution of the artifacts must be implemented
|
||||||
|
|
||||||
|
## Proposed solution
|
||||||
|
|
||||||
|
### Userspace libs artifacts
|
||||||
|
|
||||||
|
Libscap and libsinsp are two distinct artifacts. They will be released with the same version number (a single [SemVer 2.0](https://semver.org/spec/v2.0.0.html) string). This proposal does not aim to change what already proposed by [20210524-versioning-and-release-of-the-libs-artifacts.md#versioning-scheme](20210524-versioning-and-release-of-the-libs-artifacts.md#versioning-scheme) with respect to the user-space components residing in `falcosecurity/libs`.
|
||||||
|
|
||||||
|
|
||||||
|
### Drivers artifacts
|
||||||
|
|
||||||
|
The kernel module and the eBPF probe are two components that can be built for any supported Kernel version. The source code of both drivers will be released with the same version number (a single [SemVer 2.0](https://semver.org/spec/v2.0.0.html) string).
|
||||||
|
|
||||||
|
However, a few considerations need to be taken into account. The public API is composed of two different characteristics in the driver context: the API functions (exposed to the consumer) and the data schema (delivered to the consumer). Our implementation versions those two characteristics directly in the source code (you can find the current versions respectively in [/driver/API_VERSION](/driver/API_VERSION) and [/driver/SCHEMA_VERSION](/driver/SCHEMA_VERSION)). Those versions use a SemVer compatible scheme.
|
||||||
|
|
||||||
|
|
||||||
|
For this reason, the **driver version number** must represent both characteristics, which form the public API for the drivers.
|
||||||
|
|
||||||
|
For that purpose, this document proposes to use `1.0.0` as the starting point for the driver version number, then to use the following rules to bump such version number:
|
||||||
|
- *major* increases either when `API_VERSION`’s major or `SCHEMA_VERSION`’s major number has been increased
|
||||||
|
- *minor* increases either when `API_VERSION`’s minor or `SCHEMA_VERSION`’s minor number has been increased
|
||||||
|
- *patch* increases either when `API_VERSION`’s patch or `SCHEMA_VERSION`’s patch number has been increased or when any other code changes have been introduced (for example, the support for a new kernel)
|
||||||
|
|
||||||
|
Note that no backward-incompatible changes can be introduced without bumping the *major* number of `API_VERSION` or `SCHEMA_VERSION` first. Similar logic applies for the *minor* and *patch* numbers. Since both `API_VERSION` and `SCHEMA_VERSION` follow the SemVer scheme, with this method also, the resulting driver version is guaranteed to respect what the SemVer specification mandates.
|
||||||
|
|
||||||
|
### Other considerations
|
||||||
|
|
||||||
|
When releasing the artifacts, maintainers will use these versioning schemes (i.e., when git tagging libs or drivers).
|
||||||
|
However, consumers are free to use any versioning scheme they want by overriding those values at build time (e.g., via cmake options).
|
||||||
|
|
||||||
|
Steps described in the
|
||||||
|
[20210524-versioning-and-release-of-the-libs-artifacts.md#steps](20210524-versioning-and-release-of-the-libs-artifacts.md#steps) section will need to be adapted to accommodate the two different release processes (one for the libs and another for the drivers).
|
|
@ -119,7 +119,7 @@ const static struct luaL_Reg ll_sysdig [] =
|
||||||
{"make_ts", &lua_cbacks::make_ts},
|
{"make_ts", &lua_cbacks::make_ts},
|
||||||
{"add_ts", &lua_cbacks::add_ts},
|
{"add_ts", &lua_cbacks::add_ts},
|
||||||
{"subtract_ts", &lua_cbacks::subtract_ts},
|
{"subtract_ts", &lua_cbacks::subtract_ts},
|
||||||
{"run_sysdig", &lua_cbacks::run_sysdig},
|
{"run_app", &lua_cbacks::run_app},
|
||||||
{"end_capture", &lua_cbacks::end_capture},
|
{"end_capture", &lua_cbacks::end_capture},
|
||||||
{"log", &lua_cbacks::log},
|
{"log", &lua_cbacks::log},
|
||||||
{"udp_setpeername", &lua_cbacks::udp_setpeername},
|
{"udp_setpeername", &lua_cbacks::udp_setpeername},
|
||||||
|
@ -245,7 +245,7 @@ void chiselinfo::set_callback_precise_interval(uint64_t interval)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// chisel implementation
|
// chisel implementation
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
sinsp_chisel::sinsp_chisel(sinsp* inspector, string filename)
|
sinsp_chisel::sinsp_chisel(sinsp* inspector, string filename, bool is_file)
|
||||||
{
|
{
|
||||||
m_inspector = inspector;
|
m_inspector = inspector;
|
||||||
m_ls = NULL;
|
m_ls = NULL;
|
||||||
|
@ -256,7 +256,7 @@ sinsp_chisel::sinsp_chisel(sinsp* inspector, string filename)
|
||||||
m_lua_last_interval_ts = 0;
|
m_lua_last_interval_ts = 0;
|
||||||
m_udp_socket = 0;
|
m_udp_socket = 0;
|
||||||
|
|
||||||
load(filename);
|
load(filename, is_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
sinsp_chisel::~sinsp_chisel()
|
sinsp_chisel::~sinsp_chisel()
|
||||||
|
@ -1170,13 +1170,19 @@ bool sinsp_chisel::openfile(string filename, OUT ifstream* is)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sinsp_chisel::load(string cmdstr)
|
void sinsp_chisel::load(string cmdstr, bool is_file)
|
||||||
{
|
{
|
||||||
m_filename = cmdstr;
|
if (is_file) {
|
||||||
trim(cmdstr);
|
trim(cmdstr);
|
||||||
|
m_filename = cmdstr;
|
||||||
|
} else {
|
||||||
|
m_filename = "<in-memory-string>";
|
||||||
|
}
|
||||||
|
|
||||||
ifstream is;
|
ifstream is;
|
||||||
|
std::string scriptstr;
|
||||||
|
|
||||||
|
if (is_file) {
|
||||||
//
|
//
|
||||||
// Try to open the file with lua extension
|
// Try to open the file with lua extension
|
||||||
//
|
//
|
||||||
|
@ -1191,12 +1197,15 @@ void sinsp_chisel::load(string cmdstr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAS_LUA_CHISELS
|
|
||||||
//
|
//
|
||||||
// Load the file
|
// Load the file
|
||||||
//
|
//
|
||||||
std::istreambuf_iterator<char> eos;
|
std::istreambuf_iterator<char> eos;
|
||||||
std::string scriptstr(std::istreambuf_iterator<char>(is), eos);
|
scriptstr.assign(std::istreambuf_iterator<char>(is), eos);
|
||||||
|
} else {
|
||||||
|
scriptstr = cmdstr;
|
||||||
|
}
|
||||||
|
#ifdef HAS_LUA_CHISELS
|
||||||
|
|
||||||
//
|
//
|
||||||
// Open the script
|
// Open the script
|
||||||
|
|
|
@ -110,11 +110,11 @@ private:
|
||||||
class SINSP_PUBLIC sinsp_chisel
|
class SINSP_PUBLIC sinsp_chisel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sinsp_chisel(sinsp* inspector, string filename);
|
sinsp_chisel(sinsp* inspector, string filename, bool is_file = true);
|
||||||
~sinsp_chisel();
|
~sinsp_chisel();
|
||||||
static void add_lua_package_path(lua_State* ls, const char* path);
|
static void add_lua_package_path(lua_State* ls, const char* path);
|
||||||
static void get_chisel_list(vector<chisel_desc>* chisel_descs);
|
static void get_chisel_list(vector<chisel_desc>* chisel_descs);
|
||||||
void load(string cmdstr);
|
void load(string cmdstr, bool is_file = true);
|
||||||
string get_name()
|
string get_name()
|
||||||
{
|
{
|
||||||
return m_filename;
|
return m_filename;
|
||||||
|
|
|
@ -562,7 +562,7 @@ int lua_cbacks::subtract_ts(lua_State *ls)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_cbacks::run_sysdig(lua_State *ls)
|
int lua_cbacks::run_app(lua_State *ls)
|
||||||
{
|
{
|
||||||
lua_getglobal(ls, "sichisel");
|
lua_getglobal(ls, "sichisel");
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
static int make_ts(lua_State *ls);
|
static int make_ts(lua_State *ls);
|
||||||
static int add_ts(lua_State *ls);
|
static int add_ts(lua_State *ls);
|
||||||
static int subtract_ts(lua_State *ls);
|
static int subtract_ts(lua_State *ls);
|
||||||
static int run_sysdig(lua_State *ls);
|
static int run_app(lua_State *ls);
|
||||||
static int end_capture(lua_State *ls);
|
static int end_capture(lua_State *ls);
|
||||||
static int is_live(lua_State *ls);
|
static int is_live(lua_State *ls);
|
||||||
static int is_tty(lua_State *ls);
|
static int is_tty(lua_State *ls);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (C) 2021 The Falco Authors.
|
# Copyright (C) 2022 The Falco Authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -30,24 +30,24 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
set(KBUILD_FLAGS "${FALCOSECURITY_LIBS_DEBUG_FLAGS}")
|
set(KBUILD_FLAGS "${FALCOSECURITY_LIBS_DEBUG_FLAGS}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT DEFINED PROBE_VERSION)
|
if(NOT DEFINED DRIVER_VERSION)
|
||||||
set(PROBE_VERSION "${FALCOSECURITY_LIBS_VERSION}")
|
set(DRIVER_VERSION "${FALCOSECURITY_LIBS_VERSION}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT DEFINED PROBE_NAME)
|
if(NOT DEFINED DRIVER_NAME)
|
||||||
set(PROBE_NAME "scap")
|
set(DRIVER_NAME "scap")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT DEFINED PROBE_DEVICE_NAME)
|
if(NOT DEFINED DRIVER_DEVICE_NAME)
|
||||||
set(PROBE_DEVICE_NAME "${PROBE_NAME}")
|
set(DRIVER_DEVICE_NAME "${DRIVER_NAME}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
string(REPLACE "-" "_" SCAP_PROBE_MODULE_NAME "${PROBE_NAME}")
|
string(REPLACE "-" "_" SCAP_KERNEL_MODULE_NAME "${DRIVER_NAME}")
|
||||||
add_definitions(-DSCAP_PROBE_MODULE_NAME="${SCAP_PROBE_MODULE_NAME}")
|
add_definitions(-DSCAP_KERNEL_MODULE_NAME="${SCAP_KERNEL_MODULE_NAME}")
|
||||||
|
|
||||||
if(NOT DEFINED SCAP_PROBE_BPF_FILEPATH)
|
if(NOT DEFINED SCAP_PROBE_BPF_FILEPATH)
|
||||||
# note that the home folder is prepended by scap at runtime
|
# note that the home folder is prepended by scap at runtime
|
||||||
set(SCAP_PROBE_BPF_FILEPATH ".${PROBE_NAME}/${PROBE_NAME}-bpf.o")
|
set(SCAP_PROBE_BPF_FILEPATH ".${DRIVER_NAME}/${DRIVER_NAME}-bpf.o")
|
||||||
endif()
|
endif()
|
||||||
add_definitions(-DSCAP_PROBE_BPF_FILEPATH="${SCAP_PROBE_BPF_FILEPATH}")
|
add_definitions(-DSCAP_PROBE_BPF_FILEPATH="${SCAP_PROBE_BPF_FILEPATH}")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -30,6 +30,7 @@ static void signal_callback(int signal)
|
||||||
printf("seen by driver: %" PRIu64 "\n", s.n_evts);
|
printf("seen by driver: %" PRIu64 "\n", s.n_evts);
|
||||||
printf("Number of dropped events: %" PRIu64 "\n", s.n_drops);
|
printf("Number of dropped events: %" PRIu64 "\n", s.n_drops);
|
||||||
printf("Number of dropped events caused by full buffer: %" PRIu64 "\n", s.n_drops_buffer);
|
printf("Number of dropped events caused by full buffer: %" PRIu64 "\n", s.n_drops_buffer);
|
||||||
|
printf("Number of dropped events caused by full scratch map: %" PRIu64 "\n", s.n_drops_scratch_map);
|
||||||
printf("Number of dropped events caused by invalid memory access: %" PRIu64 "\n", s.n_drops_pf);
|
printf("Number of dropped events caused by invalid memory access: %" PRIu64 "\n", s.n_drops_pf);
|
||||||
printf("Number of dropped events caused by an invalid condition in the kernel instrumentation: %" PRIu64 "\n", s.n_drops_bug);
|
printf("Number of dropped events caused by an invalid condition in the kernel instrumentation: %" PRIu64 "\n", s.n_drops_bug);
|
||||||
printf("Number of preemptions: %" PRIu64 "\n", s.n_preemptions);
|
printf("Number of preemptions: %" PRIu64 "\n", s.n_preemptions);
|
||||||
|
|
|
@ -94,11 +94,6 @@ typedef struct scap_device
|
||||||
struct ppm_ring_buffer_info* m_bufinfo;
|
struct ppm_ring_buffer_info* m_bufinfo;
|
||||||
struct udig_ring_buffer_status* m_bufstatus; // used by udig
|
struct udig_ring_buffer_status* m_bufstatus; // used by udig
|
||||||
};
|
};
|
||||||
// Anonymous struct with bpf stuff
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint64_t m_evt_lost;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}scap_device;
|
}scap_device;
|
||||||
|
|
||||||
|
@ -154,6 +149,8 @@ struct scap
|
||||||
uint32_t m_fd_lookup_limit;
|
uint32_t m_fd_lookup_limit;
|
||||||
uint64_t m_unexpected_block_readsize;
|
uint64_t m_unexpected_block_readsize;
|
||||||
uint32_t m_ncpus;
|
uint32_t m_ncpus;
|
||||||
|
uint8_t m_cgroup_version;
|
||||||
|
|
||||||
// Abstraction layer for windows
|
// Abstraction layer for windows
|
||||||
#if CYGWING_AGENT || _WIN32
|
#if CYGWING_AGENT || _WIN32
|
||||||
wh_t* m_whh;
|
wh_t* m_whh;
|
||||||
|
@ -208,6 +205,16 @@ struct scap
|
||||||
|
|
||||||
// The return value from the last call to next_batch().
|
// The return value from the last call to next_batch().
|
||||||
ss_plugin_rc m_input_plugin_last_batch_res;
|
ss_plugin_rc m_input_plugin_last_batch_res;
|
||||||
|
|
||||||
|
// API version supported by the driver
|
||||||
|
// If the API version is unavailable for whatever reason,
|
||||||
|
// it's equivalent to version 0.0.0
|
||||||
|
uint64_t m_api_version;
|
||||||
|
|
||||||
|
// schema version supported by the driver
|
||||||
|
// If the schema version is unavailable for whatever reason,
|
||||||
|
// it's equivalent to version 0.0.0
|
||||||
|
uint64_t m_schema_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum ppm_dumper_type
|
typedef enum ppm_dumper_type
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2021 The Falco Authors.
|
Copyright (C) 2022 The Falco Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -56,11 +56,6 @@ limitations under the License.
|
||||||
//#define NDEBUG
|
//#define NDEBUG
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
//
|
|
||||||
// Probe version string size
|
|
||||||
//
|
|
||||||
#define SCAP_PROBE_VERSION_SIZE 32
|
|
||||||
|
|
||||||
static int32_t plugin_rc_to_scap_rc(ss_plugin_rc plugin_rc)
|
static int32_t plugin_rc_to_scap_rc(ss_plugin_rc plugin_rc)
|
||||||
{
|
{
|
||||||
switch(plugin_rc)
|
switch(plugin_rc)
|
||||||
|
@ -145,7 +140,7 @@ static uint32_t get_max_consumers()
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
uint32_t max;
|
uint32_t max;
|
||||||
FILE *pfile = fopen("/sys/module/" SCAP_PROBE_MODULE_NAME "/parameters/max_consumers", "r");
|
FILE *pfile = fopen("/sys/module/" SCAP_KERNEL_MODULE_NAME "/parameters/max_consumers", "r");
|
||||||
if(pfile != NULL)
|
if(pfile != NULL)
|
||||||
{
|
{
|
||||||
int w = fscanf(pfile, "%"PRIu32, &max);
|
int w = fscanf(pfile, "%"PRIu32, &max);
|
||||||
|
@ -387,6 +382,8 @@ scap_t* scap_open_live_int(char *error, int32_t *rc,
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
uint32_t all_scanned_devs;
|
uint32_t all_scanned_devs;
|
||||||
|
uint64_t api_version;
|
||||||
|
uint64_t schema_version;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate the device descriptors.
|
// Allocate the device descriptors.
|
||||||
|
@ -398,7 +395,7 @@ scap_t* scap_open_live_int(char *error, int32_t *rc,
|
||||||
//
|
//
|
||||||
// Open the device
|
// Open the device
|
||||||
//
|
//
|
||||||
snprintf(filename, sizeof(filename), "%s/dev/" PROBE_DEVICE_NAME "%d", scap_get_host_root(), all_scanned_devs);
|
snprintf(filename, sizeof(filename), "%s/dev/" DRIVER_DEVICE_NAME "%d", scap_get_host_root(), all_scanned_devs);
|
||||||
|
|
||||||
if((handle->m_devs[j].m_fd = open(filename, O_RDWR | O_SYNC)) < 0)
|
if((handle->m_devs[j].m_fd = open(filename, O_RDWR | O_SYNC)) < 0)
|
||||||
{
|
{
|
||||||
|
@ -412,11 +409,11 @@ scap_t* scap_open_live_int(char *error, int32_t *rc,
|
||||||
else if(errno == EBUSY)
|
else if(errno == EBUSY)
|
||||||
{
|
{
|
||||||
uint32_t curr_max_consumers = get_max_consumers();
|
uint32_t curr_max_consumers = get_max_consumers();
|
||||||
snprintf(error, SCAP_LASTERR_SIZE, "Too many consumers attached to device %s. Current value for /sys/module/" SCAP_PROBE_MODULE_NAME "/parameters/max_consumers is '%"PRIu32"'.", filename, curr_max_consumers);
|
snprintf(error, SCAP_LASTERR_SIZE, "Too many consumers attached to device %s. Current value for /sys/module/" SCAP_KERNEL_MODULE_NAME "/parameters/max_consumers is '%"PRIu32"'.", filename, curr_max_consumers);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
snprintf(error, SCAP_LASTERR_SIZE, "error opening device %s. Make sure you have root credentials and that the " PROBE_NAME " module is loaded.", filename);
|
snprintf(error, SCAP_LASTERR_SIZE, "error opening device %s. Make sure you have root credentials and that the " DRIVER_NAME " module is loaded.", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
scap_close(handle);
|
scap_close(handle);
|
||||||
|
@ -427,11 +424,71 @@ scap_t* scap_open_live_int(char *error, int32_t *rc,
|
||||||
// Set close-on-exec for the fd
|
// Set close-on-exec for the fd
|
||||||
if (fcntl(handle->m_devs[j].m_fd, F_SETFD, FD_CLOEXEC) == -1) {
|
if (fcntl(handle->m_devs[j].m_fd, F_SETFD, FD_CLOEXEC) == -1) {
|
||||||
snprintf(error, SCAP_LASTERR_SIZE, "Can not set close-on-exec flag for fd for device %s (%s)", filename, scap_strerror(handle, errno));
|
snprintf(error, SCAP_LASTERR_SIZE, "Can not set close-on-exec flag for fd for device %s (%s)", filename, scap_strerror(handle, errno));
|
||||||
|
close(handle->m_devs[j].m_fd);
|
||||||
scap_close(handle);
|
scap_close(handle);
|
||||||
*rc = SCAP_FAILURE;
|
*rc = SCAP_FAILURE;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the API version reported
|
||||||
|
if (ioctl(handle->m_devs[j].m_fd, PPM_IOCTL_GET_API_VERSION, &api_version) < 0)
|
||||||
|
{
|
||||||
|
snprintf(error, SCAP_LASTERR_SIZE, "Kernel module does not support PPM_IOCTL_GET_API_VERSION");
|
||||||
|
close(handle->m_devs[j].m_fd);
|
||||||
|
scap_close(handle);
|
||||||
|
*rc = SCAP_FAILURE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// Make sure all devices report the same API version
|
||||||
|
if (handle->m_api_version != 0 && handle->m_api_version != api_version)
|
||||||
|
{
|
||||||
|
snprintf(error, SCAP_LASTERR_SIZE, "API version mismatch: device %s reports API version %llu.%llu.%llu, expected %llu.%llu.%llu",
|
||||||
|
filename,
|
||||||
|
PPM_API_VERSION_MAJOR(api_version),
|
||||||
|
PPM_API_VERSION_MINOR(api_version),
|
||||||
|
PPM_API_VERSION_PATCH(api_version),
|
||||||
|
PPM_API_VERSION_MAJOR(handle->m_api_version),
|
||||||
|
PPM_API_VERSION_MINOR(handle->m_api_version),
|
||||||
|
PPM_API_VERSION_PATCH(handle->m_api_version)
|
||||||
|
);
|
||||||
|
close(handle->m_devs[j].m_fd);
|
||||||
|
scap_close(handle);
|
||||||
|
*rc = SCAP_FAILURE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// Set the API version from the first device
|
||||||
|
// (for subsequent devices it's a no-op thanks to the check above)
|
||||||
|
handle->m_api_version = api_version;
|
||||||
|
|
||||||
|
// Check the schema version reported
|
||||||
|
if (ioctl(handle->m_devs[j].m_fd, PPM_IOCTL_GET_SCHEMA_VERSION, &schema_version) < 0)
|
||||||
|
{
|
||||||
|
snprintf(error, SCAP_LASTERR_SIZE, "Kernel module does not support PPM_IOCTL_GET_SCHEMA_VERSION");
|
||||||
|
close(handle->m_devs[j].m_fd);
|
||||||
|
scap_close(handle);
|
||||||
|
*rc = SCAP_FAILURE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// Make sure all devices report the same schema version
|
||||||
|
if (handle->m_schema_version != 0 && handle->m_schema_version != schema_version)
|
||||||
|
{
|
||||||
|
snprintf(error, SCAP_LASTERR_SIZE, "Schema version mismatch: device %s reports schema version %llu.%llu.%llu, expected %llu.%llu.%llu",
|
||||||
|
filename,
|
||||||
|
PPM_API_VERSION_MAJOR(schema_version),
|
||||||
|
PPM_API_VERSION_MINOR(schema_version),
|
||||||
|
PPM_API_VERSION_PATCH(schema_version),
|
||||||
|
PPM_API_VERSION_MAJOR(handle->m_schema_version),
|
||||||
|
PPM_API_VERSION_MINOR(handle->m_schema_version),
|
||||||
|
PPM_API_VERSION_PATCH(handle->m_schema_version)
|
||||||
|
);
|
||||||
|
scap_close(handle);
|
||||||
|
*rc = SCAP_FAILURE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// Set the schema version from the first device
|
||||||
|
// (for subsequent devices it's a no-op thanks to the check above)
|
||||||
|
handle->m_schema_version = schema_version;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Map the ring buffer
|
// Map the ring buffer
|
||||||
//
|
//
|
||||||
|
@ -496,6 +553,34 @@ scap_t* scap_open_live_int(char *error, int32_t *rc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!scap_is_api_compatible(handle->m_api_version, SCAP_MINIMUM_DRIVER_API_VERSION))
|
||||||
|
{
|
||||||
|
snprintf(error, SCAP_LASTERR_SIZE, "Driver supports API version %llu.%llu.%llu, but running version needs %d.%d.%d",
|
||||||
|
PPM_API_VERSION_MAJOR(handle->m_api_version),
|
||||||
|
PPM_API_VERSION_MINOR(handle->m_api_version),
|
||||||
|
PPM_API_VERSION_PATCH(handle->m_api_version),
|
||||||
|
PPM_API_CURRENT_VERSION_MAJOR,
|
||||||
|
PPM_API_CURRENT_VERSION_MINOR,
|
||||||
|
PPM_API_CURRENT_VERSION_PATCH);
|
||||||
|
*rc = SCAP_FAILURE;
|
||||||
|
scap_close(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!scap_is_api_compatible(handle->m_schema_version, SCAP_MINIMUM_DRIVER_SCHEMA_VERSION))
|
||||||
|
{
|
||||||
|
snprintf(error, SCAP_LASTERR_SIZE, "Driver supports schema version %llu.%llu.%llu, but running version needs %d.%d.%d",
|
||||||
|
PPM_API_VERSION_MAJOR(handle->m_schema_version),
|
||||||
|
PPM_API_VERSION_MINOR(handle->m_schema_version),
|
||||||
|
PPM_API_VERSION_PATCH(handle->m_schema_version),
|
||||||
|
PPM_SCHEMA_CURRENT_VERSION_MAJOR,
|
||||||
|
PPM_SCHEMA_CURRENT_VERSION_MINOR,
|
||||||
|
PPM_SCHEMA_CURRENT_VERSION_PATCH);
|
||||||
|
*rc = SCAP_FAILURE;
|
||||||
|
scap_close(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for(j = 0; j < handle->m_ndevs; ++j)
|
for(j = 0; j < handle->m_ndevs; ++j)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -2013,6 +2098,7 @@ int32_t scap_get_stats(scap_t* handle, OUT scap_stats* stats)
|
||||||
stats->n_evts = 0;
|
stats->n_evts = 0;
|
||||||
stats->n_drops = 0;
|
stats->n_drops = 0;
|
||||||
stats->n_drops_buffer = 0;
|
stats->n_drops_buffer = 0;
|
||||||
|
stats->n_drops_scratch_map = 0;
|
||||||
stats->n_drops_pf = 0;
|
stats->n_drops_pf = 0;
|
||||||
stats->n_drops_bug = 0;
|
stats->n_drops_bug = 0;
|
||||||
stats->n_preemptions = 0;
|
stats->n_preemptions = 0;
|
||||||
|
@ -2969,3 +3055,42 @@ int32_t scap_set_statsd_port(scap_t* const handle, const uint16_t port)
|
||||||
return SCAP_SUCCESS;
|
return SCAP_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool scap_is_api_compatible(unsigned long driver_api_version, unsigned long required_api_version)
|
||||||
|
{
|
||||||
|
unsigned long driver_major = PPM_API_VERSION_MAJOR(driver_api_version);
|
||||||
|
unsigned long driver_minor = PPM_API_VERSION_MINOR(driver_api_version);
|
||||||
|
unsigned long driver_patch = PPM_API_VERSION_PATCH(driver_api_version);
|
||||||
|
unsigned long required_major = PPM_API_VERSION_MAJOR(required_api_version);
|
||||||
|
unsigned long required_minor = PPM_API_VERSION_MINOR(required_api_version);
|
||||||
|
unsigned long required_patch = PPM_API_VERSION_PATCH(required_api_version);
|
||||||
|
|
||||||
|
if(driver_major != required_major)
|
||||||
|
{
|
||||||
|
// major numbers disagree
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(driver_minor < required_minor)
|
||||||
|
{
|
||||||
|
// driver's minor version is < ours
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(driver_minor == required_minor && driver_patch < required_patch)
|
||||||
|
{
|
||||||
|
// driver's minor versions match and patch level is < ours
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t scap_get_driver_api_version(scap_t* handle)
|
||||||
|
{
|
||||||
|
return handle->m_api_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t scap_get_driver_schema_version(scap_t* handle)
|
||||||
|
{
|
||||||
|
return handle->m_schema_version;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2021 The Falco Authors.
|
Copyright (C) 2022 The Falco Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -59,6 +59,7 @@ struct iovec;
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "uthash.h"
|
#include "uthash.h"
|
||||||
#include "../common/types.h"
|
#include "../common/types.h"
|
||||||
|
#include "../../driver/ppm_api_version.h"
|
||||||
#include "../../driver/ppm_events_public.h"
|
#include "../../driver/ppm_events_public.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -67,6 +68,23 @@ struct iovec;
|
||||||
|
|
||||||
#include "plugin_info.h"
|
#include "plugin_info.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// The minimum API and schema versions the driver has to support before we can use it
|
||||||
|
//
|
||||||
|
// The reason to increment these would be a bug in the driver that userspace
|
||||||
|
// cannot or does not want to work around.
|
||||||
|
//
|
||||||
|
// Note: adding new events or event fields should not need a version bump
|
||||||
|
// here, since libscap has to suport old event formats anyway (for capture
|
||||||
|
// files).
|
||||||
|
//
|
||||||
|
// If a consumer relies on events or APIs added in a new version, it should
|
||||||
|
// call `scap_get_driver_api_version()` and/or `scap_get_driver_schema_version()`
|
||||||
|
// and handle the result
|
||||||
|
//
|
||||||
|
#define SCAP_MINIMUM_DRIVER_API_VERSION PPM_API_VERSION(1, 0, 0)
|
||||||
|
#define SCAP_MINIMUM_DRIVER_SCHEMA_VERSION PPM_API_VERSION(1, 0, 0)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Return types
|
// Return types
|
||||||
//
|
//
|
||||||
|
@ -94,11 +112,12 @@ typedef struct scap_stats
|
||||||
uint64_t n_evts; ///< Total number of events that were received by the driver.
|
uint64_t n_evts; ///< Total number of events that were received by the driver.
|
||||||
uint64_t n_drops; ///< Number of dropped events.
|
uint64_t n_drops; ///< Number of dropped events.
|
||||||
uint64_t n_drops_buffer; ///< Number of dropped events caused by full buffer.
|
uint64_t n_drops_buffer; ///< Number of dropped events caused by full buffer.
|
||||||
|
uint64_t n_drops_scratch_map; ///< Number of dropped events caused by full frame scratch map.
|
||||||
uint64_t n_drops_pf; ///< Number of dropped events caused by invalid memory access.
|
uint64_t n_drops_pf; ///< Number of dropped events caused by invalid memory access.
|
||||||
uint64_t n_drops_bug; ///< Number of dropped events caused by an invalid condition in the kernel instrumentation.
|
uint64_t n_drops_bug; ///< Number of dropped events caused by an invalid condition in the kernel instrumentation.
|
||||||
uint64_t n_preemptions; ///< Number of preemptions.
|
uint64_t n_preemptions; ///< Number of preemptions.
|
||||||
uint64_t n_suppressed; ///< Number of events skipped due to the tid being in a set of suppressed tids
|
uint64_t n_suppressed; ///< Number of events skipped due to the tid being in a set of suppressed tids.
|
||||||
uint64_t n_tids_suppressed; ///< Number of threads currently being suppressed
|
uint64_t n_tids_suppressed; ///< Number of threads currently being suppressed.
|
||||||
}scap_stats;
|
}scap_stats;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -1121,6 +1140,21 @@ int32_t scap_set_fullcapture_port_range(scap_t* handle, uint16_t range_start, ui
|
||||||
*/
|
*/
|
||||||
int32_t scap_set_statsd_port(scap_t* handle, uint16_t port);
|
int32_t scap_set_statsd_port(scap_t* handle, uint16_t port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is `driver_api_version` compatible with `required_api_version`?
|
||||||
|
*/
|
||||||
|
bool scap_is_api_compatible(unsigned long driver_api_version, unsigned long required_api_version);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get API version supported by the driver
|
||||||
|
*/
|
||||||
|
uint64_t scap_get_driver_api_version(scap_t* handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get schema version supported by the driver
|
||||||
|
*/
|
||||||
|
uint64_t scap_get_driver_schema_version(scap_t* handle);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -310,10 +310,10 @@ static int32_t load_maps(scap_t *handle, struct bpf_map_data *maps, int nr_maps)
|
||||||
|
|
||||||
for(j = 0; j < nr_maps; ++j)
|
for(j = 0; j < nr_maps; ++j)
|
||||||
{
|
{
|
||||||
if(j == SYSDIG_PERF_MAP ||
|
if(j == SCAP_PERF_MAP ||
|
||||||
j == SYSDIG_LOCAL_STATE_MAP ||
|
j == SCAP_LOCAL_STATE_MAP ||
|
||||||
j == SYSDIG_FRAME_SCRATCH_MAP ||
|
j == SCAP_FRAME_SCRATCH_MAP ||
|
||||||
j == SYSDIG_TMP_SCRATCH_MAP)
|
j == SCAP_TMP_SCRATCH_MAP)
|
||||||
{
|
{
|
||||||
maps[j].def.max_entries = handle->m_ncpus;
|
maps[j].def.max_entries = handle->m_ncpus;
|
||||||
}
|
}
|
||||||
|
@ -564,6 +564,8 @@ static int32_t load_bpf_file(scap_t *handle, const char *path)
|
||||||
struct bpf_map_data maps[BPF_MAPS_MAX];
|
struct bpf_map_data maps[BPF_MAPS_MAX];
|
||||||
struct utsname osname;
|
struct utsname osname;
|
||||||
int32_t res = SCAP_FAILURE;
|
int32_t res = SCAP_FAILURE;
|
||||||
|
bool got_api_version = false;
|
||||||
|
bool got_schema_version = false;
|
||||||
|
|
||||||
if(uname(&osname))
|
if(uname(&osname))
|
||||||
{
|
{
|
||||||
|
@ -622,13 +624,13 @@ static int32_t load_bpf_file(scap_t *handle, const char *path)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(strcmp(shname, "probe_version") == 0) {
|
else if(strcmp(shname, "api_version") == 0) {
|
||||||
if(strcmp(PROBE_VERSION, data->d_buf))
|
got_api_version = true;
|
||||||
{
|
memcpy(&handle->m_api_version, data->d_buf, sizeof(handle->m_api_version));
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "BPF probe version is %s, but running version is %s",
|
|
||||||
(char *) data->d_buf, PROBE_VERSION);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
else if(strcmp(shname, "schema_version") == 0) {
|
||||||
|
got_schema_version = true;
|
||||||
|
memcpy(&handle->m_schema_version, data->d_buf, sizeof(handle->m_schema_version));
|
||||||
}
|
}
|
||||||
else if(strcmp(shname, "license") == 0)
|
else if(strcmp(shname, "license") == 0)
|
||||||
{
|
{
|
||||||
|
@ -637,6 +639,18 @@ static int32_t load_bpf_file(scap_t *handle, const char *path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!got_api_version)
|
||||||
|
{
|
||||||
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "missing api_version section");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!got_schema_version)
|
||||||
|
{
|
||||||
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "missing schema_version section");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if(!symbols)
|
if(!symbols)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "missing SHT_SYMTAB section");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "missing SHT_SYMTAB section");
|
||||||
|
@ -756,14 +770,14 @@ static int32_t populate_syscall_routing_table_map(scap_t *handle)
|
||||||
for(j = 0; j < SYSCALL_TABLE_SIZE; ++j)
|
for(j = 0; j < SYSCALL_TABLE_SIZE; ++j)
|
||||||
{
|
{
|
||||||
long code = g_syscall_code_routing_table[j];
|
long code = g_syscall_code_routing_table[j];
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SYSCALL_CODE_ROUTING_TABLE], &j, &code, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SYSCALL_CODE_ROUTING_TABLE], &j, &code, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SYSCALL_CODE_ROUTING_TABLE bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SYSCALL_CODE_ROUTING_TABLE bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bpf_map_freeze(handle->m_bpf_map_fds[SYSDIG_SYSCALL_CODE_ROUTING_TABLE]);
|
return bpf_map_freeze(handle->m_bpf_map_fds[SCAP_SYSCALL_CODE_ROUTING_TABLE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t populate_syscall_table_map(scap_t *handle)
|
static int32_t populate_syscall_table_map(scap_t *handle)
|
||||||
|
@ -779,9 +793,9 @@ static int32_t populate_syscall_table_map(scap_t *handle)
|
||||||
p = &uninterested_pair;
|
p = &uninterested_pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SYSCALL_TABLE], &j, p, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SYSCALL_TABLE], &j, p, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SYSCALL_TABLE bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SYSCALL_TABLE bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -796,14 +810,14 @@ static int32_t populate_event_table_map(scap_t *handle)
|
||||||
for(j = 0; j < PPM_EVENT_MAX; ++j)
|
for(j = 0; j < PPM_EVENT_MAX; ++j)
|
||||||
{
|
{
|
||||||
const struct ppm_event_info *e = &g_event_info[j];
|
const struct ppm_event_info *e = &g_event_info[j];
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_EVENT_INFO_TABLE], &j, e, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_EVENT_INFO_TABLE], &j, e, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_EVENT_INFO_TABLE bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_EVENT_INFO_TABLE bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bpf_map_freeze(handle->m_bpf_map_fds[SYSDIG_EVENT_INFO_TABLE]);
|
return bpf_map_freeze(handle->m_bpf_map_fds[SCAP_EVENT_INFO_TABLE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t populate_fillers_table_map(scap_t *handle)
|
static int32_t populate_fillers_table_map(scap_t *handle)
|
||||||
|
@ -813,9 +827,9 @@ static int32_t populate_fillers_table_map(scap_t *handle)
|
||||||
for(j = 0; j < PPM_EVENT_MAX; ++j)
|
for(j = 0; j < PPM_EVENT_MAX; ++j)
|
||||||
{
|
{
|
||||||
const struct ppm_event_entry *e = &g_ppm_events[j];
|
const struct ppm_event_entry *e = &g_ppm_events[j];
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_FILLERS_TABLE], &j, e, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_FILLERS_TABLE], &j, e, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_FILLERS_TABLE bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_FILLERS_TABLE bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -829,7 +843,7 @@ static int32_t populate_fillers_table_map(scap_t *handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bpf_map_freeze(handle->m_bpf_map_fds[SYSDIG_FILLERS_TABLE]);
|
return bpf_map_freeze(handle->m_bpf_map_fds[SCAP_FILLERS_TABLE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -852,19 +866,19 @@ static int32_t calibrate_socket_file_ops()
|
||||||
|
|
||||||
int32_t scap_bpf_start_capture(scap_t *handle)
|
int32_t scap_bpf_start_capture(scap_t *handle)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings settings;
|
struct scap_bpf_settings settings;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings) != 0)
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.capture_enabled = true;
|
settings.capture_enabled = true;
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,19 +894,19 @@ int32_t scap_bpf_start_capture(scap_t *handle)
|
||||||
|
|
||||||
int32_t scap_bpf_stop_capture(scap_t *handle)
|
int32_t scap_bpf_stop_capture(scap_t *handle)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings settings;
|
struct scap_bpf_settings settings;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings) != 0)
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.capture_enabled = false;
|
settings.capture_enabled = false;
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,7 +915,7 @@ int32_t scap_bpf_stop_capture(scap_t *handle)
|
||||||
|
|
||||||
int32_t scap_bpf_set_snaplen(scap_t* handle, uint32_t snaplen)
|
int32_t scap_bpf_set_snaplen(scap_t* handle, uint32_t snaplen)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings settings;
|
struct scap_bpf_settings settings;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
if(snaplen > RW_MAX_SNAPLEN)
|
if(snaplen > RW_MAX_SNAPLEN)
|
||||||
|
@ -910,16 +924,16 @@ int32_t scap_bpf_set_snaplen(scap_t* handle, uint32_t snaplen)
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings) != 0)
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.snaplen = snaplen;
|
settings.snaplen = snaplen;
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -928,20 +942,20 @@ int32_t scap_bpf_set_snaplen(scap_t* handle, uint32_t snaplen)
|
||||||
|
|
||||||
int32_t scap_bpf_set_fullcapture_port_range(scap_t* handle, uint16_t range_start, uint16_t range_end)
|
int32_t scap_bpf_set_fullcapture_port_range(scap_t* handle, uint16_t range_start, uint16_t range_end)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings settings;
|
struct scap_bpf_settings settings;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings) != 0)
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.fullcapture_port_range_start = range_start;
|
settings.fullcapture_port_range_start = range_start;
|
||||||
settings.fullcapture_port_range_end = range_end;
|
settings.fullcapture_port_range_end = range_end;
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,20 +964,20 @@ int32_t scap_bpf_set_fullcapture_port_range(scap_t* handle, uint16_t range_start
|
||||||
|
|
||||||
int32_t scap_bpf_set_statsd_port(scap_t* const handle, const uint16_t port)
|
int32_t scap_bpf_set_statsd_port(scap_t* const handle, const uint16_t port)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings settings = {};
|
struct scap_bpf_settings settings = {};
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings) != 0)
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.statsd_port = port;
|
settings.statsd_port = port;
|
||||||
|
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -972,19 +986,19 @@ int32_t scap_bpf_set_statsd_port(scap_t* const handle, const uint16_t port)
|
||||||
|
|
||||||
int32_t scap_bpf_disable_dynamic_snaplen(scap_t* handle)
|
int32_t scap_bpf_disable_dynamic_snaplen(scap_t* handle)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings settings;
|
struct scap_bpf_settings settings;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings) != 0)
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.do_dynamic_snaplen = false;
|
settings.do_dynamic_snaplen = false;
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,20 +1023,20 @@ int32_t scap_bpf_start_dropping_mode(scap_t* handle, uint32_t sampling_ratio)
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sysdig_bpf_settings settings;
|
struct scap_bpf_settings settings;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings) != 0)
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.sampling_ratio = sampling_ratio;
|
settings.sampling_ratio = sampling_ratio;
|
||||||
settings.dropping_mode = true;
|
settings.dropping_mode = true;
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1031,20 +1045,20 @@ int32_t scap_bpf_start_dropping_mode(scap_t* handle, uint32_t sampling_ratio)
|
||||||
|
|
||||||
int32_t scap_bpf_stop_dropping_mode(scap_t* handle)
|
int32_t scap_bpf_stop_dropping_mode(scap_t* handle)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings settings;
|
struct scap_bpf_settings settings;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings) != 0)
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.sampling_ratio = 1;
|
settings.sampling_ratio = 1;
|
||||||
settings.dropping_mode = false;
|
settings.dropping_mode = false;
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1053,19 +1067,19 @@ int32_t scap_bpf_stop_dropping_mode(scap_t* handle)
|
||||||
|
|
||||||
int32_t scap_bpf_enable_dynamic_snaplen(scap_t* handle)
|
int32_t scap_bpf_enable_dynamic_snaplen(scap_t* handle)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings settings;
|
struct scap_bpf_settings settings;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings) != 0)
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.do_dynamic_snaplen = true;
|
settings.do_dynamic_snaplen = true;
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1074,19 +1088,19 @@ int32_t scap_bpf_enable_dynamic_snaplen(scap_t* handle)
|
||||||
|
|
||||||
int32_t scap_bpf_enable_page_faults(scap_t* handle)
|
int32_t scap_bpf_enable_page_faults(scap_t* handle)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings settings;
|
struct scap_bpf_settings settings;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings) != 0)
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.page_faults = true;
|
settings.page_faults = true;
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1095,19 +1109,19 @@ int32_t scap_bpf_enable_page_faults(scap_t* handle)
|
||||||
|
|
||||||
int32_t scap_bpf_enable_tracers_capture(scap_t* handle)
|
int32_t scap_bpf_enable_tracers_capture(scap_t* handle)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings settings;
|
struct scap_bpf_settings settings;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings) != 0)
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.tracers_enabled = true;
|
settings.tracers_enabled = true;
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1274,7 +1288,7 @@ static int32_t set_runtime_params(scap_t *handle)
|
||||||
|
|
||||||
static int32_t set_default_settings(scap_t *handle)
|
static int32_t set_default_settings(scap_t *handle)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_settings settings;
|
struct scap_bpf_settings settings;
|
||||||
|
|
||||||
if(set_boot_time(handle, &settings.boot_time) != SCAP_SUCCESS)
|
if(set_boot_time(handle, &settings.boot_time) != SCAP_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -1295,9 +1309,9 @@ static int32_t set_default_settings(scap_t *handle)
|
||||||
settings.statsd_port = 8125;
|
settings.statsd_port = 8125;
|
||||||
|
|
||||||
int k = 0;
|
int k = 0;
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_SETTINGS_MAP bpf_map_update_elem < 0");
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0");
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1410,9 +1424,9 @@ int32_t scap_bpf_load(scap_t *handle, const char *bpf_probe)
|
||||||
|
|
||||||
handle->m_devs[online_cpu].m_fd = pmu_fd;
|
handle->m_devs[online_cpu].m_fd = pmu_fd;
|
||||||
|
|
||||||
if(bpf_map_update_elem(handle->m_bpf_map_fds[SYSDIG_PERF_MAP], &j, &pmu_fd, BPF_ANY) != 0)
|
if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_PERF_MAP], &j, &pmu_fd, BPF_ANY) != 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SYSDIG_PERF_MAP bpf_map_update_elem < 0: %s", scap_strerror(handle, errno));
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_PERF_MAP bpf_map_update_elem < 0: %s", scap_strerror(handle, errno));
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1455,19 +1469,20 @@ int32_t scap_bpf_get_stats(scap_t* handle, OUT scap_stats* stats)
|
||||||
|
|
||||||
for(j = 0; j < handle->m_ncpus; j++)
|
for(j = 0; j < handle->m_ncpus; j++)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_per_cpu_state v;
|
struct scap_bpf_per_cpu_state v;
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_LOCAL_STATE_MAP], &j, &v))
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_LOCAL_STATE_MAP], &j, &v))
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "Error looking up local state %d\n", j);
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "Error looking up local state %d\n", j);
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
stats->n_evts += v.n_evts;
|
stats->n_evts += v.n_evts;
|
||||||
stats->n_drops_buffer += handle->m_devs[j].m_evt_lost + v.n_drops_buffer;
|
stats->n_drops_buffer += v.n_drops_buffer;
|
||||||
|
stats->n_drops_scratch_map += v.n_drops_scratch_map;
|
||||||
stats->n_drops_pf += v.n_drops_pf;
|
stats->n_drops_pf += v.n_drops_pf;
|
||||||
stats->n_drops_bug += v.n_drops_bug;
|
stats->n_drops_bug += v.n_drops_bug;
|
||||||
stats->n_drops += handle->m_devs[j].m_evt_lost +
|
stats->n_drops += v.n_drops_buffer +
|
||||||
v.n_drops_buffer +
|
v.n_drops_scratch_map +
|
||||||
v.n_drops_pf +
|
v.n_drops_pf +
|
||||||
v.n_drops_bug;
|
v.n_drops_bug;
|
||||||
}
|
}
|
||||||
|
@ -1481,8 +1496,8 @@ int32_t scap_bpf_get_n_tracepoint_hit(scap_t* handle, long* ret)
|
||||||
|
|
||||||
for(j = 0; j < handle->m_ncpus; j++)
|
for(j = 0; j < handle->m_ncpus; j++)
|
||||||
{
|
{
|
||||||
struct sysdig_bpf_per_cpu_state v;
|
struct scap_bpf_per_cpu_state v;
|
||||||
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SYSDIG_LOCAL_STATE_MAP], &j, &v))
|
if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_LOCAL_STATE_MAP], &j, &v))
|
||||||
{
|
{
|
||||||
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "Error looking up local state %d\n", j);
|
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "Error looking up local state %d\n", j);
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
|
|
|
@ -124,13 +124,7 @@ static inline int32_t scap_bpf_advance_to_evt(scap_t *handle, uint16_t cpuid, bo
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(e->type == PERF_RECORD_LOST)
|
else if(e->type != PERF_RECORD_LOST)
|
||||||
{
|
|
||||||
struct perf_lost_sample *lost = (struct perf_lost_sample *) e;
|
|
||||||
ASSERT(*len >= sizeof(*lost));
|
|
||||||
dev->m_evt_lost += lost->lost;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
printf("Unknown event type=%d size=%d\n",
|
printf("Unknown event type=%d size=%d\n",
|
||||||
e->type, e->size);
|
e->type, e->size);
|
||||||
|
|
|
@ -378,6 +378,9 @@ int32_t scap_proc_fill_cgroups(scap_t *handle, struct scap_threadinfo* tinfo, co
|
||||||
char* subsys_list;
|
char* subsys_list;
|
||||||
char* cgroup;
|
char* cgroup;
|
||||||
char* scratch;
|
char* scratch;
|
||||||
|
// Default subsys list for cgroups v2 unified hierarchy.
|
||||||
|
// These are the ones we actually use in cri container engine.
|
||||||
|
char default_subsys_list[] = "cpu,memory,cpuset";
|
||||||
|
|
||||||
// id
|
// id
|
||||||
token = strtok_r(line, ":", &scratch);
|
token = strtok_r(line, ":", &scratch);
|
||||||
|
@ -405,12 +408,43 @@ int32_t scap_proc_fill_cgroups(scap_t *handle, struct scap_threadinfo* tinfo, co
|
||||||
// strsep() should be used to fix this but it's not available
|
// strsep() should be used to fix this but it's not available
|
||||||
// on CentOS 6 (has been added from Glibc 2.19)
|
// on CentOS 6 (has been added from Glibc 2.19)
|
||||||
if(subsys_list-token-strlen(token) > 1)
|
if(subsys_list-token-strlen(token) > 1)
|
||||||
|
{
|
||||||
|
// Subsys list empty (ie: it contains cgroup path instead)!
|
||||||
|
//
|
||||||
|
// See https://man7.org/linux/man-pages/man7/cgroups.7.html:
|
||||||
|
// 5:cpuacct,cpu,cpuset:/daemons
|
||||||
|
//
|
||||||
|
// The colon-separated fields are, from left to right:
|
||||||
|
//
|
||||||
|
// 1. For cgroups version 1 hierarchies, this field contains
|
||||||
|
// a unique hierarchy ID number that can be matched to a
|
||||||
|
// hierarchy ID in /proc/cgroups. For the cgroups version
|
||||||
|
// 2 hierarchy, this field contains the value 0.
|
||||||
|
//
|
||||||
|
// 2. For cgroups version 1 hierarchies, this field contains
|
||||||
|
// a comma-separated list of the controllers bound to the
|
||||||
|
// hierarchy. For the cgroups version 2 hierarchy, this
|
||||||
|
// field is empty.
|
||||||
|
//
|
||||||
|
// 3. This field contains the pathname of the control group
|
||||||
|
// in the hierarchy to which the process belongs. This
|
||||||
|
// pathname is relative to the mount point of the
|
||||||
|
// hierarchy.
|
||||||
|
//
|
||||||
|
// -> for cgroup2: id is always 0 and subsys list is always empty (single unified hierarchy)
|
||||||
|
// -> for cgroup1: skip subsys empty because it means controller is not mounted on any hierarchy
|
||||||
|
if (handle->m_cgroup_version == 2 && strcmp(token, "0") == 0)
|
||||||
|
{
|
||||||
|
cgroup = subsys_list;
|
||||||
|
subsys_list = default_subsys_list; // force-set a default subsys list
|
||||||
|
} else
|
||||||
{
|
{
|
||||||
// skip cgroups like this:
|
// skip cgroups like this:
|
||||||
// 0::/init.scope
|
// 0::/init.scope
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
// cgroup should be the only thing remaining so use newline as the delimiter.
|
// cgroup should be the only thing remaining so use newline as the delimiter.
|
||||||
cgroup = strtok_r(NULL, "\n", &scratch);
|
cgroup = strtok_r(NULL, "\n", &scratch);
|
||||||
if(cgroup == NULL)
|
if(cgroup == NULL)
|
||||||
|
@ -421,6 +455,7 @@ int32_t scap_proc_fill_cgroups(scap_t *handle, struct scap_threadinfo* tinfo, co
|
||||||
filename);
|
filename);
|
||||||
return SCAP_FAILURE;
|
return SCAP_FAILURE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while((token = strtok_r(subsys_list, ",", &scratch)) != NULL)
|
while((token = strtok_r(subsys_list, ",", &scratch)) != NULL)
|
||||||
{
|
{
|
||||||
|
@ -642,6 +677,36 @@ static int32_t scap_proc_add_from_proc(scap_t* handle, uint32_t tid, char* procd
|
||||||
int32_t res = SCAP_SUCCESS;
|
int32_t res = SCAP_SUCCESS;
|
||||||
struct stat dirstat;
|
struct stat dirstat;
|
||||||
|
|
||||||
|
|
||||||
|
if (handle->m_cgroup_version == 0)
|
||||||
|
{
|
||||||
|
snprintf(dir_name, sizeof(dir_name), "%s/filesystems", procdirname);
|
||||||
|
f = fopen(dir_name, "r");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
while(fgets(line, sizeof(line), f) != NULL)
|
||||||
|
{
|
||||||
|
// NOTE: we do not support mixing cgroups v1 v2 controllers.
|
||||||
|
// Neither docker nor podman support this: https://github.com/docker/for-linux/issues/1256
|
||||||
|
if (strstr(line, "cgroup2"))
|
||||||
|
{
|
||||||
|
handle->m_cgroup_version = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strstr(line, "cgroup"))
|
||||||
|
{
|
||||||
|
handle->m_cgroup_version = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
ASSERT(false);
|
||||||
|
snprintf(error, SCAP_LASTERR_SIZE, "failed to fetch cgroup version information");
|
||||||
|
return SCAP_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(dir_name, sizeof(dir_name), "%s/%u/", procdirname, tid);
|
snprintf(dir_name, sizeof(dir_name), "%s/%u/", procdirname, tid);
|
||||||
snprintf(filename, sizeof(filename), "%sexe", dir_name);
|
snprintf(filename, sizeof(filename), "%sexe", dir_name);
|
||||||
|
|
||||||
|
@ -1520,6 +1585,7 @@ int32_t scap_check_suppressed(scap_t *handle, scap_evt *pevent, bool *suppressed
|
||||||
case PPME_SYSCALL_VFORK_20_X:
|
case PPME_SYSCALL_VFORK_20_X:
|
||||||
case PPME_SYSCALL_EXECVE_19_X:
|
case PPME_SYSCALL_EXECVE_19_X:
|
||||||
case PPME_SYSCALL_EXECVEAT_X:
|
case PPME_SYSCALL_EXECVEAT_X:
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
|
|
||||||
lens = (uint16_t *)((char *)pevent + sizeof(struct ppm_evt_hdr));
|
lens = (uint16_t *)((char *)pevent + sizeof(struct ppm_evt_hdr));
|
||||||
valptr = (char *)lens + pevent->nparams * sizeof(uint16_t);
|
valptr = (char *)lens + pevent->nparams * sizeof(uint16_t);
|
||||||
|
|
|
@ -355,6 +355,9 @@ const struct ppm_syscall_desc g_syscall_info_table[PPM_SC_MAX] = {
|
||||||
/*PPM_SC_UMOUNT2*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "umount2" },
|
/*PPM_SC_UMOUNT2*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "umount2" },
|
||||||
/*PPM_SC_EXECVE*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "execve" },
|
/*PPM_SC_EXECVE*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "execve" },
|
||||||
/*PPM_SC_EXECVEAT*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "execveat" },
|
/*PPM_SC_EXECVEAT*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "execveat" },
|
||||||
|
/*PPM_SC_COPY_FILE_RANGE*/ {EC_FILE, (enum ppm_event_flags)(EF_NONE), "copy_file_range" },
|
||||||
|
/*PPM_SC_CLONE*/ {EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "clone" },
|
||||||
|
/*PPM_SC_CLONE3*/ {EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "clone3" },
|
||||||
};
|
};
|
||||||
|
|
||||||
bool validate_info_table_size()
|
bool validate_info_table_size()
|
||||||
|
|
|
@ -149,11 +149,13 @@ if(NOT MINIMAL_BUILD)
|
||||||
list(APPEND SINSP_SOURCES
|
list(APPEND SINSP_SOURCES
|
||||||
container_engine/docker/docker_linux.cpp
|
container_engine/docker/docker_linux.cpp
|
||||||
container_engine/docker/connection_linux.cpp
|
container_engine/docker/connection_linux.cpp
|
||||||
|
container_engine/docker/podman.cpp
|
||||||
container_engine/libvirt_lxc.cpp
|
container_engine/libvirt_lxc.cpp
|
||||||
container_engine/lxc.cpp
|
container_engine/lxc.cpp
|
||||||
container_engine/mesos.cpp
|
container_engine/mesos.cpp
|
||||||
container_engine/rkt.cpp
|
container_engine/rkt.cpp
|
||||||
container_engine/bpm.cpp
|
container_engine/bpm.cpp
|
||||||
|
procfs_utils.cpp
|
||||||
runc.cpp)
|
runc.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ limitations under the License.
|
||||||
#include "container_engine/docker/docker_win.h"
|
#include "container_engine/docker/docker_win.h"
|
||||||
#else
|
#else
|
||||||
#include "container_engine/docker/docker_linux.h"
|
#include "container_engine/docker/docker_linux.h"
|
||||||
|
#include "container_engine/docker/podman.h"
|
||||||
#endif
|
#endif
|
||||||
#include "container_engine/rkt.h"
|
#include "container_engine/rkt.h"
|
||||||
#include "container_engine/libvirt_lxc.h"
|
#include "container_engine/libvirt_lxc.h"
|
||||||
|
@ -534,6 +535,11 @@ void sinsp_container_manager::create_engines()
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
{
|
||||||
|
auto podman_engine = std::make_shared<container_engine::podman>(*this);
|
||||||
|
m_container_engines.push_back(podman_engine);
|
||||||
|
m_container_engine_by_type[CT_PODMAN] = podman_engine;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
auto docker_engine = std::make_shared<container_engine::docker_linux>(*this);
|
auto docker_engine = std::make_shared<container_engine::docker_linux>(*this);
|
||||||
m_container_engines.push_back(docker_engine);
|
m_container_engines.push_back(docker_engine);
|
||||||
|
@ -634,6 +640,13 @@ void sinsp_container_manager::set_cri_socket_path(const std::string &path)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sinsp_container_manager::add_cri_socket_path(const std::string &path)
|
||||||
|
{
|
||||||
|
#if !defined(MINIMAL_BUILD) && defined(HAS_CAPTURE)
|
||||||
|
libsinsp::container_engine::cri::add_cri_socket_path(path);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void sinsp_container_manager::set_cri_timeout(int64_t timeout_ms)
|
void sinsp_container_manager::set_cri_timeout(int64_t timeout_ms)
|
||||||
{
|
{
|
||||||
#if !defined(MINIMAL_BUILD) && defined(HAS_CAPTURE)
|
#if !defined(MINIMAL_BUILD) && defined(HAS_CAPTURE)
|
||||||
|
|
|
@ -151,6 +151,7 @@ public:
|
||||||
void set_query_docker_image_info(bool query_image_info);
|
void set_query_docker_image_info(bool query_image_info);
|
||||||
void set_cri_extra_queries(bool extra_queries);
|
void set_cri_extra_queries(bool extra_queries);
|
||||||
void set_cri_socket_path(const std::string& path);
|
void set_cri_socket_path(const std::string& path);
|
||||||
|
void add_cri_socket_path(const std::string &path);
|
||||||
void set_cri_timeout(int64_t timeout_ms);
|
void set_cri_timeout(int64_t timeout_ms);
|
||||||
void set_cri_async(bool async);
|
void set_cri_async(bool async);
|
||||||
void set_cri_delay(uint64_t delay_ms);
|
void set_cri_delay(uint64_t delay_ms);
|
||||||
|
|
|
@ -207,14 +207,29 @@ bool cri_async_source::lookup_sync(const libsinsp::cgroup_limits::cgroup_limits_
|
||||||
|
|
||||||
cri::cri(container_cache_interface &cache) : container_engine_base(cache)
|
cri::cri(container_cache_interface &cache) : container_engine_base(cache)
|
||||||
{
|
{
|
||||||
if(s_cri_unix_socket_path.empty()) {
|
if (s_cri_unix_socket_paths.empty())
|
||||||
return;
|
{
|
||||||
|
// Default value when empty
|
||||||
|
s_cri_unix_socket_paths.emplace_back("/run/containerd/containerd.sock");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cri_path = scap_get_host_root() + s_cri_unix_socket_path;
|
// Try all specified unix socket paths
|
||||||
|
// NOTE: having multiple container runtimes on the same host is a sporadic case,
|
||||||
|
// so we wouldn't make things complex to support that.
|
||||||
|
// On the other hand, specifying multiple unix socket paths (and using only the first match)
|
||||||
|
// will solve the "same config, multiple hosts" use case.
|
||||||
|
for (auto &p : s_cri_unix_socket_paths)
|
||||||
|
{
|
||||||
|
if(p.empty())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cri_path = scap_get_host_root() + p;
|
||||||
struct stat s = {};
|
struct stat s = {};
|
||||||
if(stat(cri_path.c_str(), &s) != 0 || (s.st_mode & S_IFMT) != S_IFSOCK) {
|
if(stat(cri_path.c_str(), &s) != 0 || (s.st_mode & S_IFMT) != S_IFSOCK)
|
||||||
return;
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cri = std::unique_ptr<libsinsp::cri::cri_interface>(new libsinsp::cri::cri_interface(cri_path));
|
m_cri = std::unique_ptr<libsinsp::cri::cri_interface>(new libsinsp::cri::cri_interface(cri_path));
|
||||||
|
@ -222,6 +237,13 @@ cri::cri(container_cache_interface &cache) : container_engine_base(cache)
|
||||||
{
|
{
|
||||||
m_cri.reset(nullptr);
|
m_cri.reset(nullptr);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Store used unix_socket_path
|
||||||
|
s_cri_unix_socket_path = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cri::cleanup()
|
void cri::cleanup()
|
||||||
|
@ -235,7 +257,13 @@ void cri::cleanup()
|
||||||
|
|
||||||
void cri::set_cri_socket_path(const std::string& path)
|
void cri::set_cri_socket_path(const std::string& path)
|
||||||
{
|
{
|
||||||
s_cri_unix_socket_path = path;
|
s_cri_unix_socket_paths.clear();
|
||||||
|
add_cri_socket_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cri::add_cri_socket_path(const std::string& path)
|
||||||
|
{
|
||||||
|
s_cri_unix_socket_paths.push_back(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cri::set_cri_timeout(int64_t timeout_ms)
|
void cri::set_cri_timeout(int64_t timeout_ms)
|
||||||
|
@ -260,9 +288,9 @@ void cri::set_cri_delay(uint64_t delay_ms)
|
||||||
bool cri::resolve(sinsp_threadinfo *tinfo, bool query_os_for_missing_info)
|
bool cri::resolve(sinsp_threadinfo *tinfo, bool query_os_for_missing_info)
|
||||||
{
|
{
|
||||||
container_cache_interface *cache = &container_cache();
|
container_cache_interface *cache = &container_cache();
|
||||||
std::string container_id;
|
std::string container_id, cgroup;
|
||||||
|
|
||||||
if(!matches_runc_cgroups(tinfo, CRI_CGROUP_LAYOUT, container_id))
|
if(!matches_runc_cgroups(tinfo, CRI_CGROUP_LAYOUT, container_id, cgroup))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,7 @@ public:
|
||||||
void update_with_size(const std::string& container_id) override;
|
void update_with_size(const std::string& container_id) override;
|
||||||
void cleanup() override;
|
void cleanup() override;
|
||||||
static void set_cri_socket_path(const std::string& path);
|
static void set_cri_socket_path(const std::string& path);
|
||||||
|
static void add_cri_socket_path(const std::string& path);
|
||||||
static void set_cri_timeout(int64_t timeout_ms);
|
static void set_cri_timeout(int64_t timeout_ms);
|
||||||
static void set_extra_queries(bool extra_queries);
|
static void set_extra_queries(bool extra_queries);
|
||||||
static void set_async(bool async_limits);
|
static void set_async(bool async_limits);
|
||||||
|
|
|
@ -55,7 +55,7 @@ void docker_async_source::run_impl()
|
||||||
sinsp_container_info res;
|
sinsp_container_info res;
|
||||||
|
|
||||||
res.m_lookup_state = sinsp_container_lookup_state::SUCCESSFUL;
|
res.m_lookup_state = sinsp_container_lookup_state::SUCCESSFUL;
|
||||||
res.m_type = CT_DOCKER;
|
res.m_type = request.container_type;
|
||||||
res.m_id = request.container_id;
|
res.m_id = request.container_id;
|
||||||
|
|
||||||
if(!parse_docker(request, res))
|
if(!parse_docker(request, res))
|
||||||
|
@ -391,7 +391,7 @@ void docker_async_source::fetch_image_info(const docker_lookup_request& request,
|
||||||
"docker_async url: %s",
|
"docker_async url: %s",
|
||||||
url.c_str());
|
url.c_str());
|
||||||
|
|
||||||
if(!(m_connection.get_docker(request, url, img_json) == docker_connection::RESP_OK))
|
if(m_connection.get_docker(request, url, img_json) != docker_connection::RESP_OK)
|
||||||
{
|
{
|
||||||
g_logger.format(sinsp_logger::SEV_ERROR,
|
g_logger.format(sinsp_logger::SEV_ERROR,
|
||||||
"docker_async (%s) image (%s): Could not fetch image info",
|
"docker_async (%s) image (%s): Could not fetch image info",
|
||||||
|
@ -420,8 +420,87 @@ void docker_async_source::fetch_image_info(const docker_lookup_request& request,
|
||||||
parse_image_info(container, img_root);
|
parse_image_info(container, img_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void docker_async_source::fetch_image_info_from_list(const docker_lookup_request& request, sinsp_container_info& container)
|
||||||
|
{
|
||||||
|
Json::Reader reader;
|
||||||
|
|
||||||
|
g_logger.format(sinsp_logger::SEV_DEBUG,
|
||||||
|
"docker_async (%s): Fetching image list",
|
||||||
|
request.container_id.c_str());
|
||||||
|
|
||||||
|
std::string img_json;
|
||||||
|
std::string url = "/images/json?digests=1";
|
||||||
|
|
||||||
|
g_logger.format(sinsp_logger::SEV_DEBUG,
|
||||||
|
"docker_async url: %s",
|
||||||
|
url.c_str());
|
||||||
|
|
||||||
|
if(!(m_connection.get_docker(request, url, img_json) == docker_connection::RESP_OK))
|
||||||
|
{
|
||||||
|
g_logger.format(sinsp_logger::SEV_ERROR,
|
||||||
|
"docker_async (%s): Could not fetch image list",
|
||||||
|
request.container_id.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_logger.format(sinsp_logger::SEV_DEBUG,
|
||||||
|
"docker_async (%s): Image list fetch returned \"%s\"",
|
||||||
|
request.container_id.c_str(),
|
||||||
|
img_json.c_str());
|
||||||
|
|
||||||
|
Json::Value img_root;
|
||||||
|
if(!reader.parse(img_json, img_root))
|
||||||
|
{
|
||||||
|
g_logger.format(sinsp_logger::SEV_ERROR,
|
||||||
|
"docker_async (%s): Could not parse json image list \"%s\"",
|
||||||
|
request.container_id.c_str(),
|
||||||
|
img_json.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string match_name = container.m_imagerepo + ':' + container.m_imagetag;
|
||||||
|
for(const auto& img : img_root)
|
||||||
|
{
|
||||||
|
// the "Names" field is podman specific. we could parse repotags
|
||||||
|
// twice but this is less effort and we only call this function
|
||||||
|
// for podman anyway
|
||||||
|
const auto& names = img["Names"];
|
||||||
|
if(!names.isArray())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const auto& name : names)
|
||||||
|
{
|
||||||
|
if(name == match_name)
|
||||||
|
{
|
||||||
|
std::string imgstr = img["Id"].asString();
|
||||||
|
size_t cpos = imgstr.find(':');
|
||||||
|
if(cpos != std::string::npos)
|
||||||
|
{
|
||||||
|
imgstr = imgstr.substr(cpos + 1);
|
||||||
|
}
|
||||||
|
container.m_imageid = std::move(imgstr);
|
||||||
|
|
||||||
|
parse_image_info(container, img);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void docker_async_source::parse_image_info(sinsp_container_info& container, const Json::Value& img)
|
void docker_async_source::parse_image_info(sinsp_container_info& container, const Json::Value& img)
|
||||||
{
|
{
|
||||||
|
const auto& podman_digest = img["Digest"];
|
||||||
|
if(podman_digest.isString())
|
||||||
|
{
|
||||||
|
// img["Digest"] if present is the digest in the form we need it
|
||||||
|
// e.g. "sha256:b6a9fc3535388a6fc04f3bdb83fb4d9d0b4ffd85e7609a6ff2f0f731427823e3"
|
||||||
|
// so just use it directly
|
||||||
|
container.m_imagedigest = podman_digest.asString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// img_root["RepoDigests"] contains only digests for images pulled from registries.
|
// img_root["RepoDigests"] contains only digests for images pulled from registries.
|
||||||
// If an image gets retagged and is never pushed to any registry, we will not find
|
// If an image gets retagged and is never pushed to any registry, we will not find
|
||||||
// that entry in container.m_imagerepo. Also, for locally built images we have the
|
// that entry in container.m_imagerepo. Also, for locally built images we have the
|
||||||
|
@ -450,14 +529,13 @@ void docker_async_source::parse_image_info(sinsp_container_info& container, cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix image digest for locally tagged images or multiple repo digests.
|
// fix image digest for locally tagged images or multiple repo digests.
|
||||||
// Case 1: One repo digest with many tags.
|
// Case 1: One repo digest with many tags.
|
||||||
// Case 2: Many repo digests with the same digest value.
|
// Case 2: Many repo digests with the same digest value.
|
||||||
if(container.m_imagedigest.empty() && imageDigestSet.size() == 1) {
|
if(container.m_imagedigest.empty() && imageDigestSet.size() == 1) {
|
||||||
container.m_imagedigest = *imageDigestSet.begin();
|
container.m_imagedigest = *imageDigestSet.begin();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for(const auto& rtag : img["RepoTags"])
|
for(const auto& rtag : img["RepoTags"])
|
||||||
{
|
{
|
||||||
if(rtag.isString())
|
if(rtag.isString())
|
||||||
|
@ -480,7 +558,12 @@ void docker_async_source::get_image_info(const docker_lookup_request& request, s
|
||||||
{
|
{
|
||||||
container.m_image = root["Config"]["Image"].asString();
|
container.m_image = root["Config"]["Image"].asString();
|
||||||
|
|
||||||
|
// podman has the image *name*, not the *id* in the Image field
|
||||||
|
// detect that with the presence of '/' in the field
|
||||||
std::string imgstr = root["Image"].asString();
|
std::string imgstr = root["Image"].asString();
|
||||||
|
if(imgstr.find('/') == std::string::npos)
|
||||||
|
{
|
||||||
|
// no '/' in the Image field, assume it's a Docker image id
|
||||||
size_t cpos = imgstr.find(':');
|
size_t cpos = imgstr.find(':');
|
||||||
if(cpos != std::string::npos)
|
if(cpos != std::string::npos)
|
||||||
{
|
{
|
||||||
|
@ -528,6 +611,34 @@ void docker_async_source::get_image_info(const docker_lookup_request& request, s
|
||||||
{
|
{
|
||||||
container.m_imagetag = "latest";
|
container.m_imagetag = "latest";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// a '/' is present in the Image field. Parse it into parts
|
||||||
|
std::string hostname, port;
|
||||||
|
sinsp_utils::split_container_image(imgstr,
|
||||||
|
hostname,
|
||||||
|
port,
|
||||||
|
container.m_imagerepo,
|
||||||
|
container.m_imagetag,
|
||||||
|
container.m_imagedigest,
|
||||||
|
false);
|
||||||
|
|
||||||
|
// we need the tag set in the call to `fetch_image_from_list`
|
||||||
|
// so set it here instead of after the if/else
|
||||||
|
if(container.m_imagetag.empty())
|
||||||
|
{
|
||||||
|
container.m_imagetag = "latest";
|
||||||
|
}
|
||||||
|
|
||||||
|
// we don't have the image id so we need to list all images
|
||||||
|
// and find the matching one by comparing the repo names
|
||||||
|
if(m_query_image_info)
|
||||||
|
{
|
||||||
|
fetch_image_info_from_list(request, container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
void docker_async_source::parse_json_mounts(const Json::Value &mnt_obj, vector<sinsp_container_info::container_mount_info> &mounts)
|
void docker_async_source::parse_json_mounts(const Json::Value &mnt_obj, vector<sinsp_container_info::container_mount_info> &mounts)
|
||||||
{
|
{
|
||||||
|
@ -549,8 +660,8 @@ bool docker_async_source::parse_docker(const docker_lookup_request& request, sin
|
||||||
string json;
|
string json;
|
||||||
|
|
||||||
g_logger.format(sinsp_logger::SEV_DEBUG,
|
g_logger.format(sinsp_logger::SEV_DEBUG,
|
||||||
"docker_async (%s): Looking up info for container",
|
"docker_async (%s): Looking up info for container via socket %s",
|
||||||
request.container_id.c_str());
|
request.container_id.c_str(), request.docker_socket.c_str());
|
||||||
|
|
||||||
std::string api_request = "/containers/" + request.container_id + "/json";
|
std::string api_request = "/containers/" + request.container_id + "/json";
|
||||||
if(request.request_rw_size)
|
if(request.request_rw_size)
|
||||||
|
@ -651,6 +762,8 @@ bool docker_async_source::parse_docker(const docker_lookup_request& request, sin
|
||||||
|
|
||||||
if(parse_docker(docker_lookup_request(secondary_container_id,
|
if(parse_docker(docker_lookup_request(secondary_container_id,
|
||||||
request.docker_socket,
|
request.docker_socket,
|
||||||
|
request.container_type,
|
||||||
|
request.uid,
|
||||||
false /*don't request size since we just need the IP*/),
|
false /*don't request size since we just need the IP*/),
|
||||||
pcnt))
|
pcnt))
|
||||||
{
|
{
|
||||||
|
@ -722,6 +835,18 @@ bool docker_async_source::parse_docker(const docker_lookup_request& request, sin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(request.container_type == sinsp_container_type::CT_PODMAN)
|
||||||
|
{
|
||||||
|
if(request.uid == 0)
|
||||||
|
{
|
||||||
|
container.m_labels.erase("podman_owner_uid");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
container.m_labels["podman_owner_uid"] = to_string(request.uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const Json::Value& env_vars = config_obj["Env"];
|
const Json::Value& env_vars = config_obj["Env"];
|
||||||
|
|
||||||
for(const auto& env_var : env_vars)
|
for(const auto& env_var : env_vars)
|
||||||
|
|
|
@ -74,6 +74,11 @@ private:
|
||||||
// Fetch the image info for the current container's m_imageid
|
// Fetch the image info for the current container's m_imageid
|
||||||
void fetch_image_info(const docker_lookup_request& request, sinsp_container_info& container);
|
void fetch_image_info(const docker_lookup_request& request, sinsp_container_info& container);
|
||||||
|
|
||||||
|
// Podman reports image repository/tag instead of the image id,
|
||||||
|
// so to fetch the image digest we need to list all the images,
|
||||||
|
// find one with matching repository/tag and get the digest from there
|
||||||
|
void fetch_image_info_from_list(const docker_lookup_request& request, sinsp_container_info& container);
|
||||||
|
|
||||||
container_cache_interface *m_cache;
|
container_cache_interface *m_cache;
|
||||||
docker_connection m_connection;
|
docker_connection m_connection;
|
||||||
static bool m_query_image_info;
|
static bool m_query_image_info;
|
||||||
|
|
|
@ -18,7 +18,7 @@ docker_base::resolve_impl(sinsp_threadinfo *tinfo, const docker_lookup_request&
|
||||||
g_logger.log("docker_async: Creating docker async source",
|
g_logger.log("docker_async: Creating docker async source",
|
||||||
sinsp_logger::SEV_DEBUG);
|
sinsp_logger::SEV_DEBUG);
|
||||||
uint64_t max_wait_ms = 10000;
|
uint64_t max_wait_ms = 10000;
|
||||||
docker_async_source *src = new docker_async_source(docker_async_source::NO_WAIT_LOOKUP, max_wait_ms, cache);
|
auto src = new docker_async_source(docker_async_source::NO_WAIT_LOOKUP, max_wait_ms, cache);
|
||||||
m_docker_info_source.reset(src);
|
m_docker_info_source.reset(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,21 +31,21 @@ docker_base::resolve_impl(sinsp_threadinfo *tinfo, const docker_lookup_request&
|
||||||
if(!query_os_for_missing_info)
|
if(!query_os_for_missing_info)
|
||||||
{
|
{
|
||||||
auto container = std::make_shared<sinsp_container_info>();
|
auto container = std::make_shared<sinsp_container_info>();
|
||||||
container->m_type = CT_DOCKER;
|
container->m_type = request.container_type;
|
||||||
container->m_id = request.container_id;
|
container->m_id = request.container_id;
|
||||||
cache->notify_new_container(*container);
|
cache->notify_new_container(*container);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAS_CAPTURE
|
#ifdef HAS_CAPTURE
|
||||||
if(cache->should_lookup(request.container_id, CT_DOCKER))
|
if(cache->should_lookup(request.container_id, request.container_type))
|
||||||
{
|
{
|
||||||
g_logger.format(sinsp_logger::SEV_DEBUG,
|
g_logger.format(sinsp_logger::SEV_DEBUG,
|
||||||
"docker_async (%s): No existing container info",
|
"docker_async (%s): No existing container info",
|
||||||
request.container_id.c_str());
|
request.container_id.c_str());
|
||||||
|
|
||||||
// give docker a chance to return metadata for this container
|
// give docker a chance to return metadata for this container
|
||||||
cache->set_lookup_status(request.container_id, CT_DOCKER, sinsp_container_lookup_state::STARTED);
|
cache->set_lookup_status(request.container_id, request.container_type, sinsp_container_lookup_state::STARTED);
|
||||||
parse_docker_async(request, cache);
|
parse_docker_async(request, cache);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,9 +35,9 @@ std::string docker_linux::m_docker_sock = "/var/run/docker.sock";
|
||||||
|
|
||||||
bool docker_linux::resolve(sinsp_threadinfo *tinfo, bool query_os_for_missing_info)
|
bool docker_linux::resolve(sinsp_threadinfo *tinfo, bool query_os_for_missing_info)
|
||||||
{
|
{
|
||||||
std::string container_id;
|
std::string container_id, cgroup;
|
||||||
|
|
||||||
if(!matches_runc_cgroups(tinfo, DOCKER_CGROUP_LAYOUT, container_id))
|
if(!matches_runc_cgroups(tinfo, DOCKER_CGROUP_LAYOUT, container_id, cgroup))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,8 @@ bool docker_linux::resolve(sinsp_threadinfo *tinfo, bool query_os_for_missing_in
|
||||||
return resolve_impl(tinfo, docker_lookup_request(
|
return resolve_impl(tinfo, docker_lookup_request(
|
||||||
container_id,
|
container_id,
|
||||||
m_docker_sock,
|
m_docker_sock,
|
||||||
|
CT_DOCKER,
|
||||||
|
0,
|
||||||
false), query_os_for_missing_info);
|
false), query_os_for_missing_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +67,6 @@ void docker_linux::update_with_size(const std::string &container_id)
|
||||||
container_id.c_str());
|
container_id.c_str());
|
||||||
|
|
||||||
sinsp_container_info result;
|
sinsp_container_info result;
|
||||||
docker_lookup_request instruction(container_id, m_docker_sock, true /*request rw size*/);
|
docker_lookup_request instruction(container_id, m_docker_sock, CT_DOCKER, 0, true /*request rw size*/);
|
||||||
(void)m_docker_info_source->lookup(instruction, result, cb);
|
(void)m_docker_info_source->lookup(instruction, result, cb);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,12 +42,9 @@ bool docker_win::resolve(sinsp_threadinfo *tinfo, bool query_os_for_missing_info
|
||||||
return resolve_impl(tinfo, docker_async_instruction(
|
return resolve_impl(tinfo, docker_async_instruction(
|
||||||
container_id,
|
container_id,
|
||||||
"",
|
"",
|
||||||
|
CT_DOCKER,
|
||||||
|
0,
|
||||||
false), query_os_for_missing_info);
|
false), query_os_for_missing_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void docker_win::update_with_size(const std::string &container_id)
|
|
||||||
{
|
|
||||||
// not supported
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CYGWING_AGENT
|
#endif // CYGWING_AGENT
|
||||||
|
|
|
@ -13,7 +13,6 @@ public:
|
||||||
|
|
||||||
// implement container_engine_base
|
// implement container_engine_base
|
||||||
bool resolve(sinsp_threadinfo *tinfo, bool query_os_for_missing_info) override;
|
bool resolve(sinsp_threadinfo *tinfo, bool query_os_for_missing_info) override;
|
||||||
void update_with_size(const std::string& container_id) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::string s_incomplete_info_name;
|
static std::string s_incomplete_info_name;
|
||||||
|
|
|
@ -1,19 +1,27 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "container_engine/sinsp_container_type.h"
|
||||||
|
|
||||||
namespace libsinsp {
|
namespace libsinsp {
|
||||||
namespace container_engine {
|
namespace container_engine {
|
||||||
|
|
||||||
struct docker_lookup_request
|
struct docker_lookup_request
|
||||||
{
|
{
|
||||||
docker_lookup_request() :
|
docker_lookup_request() :
|
||||||
|
container_type(CT_DOCKER),
|
||||||
|
uid(0),
|
||||||
request_rw_size(false)
|
request_rw_size(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
docker_lookup_request(const std::string& container_id_value,
|
docker_lookup_request(const std::string& container_id_value,
|
||||||
const std::string& docker_socket_value,
|
const std::string& docker_socket_value,
|
||||||
|
sinsp_container_type container_type_value,
|
||||||
|
unsigned long uid_value,
|
||||||
bool rw_size_value) :
|
bool rw_size_value) :
|
||||||
container_id(container_id_value),
|
container_id(container_id_value),
|
||||||
docker_socket(docker_socket_value),
|
docker_socket(docker_socket_value),
|
||||||
|
container_type(container_type_value),
|
||||||
|
uid(uid_value),
|
||||||
request_rw_size(rw_size_value)
|
request_rw_size(rw_size_value)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -29,6 +37,16 @@ struct docker_lookup_request
|
||||||
return docker_socket < rhs.docker_socket;
|
return docker_socket < rhs.docker_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(container_type != rhs.container_type)
|
||||||
|
{
|
||||||
|
return container_type < rhs.container_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uid != rhs.uid)
|
||||||
|
{
|
||||||
|
return uid < rhs.uid;
|
||||||
|
}
|
||||||
|
|
||||||
return request_rw_size < rhs.request_rw_size;
|
return request_rw_size < rhs.request_rw_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,11 +54,15 @@ struct docker_lookup_request
|
||||||
{
|
{
|
||||||
return container_id == rhs.container_id &&
|
return container_id == rhs.container_id &&
|
||||||
docker_socket == rhs.docker_socket &&
|
docker_socket == rhs.docker_socket &&
|
||||||
|
container_type == rhs.container_type &&
|
||||||
|
uid == rhs.uid &&
|
||||||
request_rw_size == rhs.request_rw_size;
|
request_rw_size == rhs.request_rw_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string container_id;
|
std::string container_id;
|
||||||
std::string docker_socket;
|
std::string docker_socket;
|
||||||
|
sinsp_container_type container_type;
|
||||||
|
unsigned long uid;
|
||||||
bool request_rw_size;
|
bool request_rw_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2021 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 "podman.h"
|
||||||
|
|
||||||
|
#include "container_engine/docker/lookup_request.h"
|
||||||
|
#include "procfs_utils.h"
|
||||||
|
#include "runc.h"
|
||||||
|
#include "sinsp.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
using namespace libsinsp::container_engine;
|
||||||
|
using namespace libsinsp::runc;
|
||||||
|
|
||||||
|
std::string podman::m_api_sock = "/run/podman/podman.sock";
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr const cgroup_layout ROOT_PODMAN_CGROUP_LAYOUT[] = {
|
||||||
|
{"/libpod-", ".scope"}, // podman
|
||||||
|
{nullptr, nullptr}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string get_systemd_cgroup(const sinsp_threadinfo *tinfo)
|
||||||
|
{
|
||||||
|
// the kernel driver does not return cgroups without subsystems (e.g. name=systemd)
|
||||||
|
// in the cgroups field, so we have to do a check here, and load /proc/pid/cgroups
|
||||||
|
// ourselves if needed
|
||||||
|
|
||||||
|
for(const auto& it : tinfo->m_cgroups)
|
||||||
|
{
|
||||||
|
if(it.first == "name=systemd")
|
||||||
|
{
|
||||||
|
return it.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream cgroups_file;
|
||||||
|
cgroups_file << scap_get_host_root() << "/proc/" << tinfo->m_tid << "/cgroup";
|
||||||
|
|
||||||
|
std::ifstream cgroups(cgroups_file.str());
|
||||||
|
return libsinsp::procfs_utils::get_systemd_cgroup(cgroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_userns_root_uid(const sinsp_threadinfo *tinfo)
|
||||||
|
{
|
||||||
|
std::stringstream uid_map_file;
|
||||||
|
uid_map_file << scap_get_host_root() << "/proc/" << tinfo->m_tid << "/uid_map";
|
||||||
|
|
||||||
|
std::ifstream uid_map(uid_map_file.str());
|
||||||
|
return libsinsp::procfs_utils::get_userns_root_uid(uid_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether `tinfo` belongs to a podman container
|
||||||
|
//
|
||||||
|
// Returns the uid of the container owner:
|
||||||
|
// 0 for root containers,
|
||||||
|
// >0 for rootless containers,
|
||||||
|
// NO_MATCH if the process is not in a podman container
|
||||||
|
int detect_podman(const sinsp_threadinfo *tinfo, std::string& container_id)
|
||||||
|
{
|
||||||
|
std::string cgroup;
|
||||||
|
if(matches_runc_cgroups(tinfo, ROOT_PODMAN_CGROUP_LAYOUT, container_id, cgroup))
|
||||||
|
{
|
||||||
|
// User: /user.slice/user-1000.slice/user@1000.service/user.slice/libpod-$ID.scope/container
|
||||||
|
// Root: /machine.slice/libpod-$ID.scope/container
|
||||||
|
int uid;
|
||||||
|
if (sscanf(cgroup.c_str(), "/user.slice/user-%d.slice/", &uid) == 1)
|
||||||
|
{
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
return 0; // root
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string systemd_cgroup = get_systemd_cgroup(tinfo);
|
||||||
|
if(systemd_cgroup.empty())
|
||||||
|
{
|
||||||
|
// can't get the cgroup name
|
||||||
|
return libsinsp::procfs_utils::NO_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t pos = systemd_cgroup.find("podman-");
|
||||||
|
if(pos == std::string::npos)
|
||||||
|
{
|
||||||
|
return libsinsp::procfs_utils::NO_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
int podman_pid; // unused except to set the sscanf return value
|
||||||
|
char c; // ^ same
|
||||||
|
if(sscanf(systemd_cgroup.c_str() + pos, "podman-%d.scope/%c", &podman_pid, &c) != 2)
|
||||||
|
{
|
||||||
|
// cgroup doesn't match the expected pattern
|
||||||
|
return libsinsp::procfs_utils::NO_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!match_one_container_id(systemd_cgroup, ".scope/", "", container_id))
|
||||||
|
{
|
||||||
|
return libsinsp::procfs_utils::NO_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uid = get_userns_root_uid(tinfo);
|
||||||
|
if(uid == 0)
|
||||||
|
{
|
||||||
|
// root doesn't spawn rootless containers
|
||||||
|
return libsinsp::procfs_utils::NO_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool podman::resolve(sinsp_threadinfo *tinfo, bool query_os_for_missing_info)
|
||||||
|
{
|
||||||
|
std::string container_id, api_sock;
|
||||||
|
int uid = detect_podman(tinfo, container_id);
|
||||||
|
|
||||||
|
switch(uid)
|
||||||
|
{
|
||||||
|
case 0: // root, use the default socket
|
||||||
|
api_sock = m_api_sock;
|
||||||
|
break;
|
||||||
|
case libsinsp::procfs_utils::NO_MATCH:
|
||||||
|
return false;
|
||||||
|
default: // rootless container, use the user's socket
|
||||||
|
api_sock = "/run/user/" + std::to_string(uid) + "/podman/podman.sock";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
docker_lookup_request request(container_id, api_sock, CT_PODMAN, uid, false);
|
||||||
|
return resolve_impl(tinfo, request, query_os_for_missing_info);
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "container_engine/docker/base.h"
|
||||||
|
|
||||||
|
namespace libsinsp {
|
||||||
|
namespace container_engine {
|
||||||
|
|
||||||
|
class podman : public docker_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
podman(container_cache_interface& cache): docker_base(cache) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::string m_api_sock;
|
||||||
|
|
||||||
|
// implement container_engine_base
|
||||||
|
bool resolve(sinsp_threadinfo *tinfo, bool query_os_for_missing_info) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,4 +30,5 @@ enum sinsp_container_type
|
||||||
CT_CRIO = 8,
|
CT_CRIO = 8,
|
||||||
CT_BPM = 9,
|
CT_BPM = 9,
|
||||||
CT_STATIC = 10,
|
CT_STATIC = 10,
|
||||||
|
CT_PODMAN = 11,
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,8 @@ static inline bool is_docker_compatible(sinsp_container_type t)
|
||||||
return t == CT_DOCKER ||
|
return t == CT_DOCKER ||
|
||||||
t == CT_CRI ||
|
t == CT_CRI ||
|
||||||
t == CT_CONTAINERD ||
|
t == CT_CONTAINERD ||
|
||||||
t == CT_CRIO;
|
t == CT_CRIO ||
|
||||||
|
t == CT_PODMAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -33,10 +33,11 @@ bool pod_uses_host_netns(const runtime::v1alpha2::PodSandboxStatusResponse& resp
|
||||||
|
|
||||||
namespace libsinsp {
|
namespace libsinsp {
|
||||||
namespace cri {
|
namespace cri {
|
||||||
std::string s_cri_unix_socket_path = "/run/containerd/containerd.sock";
|
std::vector<std::string> s_cri_unix_socket_paths;
|
||||||
int64_t s_cri_timeout = 1000;
|
int64_t s_cri_timeout = 1000;
|
||||||
int64_t s_cri_size_timeout = 10000;
|
int64_t s_cri_size_timeout = 10000;
|
||||||
sinsp_container_type s_cri_runtime_type = CT_CRI;
|
sinsp_container_type s_cri_runtime_type = CT_CRI;
|
||||||
|
std::string s_cri_unix_socket_path;
|
||||||
bool s_cri_extra_queries = true;
|
bool s_cri_extra_queries = true;
|
||||||
|
|
||||||
cri_interface::cri_interface(const std::string& cri_path)
|
cri_interface::cri_interface(const std::string& cri_path)
|
||||||
|
@ -57,9 +58,8 @@ cri_interface::cri_interface(const std::string& cri_path)
|
||||||
if (!status.ok())
|
if (!status.ok())
|
||||||
{
|
{
|
||||||
g_logger.format(sinsp_logger::SEV_NOTICE, "cri: CRI runtime returned an error after version check at %s: %s",
|
g_logger.format(sinsp_logger::SEV_NOTICE, "cri: CRI runtime returned an error after version check at %s: %s",
|
||||||
s_cri_unix_socket_path.c_str(), status.error_message().c_str());
|
cri_path.c_str(), status.error_message().c_str());
|
||||||
m_cri.reset(nullptr);
|
m_cri.reset(nullptr);
|
||||||
s_cri_unix_socket_path = "";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,6 @@ cri_interface::cri_interface(const std::string& cri_path)
|
||||||
{
|
{
|
||||||
m_cri_runtime_type = CT_CRI;
|
m_cri_runtime_type = CT_CRI;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_cri_runtime_type = m_cri_runtime_type;
|
s_cri_runtime_type = m_cri_runtime_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,10 @@ namespace libsinsp {
|
||||||
namespace cri {
|
namespace cri {
|
||||||
|
|
||||||
// these shouldn't be globals but we still need references to *the* CRI runtime
|
// these shouldn't be globals but we still need references to *the* CRI runtime
|
||||||
extern std::string s_cri_unix_socket_path;
|
extern std::vector<std::string> s_cri_unix_socket_paths;
|
||||||
extern int64_t s_cri_timeout;
|
extern int64_t s_cri_timeout;
|
||||||
|
// TODO: drop these 2 below
|
||||||
|
extern std::string s_cri_unix_socket_path;
|
||||||
extern sinsp_container_type s_cri_runtime_type;
|
extern sinsp_container_type s_cri_runtime_type;
|
||||||
extern bool s_cri_extra_queries;
|
extern bool s_cri_extra_queries;
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ typedef enum filtercheck_field_flags
|
||||||
EPF_PRINT_ONLY = 1 << 1, ///< this field can only be printed.
|
EPF_PRINT_ONLY = 1 << 1, ///< this field can only be printed.
|
||||||
EPF_REQUIRES_ARGUMENT = 1 << 2, ///< this field includes an argument, under the form 'property.argument'.
|
EPF_REQUIRES_ARGUMENT = 1 << 2, ///< this field includes an argument, under the form 'property.argument'.
|
||||||
EPF_TABLE_ONLY = 1 << 3, ///< this field is designed to be used in a table and won't appear in the field listing.
|
EPF_TABLE_ONLY = 1 << 3, ///< this field is designed to be used in a table and won't appear in the field listing.
|
||||||
|
EPF_INFO = 1 << 4, ///< this field contains summary information about the event.
|
||||||
|
EPF_CONVERSATION = 1 << 5, ///< this field can be used to identify conversations.
|
||||||
}filtercheck_field_flags;
|
}filtercheck_field_flags;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -59,6 +61,7 @@ typedef struct filtercheck_field_info
|
||||||
filtercheck_field_flags m_flags; ///< Field flags.
|
filtercheck_field_flags m_flags; ///< Field flags.
|
||||||
ppm_print_format m_print_format; ///< If this is a numeric field, this flag specifies if it should be rendered as octal, decimal or hex.
|
ppm_print_format m_print_format; ///< If this is a numeric field, this flag specifies if it should be rendered as octal, decimal or hex.
|
||||||
char m_name[64]; ///< Field name.
|
char m_name[64]; ///< Field name.
|
||||||
|
char m_display[64]; ///< Field display name (short description). May be empty.
|
||||||
char m_description[1024]; ///< Field description.
|
char m_description[1024]; ///< Field description.
|
||||||
}filtercheck_field_info;
|
}filtercheck_field_info;
|
||||||
|
|
||||||
|
@ -532,7 +535,6 @@ VISIBILITY_PRIVATE
|
||||||
friend class sinsp_analyzer;
|
friend class sinsp_analyzer;
|
||||||
friend class sinsp_filter_check_event;
|
friend class sinsp_filter_check_event;
|
||||||
friend class sinsp_filter_check_thread;
|
friend class sinsp_filter_check_thread;
|
||||||
friend class sinsp_evttype_filter;
|
|
||||||
friend class sinsp_dumper;
|
friend class sinsp_dumper;
|
||||||
friend class sinsp_analyzer_fd_listener;
|
friend class sinsp_analyzer_fd_listener;
|
||||||
friend class sinsp_analyzer_parsers;
|
friend class sinsp_analyzer_parsers;
|
||||||
|
|
|
@ -218,6 +218,8 @@ std::string get_event_type(uint16_t type)
|
||||||
case PPME_SYSCALL_CLONE_16_X:
|
case PPME_SYSCALL_CLONE_16_X:
|
||||||
case PPME_SYSCALL_CLONE_17_X:
|
case PPME_SYSCALL_CLONE_17_X:
|
||||||
case PPME_SYSCALL_CLONE_20_X: return "clone";
|
case PPME_SYSCALL_CLONE_20_X: return "clone";
|
||||||
|
case PPME_SYSCALL_CLONE3_E:
|
||||||
|
case PPME_SYSCALL_CLONE3_X: return "clone3";
|
||||||
case PPME_SYSCALL_EXECVE_8_E:
|
case PPME_SYSCALL_EXECVE_8_E:
|
||||||
case PPME_SYSCALL_EXECVE_13_E:
|
case PPME_SYSCALL_EXECVE_13_E:
|
||||||
case PPME_SYSCALL_EXECVE_14_E:
|
case PPME_SYSCALL_EXECVE_14_E:
|
||||||
|
|
|
@ -2029,298 +2029,6 @@ sinsp_filter* sinsp_filter_compiler::compile_()
|
||||||
return m_filter;
|
return m_filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
sinsp_evttype_filter::sinsp_evttype_filter()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
sinsp_evttype_filter::~sinsp_evttype_filter()
|
|
||||||
{
|
|
||||||
for(const auto &val : m_filters)
|
|
||||||
{
|
|
||||||
delete val.second->filter;
|
|
||||||
delete val.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto &ruleset : m_rulesets)
|
|
||||||
{
|
|
||||||
delete ruleset;
|
|
||||||
}
|
|
||||||
m_filters.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
sinsp_evttype_filter::ruleset_filters::ruleset_filters()
|
|
||||||
{
|
|
||||||
memset(m_filter_by_evttype, 0, PPM_EVENT_MAX * sizeof(list<filter_wrapper *> *));
|
|
||||||
memset(m_filter_by_syscall, 0, PPM_SC_MAX * sizeof(list<filter_wrapper *> *));
|
|
||||||
}
|
|
||||||
|
|
||||||
sinsp_evttype_filter::ruleset_filters::~ruleset_filters()
|
|
||||||
{
|
|
||||||
for(int i = 0; i < PPM_EVENT_MAX; i++)
|
|
||||||
{
|
|
||||||
if(m_filter_by_evttype[i])
|
|
||||||
{
|
|
||||||
delete m_filter_by_evttype[i];
|
|
||||||
m_filter_by_evttype[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < PPM_SC_MAX; i++)
|
|
||||||
{
|
|
||||||
if(m_filter_by_syscall[i])
|
|
||||||
{
|
|
||||||
delete m_filter_by_syscall[i];
|
|
||||||
m_filter_by_syscall[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sinsp_evttype_filter::ruleset_filters::add_filter(filter_wrapper *wrap)
|
|
||||||
{
|
|
||||||
for(uint32_t etype = 0; etype < PPM_EVENT_MAX; etype++)
|
|
||||||
{
|
|
||||||
if(wrap->evttypes[etype])
|
|
||||||
{
|
|
||||||
if(!m_filter_by_evttype[etype])
|
|
||||||
{
|
|
||||||
m_filter_by_evttype[etype] = new std::list<filter_wrapper *>();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_filter_by_evttype[etype]->push_back(wrap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint32_t syscall = 0; syscall < PPM_SC_MAX; syscall++)
|
|
||||||
{
|
|
||||||
if(wrap->syscalls[syscall])
|
|
||||||
{
|
|
||||||
if(!m_filter_by_syscall[syscall])
|
|
||||||
{
|
|
||||||
m_filter_by_syscall[syscall] = new std::list<filter_wrapper *>();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_filter_by_syscall[syscall]->push_back(wrap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sinsp_evttype_filter::ruleset_filters::remove_filter(filter_wrapper *wrap)
|
|
||||||
{
|
|
||||||
for(uint32_t etype = 0; etype < PPM_EVENT_MAX; etype++)
|
|
||||||
{
|
|
||||||
if(wrap->evttypes[etype])
|
|
||||||
{
|
|
||||||
if(m_filter_by_evttype[etype])
|
|
||||||
{
|
|
||||||
m_filter_by_evttype[etype]->erase(std::remove(m_filter_by_evttype[etype]->begin(),
|
|
||||||
m_filter_by_evttype[etype]->end(),
|
|
||||||
wrap),
|
|
||||||
m_filter_by_evttype[etype]->end());
|
|
||||||
|
|
||||||
if(m_filter_by_evttype[etype]->size() == 0)
|
|
||||||
{
|
|
||||||
delete m_filter_by_evttype[etype];
|
|
||||||
m_filter_by_evttype[etype] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint32_t syscall = 0; syscall < PPM_SC_MAX; syscall++)
|
|
||||||
{
|
|
||||||
if(wrap->syscalls[syscall])
|
|
||||||
{
|
|
||||||
if(m_filter_by_syscall[syscall])
|
|
||||||
{
|
|
||||||
m_filter_by_syscall[syscall]->erase(std::remove(m_filter_by_syscall[syscall]->begin(),
|
|
||||||
m_filter_by_syscall[syscall]->end(),
|
|
||||||
wrap),
|
|
||||||
m_filter_by_syscall[syscall]->end());
|
|
||||||
|
|
||||||
if(m_filter_by_syscall[syscall]->size() == 0)
|
|
||||||
{
|
|
||||||
delete m_filter_by_syscall[syscall];
|
|
||||||
m_filter_by_syscall[syscall] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool sinsp_evttype_filter::ruleset_filters::run(sinsp_evt *evt)
|
|
||||||
{
|
|
||||||
list<filter_wrapper *> *filters;
|
|
||||||
|
|
||||||
uint16_t etype = evt->m_pevt->type;
|
|
||||||
|
|
||||||
if(etype == PPME_GENERIC_E || etype == PPME_GENERIC_X)
|
|
||||||
{
|
|
||||||
sinsp_evt_param *parinfo = evt->get_param(0);
|
|
||||||
ASSERT(parinfo->m_len == sizeof(uint16_t));
|
|
||||||
uint16_t evid = *(uint16_t *)parinfo->m_val;
|
|
||||||
|
|
||||||
filters = m_filter_by_syscall[evid];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
filters = m_filter_by_evttype[etype];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filters) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &wrap : *filters)
|
|
||||||
{
|
|
||||||
if(wrap->filter->run(evt))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sinsp_evttype_filter::ruleset_filters::evttypes_for_ruleset(std::vector<bool> &evttypes)
|
|
||||||
{
|
|
||||||
evttypes.assign(PPM_EVENT_MAX+1, false);
|
|
||||||
|
|
||||||
for(uint32_t etype = 0; etype < PPM_EVENT_MAX; etype++)
|
|
||||||
{
|
|
||||||
list<filter_wrapper *> *filters = m_filter_by_evttype[etype];
|
|
||||||
if(filters)
|
|
||||||
{
|
|
||||||
evttypes[etype] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sinsp_evttype_filter::ruleset_filters::syscalls_for_ruleset(std::vector<bool> &syscalls)
|
|
||||||
{
|
|
||||||
syscalls.assign(PPM_SC_MAX+1, false);
|
|
||||||
|
|
||||||
for(uint32_t evid = 0; evid < PPM_SC_MAX; evid++)
|
|
||||||
{
|
|
||||||
list<filter_wrapper *> *filters = m_filter_by_syscall[evid];
|
|
||||||
if(filters)
|
|
||||||
{
|
|
||||||
syscalls[evid] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void sinsp_evttype_filter::add(string &name,
|
|
||||||
set<uint32_t> &evttypes,
|
|
||||||
set<uint32_t> &syscalls,
|
|
||||||
set<string> &tags,
|
|
||||||
sinsp_filter *filter)
|
|
||||||
{
|
|
||||||
filter_wrapper *wrap = new filter_wrapper();
|
|
||||||
wrap->filter = filter;
|
|
||||||
|
|
||||||
// If no evttypes or syscalls are specified, the filter is
|
|
||||||
// enabled for all evttypes/syscalls.
|
|
||||||
bool def = ((evttypes.size() == 0 && syscalls.size() == 0) ? true : false);
|
|
||||||
|
|
||||||
wrap->evttypes.assign(PPM_EVENT_MAX+1, def);
|
|
||||||
for(auto &evttype : evttypes)
|
|
||||||
{
|
|
||||||
wrap->evttypes[evttype] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
wrap->syscalls.assign(PPM_SC_MAX+1, def);
|
|
||||||
for(auto &syscall : syscalls)
|
|
||||||
{
|
|
||||||
wrap->syscalls[syscall] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_filters.insert(pair<string,filter_wrapper *>(name, wrap));
|
|
||||||
|
|
||||||
for(const auto &tag: tags)
|
|
||||||
{
|
|
||||||
auto it = m_filter_by_tag.lower_bound(tag);
|
|
||||||
|
|
||||||
if(it == m_filter_by_tag.end() ||
|
|
||||||
it->first != tag)
|
|
||||||
{
|
|
||||||
it = m_filter_by_tag.emplace_hint(it,
|
|
||||||
std::make_pair(tag, std::list<filter_wrapper*>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
it->second.push_back(wrap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sinsp_evttype_filter::enable(const string &pattern, bool enabled, uint16_t ruleset)
|
|
||||||
{
|
|
||||||
regex re(pattern);
|
|
||||||
|
|
||||||
while (m_rulesets.size() < (size_t) ruleset + 1)
|
|
||||||
{
|
|
||||||
m_rulesets.push_back(new ruleset_filters());
|
|
||||||
}
|
|
||||||
|
|
||||||
for(const auto &val : m_filters)
|
|
||||||
{
|
|
||||||
if (regex_match(val.first, re))
|
|
||||||
{
|
|
||||||
if(enabled)
|
|
||||||
{
|
|
||||||
m_rulesets[ruleset]->add_filter(val.second);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_rulesets[ruleset]->remove_filter(val.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sinsp_evttype_filter::enable_tags(const set<string> &tags, bool enabled, uint16_t ruleset)
|
|
||||||
{
|
|
||||||
while (m_rulesets.size() < (size_t) ruleset + 1)
|
|
||||||
{
|
|
||||||
m_rulesets.push_back(new ruleset_filters());
|
|
||||||
}
|
|
||||||
|
|
||||||
for(const auto &tag : tags)
|
|
||||||
{
|
|
||||||
for(const auto &wrap : m_filter_by_tag[tag])
|
|
||||||
{
|
|
||||||
if(enabled)
|
|
||||||
{
|
|
||||||
m_rulesets[ruleset]->add_filter(wrap);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_rulesets[ruleset]->remove_filter(wrap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sinsp_evttype_filter::run(sinsp_evt *evt, uint16_t ruleset)
|
|
||||||
{
|
|
||||||
if(m_rulesets.size() < (size_t) ruleset + 1)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_rulesets[ruleset]->run(evt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sinsp_evttype_filter::evttypes_for_ruleset(std::vector<bool> &evttypes, uint16_t ruleset)
|
|
||||||
{
|
|
||||||
return m_rulesets[ruleset]->evttypes_for_ruleset(evttypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sinsp_evttype_filter::syscalls_for_ruleset(std::vector<bool> &syscalls, uint16_t ruleset)
|
|
||||||
{
|
|
||||||
return m_rulesets[ruleset]->syscalls_for_ruleset(syscalls);
|
|
||||||
}
|
|
||||||
|
|
||||||
sinsp_filter_factory::sinsp_filter_factory(sinsp *inspector,
|
sinsp_filter_factory::sinsp_filter_factory(sinsp *inspector,
|
||||||
filter_check_list &available_checks)
|
filter_check_list &available_checks)
|
||||||
: m_inspector(inspector), m_available_checks(available_checks)
|
: m_inspector(inspector), m_available_checks(available_checks)
|
||||||
|
|
|
@ -103,105 +103,6 @@ private:
|
||||||
friend class sinsp_evt_formatter;
|
friend class sinsp_evt_formatter;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief This class represents a filter optimized using event
|
|
||||||
types. It actually consists of collections of sinsp_filter objects
|
|
||||||
grouped by event type.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class SINSP_PUBLIC sinsp_evttype_filter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
sinsp_evttype_filter();
|
|
||||||
virtual ~sinsp_evttype_filter();
|
|
||||||
|
|
||||||
void add(std::string &name,
|
|
||||||
std::set<uint32_t> &evttypes,
|
|
||||||
std::set<uint32_t> &syscalls,
|
|
||||||
std::set<string> &tags,
|
|
||||||
sinsp_filter* filter);
|
|
||||||
|
|
||||||
// rulesets are arbitrary numbers and should be managed by the caller.
|
|
||||||
// Note that rulesets are used to index into a std::vector so
|
|
||||||
// specifying unnecessarily large rulesets will result in
|
|
||||||
// unnecessarily large vectors.
|
|
||||||
|
|
||||||
// Find those rules matching the provided pattern and set
|
|
||||||
// their enabled status to enabled.
|
|
||||||
void enable(const std::string &pattern, bool enabled, uint16_t ruleset = 0);
|
|
||||||
|
|
||||||
// Find those rules that have a tag in the set of tags and set
|
|
||||||
// their enabled status to enabled. Note that the enabled
|
|
||||||
// status is on the rules, and not the tags--if a rule R has
|
|
||||||
// tags (a, b), and you call enable_tags([a], true) and then
|
|
||||||
// enable_tags([b], false), R will be disabled despite the
|
|
||||||
// fact it has tag a and was enabled by the first call to
|
|
||||||
// enable_tags.
|
|
||||||
void enable_tags(const std::set<string> &tags, bool enabled, uint16_t ruleset = 0);
|
|
||||||
|
|
||||||
// Match all filters against the provided event.
|
|
||||||
bool run(sinsp_evt *evt, uint16_t ruleset = 0);
|
|
||||||
|
|
||||||
// Populate the provided vector, indexed by event type, of the
|
|
||||||
// event types associated with the given ruleset id. For
|
|
||||||
// example, evttypes[10] = true would mean that this ruleset
|
|
||||||
// relates to event type 10.
|
|
||||||
void evttypes_for_ruleset(std::vector<bool> &evttypes, uint16_t ruleset);
|
|
||||||
|
|
||||||
// Populate the provided vector, indexed by syscall code, of the
|
|
||||||
// syscall codes associated with the given ruleset id. For
|
|
||||||
// example, syscalls[10] = true would mean that this ruleset
|
|
||||||
// relates to syscall code 10.
|
|
||||||
void syscalls_for_ruleset(std::vector<bool> &syscalls, uint16_t ruleset);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
struct filter_wrapper {
|
|
||||||
sinsp_filter *filter;
|
|
||||||
|
|
||||||
// Indexes from event type to enabled/disabled.
|
|
||||||
std::vector<bool> evttypes;
|
|
||||||
|
|
||||||
// Indexes from syscall code to enabled/disabled.
|
|
||||||
std::vector<bool> syscalls;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A group of filters all having the same ruleset
|
|
||||||
class ruleset_filters {
|
|
||||||
public:
|
|
||||||
ruleset_filters();
|
|
||||||
|
|
||||||
virtual ~ruleset_filters();
|
|
||||||
|
|
||||||
void add_filter(filter_wrapper *wrap);
|
|
||||||
void remove_filter(filter_wrapper *wrap);
|
|
||||||
|
|
||||||
bool run(sinsp_evt *evt);
|
|
||||||
|
|
||||||
void evttypes_for_ruleset(std::vector<bool> &evttypes);
|
|
||||||
|
|
||||||
void syscalls_for_ruleset(std::vector<bool> &syscalls);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Maps from event type to filter. There can be multiple
|
|
||||||
// filters per event type.
|
|
||||||
std::list<filter_wrapper *> *m_filter_by_evttype[PPM_EVENT_MAX];
|
|
||||||
|
|
||||||
// Maps from syscall number to filter. There can be multiple
|
|
||||||
// filters per syscall number
|
|
||||||
std::list<filter_wrapper *> *m_filter_by_syscall[PPM_SC_MAX];
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<ruleset_filters *> m_rulesets;
|
|
||||||
|
|
||||||
// Maps from tag to list of filters having that tag.
|
|
||||||
std::map<std::string, std::list<filter_wrapper *>> m_filter_by_tag;
|
|
||||||
|
|
||||||
// This holds all the filters passed to add(), so they can
|
|
||||||
// be cleaned up.
|
|
||||||
map<std::string,filter_wrapper *> m_filters;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
class sinsp_filter_factory : public gen_event_filter_factory
|
class sinsp_filter_factory : public gen_event_filter_factory
|
||||||
|
|
|
@ -95,47 +95,47 @@ int32_t gmt2local(time_t t)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_fd_fields[] =
|
const filtercheck_field_info sinsp_filter_check_fd_fields[] =
|
||||||
{
|
{
|
||||||
{PT_INT64, EPF_NONE, PF_ID, "fd.num", "the unique number identifying the file descriptor."},
|
{PT_INT64, EPF_NONE, PF_ID, "fd.num", "FD Number", "the unique number identifying the file descriptor."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_DEC, "fd.type", "type of FD. Can be 'file', 'directory', 'ipv4', 'ipv6', 'unix', 'pipe', 'event', 'signalfd', 'eventpoll', 'inotify' or 'signalfd'."},
|
{PT_CHARBUF, EPF_NONE, PF_DEC, "fd.type", "FD Type", "type of FD. Can be 'file', 'directory', 'ipv4', 'ipv6', 'unix', 'pipe', 'event', 'signalfd', 'eventpoll', 'inotify' or 'signalfd'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_DEC, "fd.typechar", "type of FD as a single character. Can be 'f' for file, 4 for IPv4 socket, 6 for IPv6 socket, 'u' for unix socket, p for pipe, 'e' for eventfd, 's' for signalfd, 'l' for eventpoll, 'i' for inotify, 'o' for unknown."},
|
{PT_CHARBUF, EPF_NONE, PF_DEC, "fd.typechar", "FD Type Char", "type of FD as a single character. Can be 'f' for file, 4 for IPv4 socket, 6 for IPv6 socket, 'u' for unix socket, p for pipe, 'e' for eventfd, 's' for signalfd, 'l' for eventpoll, 'i' for inotify, 'o' for unknown."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.name", "FD full name. If the fd is a file, this field contains the full path. If the FD is a socket, this field contain the connection tuple."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.name", "FD Name", "FD full name. If the fd is a file, this field contains the full path. If the FD is a socket, this field contain the connection tuple."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.directory", "If the fd is a file, the directory that contains it."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.directory", "FD Directory", "If the fd is a file, the directory that contains it."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.filename", "If the fd is a file, the filename without the path."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.filename", "FD Filename", "If the fd is a file, the filename without the path."},
|
||||||
{PT_IPADDR, EPF_FILTER_ONLY, PF_NA, "fd.ip", "matches the ip address (client or server) of the fd."},
|
{PT_IPADDR, EPF_FILTER_ONLY, PF_NA, "fd.ip", "FD IP Address", "matches the ip address (client or server) of the fd."},
|
||||||
{PT_IPADDR, EPF_NONE, PF_NA, "fd.cip", "client IP address."},
|
{PT_IPADDR, EPF_NONE, PF_NA, "fd.cip", "FD Client Address", "client IP address."},
|
||||||
{PT_IPADDR, EPF_NONE, PF_NA, "fd.sip", "server IP address."},
|
{PT_IPADDR, EPF_NONE, PF_NA, "fd.sip", "FD Server Address", "server IP address."},
|
||||||
{PT_IPADDR, EPF_NONE, PF_NA, "fd.lip", "local IP address."},
|
{PT_IPADDR, EPF_NONE, PF_NA, "fd.lip", "FD Local Address", "local IP address."},
|
||||||
{PT_IPADDR, EPF_NONE, PF_NA, "fd.rip", "remote IP address."},
|
{PT_IPADDR, EPF_NONE, PF_NA, "fd.rip", "FD Remote Address", "remote IP address."},
|
||||||
{PT_PORT, EPF_FILTER_ONLY, PF_DEC, "fd.port", "matches the port (either client or server) of the fd."},
|
{PT_PORT, EPF_FILTER_ONLY, PF_DEC, "fd.port", "FD Port", "matches the port (either client or server) of the fd."},
|
||||||
{PT_PORT, EPF_NONE, PF_DEC, "fd.cport", "for TCP/UDP FDs, the client port."},
|
{PT_PORT, EPF_NONE, PF_DEC, "fd.cport", "FD Client Port", "for TCP/UDP FDs, the client port."},
|
||||||
{PT_PORT, EPF_NONE, PF_DEC, "fd.sport", "for TCP/UDP FDs, server port."},
|
{PT_PORT, EPF_NONE, PF_DEC, "fd.sport", "FD Server Port", "for TCP/UDP FDs, server port."},
|
||||||
{PT_PORT, EPF_NONE, PF_DEC, "fd.lport", "for TCP/UDP FDs, the local port."},
|
{PT_PORT, EPF_NONE, PF_DEC, "fd.lport", "FD Local Port", "for TCP/UDP FDs, the local port."},
|
||||||
{PT_PORT, EPF_NONE, PF_DEC, "fd.rport", "for TCP/UDP FDs, the remote port."},
|
{PT_PORT, EPF_NONE, PF_DEC, "fd.rport", "FD Remote Port", "for TCP/UDP FDs, the remote port."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.l4proto", "the IP protocol of a socket. Can be 'tcp', 'udp', 'icmp' or 'raw'."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.l4proto", "FD IP Protocol", "the IP protocol of a socket. Can be 'tcp', 'udp', 'icmp' or 'raw'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.sockfamily", "the socket family for socket events. Can be 'ip' or 'unix'."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.sockfamily", "FD Socket Family", "the socket family for socket events. Can be 'ip' or 'unix'."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "fd.is_server", "'true' if the process owning this FD is the server endpoint in the connection."},
|
{PT_BOOL, EPF_NONE, PF_NA, "fd.is_server", "FD Server", "'true' if the process owning this FD is the server endpoint in the connection."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.uid", "a unique identifier for the FD, created by chaining the FD number and the thread ID."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.uid", "FD ID", "a unique identifier for the FD, created by chaining the FD number and the thread ID."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.containername", "chaining of the container ID and the FD name. Useful when trying to identify which container an FD belongs to."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.containername", "FD Container Name", "chaining of the container ID and the FD name. Useful when trying to identify which container an FD belongs to."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.containerdirectory", "chaining of the container ID and the directory name. Useful when trying to identify which container a directory belongs to."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.containerdirectory", "FD Container Directory", "chaining of the container ID and the directory name. Useful when trying to identify which container a directory belongs to."},
|
||||||
{PT_PORT, EPF_FILTER_ONLY, PF_NA, "fd.proto", "matches the protocol (either client or server) of the fd."},
|
{PT_PORT, EPF_FILTER_ONLY, PF_NA, "fd.proto", "FD Protocol", "matches the protocol (either client or server) of the fd."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.cproto", "for TCP/UDP FDs, the client protocol."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.cproto", "FD Client Protocol", "for TCP/UDP FDs, the client protocol."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.sproto", "for TCP/UDP FDs, server protocol."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.sproto", "FD Server Protocol", "for TCP/UDP FDs, server protocol."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.lproto", "for TCP/UDP FDs, the local protocol."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.lproto", "FD Local Protocol", "for TCP/UDP FDs, the local protocol."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.rproto", "for TCP/UDP FDs, the remote protocol."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.rproto", "FD Remote Protocol", "for TCP/UDP FDs, the remote protocol."},
|
||||||
{PT_IPNET, EPF_FILTER_ONLY, PF_NA, "fd.net", "matches the IP network (client or server) of the fd."},
|
{PT_IPNET, EPF_FILTER_ONLY, PF_NA, "fd.net", "FD IP Network", "matches the IP network (client or server) of the fd."},
|
||||||
{PT_IPNET, EPF_FILTER_ONLY, PF_NA, "fd.cnet", "matches the client IP network of the fd."},
|
{PT_IPNET, EPF_FILTER_ONLY, PF_NA, "fd.cnet", "FD Client Network", "matches the client IP network of the fd."},
|
||||||
{PT_IPNET, EPF_FILTER_ONLY, PF_NA, "fd.snet", "matches the server IP network of the fd."},
|
{PT_IPNET, EPF_FILTER_ONLY, PF_NA, "fd.snet", "FD Server Network", "matches the server IP network of the fd."},
|
||||||
{PT_IPNET, EPF_FILTER_ONLY, PF_NA, "fd.lnet", "matches the local IP network of the fd."},
|
{PT_IPNET, EPF_FILTER_ONLY, PF_NA, "fd.lnet", "FD Local Network", "matches the local IP network of the fd."},
|
||||||
{PT_IPNET, EPF_FILTER_ONLY, PF_NA, "fd.rnet", "matches the remote IP network of the fd."},
|
{PT_IPNET, EPF_FILTER_ONLY, PF_NA, "fd.rnet", "FD Remote Network", "matches the remote IP network of the fd."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "fd.connected", "for TCP/UDP FDs, 'true' if the socket is connected."},
|
{PT_BOOL, EPF_NONE, PF_NA, "fd.connected", "FD Connected", "for TCP/UDP FDs, 'true' if the socket is connected."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "fd.name_changed", "True when an event changes the name of an fd used by this event. This can occur in some cases such as udp connections where the connection tuple changes."},
|
{PT_BOOL, EPF_NONE, PF_NA, "fd.name_changed", "FD Name Changed", "True when an event changes the name of an fd used by this event. This can occur in some cases such as udp connections where the connection tuple changes."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.cip.name", "Domain name associated with the client IP address."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.cip.name", "FD Client Domain Name", "Domain name associated with the client IP address."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.sip.name", "Domain name associated with the server IP address."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.sip.name", "FD Server Domain Name", "Domain name associated with the server IP address."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.lip.name", "Domain name associated with the local IP address."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.lip.name", "FD Local Domain Name", "Domain name associated with the local IP address."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.rip.name", "Domain name associated with the remote IP address."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.rip.name", "FD Remote Domain Name", "Domain name associated with the remote IP address."},
|
||||||
{PT_INT32, EPF_NONE, PF_HEX, "fd.dev", "device number (major/minor) containing the referenced file"},
|
{PT_INT32, EPF_NONE, PF_HEX, "fd.dev", "FD Device", "device number (major/minor) containing the referenced file"},
|
||||||
{PT_INT32, EPF_NONE, PF_DEC, "fd.dev.major", "major device number containing the referenced file"},
|
{PT_INT32, EPF_NONE, PF_DEC, "fd.dev.major", "FD Major Device", "major device number containing the referenced file"},
|
||||||
{PT_INT32, EPF_NONE, PF_DEC, "fd.dev.minor", "minor device number containing the referenced file"},
|
{PT_INT32, EPF_NONE, PF_DEC, "fd.dev.minor", "FD Minor Device", "minor device number containing the referenced file"},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_fd::sinsp_filter_check_fd()
|
sinsp_filter_check_fd::sinsp_filter_check_fd()
|
||||||
|
@ -1810,56 +1810,56 @@ bool sinsp_filter_check_fd::compare(sinsp_evt *evt)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_thread_fields[] =
|
const filtercheck_field_info sinsp_filter_check_thread_fields[] =
|
||||||
{
|
{
|
||||||
{PT_INT64, EPF_NONE, PF_ID, "proc.pid", "the id of the process generating the event."},
|
{PT_INT64, EPF_NONE, PF_ID, "proc.pid", "Process ID", "the id of the process generating the event."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.exe", "the first command line argument (usually the executable name or a custom one)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.exe", "First Argument", "the first command line argument (usually the executable name or a custom one)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.name", "the name (excluding the path) of the executable generating the event."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.name", "Name", "the name (excluding the path) of the executable generating the event."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.args", "the arguments passed on the command line when starting the process generating the event."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.args", "Arguments", "the arguments passed on the command line when starting the process generating the event."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.env", "the environment variables of the process generating the event."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.env", "Environment", "the environment variables of the process generating the event."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.cmdline", "full process command line, i.e. proc.name + proc.args."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.cmdline", "Command Line", "full process command line, i.e. proc.name + proc.args."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.exeline", "full process command line, with exe as first argument, i.e. proc.exe + proc.args."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.exeline", "Executable Command Line", "full process command line, with exe as first argument, i.e. proc.exe + proc.args."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.cwd", "the current working directory of the event."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.cwd", "Current Working Directory", "the current working directory of the event."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "proc.nthreads", "the number of threads that the process generating the event currently has, including the main process thread."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "proc.nthreads", "Threads", "the number of threads that the process generating the event currently has, including the main process thread."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "proc.nchilds", "the number of child threads that the process generating the event currently has. This excludes the main process thread."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "proc.nchilds", "Children", "the number of child threads that the process generating the event currently has. This excludes the main process thread."},
|
||||||
{PT_INT64, EPF_NONE, PF_ID, "proc.ppid", "the pid of the parent of the process generating the event."},
|
{PT_INT64, EPF_NONE, PF_ID, "proc.ppid", "Parent Process ID", "the pid of the parent of the process generating the event."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.pname", "the name (excluding the path) of the parent of the process generating the event."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.pname", "Parent Name", "the name (excluding the path) of the parent of the process generating the event."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.pcmdline", "the full command line (proc.name + proc.args) of the parent of the process generating the event."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.pcmdline", "Parent Command Line", "the full command line (proc.name + proc.args) of the parent of the process generating the event."},
|
||||||
{PT_INT64, EPF_NONE, PF_ID, "proc.apid", "the pid of one of the process ancestors. E.g. proc.apid[1] returns the parent pid, proc.apid[2] returns the grandparent pid, and so on. proc.apid[0] is the pid of the current process. proc.apid without arguments can be used in filters only and matches any of the process ancestors, e.g. proc.apid=1234."},
|
{PT_INT64, EPF_NONE, PF_ID, "proc.apid", "Ancestor Process ID", "the pid of one of the process ancestors. E.g. proc.apid[1] returns the parent pid, proc.apid[2] returns the grandparent pid, and so on. proc.apid[0] is the pid of the current process. proc.apid without arguments can be used in filters only and matches any of the process ancestors, e.g. proc.apid=1234."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.aname", "the name (excluding the path) of one of the process ancestors. E.g. proc.aname[1] returns the parent name, proc.aname[2] returns the grandparent name, and so on. proc.aname[0] is the name of the current process. proc.aname without arguments can be used in filters only and matches any of the process ancestors, e.g. proc.aname=bash."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.aname", "Ancestor Name", "the name (excluding the path) of one of the process ancestors. E.g. proc.aname[1] returns the parent name, proc.aname[2] returns the grandparent name, and so on. proc.aname[0] is the name of the current process. proc.aname without arguments can be used in filters only and matches any of the process ancestors, e.g. proc.aname=bash."},
|
||||||
{PT_INT64, EPF_NONE, PF_ID, "proc.loginshellid", "the pid of the oldest shell among the ancestors of the current process, if there is one. This field can be used to separate different user sessions, and is useful in conjunction with chisels like spy_user."},
|
{PT_INT64, EPF_NONE, PF_ID, "proc.loginshellid", "Login Shell ID", "the pid of the oldest shell among the ancestors of the current process, if there is one. This field can be used to separate different user sessions, and is useful in conjunction with chisels like spy_user."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_DEC, "proc.duration", "number of nanoseconds since the process started."},
|
{PT_RELTIME, EPF_NONE, PF_DEC, "proc.duration", "Duration", "number of nanoseconds since the process started."},
|
||||||
{PT_UINT64, EPF_NONE, PF_DEC, "proc.fdopencount", "number of open FDs for the process"},
|
{PT_UINT64, EPF_NONE, PF_DEC, "proc.fdopencount", "FD Count", "number of open FDs for the process"},
|
||||||
{PT_INT64, EPF_NONE, PF_DEC, "proc.fdlimit", "maximum number of FDs the process can open."},
|
{PT_INT64, EPF_NONE, PF_DEC, "proc.fdlimit", "FD Limit", "maximum number of FDs the process can open."},
|
||||||
{PT_DOUBLE, EPF_NONE, PF_DEC, "proc.fdusage", "the ratio between open FDs and maximum available FDs for the process."},
|
{PT_DOUBLE, EPF_NONE, PF_DEC, "proc.fdusage", "FD Usage", "the ratio between open FDs and maximum available FDs for the process."},
|
||||||
{PT_UINT64, EPF_NONE, PF_DEC, "proc.vmsize", "total virtual memory for the process (as kb)."},
|
{PT_UINT64, EPF_NONE, PF_DEC, "proc.vmsize", "VM Size", "total virtual memory for the process (as kb)."},
|
||||||
{PT_UINT64, EPF_NONE, PF_DEC, "proc.vmrss", "resident non-swapped memory for the process (as kb)."},
|
{PT_UINT64, EPF_NONE, PF_DEC, "proc.vmrss", "VM RSS", "resident non-swapped memory for the process (as kb)."},
|
||||||
{PT_UINT64, EPF_NONE, PF_DEC, "proc.vmswap", "swapped memory for the process (as kb)."},
|
{PT_UINT64, EPF_NONE, PF_DEC, "proc.vmswap", "VM Swap", "swapped memory for the process (as kb)."},
|
||||||
{PT_UINT64, EPF_NONE, PF_DEC, "thread.pfmajor", "number of major page faults since thread start."},
|
{PT_UINT64, EPF_NONE, PF_DEC, "thread.pfmajor", "Major Page Faults", "number of major page faults since thread start."},
|
||||||
{PT_UINT64, EPF_NONE, PF_DEC, "thread.pfminor", "number of minor page faults since thread start."},
|
{PT_UINT64, EPF_NONE, PF_DEC, "thread.pfminor", "Minor Page Faults", "number of minor page faults since thread start."},
|
||||||
{PT_INT64, EPF_NONE, PF_ID, "thread.tid", "the id of the thread generating the event."},
|
{PT_INT64, EPF_NONE, PF_ID, "thread.tid", "Thread ID", "the id of the thread generating the event."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "thread.ismain", "'true' if the thread generating the event is the main one in the process."},
|
{PT_BOOL, EPF_NONE, PF_NA, "thread.ismain", "Main Thread", "'true' if the thread generating the event is the main one in the process."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_DEC, "thread.exectime", "CPU time spent by the last scheduled thread, in nanoseconds. Exported by switch events only."},
|
{PT_RELTIME, EPF_NONE, PF_DEC, "thread.exectime", "Scheduled Thread CPU Time", "CPU time spent by the last scheduled thread, in nanoseconds. Exported by switch events only."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_DEC, "thread.totexectime", "Total CPU time, in nanoseconds since the beginning of the capture, for the current thread. Exported by switch events only."},
|
{PT_RELTIME, EPF_NONE, PF_DEC, "thread.totexectime", "Current Thread CPU Time", "Total CPU time, in nanoseconds since the beginning of the capture, for the current thread. Exported by switch events only."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "thread.cgroups", "all the cgroups the thread belongs to, aggregated into a single string."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "thread.cgroups", "Thread Cgroups", "all the cgroups the thread belongs to, aggregated into a single string."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "thread.cgroup", "the cgroup the thread belongs to, for a specific subsystem. E.g. thread.cgroup.cpuacct."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "thread.cgroup", "Thread Cgroup", "the cgroup the thread belongs to, for a specific subsystem. E.g. thread.cgroup.cpuacct."},
|
||||||
{PT_INT64, EPF_NONE, PF_ID, "thread.vtid", "the id of the thread generating the event as seen from its current PID namespace."},
|
{PT_INT64, EPF_NONE, PF_ID, "thread.vtid", "Virtual Thread ID", "the id of the thread generating the event as seen from its current PID namespace."},
|
||||||
{PT_INT64, EPF_NONE, PF_ID, "proc.vpid", "the id of the process generating the event as seen from its current PID namespace."},
|
{PT_INT64, EPF_NONE, PF_ID, "proc.vpid", "Virtual Process ID", "the id of the process generating the event as seen from its current PID namespace."},
|
||||||
{PT_DOUBLE, EPF_NONE, PF_NA, "thread.cpu", "the CPU consumed by the thread in the last second."},
|
{PT_DOUBLE, EPF_NONE, PF_NA, "thread.cpu", "Thread CPU", "the CPU consumed by the thread in the last second."},
|
||||||
{PT_DOUBLE, EPF_NONE, PF_NA, "thread.cpu.user", "the user CPU consumed by the thread in the last second."},
|
{PT_DOUBLE, EPF_NONE, PF_NA, "thread.cpu.user", "Thread User CPU", "the user CPU consumed by the thread in the last second."},
|
||||||
{PT_DOUBLE, EPF_NONE, PF_NA, "thread.cpu.system", "the system CPU consumed by the thread in the last second."},
|
{PT_DOUBLE, EPF_NONE, PF_NA, "thread.cpu.system", "Thread System CPU", "the system CPU consumed by the thread in the last second."},
|
||||||
{PT_UINT64, EPF_NONE, PF_DEC, "thread.vmsize", "For the process main thread, this is the total virtual memory for the process (as kb). For the other threads, this field is zero."},
|
{PT_UINT64, EPF_NONE, PF_DEC, "thread.vmsize", "Thread VM Size (kb)", "For the process main thread, this is the total virtual memory for the process (as kb). For the other threads, this field is zero."},
|
||||||
{PT_UINT64, EPF_NONE, PF_DEC, "thread.vmrss", "For the process main thread, this is the resident non-swapped memory for the process (as kb). For the other threads, this field is zero."},
|
{PT_UINT64, EPF_NONE, PF_DEC, "thread.vmrss", "Thread VM RSS (kb)", "For the process main thread, this is the resident non-swapped memory for the process (as kb). For the other threads, this field is zero."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "thread.vmsize.b", "For the process main thread, this is the total virtual memory for the process (in bytes). For the other threads, this field is zero."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "thread.vmsize.b", "Thread VM Size (b)", "For the process main thread, this is the total virtual memory for the process (in bytes). For the other threads, this field is zero."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "thread.vmrss.b", "For the process main thread, this is the resident non-swapped memory for the process (in bytes). For the other threads, this field is zero."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "thread.vmrss.b", "Thread VM RSS (b)", "For the process main thread, this is the resident non-swapped memory for the process (in bytes). For the other threads, this field is zero."},
|
||||||
{PT_INT64, EPF_NONE, PF_ID, "proc.sid", "the session id of the process generating the event."},
|
{PT_INT64, EPF_NONE, PF_ID, "proc.sid", "Process Session ID", "the session id of the process generating the event."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.sname", "the name of the current process's session leader. This is either the process with pid=proc.sid or the eldest ancestor that has the same sid as the current process."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.sname", "Process Session Name", "the name of the current process's session leader. This is either the process with pid=proc.sid or the eldest ancestor that has the same sid as the current process."},
|
||||||
{PT_INT32, EPF_NONE, PF_ID, "proc.tty", "The controlling terminal of the process. 0 for processes without a terminal."},
|
{PT_INT32, EPF_NONE, PF_ID, "proc.tty", "Process TTY", "The controlling terminal of the process. 0 for processes without a terminal."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.exepath", "The full executable path of the process."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.exepath", "Process Executable Path", "The full executable path of the process."},
|
||||||
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "thread.nametid", "this field chains the process name and tid of a thread and can be used as a specific identifier of a thread for a specific execve."},
|
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "thread.nametid", "Thread Name + ID", "this field chains the process name and tid of a thread and can be used as a specific identifier of a thread for a specific execve."},
|
||||||
{PT_INT64, EPF_NONE, PF_ID, "proc.vpgid", "the process group id of the process generating the event, as seen from its current PID namespace."},
|
{PT_INT64, EPF_NONE, PF_ID, "proc.vpgid", "Process Virtual Group ID", "the process group id of the process generating the event, as seen from its current PID namespace."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "proc.is_container_healthcheck", "true if this process is running as a part of the container's health check."},
|
{PT_BOOL, EPF_NONE, PF_NA, "proc.is_container_healthcheck", "Process Is Container Healthcheck", "true if this process is running as a part of the container's health check."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "proc.is_container_liveness_probe", "true if this process is running as a part of the container's liveness probe."},
|
{PT_BOOL, EPF_NONE, PF_NA, "proc.is_container_liveness_probe", "Process Is Container Liveness", "true if this process is running as a part of the container's liveness probe."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "proc.is_container_readiness_probe", "true if this process is running as a part of the container's readiness probe."},
|
{PT_BOOL, EPF_NONE, PF_NA, "proc.is_container_readiness_probe", "Process Is Container Readiness", "true if this process is running as a part of the container's readiness probe."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "proc.is_exe_writable", "true if this process' executable file is writable by the same user that spawned the process."},
|
{PT_BOOL, EPF_NONE, PF_NA, "proc.is_exe_writable", "Process Executable Is Writable", "true if this process' executable file is writable by the same user that spawned the process."},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_thread::sinsp_filter_check_thread()
|
sinsp_filter_check_thread::sinsp_filter_check_thread()
|
||||||
|
@ -2798,20 +2798,20 @@ bool sinsp_filter_check_thread::compare(sinsp_evt *evt)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_gen_event_fields[] =
|
const filtercheck_field_info sinsp_filter_check_gen_event_fields[] =
|
||||||
{
|
{
|
||||||
{PT_UINT64, EPF_NONE, PF_ID, "evt.num", "event number."},
|
{PT_UINT64, EPF_NONE, PF_ID, "evt.num", "Event Number", "event number."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.time", "event timestamp as a time string that includes the nanosecond part."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.time", "Time", "event timestamp as a time string that includes the nanosecond part."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.time.s", "event timestamp as a time string with no nanoseconds."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.time.s", "Time (s)", "event timestamp as a time string with no nanoseconds."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.time.iso8601", "event timestamp in ISO 8601 format, including nanoseconds and time zone offset (in UTC)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.time.iso8601", "ISO 8601 Time", "event timestamp in ISO 8601 format, including nanoseconds and time zone offset (in UTC)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.datetime", "event timestamp as a time string that includes the date."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.datetime", "Datetime", "event timestamp as a time string that includes the date."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.datetime.s", "event timestamp as a datetime string with no nanoseconds."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.datetime.s", "Datetime (s)", "event timestamp as a datetime string with no nanoseconds."},
|
||||||
{PT_ABSTIME, EPF_NONE, PF_DEC, "evt.rawtime", "absolute event timestamp, i.e. nanoseconds from epoch."},
|
{PT_ABSTIME, EPF_NONE, PF_DEC, "evt.rawtime", "Absolute Time", "absolute event timestamp, i.e. nanoseconds from epoch."},
|
||||||
{PT_ABSTIME, EPF_NONE, PF_DEC, "evt.rawtime.s", "integer part of the event timestamp (e.g. seconds since epoch)."},
|
{PT_ABSTIME, EPF_NONE, PF_DEC, "evt.rawtime.s", "Absolute Time (s)", "integer part of the event timestamp (e.g. seconds since epoch)."},
|
||||||
{PT_ABSTIME, EPF_NONE, PF_10_PADDED_DEC, "evt.rawtime.ns", "fractional part of the absolute event timestamp."},
|
{PT_ABSTIME, EPF_NONE, PF_10_PADDED_DEC, "evt.rawtime.ns", "Absolute Time (ns)", "fractional part of the absolute event timestamp."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_10_PADDED_DEC, "evt.reltime", "number of nanoseconds from the beginning of the capture."},
|
{PT_RELTIME, EPF_NONE, PF_10_PADDED_DEC, "evt.reltime", "Relative Time", "number of nanoseconds from the beginning of the capture."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.reltime.s", "number of seconds from the beginning of the capture."},
|
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.reltime.s", "Relative Time (s)", "number of seconds from the beginning of the capture."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_10_PADDED_DEC, "evt.reltime.ns", "fractional part (in ns) of the time from the beginning of the capture."},
|
{PT_RELTIME, EPF_NONE, PF_10_PADDED_DEC, "evt.reltime.ns", "Relative Time (ns)", "fractional part (in ns) of the time from the beginning of the capture."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.pluginname", "if the event comes from a plugin, the name of the plugin that generated it. The plugin must be currently loaded."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.pluginname", "Plugin Name", "if the event comes from a plugin, the name of the plugin that generated it. The plugin must be currently loaded."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.plugininfo", "if the event comes from a plugin, a summary of the event as formatted by the plugin. The plugin must be currently loaded."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.plugininfo", "Plugin Info", "if the event comes from a plugin, a summary of the event as formatted by the plugin. The plugin must be currently loaded."},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_gen_event::sinsp_filter_check_gen_event()
|
sinsp_filter_check_gen_event::sinsp_filter_check_gen_event()
|
||||||
|
@ -2941,63 +2941,63 @@ uint8_t* sinsp_filter_check_gen_event::extract(sinsp_evt *evt, OUT uint32_t* len
|
||||||
|
|
||||||
const filtercheck_field_info sinsp_filter_check_event_fields[] =
|
const filtercheck_field_info sinsp_filter_check_event_fields[] =
|
||||||
{
|
{
|
||||||
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.latency", "delta between an exit event and the correspondent enter event, in nanoseconds."},
|
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.latency", "Latency", "delta between an exit event and the correspondent enter event, in nanoseconds."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.latency.s", "integer part of the event latency delta."},
|
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.latency.s", "Latency (s)", "integer part of the event latency delta."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_10_PADDED_DEC, "evt.latency.ns", "fractional part of the event latency delta."},
|
{PT_RELTIME, EPF_NONE, PF_10_PADDED_DEC, "evt.latency.ns", "Latency (ns)", "fractional part of the event latency delta."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.latency.quantized", "10-base log of the delta between an exit event and the correspondent enter event."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.latency.quantized", "Quantized Latency", "10-base log of the delta between an exit event and the correspondent enter event."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.latency.human", "delta between an exit event and the correspondent enter event, as a human readable string (e.g. 10.3ms)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.latency.human", "Human-Readable Latency", "delta between an exit event and the correspondent enter event, as a human readable string (e.g. 10.3ms)."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.deltatime", "delta between this event and the previous event, in nanoseconds."},
|
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.deltatime", "Delta", "delta between this event and the previous event, in nanoseconds."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.deltatime.s", "integer part of the delta between this event and the previous event."},
|
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.deltatime.s", "Delta (s)", "integer part of the delta between this event and the previous event."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_10_PADDED_DEC, "evt.deltatime.ns", "fractional part of the delta between this event and the previous event."},
|
{PT_RELTIME, EPF_NONE, PF_10_PADDED_DEC, "evt.deltatime.ns", "Delta (ns)", "fractional part of the delta between this event and the previous event."},
|
||||||
{PT_CHARBUF, EPF_PRINT_ONLY, PF_NA, "evt.outputtime", "this depends on -t param, default is %evt.time ('h')."},
|
{PT_CHARBUF, EPF_PRINT_ONLY, PF_NA, "evt.outputtime", "Output Time", "this depends on -t param, default is %evt.time ('h')."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_DIR, "evt.dir", "event direction can be either '>' for enter events or '<' for exit events."},
|
{PT_CHARBUF, EPF_NONE, PF_DIR, "evt.dir", "Direction", "event direction can be either '>' for enter events or '<' for exit events."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.type", "The name of the event (e.g. 'open')."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.type", "Type", "The name of the event (e.g. 'open')."},
|
||||||
{PT_UINT32, EPF_REQUIRES_ARGUMENT, PF_NA, "evt.type.is", "allows one to specify an event type, and returns 1 for events that are of that type. For example, evt.type.is.open returns 1 for open events, 0 for any other event."},
|
{PT_UINT32, EPF_REQUIRES_ARGUMENT, PF_NA, "evt.type.is", "Type Is", "allows one to specify an event type, and returns 1 for events that are of that type. For example, evt.type.is.open returns 1 for open events, 0 for any other event."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "syscall.type", "For system call events, the name of the system call (e.g. 'open'). Unset for other events (e.g. switch or internal events). Use this field instead of evt.type if you need to make sure that the filtered/printed value is actually a system call."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "syscall.type", "Syscall Type", "For system call events, the name of the system call (e.g. 'open'). Unset for other events (e.g. switch or internal events). Use this field instead of evt.type if you need to make sure that the filtered/printed value is actually a system call."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.category", "The event category. Example values are 'file' (for file operations like open and close), 'net' (for network operations like socket and bind), memory (for things like brk or mmap), and so on."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.category", "Category", "The event category. Example values are 'file' (for file operations like open and close), 'net' (for network operations like socket and bind), memory (for things like brk or mmap), and so on."},
|
||||||
{PT_INT16, EPF_NONE, PF_ID, "evt.cpu", "number of the CPU where this event happened."},
|
{PT_INT16, EPF_NONE, PF_ID, "evt.cpu", "CPU Number", "number of the CPU where this event happened."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.args", "all the event arguments, aggregated into a single string."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.args", "Arguments", "all the event arguments, aggregated into a single string."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evt.arg", "one of the event arguments specified by name or by number. Some events (e.g. return codes or FDs) will be converted into a text representation when possible. E.g. 'evt.arg.fd' or 'evt.arg[0]'."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evt.arg", "Argument", "one of the event arguments specified by name or by number. Some events (e.g. return codes or FDs) will be converted into a text representation when possible. E.g. 'evt.arg.fd' or 'evt.arg[0]'."},
|
||||||
{PT_DYN, EPF_REQUIRES_ARGUMENT, PF_NA, "evt.rawarg", "one of the event arguments specified by name. E.g. 'evt.rawarg.fd'."},
|
{PT_DYN, EPF_REQUIRES_ARGUMENT, PF_NA, "evt.rawarg", "Raw Argument", "one of the event arguments specified by name. E.g. 'evt.rawarg.fd'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.info", "for most events, this field returns the same value as evt.args. However, for some events (like writes to /dev/log) it provides higher level information coming from decoding the arguments."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.info", "Information", "for most events, this field returns the same value as evt.args. However, for some events (like writes to /dev/log) it provides higher level information coming from decoding the arguments."},
|
||||||
{PT_BYTEBUF, EPF_NONE, PF_NA, "evt.buffer", "the binary data buffer for events that have one, like read(), recvfrom(), etc. Use this field in filters with 'contains' to search into I/O data buffers."},
|
{PT_BYTEBUF, EPF_NONE, PF_NA, "evt.buffer", "Buffer", "the binary data buffer for events that have one, like read(), recvfrom(), etc. Use this field in filters with 'contains' to search into I/O data buffers."},
|
||||||
{PT_UINT64, EPF_NONE, PF_DEC, "evt.buflen", "the length of the binary data buffer for events that have one, like read(), recvfrom(), etc."},
|
{PT_UINT64, EPF_NONE, PF_DEC, "evt.buflen", "Buffer Length", "the length of the binary data buffer for events that have one, like read(), recvfrom(), etc."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_DEC, "evt.res", "event return value, as a string. If the event failed, the result is an error code string (e.g. 'ENOENT'), otherwise the result is the string 'SUCCESS'."},
|
{PT_CHARBUF, EPF_NONE, PF_DEC, "evt.res", "Return Value", "event return value, as a string. If the event failed, the result is an error code string (e.g. 'ENOENT'), otherwise the result is the string 'SUCCESS'."},
|
||||||
{PT_INT64, EPF_NONE, PF_DEC, "evt.rawres", "event return value, as a number (e.g. -2). Useful for range comparisons."},
|
{PT_INT64, EPF_NONE, PF_DEC, "evt.rawres", "Raw Return Value", "event return value, as a number (e.g. -2). Useful for range comparisons."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "evt.failed", "'true' for events that returned an error status."},
|
{PT_BOOL, EPF_NONE, PF_NA, "evt.failed", "Failed", "'true' for events that returned an error status."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_io", "'true' for events that read or write to FDs, like read(), send, recvfrom(), etc."},
|
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_io", "Is I/O", "'true' for events that read or write to FDs, like read(), send, recvfrom(), etc."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_io_read", "'true' for events that read from FDs, like read(), recv(), recvfrom(), etc."},
|
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_io_read", "Is Read", "'true' for events that read from FDs, like read(), recv(), recvfrom(), etc."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_io_write", "'true' for events that write to FDs, like write(), send(), etc."},
|
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_io_write", "Is Write", "'true' for events that write to FDs, like write(), send(), etc."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.io_dir", "'r' for events that read from FDs, like read(); 'w' for events that write to FDs, like write()."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "evt.io_dir", "I/O Direction", "'r' for events that read from FDs, like read(); 'w' for events that write to FDs, like write()."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_wait", "'true' for events that make the thread wait, e.g. sleep(), select(), poll()."},
|
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_wait", "Is Wait", "'true' for events that make the thread wait, e.g. sleep(), select(), poll()."},
|
||||||
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.wait_latency", "for events that make the thread wait (e.g. sleep(), select(), poll()), this is the time spent waiting for the event to return, in nanoseconds."},
|
{PT_RELTIME, EPF_NONE, PF_DEC, "evt.wait_latency", "Wait Latency", "for events that make the thread wait (e.g. sleep(), select(), poll()), this is the time spent waiting for the event to return, in nanoseconds."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_syslog", "'true' for events that are writes to /dev/log."},
|
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_syslog", "Is Syslog", "'true' for events that are writes to /dev/log."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count", "This filter field always returns 1 and can be used to count events from inside chisels."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count", "Count", "This filter field always returns 1 and can be used to count events from inside chisels."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.error", "This filter field returns 1 for events that returned with an error, and can be used to count event failures from inside chisels."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.error", "Error Count", "This filter field returns 1 for events that returned with an error, and can be used to count event failures from inside chisels."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.error.file", "This filter field returns 1 for events that returned with an error and are related to file I/O, and can be used to count event failures from inside chisels."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.error.file", "File Error Count", "This filter field returns 1 for events that returned with an error and are related to file I/O, and can be used to count event failures from inside chisels."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.error.net", "This filter field returns 1 for events that returned with an error and are related to network I/O, and can be used to count event failures from inside chisels."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.error.net", "Network Error Count", "This filter field returns 1 for events that returned with an error and are related to network I/O, and can be used to count event failures from inside chisels."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.error.memory", "This filter field returns 1 for events that returned with an error and are related to memory allocation, and can be used to count event failures from inside chisels."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.error.memory", "Memory Error Count", "This filter field returns 1 for events that returned with an error and are related to memory allocation, and can be used to count event failures from inside chisels."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.error.other", "This filter field returns 1 for events that returned with an error and are related to none of the previous categories, and can be used to count event failures from inside chisels."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.error.other", "Other Error Count", "This filter field returns 1 for events that returned with an error and are related to none of the previous categories, and can be used to count event failures from inside chisels."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.exit", "This filter field returns 1 for exit events, and can be used to count single events from inside chisels."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "evt.count.exit", "Exit Count", "This filter field returns 1 for exit events, and can be used to count single events from inside chisels."},
|
||||||
{PT_UINT32, EPF_TABLE_ONLY, PF_DEC, "evt.count.procinfo", "This filter field returns 1 for procinfo events generated by process main threads, and can be used to count processes from inside views."},
|
{PT_UINT32, EPF_TABLE_ONLY, PF_DEC, "evt.count.procinfo", "Procinfo Count", "This filter field returns 1 for procinfo events generated by process main threads, and can be used to count processes from inside views."},
|
||||||
{PT_UINT32, EPF_TABLE_ONLY, PF_DEC, "evt.count.threadinfo", "This filter field returns 1 for procinfo events, and can be used to count processes from inside views."},
|
{PT_UINT32, EPF_TABLE_ONLY, PF_DEC, "evt.count.threadinfo", "Thread Info Count", "This filter field returns 1 for procinfo events, and can be used to count processes from inside views."},
|
||||||
{PT_UINT64, (filtercheck_field_flags) (EPF_FILTER_ONLY | EPF_REQUIRES_ARGUMENT), PF_DEC, "evt.around", "Accepts the event if it's around the specified time interval. The syntax is evt.around[T]=D, where T is the value returned by %evt.rawtime for the event and D is a delta in milliseconds. For example, evt.around[1404996934793590564]=1000 will return the events with timestamp with one second before the timestamp and one second after it, for a total of two seconds of capture."},
|
{PT_UINT64, (filtercheck_field_flags) (EPF_FILTER_ONLY | EPF_REQUIRES_ARGUMENT), PF_DEC, "evt.around", "Around Interval", "Accepts the event if it's around the specified time interval. The syntax is evt.around[T]=D, where T is the value returned by %evt.rawtime for the event and D is a delta in milliseconds. For example, evt.around[1404996934793590564]=1000 will return the events with timestamp with one second before the timestamp and one second after it, for a total of two seconds of capture."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evt.abspath", "Absolute path calculated from dirfd and name during syscalls like renameat and symlinkat. Use 'evt.abspath.src' or 'evt.abspath.dst' for syscalls that support multiple paths."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evt.abspath", "Absolute Path", "Absolute path calculated from dirfd and name during syscalls like renameat and symlinkat. Use 'evt.abspath.src' or 'evt.abspath.dst' for syscalls that support multiple paths."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.in", "the length of the binary data buffer, but only for input I/O events."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.in", "Input Buffer Length", "the length of the binary data buffer, but only for input I/O events."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.out", "the length of the binary data buffer, but only for output I/O events."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.out", "Output Buffer Length", "the length of the binary data buffer, but only for output I/O events."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.file", "the length of the binary data buffer, but only for file I/O events."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.file", "File Buffer Length", "the length of the binary data buffer, but only for file I/O events."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.file.in", "the length of the binary data buffer, but only for input file I/O events."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.file.in", "File Input Buffer Length", "the length of the binary data buffer, but only for input file I/O events."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.file.out", "the length of the binary data buffer, but only for output file I/O events."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.file.out", "File Output Buffer Length", "the length of the binary data buffer, but only for output file I/O events."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.net", "the length of the binary data buffer, but only for network I/O events."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.net", "Network Buffer Length", "the length of the binary data buffer, but only for network I/O events."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.net.in", "the length of the binary data buffer, but only for input network I/O events."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.net.in", "Network Input Buffer Length", "the length of the binary data buffer, but only for input network I/O events."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.net.out", "the length of the binary data buffer, but only for output network I/O events."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.net.out", "Network Output Buffer Length", "the length of the binary data buffer, but only for output network I/O events."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_open_read", "'true' for open/openat/openat2 events where the path was opened for reading"},
|
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_open_read", "Is Opened For Reading", "'true' for open/openat/openat2 events where the path was opened for reading"},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_open_write", "'true' for open/openat/openat2 events where the path was opened for writing"},
|
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_open_write", "Is Opened For Writing", "'true' for open/openat/openat2 events where the path was opened for writing"},
|
||||||
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "evt.infra.docker.name", "for docker infrastructure events, the name of the event."},
|
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "evt.infra.docker.name", "Docker Name", "for docker infrastructure events, the name of the event."},
|
||||||
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "evt.infra.docker.container.id", "for docker infrastructure events, the id of the impacted container."},
|
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "evt.infra.docker.container.id", "Docker ID", "for docker infrastructure events, the id of the impacted container."},
|
||||||
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "evt.infra.docker.container.name", "for docker infrastructure events, the name of the impacted container."},
|
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "evt.infra.docker.container.name", "Container Name", "for docker infrastructure events, the name of the impacted container."},
|
||||||
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "evt.infra.docker.container.image", "for docker infrastructure events, the image name of the impacted container."},
|
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "evt.infra.docker.container.image", "Container Image", "for docker infrastructure events, the image name of the impacted container."},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_open_exec", "'true' for open/openat/openat2 or creat events where a file is created with execute permissions"},
|
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_open_exec", "Is Created With Execute Permissions", "'true' for open/openat/openat2 or creat events where a file is created with execute permissions"},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_event::sinsp_filter_check_event()
|
sinsp_filter_check_event::sinsp_filter_check_event()
|
||||||
|
@ -4753,12 +4753,12 @@ bool sinsp_filter_check_event::compare(sinsp_evt *evt)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_user_fields[] =
|
const filtercheck_field_info sinsp_filter_check_user_fields[] =
|
||||||
{
|
{
|
||||||
{PT_UINT32, EPF_NONE, PF_ID, "user.uid", "user ID."},
|
{PT_UINT32, EPF_NONE, PF_ID, "user.uid", "User ID", "user ID."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "user.name", "user name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "user.name", "User Name", "user name."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "user.homedir", "home directory of the user."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "user.homedir", "Home Directory", "home directory of the user."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "user.shell", "user's shell."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "user.shell", "Shell", "user's shell."},
|
||||||
{PT_INT32, EPF_NONE, PF_ID, "user.loginuid", "audit user id (auid)."},
|
{PT_INT32, EPF_NONE, PF_ID, "user.loginuid", "Login User ID", "audit user id (auid)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "user.loginname", "audit user name (auid)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "user.loginname", "Login User Name", "audit user name (auid)."},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_user::sinsp_filter_check_user()
|
sinsp_filter_check_user::sinsp_filter_check_user()
|
||||||
|
@ -4830,8 +4830,8 @@ uint8_t* sinsp_filter_check_user::extract(sinsp_evt *evt, OUT uint32_t* len, boo
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_group_fields[] =
|
const filtercheck_field_info sinsp_filter_check_group_fields[] =
|
||||||
{
|
{
|
||||||
{PT_UINT64, EPF_NONE, PF_ID, "group.gid", "group ID."},
|
{PT_UINT64, EPF_NONE, PF_ID, "group.gid", "Group ID", "group ID."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "group.name", "group name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "group.name", "Group Name", "group name."},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_group::sinsp_filter_check_group()
|
sinsp_filter_check_group::sinsp_filter_check_group()
|
||||||
|
@ -4887,26 +4887,26 @@ uint8_t* sinsp_filter_check_group::extract(sinsp_evt *evt, OUT uint32_t* len, bo
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_tracer_fields[] =
|
const filtercheck_field_info sinsp_filter_check_tracer_fields[] =
|
||||||
{
|
{
|
||||||
{PT_INT64, EPF_NONE, PF_ID, "span.id", "ID of the span. This is a unique identifier that is used to match the enter and exit tracer events for this span. It can also be used to match different spans belonging to a trace."},
|
{PT_INT64, EPF_NONE, PF_ID, "span.id", "Span ID", "ID of the span. This is a unique identifier that is used to match the enter and exit tracer events for this span. It can also be used to match different spans belonging to a trace."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "span.time", "time of the span's enter tracer as a human readable string that includes the nanosecond part."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "span.time", "Time", "time of the span's enter tracer as a human readable string that includes the nanosecond part."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "span.ntags", "number of tags that this span has."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "span.ntags", "Tag Count", "number of tags that this span has."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "span.nargs", "number of arguments that this span has."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "span.nargs", "Argument Count", "number of arguments that this span has."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "span.tags", "dot-separated list of all of the span's tags."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "span.tags", "Tags", "dot-separated list of all of the span's tags."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "span.tag", "one of the span's tags, specified by 0-based offset, e.g. 'span.tag[1]'. You can use a negative offset to pick elements from the end of the tag list. For example, 'span.tag[-1]' returns the last tag."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "span.tag", "Tag", "one of the span's tags, specified by 0-based offset, e.g. 'span.tag[1]'. You can use a negative offset to pick elements from the end of the tag list. For example, 'span.tag[-1]' returns the last tag."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "span.args", "comma-separated list of the span's arguments." },
|
{PT_CHARBUF, EPF_NONE, PF_NA, "span.args", "Arguments", "comma-separated list of the span's arguments." },
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "span.arg", "one of the span arguments, specified by name or by 0-based offset. E.g. 'span.arg.xxx' or 'span.arg[1]'. You can use a negative offset to pick elements from the end of the tag list. For example, 'span.arg[-1]' returns the last argument." },
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "span.arg", "Argument", "one of the span arguments, specified by name or by 0-based offset. E.g. 'span.arg.xxx' or 'span.arg[1]'. You can use a negative offset to pick elements from the end of the tag list. For example, 'span.arg[-1]' returns the last argument." },
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "span.enterargs", "comma-separated list of the span's enter tracer event arguments. For enter tracers, this is the same as evt.args. For exit tracers, this is the evt.args of the corresponding enter tracer." },
|
{PT_CHARBUF, EPF_NONE, PF_NA, "span.enterargs", "Enter Arguments", "comma-separated list of the span's enter tracer event arguments. For enter tracers, this is the same as evt.args. For exit tracers, this is the evt.args of the corresponding enter tracer." },
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "span.enterarg", "one of the span's enter arguments, specified by name or by 0-based offset. For enter tracer events, this is the same as evt.arg. For exit tracer events, this is the evt.arg of the corresponding enter event." },
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "span.enterarg", "Enter Argument", "one of the span's enter arguments, specified by name or by 0-based offset. For enter tracer events, this is the same as evt.arg. For exit tracer events, this is the evt.arg of the corresponding enter event." },
|
||||||
{PT_RELTIME, EPF_NONE, PF_DEC, "span.duration", "delta between this span's exit tracer event and the enter tracer event."},
|
{PT_RELTIME, EPF_NONE, PF_DEC, "span.duration", "Duration", "delta between this span's exit tracer event and the enter tracer event."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "span.duration.quantized", "10-base log of the delta between an exit tracer event and the correspondent enter event."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "span.duration.quantized", "Quantized Duration", "10-base log of the delta between an exit tracer event and the correspondent enter event."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "span.duration.human", "delta between this span's exit tracer event and the enter event, as a human readable string (e.g. 10.3ms)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "span.duration.human", "Human-Readable Duration", "delta between this span's exit tracer event and the enter event, as a human readable string (e.g. 10.3ms)."},
|
||||||
{PT_RELTIME, (filtercheck_field_flags) (EPF_TABLE_ONLY | EPF_REQUIRES_ARGUMENT), PF_DEC, "span.duration.fortag", "duration of the span if the number of tags matches the field argument, otherwise 0. For example, span.duration.fortag[1] returns the duration of all the spans with 1 tag, and zero for all the other ones."},
|
{PT_RELTIME, (filtercheck_field_flags) (EPF_TABLE_ONLY | EPF_REQUIRES_ARGUMENT), PF_DEC, "span.duration.fortag", "Duration For Tag", "duration of the span if the number of tags matches the field argument, otherwise 0. For example, span.duration.fortag[1] returns the duration of all the spans with 1 tag, and zero for all the other ones."},
|
||||||
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "span.count", "1 for span exit events."},
|
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "span.count", "Span Count", "1 for span exit events."},
|
||||||
{PT_UINT64, (filtercheck_field_flags) (EPF_TABLE_ONLY | EPF_REQUIRES_ARGUMENT), PF_DEC, "span.count.fortag", "1 if the span's number of tags matches the field argument, and zero for all the other ones."},
|
{PT_UINT64, (filtercheck_field_flags) (EPF_TABLE_ONLY | EPF_REQUIRES_ARGUMENT), PF_DEC, "span.count.fortag", "Count For Tag", "1 if the span's number of tags matches the field argument, and zero for all the other ones."},
|
||||||
{PT_UINT64, (filtercheck_field_flags) (EPF_TABLE_ONLY | EPF_REQUIRES_ARGUMENT), PF_DEC, "span.childcount.fortag", "1 if the span's number of tags is greater than the field argument, and zero for all the other ones."},
|
{PT_UINT64, (filtercheck_field_flags) (EPF_TABLE_ONLY | EPF_REQUIRES_ARGUMENT), PF_DEC, "span.childcount.fortag", "Child Count For Tag", "1 if the span's number of tags is greater than the field argument, and zero for all the other ones."},
|
||||||
{PT_CHARBUF, (filtercheck_field_flags) (EPF_TABLE_ONLY | EPF_REQUIRES_ARGUMENT), PF_NA, "span.idtag", "id used by the span list view."},
|
{PT_CHARBUF, (filtercheck_field_flags) (EPF_TABLE_ONLY | EPF_REQUIRES_ARGUMENT), PF_NA, "span.idtag", "List View ID", "id used by the span list view."},
|
||||||
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "span.rawtime", "id used by the span list view."},
|
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "span.rawtime", "List View Time", "id used by the span list view."},
|
||||||
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "span.rawparenttime", "id used by the span list view."},
|
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "span.rawparenttime", "List View Parent Time", "id used by the span list view."},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_tracer::sinsp_filter_check_tracer()
|
sinsp_filter_check_tracer::sinsp_filter_check_tracer()
|
||||||
|
@ -5482,34 +5482,34 @@ uint8_t* sinsp_filter_check_tracer::extract(sinsp_evt *evt, OUT uint32_t* len, b
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_evtin_fields[] =
|
const filtercheck_field_info sinsp_filter_check_evtin_fields[] =
|
||||||
{
|
{
|
||||||
{ PT_INT64, EPF_NONE, PF_ID, "evtin.span.id", "accepts all the events that are between the enter and exit tracers of the spans with the given ID and are generated by the same thread that generated the tracers." },
|
{ PT_INT64, EPF_NONE, PF_ID, "evtin.span.id", "In Span ID", "accepts all the events that are between the enter and exit tracers of the spans with the given ID and are generated by the same thread that generated the tracers." },
|
||||||
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.ntags", "accepts all the events that are between the enter and exit tracers of the spans with the given number of tags and are generated by the same thread that generated the tracers." },
|
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.ntags", "In Span Tag Count", "accepts all the events that are between the enter and exit tracers of the spans with the given number of tags and are generated by the same thread that generated the tracers." },
|
||||||
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.nargs", "accepts all the events that are between the enter and exit tracers of the spans with the given number of arguments and are generated by the same thread that generated the tracers." },
|
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.nargs", "In Span Argument Count", "accepts all the events that are between the enter and exit tracers of the spans with the given number of arguments and are generated by the same thread that generated the tracers." },
|
||||||
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.tags", "accepts all the events that are between the enter and exit tracers of the spans with the given tags and are generated by the same thread that generated the tracers." },
|
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.tags", "In Span Tags", "accepts all the events that are between the enter and exit tracers of the spans with the given tags and are generated by the same thread that generated the tracers." },
|
||||||
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.tag", "accepts all the events that are between the enter and exit tracers of the spans with the given tag and are generated by the same thread that generated the tracers. See the description of span.tag for information about the syntax accepted by this field." },
|
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.tag", "In Span Tag", "accepts all the events that are between the enter and exit tracers of the spans with the given tag and are generated by the same thread that generated the tracers. See the description of span.tag for information about the syntax accepted by this field." },
|
||||||
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.args", "accepts all the events that are between the enter and exit tracers of the spans with the given arguments and are generated by the same thread that generated the tracers." },
|
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.args", "In Span Arguments", "accepts all the events that are between the enter and exit tracers of the spans with the given arguments and are generated by the same thread that generated the tracers." },
|
||||||
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.arg", "accepts all the events that are between the enter and exit tracers of the spans with the given argument and are generated by the same thread that generated the tracers. See the description of span.arg for information about the syntax accepted by this field." },
|
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.arg", "In Span Argument", "accepts all the events that are between the enter and exit tracers of the spans with the given argument and are generated by the same thread that generated the tracers. See the description of span.arg for information about the syntax accepted by this field." },
|
||||||
{ PT_INT64, EPF_NONE, PF_ID, "evtin.span.p.id", "same as evtin.span.id, but also accepts events generated by other threads in the same process that produced the span." },
|
{ PT_INT64, EPF_NONE, PF_ID, "evtin.span.p.id", "In Parent ID", "same as evtin.span.id, but also accepts events generated by other threads in the same process that produced the span." },
|
||||||
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.p.ntags", "same as evtin.span.ntags, but also accepts events generated by other threads in the same process that produced the span." },
|
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.p.ntags", "In Parent Tag Count", "same as evtin.span.ntags, but also accepts events generated by other threads in the same process that produced the span." },
|
||||||
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.p.nargs", "same as evtin.span.nargs, but also accepts events generated by other threads in the same process that produced the span." },
|
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.p.nargs", "In Parent Argument Count", "same as evtin.span.nargs, but also accepts events generated by other threads in the same process that produced the span." },
|
||||||
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.p.tags", "same as evtin.span.tags, but also accepts events generated by other threads in the same process that produced the span." },
|
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.p.tags", "In Parent Tags", "same as evtin.span.tags, but also accepts events generated by other threads in the same process that produced the span." },
|
||||||
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.p.tag", "same as evtin.span.tag, but also accepts events generated by other threads in the same process that produced the span." },
|
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.p.tag", "In Parent Tag", "same as evtin.span.tag, but also accepts events generated by other threads in the same process that produced the span." },
|
||||||
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.p.args", "same as evtin.span.args, but also accepts events generated by other threads in the same process that produced the span." },
|
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.p.args", "In Parent Arguments", "same as evtin.span.args, but also accepts events generated by other threads in the same process that produced the span." },
|
||||||
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.p.arg", "same as evtin.span.arg, but also accepts events generated by other threads in the same process that produced the span." },
|
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.p.arg", "In Parent Argument", "same as evtin.span.arg, but also accepts events generated by other threads in the same process that produced the span." },
|
||||||
{ PT_INT64, EPF_NONE, PF_ID, "evtin.span.s.id", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
{ PT_INT64, EPF_NONE, PF_ID, "evtin.span.s.id", "In Script ID", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
||||||
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.s.ntags", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.s.ntags", "In Script Tag Count", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
||||||
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.s.nargs", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.s.nargs", "In Script Argument Count", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
||||||
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.s.tags", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.s.tags", "In Script Tags", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
||||||
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.s.tag", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.s.tag", "In Script Tag", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
||||||
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.s.args", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.s.args", "In Script Arguments", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
||||||
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.s.arg", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.s.arg", "In Script Argument", "same as evtin.span.id, but also accepts events generated by the script that produced the span, i.e. by the processes whose parent PID is the same as the one of the process generating the span." },
|
||||||
{ PT_INT64, EPF_NONE, PF_ID, "evtin.span.m.id", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
{ PT_INT64, EPF_NONE, PF_ID, "evtin.span.m.id", "In Machine ID", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
||||||
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.m.ntags", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.m.ntags", "In Machine Tag Count", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
||||||
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.m.nargs", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
{ PT_UINT32, EPF_NONE, PF_DEC, "evtin.span.m.nargs", "In Machine Argument Count", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
||||||
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.m.tags", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.m.tags", "In Machine Tags", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
||||||
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.m.tag", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.m.tag", "In Machine Tag", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
||||||
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.m.args", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
{ PT_CHARBUF, EPF_NONE, PF_NA, "evtin.span.m.args", "In Machine Arguments", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
||||||
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.m.arg", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
{ PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "evtin.span.m.arg", "In Machine Argument", "same as evtin.span.id, but accepts all the events generated on the machine during the span, including other threads and other processes." },
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_evtin::sinsp_filter_check_evtin()
|
sinsp_filter_check_evtin::sinsp_filter_check_evtin()
|
||||||
|
@ -6037,7 +6037,7 @@ fcec_end:
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info rawstring_check_fields[] =
|
const filtercheck_field_info rawstring_check_fields[] =
|
||||||
{
|
{
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "NA", "INTERNAL."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "NA", "NA", "INTERNAL."},
|
||||||
};
|
};
|
||||||
|
|
||||||
rawstring_check::rawstring_check(string text)
|
rawstring_check::rawstring_check(string text)
|
||||||
|
@ -6076,11 +6076,11 @@ uint8_t* rawstring_check::extract(sinsp_evt *evt, OUT uint32_t* len, bool saniti
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_syslog_fields[] =
|
const filtercheck_field_info sinsp_filter_check_syslog_fields[] =
|
||||||
{
|
{
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "syslog.facility.str", "facility as a string."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "syslog.facility.str", "Facility", "facility as a string."},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "syslog.facility", "facility as a number (0-23)."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "syslog.facility", "Numeric Facility", "facility as a number (0-23)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "syslog.severity.str", "severity as a string. Can have one of these values: emerg, alert, crit, err, warn, notice, info, debug"},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "syslog.severity.str", "Severity", "severity as a string. Can have one of these values: emerg, alert, crit, err, warn, notice, info, debug"},
|
||||||
{PT_UINT32, EPF_NONE, PF_DEC, "syslog.severity", "severity as a number (0-7)."},
|
{PT_UINT32, EPF_NONE, PF_DEC, "syslog.severity", "Numeric Severity", "severity as a number (0-7)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "syslog.message", "message sent to syslog."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "syslog.message", "Message", "message sent to syslog."},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_syslog::sinsp_filter_check_syslog()
|
sinsp_filter_check_syslog::sinsp_filter_check_syslog()
|
||||||
|
@ -6143,25 +6143,25 @@ uint8_t* sinsp_filter_check_syslog::extract(sinsp_evt *evt, OUT uint32_t* len, b
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_container_fields[] =
|
const filtercheck_field_info sinsp_filter_check_container_fields[] =
|
||||||
{
|
{
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.id", "the container id."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.id", "Container ID", "the container id."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.name", "the container name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.name", "Container Name", "the container name."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.image", "the container image name (e.g. falcosecurity/falco:latest for docker)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.image", "Image Name", "the container image name (e.g. falcosecurity/falco:latest for docker)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.image.id", "the container image id (e.g. 6f7e2741b66b)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.image.id", "Image ID", "the container image id (e.g. 6f7e2741b66b)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.type", "the container type, eg: docker or rkt"},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.type", "Type", "the container type, eg: docker or rkt"},
|
||||||
{PT_BOOL, EPF_NONE, PF_NA, "container.privileged", "true for containers running as privileged, false otherwise"},
|
{PT_BOOL, EPF_NONE, PF_NA, "container.privileged", "Privileged", "true for containers running as privileged, false otherwise"},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.mounts", "A space-separated list of mount information. Each item in the list has the format <source>:<dest>:<mode>:<rdrw>:<propagation>"},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.mounts", "Mounts", "A space-separated list of mount information. Each item in the list has the format <source>:<dest>:<mode>:<rdrw>:<propagation>"},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount", "Information about a single mount, specified by number (e.g. container.mount[0]) or mount source (container.mount[/usr/local]). The pathname can be a glob (container.mount[/usr/local/*]), in which case the first matching mount will be returned. The information has the format <source>:<dest>:<mode>:<rdrw>:<propagation>. If there is no mount with the specified index or matching the provided source, returns the string \"none\" instead of a NULL value."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount", "Mount", "Information about a single mount, specified by number (e.g. container.mount[0]) or mount source (container.mount[/usr/local]). The pathname can be a glob (container.mount[/usr/local/*]), in which case the first matching mount will be returned. The information has the format <source>:<dest>:<mode>:<rdrw>:<propagation>. If there is no mount with the specified index or matching the provided source, returns the string \"none\" instead of a NULL value."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount.source", "the mount source, specified by number (e.g. container.mount.source[0]) or mount destination (container.mount.source[/host/lib/modules]). The pathname can be a glob."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount.source", "Mount Source", "the mount source, specified by number (e.g. container.mount.source[0]) or mount destination (container.mount.source[/host/lib/modules]). The pathname can be a glob."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount.dest", "the mount destination, specified by number (e.g. container.mount.dest[0]) or mount source (container.mount.dest[/lib/modules]). The pathname can be a glob."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount.dest", "Mount Destination", "the mount destination, specified by number (e.g. container.mount.dest[0]) or mount source (container.mount.dest[/lib/modules]). The pathname can be a glob."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount.mode", "the mount mode, specified by number (e.g. container.mount.mode[0]) or mount source (container.mount.mode[/usr/local]). The pathname can be a glob."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount.mode", "Mount Mode", "the mount mode, specified by number (e.g. container.mount.mode[0]) or mount source (container.mount.mode[/usr/local]). The pathname can be a glob."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount.rdwr", "the mount rdwr value, specified by number (e.g. container.mount.rdwr[0]) or mount source (container.mount.rdwr[/usr/local]). The pathname can be a glob."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount.rdwr", "Mount Read/Write", "the mount rdwr value, specified by number (e.g. container.mount.rdwr[0]) or mount source (container.mount.rdwr[/usr/local]). The pathname can be a glob."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount.propagation", "the mount propagation value, specified by number (e.g. container.mount.propagation[0]) or mount source (container.mount.propagation[/usr/local]). The pathname can be a glob."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "container.mount.propagation", "Mount Propagation", "the mount propagation value, specified by number (e.g. container.mount.propagation[0]) or mount source (container.mount.propagation[/usr/local]). The pathname can be a glob."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.image.repository", "the container image repository (e.g. falcosecurity/falco)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.image.repository", "Repository", "the container image repository (e.g. falcosecurity/falco)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.image.tag", "the container image tag (e.g. stable, latest)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.image.tag", "Image Tag", "the container image tag (e.g. stable, latest)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.image.digest", "the container image registry digest (e.g. sha256:d977378f890d445c15e51795296e4e5062f109ce6da83e0a355fc4ad8699d27)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.image.digest", "Registry Digest", "the container image registry digest (e.g. sha256:d977378f890d445c15e51795296e4e5062f109ce6da83e0a355fc4ad8699d27)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.healthcheck", "The container's health check. Will be the null value (\"N/A\") if no healthcheck configured, \"NONE\" if configured but explicitly not created, and the healthcheck command line otherwise"},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.healthcheck", "Health Check", "The container's health check. Will be the null value (\"N/A\") if no healthcheck configured, \"NONE\" if configured but explicitly not created, and the healthcheck command line otherwise"},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.liveness_probe", "The container's liveness probe. Will be the null value (\"N/A\") if no liveness probe configured, the liveness probe command line otherwise"},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.liveness_probe", "Liveness", "The container's liveness probe. Will be the null value (\"N/A\") if no liveness probe configured, the liveness probe command line otherwise"},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "container.readiness_probe", "The container's readiness probe. Will be the null value (\"N/A\") if no readiness probe configured, the readiness probe command line otherwise"}
|
{PT_CHARBUF, EPF_NONE, PF_NA, "container.readiness_probe", "Readiness", "The container's readiness probe. Will be the null value (\"N/A\") if no readiness probe configured, the readiness probe command line otherwise"}
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_container::sinsp_filter_check_container()
|
sinsp_filter_check_container::sinsp_filter_check_container()
|
||||||
|
@ -7040,7 +7040,7 @@ Json::Value sinsp_filter_check_reference::tojson(sinsp_evt* evt,
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_utils_fields[] =
|
const filtercheck_field_info sinsp_filter_check_utils_fields[] =
|
||||||
{
|
{
|
||||||
{PT_UINT64, EPF_NONE, PF_ID, "util.cnt", "incremental counter."},
|
{PT_UINT64, EPF_NONE, PF_ID, "util.cnt", "Counter", "incremental counter."},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_utils::sinsp_filter_check_utils()
|
sinsp_filter_check_utils::sinsp_filter_check_utils()
|
||||||
|
@ -7079,12 +7079,12 @@ uint8_t* sinsp_filter_check_utils::extract(sinsp_evt *evt, OUT uint32_t* len, bo
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_fdlist_fields[] =
|
const filtercheck_field_info sinsp_filter_check_fdlist_fields[] =
|
||||||
{
|
{
|
||||||
{PT_CHARBUF, EPF_NONE, PF_ID, "fdlist.nums", "for poll events, this is a comma-separated list of the FD numbers in the 'fds' argument, returned as a string."},
|
{PT_CHARBUF, EPF_NONE, PF_ID, "fdlist.nums", "FD Numbers", "for poll events, this is a comma-separated list of the FD numbers in the 'fds' argument, returned as a string."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fdlist.names", "for poll events, this is a comma-separated list of the FD names in the 'fds' argument, returned as a string."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fdlist.names", "FD Names", "for poll events, this is a comma-separated list of the FD names in the 'fds' argument, returned as a string."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fdlist.cips", "for poll events, this is a comma-separated list of the client IP addresses in the 'fds' argument, returned as a string."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fdlist.cips", "FD Client Addresses", "for poll events, this is a comma-separated list of the client IP addresses in the 'fds' argument, returned as a string."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "fdlist.sips", "for poll events, this is a comma-separated list of the server IP addresses in the 'fds' argument, returned as a string."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "fdlist.sips", "FD Source Addresses", "for poll events, this is a comma-separated list of the server IP addresses in the 'fds' argument, returned as a string."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_DEC, "fdlist.cports", "for TCP/UDP FDs, for poll events, this is a comma-separated list of the client TCP/UDP ports in the 'fds' argument, returned as a string."},
|
{PT_CHARBUF, EPF_NONE, PF_DEC, "fdlist.cports", "FD Client Ports", "for TCP/UDP FDs, for poll events, this is a comma-separated list of the client TCP/UDP ports in the 'fds' argument, returned as a string."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_DEC, "fdlist.sports", "for poll events, this is a comma-separated list of the server TCP/UDP ports in the 'fds' argument, returned as a string."},
|
{PT_CHARBUF, EPF_NONE, PF_DEC, "fdlist.sports", "FD Source Ports", "for poll events, this is a comma-separated list of the server TCP/UDP ports in the 'fds' argument, returned as a string."},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_fdlist::sinsp_filter_check_fdlist()
|
sinsp_filter_check_fdlist::sinsp_filter_check_fdlist()
|
||||||
|
@ -7288,30 +7288,30 @@ uint8_t* sinsp_filter_check_fdlist::extract(sinsp_evt *evt, OUT uint32_t* len, b
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
const filtercheck_field_info sinsp_filter_check_k8s_fields[] =
|
const filtercheck_field_info sinsp_filter_check_k8s_fields[] =
|
||||||
{
|
{
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.pod.name", "Kubernetes pod name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.pod.name", "Pod Name", "Kubernetes pod name."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.pod.id", "Kubernetes pod id."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.pod.id", "Pod ID", "Kubernetes pod id."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.pod.label", "Kubernetes pod label. E.g. 'k8s.pod.label.foo'."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.pod.label", "Pod Label", "Kubernetes pod label. E.g. 'k8s.pod.label.foo'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.pod.labels", "Kubernetes pod comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.pod.labels", "Pod Labels", "Kubernetes pod comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rc.name", "Kubernetes replication controller name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rc.name", "Replication Controller Name", "Kubernetes replication controller name."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rc.id", "Kubernetes replication controller id."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rc.id", "Replication Controller ID", "Kubernetes replication controller id."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.rc.label", "Kubernetes replication controller label. E.g. 'k8s.rc.label.foo'."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.rc.label", "Replication Controller Label", "Kubernetes replication controller label. E.g. 'k8s.rc.label.foo'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rc.labels", "Kubernetes replication controller comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rc.labels", "Replication Controller Labels", "Kubernetes replication controller comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.svc.name", "Kubernetes service name (can return more than one value, concatenated)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.svc.name", "Service Name", "Kubernetes service name (can return more than one value, concatenated)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.svc.id", "Kubernetes service id (can return more than one value, concatenated)."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.svc.id", "Service ID", "Kubernetes service id (can return more than one value, concatenated)."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.svc.label", "Kubernetes service label. E.g. 'k8s.svc.label.foo' (can return more than one value, concatenated)."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.svc.label", "Service Label", "Kubernetes service label. E.g. 'k8s.svc.label.foo' (can return more than one value, concatenated)."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.svc.labels", "Kubernetes service comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.svc.labels", "Service Labels", "Kubernetes service comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.ns.name", "Kubernetes namespace name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.ns.name", "Namespace Name", "Kubernetes namespace name."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.ns.id", "Kubernetes namespace id."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.ns.id", "Namespace ID", "Kubernetes namespace id."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.ns.label", "Kubernetes namespace label. E.g. 'k8s.ns.label.foo'."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.ns.label", "Namespace Label", "Kubernetes namespace label. E.g. 'k8s.ns.label.foo'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.ns.labels", "Kubernetes namespace comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.ns.labels", "Namespace Labels", "Kubernetes namespace comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rs.name", "Kubernetes replica set name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rs.name", "Replica Set Name", "Kubernetes replica set name."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rs.id", "Kubernetes replica set id."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rs.id", "Replica Set ID", "Kubernetes replica set id."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.rs.label", "Kubernetes replica set label. E.g. 'k8s.rs.label.foo'."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.rs.label", "Replica Set Label", "Kubernetes replica set label. E.g. 'k8s.rs.label.foo'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rs.labels", "Kubernetes replica set comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.rs.labels", "Replica Set Labels", "Kubernetes replica set comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.deployment.name", "Kubernetes deployment name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.deployment.name", "Deployment Name", "Kubernetes deployment name."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.deployment.id", "Kubernetes deployment id."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.deployment.id", "Deployment ID", "Kubernetes deployment id."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.deployment.label", "Kubernetes deployment label. E.g. 'k8s.rs.label.foo'."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "k8s.deployment.label", "Deployment Label", "Kubernetes deployment label. E.g. 'k8s.rs.label.foo'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.deployment.labels", "Kubernetes deployment comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "k8s.deployment.labels", "Deployment Labels", "Kubernetes deployment comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_k8s::sinsp_filter_check_k8s()
|
sinsp_filter_check_k8s::sinsp_filter_check_k8s()
|
||||||
|
@ -7954,18 +7954,18 @@ uint8_t* sinsp_filter_check_k8s::extract(sinsp_evt *evt, OUT uint32_t* len, bool
|
||||||
|
|
||||||
const filtercheck_field_info sinsp_filter_check_mesos_fields[] =
|
const filtercheck_field_info sinsp_filter_check_mesos_fields[] =
|
||||||
{
|
{
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "mesos.task.name", "Mesos task name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "mesos.task.name", "Task Name", "Mesos task name."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "mesos.task.id", "Mesos task id."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "mesos.task.id", "Task ID", "Mesos task id."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "mesos.task.label", "Mesos task label. E.g. 'mesos.task.label.foo'."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "mesos.task.label", "Task Label", "Mesos task label. E.g. 'mesos.task.label.foo'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "mesos.task.labels", "Mesos task comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "mesos.task.labels", "Task Labels", "Mesos task comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "mesos.framework.name", "Mesos framework name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "mesos.framework.name", "Framework Name", "Mesos framework name."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "mesos.framework.id", "Mesos framework id."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "mesos.framework.id", "Framework ID", "Mesos framework id."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "marathon.app.name", "Marathon app name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "marathon.app.name", "App Name", "Marathon app name."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "marathon.app.id", "Marathon app id."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "marathon.app.id", "App ID", "Marathon app id."},
|
||||||
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "marathon.app.label", "Marathon app label. E.g. 'marathon.app.label.foo'."},
|
{PT_CHARBUF, EPF_REQUIRES_ARGUMENT, PF_NA, "marathon.app.label", "App Label", "Marathon app label. E.g. 'marathon.app.label.foo'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "marathon.app.labels", "Marathon app comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "marathon.app.labels", "App Labels", "Marathon app comma-separated key/value labels. E.g. 'foo1:bar1,foo2:bar2'."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "marathon.group.name", "Marathon group name."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "marathon.group.name", "Group Name", "Marathon group name."},
|
||||||
{PT_CHARBUF, EPF_NONE, PF_NA, "marathon.group.id", "Marathon group id."},
|
{PT_CHARBUF, EPF_NONE, PF_NA, "marathon.group.id", "Group ID", "Marathon group id."},
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_filter_check_mesos::sinsp_filter_check_mesos()
|
sinsp_filter_check_mesos::sinsp_filter_check_mesos()
|
||||||
|
|
|
@ -399,6 +399,47 @@ void gen_event_filter_factory::filter_fieldclass_info::wrapstring(const std::str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string gen_event_filter_factory::filter_fieldclass_info::as_markdown(const std::set<std::string>& event_sources)
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
os << "## Field Class: " << name << std::endl << std::endl;
|
||||||
|
|
||||||
|
if(desc != "")
|
||||||
|
{
|
||||||
|
os << desc << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!event_sources.empty())
|
||||||
|
{
|
||||||
|
os << "Event Sources: ";
|
||||||
|
|
||||||
|
for(const auto &src : event_sources)
|
||||||
|
{
|
||||||
|
os << src << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
os << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "Name | Type | Description" << std::endl;
|
||||||
|
os << ":----|:-----|:-----------" << std::endl;
|
||||||
|
|
||||||
|
for(auto &fld_info : fields)
|
||||||
|
{
|
||||||
|
// Skip fields that should not be included
|
||||||
|
// (e.g. hidden fields)
|
||||||
|
if(fld_info.is_skippable())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "`" << fld_info.name << "` | " << fld_info.data_type << " | " << fld_info.desc << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string gen_event_filter_factory::filter_fieldclass_info::as_string(bool verbose, const std::set<std::string>& event_sources)
|
std::string gen_event_filter_factory::filter_fieldclass_info::as_string(bool verbose, const std::set<std::string>& event_sources)
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
|
|
@ -280,6 +280,11 @@ public:
|
||||||
// event sources, and the name and description of each field.
|
// event sources, and the name and description of each field.
|
||||||
std::string as_string(bool verbose, const std::set<std::string>& event_sources = std::set<std::string>());
|
std::string as_string(bool verbose, const std::set<std::string>& event_sources = std::set<std::string>());
|
||||||
|
|
||||||
|
// Print a markdown representation of this
|
||||||
|
// field class, suitable for publication on the documentation
|
||||||
|
// website.
|
||||||
|
std::string as_markdown(const std::set<std::string>& event_sources = std::set<std::string>());
|
||||||
|
|
||||||
// How far to right-justify the name/description/etc block.
|
// How far to right-justify the name/description/etc block.
|
||||||
static uint32_t s_rightblock_start;
|
static uint32_t s_rightblock_start;
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ void sinsp_parser::process_event(sinsp_evt *evt)
|
||||||
#if defined(HAS_FILTERING) && defined(HAS_CAPTURE_FILTERING)
|
#if defined(HAS_FILTERING) && defined(HAS_CAPTURE_FILTERING)
|
||||||
bool do_filter_later = false;
|
bool do_filter_later = false;
|
||||||
|
|
||||||
if(m_inspector->m_filter || m_inspector->m_evttype_filter)
|
if(m_inspector->m_filter)
|
||||||
{
|
{
|
||||||
ppm_event_flags eflags = evt->get_info_flags();
|
ppm_event_flags eflags = evt->get_info_flags();
|
||||||
|
|
||||||
|
@ -251,12 +251,14 @@ void sinsp_parser::process_event(sinsp_evt *evt)
|
||||||
|
|
||||||
// FALLTHRU
|
// FALLTHRU
|
||||||
case PPME_SYSCALL_OPEN_E:
|
case PPME_SYSCALL_OPEN_E:
|
||||||
|
case PPME_SYSCALL_CREAT_E:
|
||||||
|
case PPME_SYSCALL_OPENAT_E:
|
||||||
|
case PPME_SYSCALL_OPENAT_2_E:
|
||||||
|
case PPME_SYSCALL_OPENAT2_E:
|
||||||
case PPME_SOCKET_SOCKET_E:
|
case PPME_SOCKET_SOCKET_E:
|
||||||
case PPME_SYSCALL_EVENTFD_E:
|
case PPME_SYSCALL_EVENTFD_E:
|
||||||
case PPME_SYSCALL_CHDIR_E:
|
case PPME_SYSCALL_CHDIR_E:
|
||||||
case PPME_SYSCALL_FCHDIR_E:
|
case PPME_SYSCALL_FCHDIR_E:
|
||||||
case PPME_SYSCALL_CREAT_E:
|
|
||||||
case PPME_SYSCALL_OPENAT_E:
|
|
||||||
case PPME_SOCKET_SHUTDOWN_E:
|
case PPME_SOCKET_SHUTDOWN_E:
|
||||||
case PPME_SYSCALL_GETRLIMIT_E:
|
case PPME_SYSCALL_GETRLIMIT_E:
|
||||||
case PPME_SYSCALL_SETRLIMIT_E:
|
case PPME_SYSCALL_SETRLIMIT_E:
|
||||||
|
@ -329,6 +331,7 @@ void sinsp_parser::process_event(sinsp_evt *evt)
|
||||||
case PPME_SYSCALL_VFORK_X:
|
case PPME_SYSCALL_VFORK_X:
|
||||||
case PPME_SYSCALL_VFORK_17_X:
|
case PPME_SYSCALL_VFORK_17_X:
|
||||||
case PPME_SYSCALL_VFORK_20_X:
|
case PPME_SYSCALL_VFORK_20_X:
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
parse_clone_exit(evt);
|
parse_clone_exit(evt);
|
||||||
break;
|
break;
|
||||||
case PPME_SYSCALL_EXECVE_8_X:
|
case PPME_SYSCALL_EXECVE_8_X:
|
||||||
|
@ -606,6 +609,7 @@ bool sinsp_parser::reset(sinsp_evt *evt)
|
||||||
etype == PPME_SYSCALL_VFORK_X ||
|
etype == PPME_SYSCALL_VFORK_X ||
|
||||||
etype == PPME_SYSCALL_VFORK_17_X ||
|
etype == PPME_SYSCALL_VFORK_17_X ||
|
||||||
etype == PPME_SYSCALL_VFORK_20_X ||
|
etype == PPME_SYSCALL_VFORK_20_X ||
|
||||||
|
etype == PPME_SYSCALL_CLONE3_X ||
|
||||||
etype == PPME_SCHEDSWITCH_6_E)
|
etype == PPME_SCHEDSWITCH_6_E)
|
||||||
{
|
{
|
||||||
query_os = false;
|
query_os = false;
|
||||||
|
@ -641,7 +645,8 @@ bool sinsp_parser::reset(sinsp_evt *evt)
|
||||||
etype == PPME_SYSCALL_FORK_20_X ||
|
etype == PPME_SYSCALL_FORK_20_X ||
|
||||||
etype == PPME_SYSCALL_VFORK_X ||
|
etype == PPME_SYSCALL_VFORK_X ||
|
||||||
etype == PPME_SYSCALL_VFORK_17_X ||
|
etype == PPME_SYSCALL_VFORK_17_X ||
|
||||||
etype == PPME_SYSCALL_VFORK_20_X)
|
etype == PPME_SYSCALL_VFORK_20_X ||
|
||||||
|
etype == PPME_SYSCALL_CLONE3_X)
|
||||||
{
|
{
|
||||||
#ifdef GATHER_INTERNAL_STATS
|
#ifdef GATHER_INTERNAL_STATS
|
||||||
m_inspector->m_thread_manager->m_failed_lookups->decrement();
|
m_inspector->m_thread_manager->m_failed_lookups->decrement();
|
||||||
|
@ -740,6 +745,19 @@ bool sinsp_parser::reset(sinsp_evt *evt)
|
||||||
//
|
//
|
||||||
if(eflags & EF_USES_FD)
|
if(eflags & EF_USES_FD)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// The copy_file_range syscall has the peculiarity of using two fds
|
||||||
|
// Set as m_lastevent_fd the output fd
|
||||||
|
//
|
||||||
|
if(etype == PPME_SYSCALL_COPY_FILE_RANGE_X)
|
||||||
|
{
|
||||||
|
sinsp_evt_param *parinfo;
|
||||||
|
|
||||||
|
parinfo = evt->get_param(1);
|
||||||
|
ASSERT(parinfo->m_len == sizeof(int64_t));
|
||||||
|
tinfo->m_lastevent_fd = *(int64_t *)parinfo->m_val;
|
||||||
|
}
|
||||||
|
|
||||||
evt->m_fdinfo = tinfo->get_fd(tinfo->m_lastevent_fd);
|
evt->m_fdinfo = tinfo->get_fd(tinfo->m_lastevent_fd);
|
||||||
|
|
||||||
if(evt->m_fdinfo == NULL)
|
if(evt->m_fdinfo == NULL)
|
||||||
|
@ -954,6 +972,7 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
|
||||||
case PPME_SYSCALL_CLONE_20_X:
|
case PPME_SYSCALL_CLONE_20_X:
|
||||||
case PPME_SYSCALL_FORK_20_X:
|
case PPME_SYSCALL_FORK_20_X:
|
||||||
case PPME_SYSCALL_VFORK_20_X:
|
case PPME_SYSCALL_VFORK_20_X:
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
parinfo = evt->get_param(15);
|
parinfo = evt->get_param(15);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -986,6 +1005,7 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
|
||||||
case PPME_SYSCALL_CLONE_20_X:
|
case PPME_SYSCALL_CLONE_20_X:
|
||||||
case PPME_SYSCALL_FORK_20_X:
|
case PPME_SYSCALL_FORK_20_X:
|
||||||
case PPME_SYSCALL_VFORK_20_X:
|
case PPME_SYSCALL_VFORK_20_X:
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
parinfo = evt->get_param(18);
|
parinfo = evt->get_param(18);
|
||||||
ASSERT(parinfo->m_len == sizeof(int64_t));
|
ASSERT(parinfo->m_len == sizeof(int64_t));
|
||||||
vtid = *(int64_t *)parinfo->m_val;
|
vtid = *(int64_t *)parinfo->m_val;
|
||||||
|
@ -1259,6 +1279,7 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
|
||||||
case PPME_SYSCALL_FORK_20_X:
|
case PPME_SYSCALL_FORK_20_X:
|
||||||
case PPME_SYSCALL_VFORK_17_X:
|
case PPME_SYSCALL_VFORK_17_X:
|
||||||
case PPME_SYSCALL_VFORK_20_X:
|
case PPME_SYSCALL_VFORK_20_X:
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
parinfo = evt->get_param(13);
|
parinfo = evt->get_param(13);
|
||||||
tinfo->m_comm = parinfo->m_val;
|
tinfo->m_comm = parinfo->m_val;
|
||||||
break;
|
break;
|
||||||
|
@ -1375,6 +1396,7 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
|
||||||
case PPME_SYSCALL_FORK_20_X:
|
case PPME_SYSCALL_FORK_20_X:
|
||||||
case PPME_SYSCALL_VFORK_17_X:
|
case PPME_SYSCALL_VFORK_17_X:
|
||||||
case PPME_SYSCALL_VFORK_20_X:
|
case PPME_SYSCALL_VFORK_20_X:
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
parinfo = evt->get_param(13);
|
parinfo = evt->get_param(13);
|
||||||
tinfo->m_comm = parinfo->m_val;
|
tinfo->m_comm = parinfo->m_val;
|
||||||
break;
|
break;
|
||||||
|
@ -1404,6 +1426,7 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
|
||||||
case PPME_SYSCALL_VFORK_X:
|
case PPME_SYSCALL_VFORK_X:
|
||||||
case PPME_SYSCALL_VFORK_17_X:
|
case PPME_SYSCALL_VFORK_17_X:
|
||||||
case PPME_SYSCALL_VFORK_20_X:
|
case PPME_SYSCALL_VFORK_20_X:
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
// Get the pgflt_maj
|
// Get the pgflt_maj
|
||||||
parinfo = evt->get_param(8);
|
parinfo = evt->get_param(8);
|
||||||
ASSERT(parinfo->m_len == sizeof(uint64_t));
|
ASSERT(parinfo->m_len == sizeof(uint64_t));
|
||||||
|
@ -1452,6 +1475,7 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
|
||||||
case PPME_SYSCALL_CLONE_20_X:
|
case PPME_SYSCALL_CLONE_20_X:
|
||||||
case PPME_SYSCALL_FORK_20_X:
|
case PPME_SYSCALL_FORK_20_X:
|
||||||
case PPME_SYSCALL_VFORK_20_X:
|
case PPME_SYSCALL_VFORK_20_X:
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
parinfo = evt->get_param(16);
|
parinfo = evt->get_param(16);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1479,6 +1503,7 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
|
||||||
case PPME_SYSCALL_CLONE_20_X:
|
case PPME_SYSCALL_CLONE_20_X:
|
||||||
case PPME_SYSCALL_FORK_20_X:
|
case PPME_SYSCALL_FORK_20_X:
|
||||||
case PPME_SYSCALL_VFORK_20_X:
|
case PPME_SYSCALL_VFORK_20_X:
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
parinfo = evt->get_param(17);
|
parinfo = evt->get_param(17);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1515,6 +1540,7 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
|
||||||
case PPME_SYSCALL_FORK_20_X:
|
case PPME_SYSCALL_FORK_20_X:
|
||||||
case PPME_SYSCALL_VFORK_20_X:
|
case PPME_SYSCALL_VFORK_20_X:
|
||||||
case PPME_SYSCALL_CLONE_20_X:
|
case PPME_SYSCALL_CLONE_20_X:
|
||||||
|
case PPME_SYSCALL_CLONE3_X:
|
||||||
parinfo = evt->get_param(14);
|
parinfo = evt->get_param(14);
|
||||||
tinfo->set_cgroups(parinfo->m_val, parinfo->m_len);
|
tinfo->set_cgroups(parinfo->m_val, parinfo->m_len);
|
||||||
m_inspector->m_container_manager.resolve_container(tinfo, m_inspector->is_live());
|
m_inspector->m_container_manager.resolve_container(tinfo, m_inspector->is_live());
|
||||||
|
@ -2094,13 +2120,17 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt)
|
||||||
sinsp_evt_param *parinfo;
|
sinsp_evt_param *parinfo;
|
||||||
int64_t fd;
|
int64_t fd;
|
||||||
char *name;
|
char *name;
|
||||||
|
char *enter_evt_name;
|
||||||
uint32_t namelen;
|
uint32_t namelen;
|
||||||
|
uint32_t enter_evt_namelen;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
uint32_t enter_evt_flags;
|
||||||
sinsp_fdinfo_t fdi;
|
sinsp_fdinfo_t fdi;
|
||||||
sinsp_evt *enter_evt = &m_tmp_evt;
|
sinsp_evt *enter_evt = &m_tmp_evt;
|
||||||
string sdir;
|
string sdir;
|
||||||
uint16_t etype = evt->get_type();
|
uint16_t etype = evt->get_type();
|
||||||
uint32_t dev = 0;
|
uint32_t dev = 0;
|
||||||
|
bool lastevent_retrieved;
|
||||||
|
|
||||||
ASSERT(evt->m_tinfo);
|
ASSERT(evt->m_tinfo);
|
||||||
if(evt->m_tinfo == nullptr)
|
if(evt->m_tinfo == nullptr)
|
||||||
|
@ -2108,17 +2138,10 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(etype != PPME_SYSCALL_OPENAT_2_X && etype != PPME_SYSCALL_OPENAT2_X)
|
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// Load the enter event so we can access its arguments
|
// Load the enter event so we can access its arguments
|
||||||
//
|
//
|
||||||
if(!retrieve_enter_event(enter_evt, evt))
|
lastevent_retrieved = retrieve_enter_event(enter_evt, evt);
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check the return value
|
// Check the return value
|
||||||
|
@ -2147,6 +2170,27 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt)
|
||||||
dev = *(uint32_t *)parinfo->m_val;
|
dev = *(uint32_t *)parinfo->m_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compare with enter event parameters
|
||||||
|
//
|
||||||
|
if(lastevent_retrieved && enter_evt->get_num_params() >= 2)
|
||||||
|
{
|
||||||
|
parinfo = enter_evt->get_param(0);
|
||||||
|
enter_evt_name = parinfo->m_val;
|
||||||
|
enter_evt_namelen = parinfo->m_len;
|
||||||
|
|
||||||
|
parinfo = enter_evt->get_param(1);
|
||||||
|
ASSERT(parinfo->m_len == sizeof(uint32_t));
|
||||||
|
enter_evt_flags = *(uint32_t *)parinfo->m_val;
|
||||||
|
|
||||||
|
if(enter_evt_namelen != 0 && strcmp(enter_evt_name, "(NULL)") != 0)
|
||||||
|
{
|
||||||
|
name = enter_evt_name;
|
||||||
|
namelen = enter_evt_namelen;
|
||||||
|
flags = enter_evt_flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sdir = evt->m_tinfo->get_cwd();
|
sdir = evt->m_tinfo->get_cwd();
|
||||||
}
|
}
|
||||||
else if(etype == PPME_SYSCALL_CREAT_X)
|
else if(etype == PPME_SYSCALL_CREAT_X)
|
||||||
|
@ -2164,6 +2208,22 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt)
|
||||||
dev = *(uint32_t *)parinfo->m_val;
|
dev = *(uint32_t *)parinfo->m_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(lastevent_retrieved && enter_evt->get_num_params() >= 1)
|
||||||
|
{
|
||||||
|
parinfo = enter_evt->get_param(0);
|
||||||
|
enter_evt_name = parinfo->m_val;
|
||||||
|
enter_evt_namelen = parinfo->m_len;
|
||||||
|
|
||||||
|
enter_evt_flags = 0;
|
||||||
|
|
||||||
|
if(enter_evt_namelen != 0 && strcmp(enter_evt_name, "(NULL)") != 0)
|
||||||
|
{
|
||||||
|
name = enter_evt_name;
|
||||||
|
namelen = enter_evt_namelen;
|
||||||
|
flags = enter_evt_flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sdir = evt->m_tinfo->get_cwd();
|
sdir = evt->m_tinfo->get_cwd();
|
||||||
}
|
}
|
||||||
else if(etype == PPME_SYSCALL_OPENAT_X)
|
else if(etype == PPME_SYSCALL_OPENAT_X)
|
||||||
|
@ -2203,6 +2263,32 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt)
|
||||||
dev = *(uint32_t *)parinfo->m_val;
|
dev = *(uint32_t *)parinfo->m_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compare with enter event parameters
|
||||||
|
//
|
||||||
|
if(lastevent_retrieved && enter_evt->get_num_params() >= 3)
|
||||||
|
{
|
||||||
|
parinfo = enter_evt->get_param(1);
|
||||||
|
enter_evt_name = parinfo->m_val;
|
||||||
|
enter_evt_namelen = parinfo->m_len;
|
||||||
|
|
||||||
|
parinfo = enter_evt->get_param(2);
|
||||||
|
ASSERT(parinfo->m_len == sizeof(uint32_t));
|
||||||
|
enter_evt_flags = *(uint32_t *)parinfo->m_val;
|
||||||
|
|
||||||
|
parinfo = enter_evt->get_param(0);
|
||||||
|
ASSERT(parinfo->m_len == sizeof(int64_t));
|
||||||
|
int64_t enter_evt_dirfd = *(int64_t *)parinfo->m_val;
|
||||||
|
|
||||||
|
if(enter_evt_namelen != 0 && strcmp(enter_evt_name, "(NULL)") != 0)
|
||||||
|
{
|
||||||
|
name = enter_evt_name;
|
||||||
|
namelen = enter_evt_namelen;
|
||||||
|
flags = enter_evt_flags;
|
||||||
|
dirfd = enter_evt_dirfd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parse_dirfd(evt, name, dirfd, &sdir);
|
parse_dirfd(evt, name, dirfd, &sdir);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2606,11 +2692,8 @@ void sinsp_parser::parse_bind_exit(sinsp_evt *evt)
|
||||||
* Register a socket in pending state
|
* Register a socket in pending state
|
||||||
*/
|
*/
|
||||||
void sinsp_parser::parse_connect_enter(sinsp_evt *evt){
|
void sinsp_parser::parse_connect_enter(sinsp_evt *evt){
|
||||||
if(!m_track_connection_status){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sinsp_evt_param *parinfo;
|
sinsp_evt_param *parinfo;
|
||||||
|
const char *parstr;
|
||||||
uint8_t *packed_data;
|
uint8_t *packed_data;
|
||||||
|
|
||||||
if(evt->m_fdinfo == NULL)
|
if(evt->m_fdinfo == NULL)
|
||||||
|
@ -2618,7 +2701,15 @@ void sinsp_parser::parse_connect_enter(sinsp_evt *evt){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_track_connection_status) {
|
||||||
evt->m_fdinfo->set_socket_pending();
|
evt->m_fdinfo->set_socket_pending();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(evt->get_num_params() < 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
parinfo = evt->get_param(1);
|
parinfo = evt->get_param(1);
|
||||||
if(parinfo->m_len == 0)
|
if(parinfo->m_len == 0)
|
||||||
{
|
{
|
||||||
|
@ -2633,12 +2724,50 @@ void sinsp_parser::parse_connect_enter(sinsp_evt *evt){
|
||||||
|
|
||||||
packed_data = (uint8_t*)parinfo->m_val;
|
packed_data = (uint8_t*)parinfo->m_val;
|
||||||
|
|
||||||
fill_client_socket_info(evt, packed_data);
|
uint8_t family = *packed_data;
|
||||||
|
|
||||||
|
if(family == PPM_AF_INET)
|
||||||
|
{
|
||||||
|
evt->m_fdinfo->m_type = SCAP_FD_IPV4_SOCK;
|
||||||
|
memcpy(&evt->m_fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dip, packed_data + 1, sizeof(uint32_t));
|
||||||
|
memcpy(&evt->m_fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dport, packed_data + 5, sizeof(uint16_t));
|
||||||
|
}
|
||||||
|
else if (family == PPM_AF_INET6)
|
||||||
|
{
|
||||||
|
uint16_t port;
|
||||||
|
memcpy(&port, packed_data + 17, sizeof(uint16_t));
|
||||||
|
uint8_t* ip = packed_data + 1;
|
||||||
|
if(sinsp_utils::is_ipv4_mapped_ipv6(ip))
|
||||||
|
{
|
||||||
|
evt->m_fdinfo->m_type = SCAP_FD_IPV4_SOCK;
|
||||||
|
memcpy(&evt->m_fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dip, packed_data + 13, sizeof(uint32_t));
|
||||||
|
evt->m_fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dport = port;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
evt->m_fdinfo->m_type = SCAP_FD_IPV6_SOCK;
|
||||||
|
evt->m_fdinfo->m_sockinfo.m_ipv6info.m_fields.m_dport = port;
|
||||||
|
memcpy(evt->m_fdinfo->m_sockinfo.m_ipv6info.m_fields.m_dip.m_b, ip, sizeof(ipv6addr));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
//
|
//
|
||||||
// If there's a listener callback, invoke it
|
// Add the friendly name to the fd info
|
||||||
//
|
//
|
||||||
if(m_fd_listener)
|
evt->m_fdinfo->m_name = evt->get_param_as_str(1, &parstr, sinsp_evt::PF_SIMPLE);
|
||||||
|
|
||||||
|
#ifndef HAS_ANALYZER
|
||||||
|
//
|
||||||
|
// Update the FD with this tuple
|
||||||
|
//
|
||||||
|
m_inspector->m_parser->set_unix_info(evt->m_fdinfo, packed_data);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If there's a listener callback and we're tracking connection status, invoke it
|
||||||
|
//
|
||||||
|
if(m_track_connection_status && m_fd_listener)
|
||||||
{
|
{
|
||||||
m_fd_listener->on_connect(evt, packed_data);
|
m_fd_listener->on_connect(evt, packed_data);
|
||||||
}
|
}
|
||||||
|
@ -2698,8 +2827,6 @@ inline void sinsp_parser::fill_client_socket_info(sinsp_evt *evt, uint8_t *packe
|
||||||
//
|
//
|
||||||
// Add the friendly name to the fd info
|
// Add the friendly name to the fd info
|
||||||
//
|
//
|
||||||
if(evt->m_fdinfo->is_role_server() && evt->m_fdinfo->is_udp_socket())
|
|
||||||
{
|
|
||||||
sinsp_utils::sockinfo_to_str(&evt->m_fdinfo->m_sockinfo,
|
sinsp_utils::sockinfo_to_str(&evt->m_fdinfo->m_sockinfo,
|
||||||
evt->m_fdinfo->m_type, &evt->m_paramstr_storage[0],
|
evt->m_fdinfo->m_type, &evt->m_paramstr_storage[0],
|
||||||
(uint32_t)evt->m_paramstr_storage.size(),
|
(uint32_t)evt->m_paramstr_storage.size(),
|
||||||
|
@ -2708,11 +2835,6 @@ inline void sinsp_parser::fill_client_socket_info(sinsp_evt *evt, uint8_t *packe
|
||||||
evt->m_fdinfo->m_name = &evt->m_paramstr_storage[0];
|
evt->m_fdinfo->m_name = &evt->m_paramstr_storage[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
evt->m_fdinfo->m_name = evt->get_param_as_str(1, &parstr, sinsp_evt::PF_SIMPLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if(!evt->m_fdinfo->is_unix_socket())
|
if(!evt->m_fdinfo->is_unix_socket())
|
||||||
{
|
{
|
||||||
|
@ -3189,16 +3311,9 @@ void sinsp_parser::parse_thread_exit(sinsp_evt *evt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sinsp_parser::set_ipv4_addresses_and_ports(sinsp_fdinfo_t* fdinfo, uint8_t* packed_data)
|
inline bool sinsp_parser::update_ipv4_addresses_and_ports(sinsp_fdinfo_t* fdinfo,
|
||||||
|
uint32_t tsip, uint16_t tsport, uint32_t tdip, uint16_t tdport)
|
||||||
{
|
{
|
||||||
uint32_t tsip, tdip;
|
|
||||||
uint16_t tsport, tdport;
|
|
||||||
|
|
||||||
tsip = *(uint32_t *)(packed_data + 1);
|
|
||||||
tsport = *(uint16_t *)(packed_data + 5);
|
|
||||||
tdip = *(uint32_t *)(packed_data + 7);
|
|
||||||
tdport = *(uint16_t *)(packed_data + 11);
|
|
||||||
|
|
||||||
if(fdinfo->m_type == SCAP_FD_IPV4_SOCK)
|
if(fdinfo->m_type == SCAP_FD_IPV4_SOCK)
|
||||||
{
|
{
|
||||||
if((tsip == fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sip &&
|
if((tsip == fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sip &&
|
||||||
|
@ -3215,12 +3330,42 @@ bool sinsp_parser::set_ipv4_addresses_and_ports(sinsp_fdinfo_t* fdinfo, uint8_t*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sip = tsip;
|
bool changed = false;
|
||||||
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sport = tsport;
|
|
||||||
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dip = tdip;
|
|
||||||
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dport = tdport;
|
|
||||||
|
|
||||||
return true;
|
if(fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sip != tsip) {
|
||||||
|
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sip = tsip;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sport != tsport) {
|
||||||
|
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sport = tsport;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dip == 0) {
|
||||||
|
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dip = tdip;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dport == 0) {
|
||||||
|
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dport = tdport;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sinsp_parser::set_ipv4_addresses_and_ports(sinsp_fdinfo_t* fdinfo, uint8_t* packed_data)
|
||||||
|
{
|
||||||
|
uint32_t tsip, tdip;
|
||||||
|
uint16_t tsport, tdport;
|
||||||
|
|
||||||
|
memcpy(&tsip, packed_data + 1, sizeof(uint32_t));
|
||||||
|
memcpy(&tsport, packed_data + 5, sizeof(uint16_t));
|
||||||
|
memcpy(&tdip, packed_data + 7, sizeof(uint32_t));
|
||||||
|
memcpy(&tdport, packed_data + 11, sizeof(uint16_t));
|
||||||
|
|
||||||
|
return update_ipv4_addresses_and_ports(fdinfo, tsip, tsport, tdip, tdport);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sinsp_parser::set_ipv4_mapped_ipv6_addresses_and_ports(sinsp_fdinfo_t* fdinfo, uint8_t* packed_data)
|
bool sinsp_parser::set_ipv4_mapped_ipv6_addresses_and_ports(sinsp_fdinfo_t* fdinfo, uint8_t* packed_data)
|
||||||
|
@ -3233,28 +3378,7 @@ bool sinsp_parser::set_ipv4_mapped_ipv6_addresses_and_ports(sinsp_fdinfo_t* fdin
|
||||||
tdip = *(uint32_t *)(packed_data + 31);
|
tdip = *(uint32_t *)(packed_data + 31);
|
||||||
tdport = *(uint16_t *)(packed_data + 35);
|
tdport = *(uint16_t *)(packed_data + 35);
|
||||||
|
|
||||||
if(fdinfo->m_type == SCAP_FD_IPV4_SOCK)
|
return update_ipv4_addresses_and_ports(fdinfo, tsip, tsport, tdip, tdport);
|
||||||
{
|
|
||||||
if((tsip == fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sip &&
|
|
||||||
tsport == fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sport &&
|
|
||||||
tdip == fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dip &&
|
|
||||||
tdport == fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dport) ||
|
|
||||||
(tdip == fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sip &&
|
|
||||||
tdport == fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sport &&
|
|
||||||
tsip == fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dip &&
|
|
||||||
tsport == fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dport)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sip = tsip;
|
|
||||||
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sport = tsport;
|
|
||||||
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dip = tdip;
|
|
||||||
fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dport = tdport;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sinsp_parser::set_ipv6_addresses_and_ports(sinsp_fdinfo_t* fdinfo, uint8_t* packed_data)
|
bool sinsp_parser::set_ipv6_addresses_and_ports(sinsp_fdinfo_t* fdinfo, uint8_t* packed_data)
|
||||||
|
@ -3284,12 +3408,29 @@ bool sinsp_parser::set_ipv6_addresses_and_ports(sinsp_fdinfo_t* fdinfo, uint8_t*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fdinfo->m_sockinfo.m_ipv6info.m_fields.m_sip = tsip;
|
bool changed = false;
|
||||||
fdinfo->m_sockinfo.m_ipv6info.m_fields.m_sport = tsport;
|
|
||||||
fdinfo->m_sockinfo.m_ipv6info.m_fields.m_dip = tdip;
|
|
||||||
fdinfo->m_sockinfo.m_ipv6info.m_fields.m_dport = tdport;
|
|
||||||
|
|
||||||
return true;
|
if(fdinfo->m_sockinfo.m_ipv6info.m_fields.m_sip != tsip) {
|
||||||
|
fdinfo->m_sockinfo.m_ipv6info.m_fields.m_sip = tsip;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fdinfo->m_sockinfo.m_ipv6info.m_fields.m_sport != tsport) {
|
||||||
|
fdinfo->m_sockinfo.m_ipv6info.m_fields.m_sport = tsport;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fdinfo->m_sockinfo.m_ipv6info.m_fields.m_dip == ipv6addr::empty_address) {
|
||||||
|
fdinfo->m_sockinfo.m_ipv6info.m_fields.m_dip = tdip;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fdinfo->m_sockinfo.m_ipv6info.m_fields.m_dport == 0) {
|
||||||
|
fdinfo->m_sockinfo.m_ipv6info.m_fields.m_dport = tdport;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sinsp_parser::set_unix_info(sinsp_fdinfo_t* fdinfo, uint8_t* packed_data)
|
bool sinsp_parser::set_unix_info(sinsp_fdinfo_t* fdinfo, uint8_t* packed_data)
|
||||||
|
|
|
@ -145,6 +145,8 @@ private:
|
||||||
void parse_setsid_exit(sinsp_evt *evt);
|
void parse_setsid_exit(sinsp_evt *evt);
|
||||||
void parse_getsockopt_exit(sinsp_evt *evt);
|
void parse_getsockopt_exit(sinsp_evt *evt);
|
||||||
|
|
||||||
|
inline bool update_ipv4_addresses_and_ports(sinsp_fdinfo_t* fdinfo,
|
||||||
|
uint32_t tsip, uint16_t tsport, uint32_t tdip, uint16_t tdport);
|
||||||
inline void fill_client_socket_info(sinsp_evt* evt, uint8_t* packed_data);
|
inline void fill_client_socket_info(sinsp_evt* evt, uint8_t* packed_data);
|
||||||
inline void add_socket(sinsp_evt* evt, int64_t fd, uint32_t domain, uint32_t type, uint32_t protocol);
|
inline void add_socket(sinsp_evt* evt, int64_t fd, uint32_t domain, uint32_t type, uint32_t protocol);
|
||||||
inline void infer_sendto_fdinfo(sinsp_evt *evt);
|
inline void infer_sendto_fdinfo(sinsp_evt *evt);
|
||||||
|
|
|
@ -336,9 +336,9 @@ std::shared_ptr<sinsp_plugin> sinsp_plugin::create_plugin(string &filepath, cons
|
||||||
std::shared_ptr<sinsp_plugin> ret;
|
std::shared_ptr<sinsp_plugin> ret;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HINSTANCE handle = LoadLibrary(filepath.c_str());
|
sinsp_plugin_handle handle = LoadLibrary(filepath.c_str());
|
||||||
#else
|
#else
|
||||||
void* handle = dlopen(filepath.c_str(), RTLD_LAZY);
|
sinsp_plugin_handle handle = dlopen(filepath.c_str(), RTLD_LAZY);
|
||||||
#endif
|
#endif
|
||||||
if(handle == NULL)
|
if(handle == NULL)
|
||||||
{
|
{
|
||||||
|
@ -392,8 +392,8 @@ std::shared_ptr<sinsp_plugin> sinsp_plugin::create_plugin(string &filepath, cons
|
||||||
switch(plugin_type)
|
switch(plugin_type)
|
||||||
{
|
{
|
||||||
case TYPE_SOURCE_PLUGIN:
|
case TYPE_SOURCE_PLUGIN:
|
||||||
splugin = new sinsp_source_plugin();
|
splugin = new sinsp_source_plugin(handle);
|
||||||
if(!splugin->resolve_dylib_symbols(handle, errstr))
|
if(!splugin->resolve_dylib_symbols(errstr))
|
||||||
{
|
{
|
||||||
delete splugin;
|
delete splugin;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -401,14 +401,18 @@ std::shared_ptr<sinsp_plugin> sinsp_plugin::create_plugin(string &filepath, cons
|
||||||
ret.reset(splugin);
|
ret.reset(splugin);
|
||||||
break;
|
break;
|
||||||
case TYPE_EXTRACTOR_PLUGIN:
|
case TYPE_EXTRACTOR_PLUGIN:
|
||||||
eplugin = new sinsp_extractor_plugin();
|
eplugin = new sinsp_extractor_plugin(handle);
|
||||||
if(!eplugin->resolve_dylib_symbols(handle, errstr))
|
if(!eplugin->resolve_dylib_symbols(errstr))
|
||||||
{
|
{
|
||||||
delete eplugin;
|
delete eplugin;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret.reset(eplugin);
|
ret.reset(eplugin);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
errstr = string("Wrong plugin type.");
|
||||||
|
destroy_handle(handle);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
errstr = "";
|
errstr = "";
|
||||||
|
@ -449,13 +453,39 @@ std::list<sinsp_plugin::info> sinsp_plugin::plugin_infos(sinsp* inspector)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sinsp_plugin::sinsp_plugin()
|
bool sinsp_plugin::is_plugin_loaded(std::string &filepath)
|
||||||
: m_nfields(0)
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
/*
|
||||||
|
* LoadLibrary maps the module into the address space of the calling process, if necessary,
|
||||||
|
* and increments the modules reference count, if it is already mapped.
|
||||||
|
* GetModuleHandle, however, returns the handle to a mapped module
|
||||||
|
* without incrementing its reference count.
|
||||||
|
*
|
||||||
|
* This returns an HMODULE indeed, but they are the same thing
|
||||||
|
*/
|
||||||
|
sinsp_plugin_handle handle = (HINSTANCE)GetModuleHandle(filepath.c_str());
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* RTLD_NOLOAD (since glibc 2.2)
|
||||||
|
* Don't load the shared object. This can be used to test if
|
||||||
|
* the object is already resident (dlopen() returns NULL if
|
||||||
|
* it is not, or the object's handle if it is resident).
|
||||||
|
* This does not increment dlobject reference count.
|
||||||
|
*/
|
||||||
|
sinsp_plugin_handle handle = dlopen(filepath.c_str(), RTLD_LAZY | RTLD_NOLOAD);
|
||||||
|
#endif
|
||||||
|
return handle != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sinsp_plugin::sinsp_plugin(sinsp_plugin_handle handle)
|
||||||
|
: m_handle(handle), m_nfields(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
sinsp_plugin::~sinsp_plugin()
|
sinsp_plugin::~sinsp_plugin()
|
||||||
{
|
{
|
||||||
|
destroy_handle(m_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sinsp_plugin::init(const char *config)
|
bool sinsp_plugin::init(const char *config)
|
||||||
|
@ -582,12 +612,12 @@ bool sinsp_plugin::extract_field(ss_plugin_event &evt, sinsp_plugin::ext_field &
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* sinsp_plugin::getsym(void* handle, const char* name, std::string &errstr)
|
void* sinsp_plugin::getsym(sinsp_plugin_handle handle, const char* name, std::string &errstr)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
ret = GetProcAddress((HINSTANCE)handle, name);
|
ret = GetProcAddress(handle, name);
|
||||||
#else
|
#else
|
||||||
ret = dlsym(handle, name);
|
ret = dlsym(handle, name);
|
||||||
#endif
|
#endif
|
||||||
|
@ -615,25 +645,25 @@ std::string sinsp_plugin::str_from_alloc_charbuf(const char* charbuf)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sinsp_plugin::resolve_dylib_symbols(void *handle, std::string &errstr)
|
bool sinsp_plugin::resolve_dylib_symbols(std::string &errstr)
|
||||||
{
|
{
|
||||||
// Some functions are required and return false if not found.
|
// Some functions are required and return false if not found.
|
||||||
if((*(void **) (&(m_plugin_info.get_required_api_version)) = getsym(handle, "plugin_get_required_api_version", errstr)) == NULL ||
|
if((*(void **) (&(m_plugin_info.get_required_api_version)) = getsym(m_handle, "plugin_get_required_api_version", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_plugin_info.get_last_error)) = getsym(handle, "plugin_get_last_error", errstr)) == NULL ||
|
(*(void **) (&(m_plugin_info.get_last_error)) = getsym(m_handle, "plugin_get_last_error", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_plugin_info.get_name)) = getsym(handle, "plugin_get_name", errstr)) == NULL ||
|
(*(void **) (&(m_plugin_info.get_name)) = getsym(m_handle, "plugin_get_name", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_plugin_info.get_description)) = getsym(handle, "plugin_get_description", errstr)) == NULL ||
|
(*(void **) (&(m_plugin_info.get_description)) = getsym(m_handle, "plugin_get_description", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_plugin_info.get_contact)) = getsym(handle, "plugin_get_contact", errstr)) == NULL ||
|
(*(void **) (&(m_plugin_info.get_contact)) = getsym(m_handle, "plugin_get_contact", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_plugin_info.get_version)) = getsym(handle, "plugin_get_version", errstr)) == NULL)
|
(*(void **) (&(m_plugin_info.get_version)) = getsym(m_handle, "plugin_get_version", errstr)) == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Others are not and the values will be checked when needed.
|
// Others are not and the values will be checked when needed.
|
||||||
(*(void **) (&m_plugin_info.init)) = getsym(handle, "plugin_init", errstr);
|
(*(void **) (&m_plugin_info.init)) = getsym(m_handle, "plugin_init", errstr);
|
||||||
(*(void **) (&m_plugin_info.destroy)) = getsym(handle, "plugin_destroy", errstr);
|
(*(void **) (&m_plugin_info.destroy)) = getsym(m_handle, "plugin_destroy", errstr);
|
||||||
(*(void **) (&m_plugin_info.get_fields)) = getsym(handle, "plugin_get_fields", errstr);
|
(*(void **) (&m_plugin_info.get_fields)) = getsym(m_handle, "plugin_get_fields", errstr);
|
||||||
(*(void **) (&m_plugin_info.extract_fields)) = getsym(handle, "plugin_extract_fields", errstr);
|
(*(void **) (&m_plugin_info.extract_fields)) = getsym(m_handle, "plugin_extract_fields", errstr);
|
||||||
(*(void **) (&m_plugin_info.get_init_schema)) = getsym(handle, "plugin_get_init_schema", errstr);
|
(*(void **) (&m_plugin_info.get_init_schema)) = getsym(m_handle, "plugin_get_init_schema", errstr);
|
||||||
|
|
||||||
m_name = str_from_alloc_charbuf(m_plugin_info.get_name());
|
m_name = str_from_alloc_charbuf(m_plugin_info.get_name());
|
||||||
m_description = str_from_alloc_charbuf(m_plugin_info.get_description());
|
m_description = str_from_alloc_charbuf(m_plugin_info.get_description());
|
||||||
|
@ -697,6 +727,8 @@ bool sinsp_plugin::resolve_dylib_symbols(void *handle, std::string &errstr)
|
||||||
{
|
{
|
||||||
throw sinsp_exception(string("error in plugin ") + m_name + ": field JSON entry has no name");
|
throw sinsp_exception(string("error in plugin ") + m_name + ": field JSON entry has no name");
|
||||||
}
|
}
|
||||||
|
const Json::Value &jvdisplay = root[j]["display"];
|
||||||
|
string fdisplay = jvdisplay.asString();
|
||||||
const Json::Value &jvdesc = root[j]["desc"];
|
const Json::Value &jvdesc = root[j]["desc"];
|
||||||
string fdesc = jvdesc.asString();
|
string fdesc = jvdesc.asString();
|
||||||
if(fdesc == "")
|
if(fdesc == "")
|
||||||
|
@ -705,6 +737,7 @@ bool sinsp_plugin::resolve_dylib_symbols(void *handle, std::string &errstr)
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(tf.m_name, fname.c_str(), sizeof(tf.m_name));
|
strlcpy(tf.m_name, fname.c_str(), sizeof(tf.m_name));
|
||||||
|
strlcpy(tf.m_display, fdisplay.c_str(), sizeof(tf.m_display));
|
||||||
strlcpy(tf.m_description, fdesc.c_str(), sizeof(tf.m_description));
|
strlcpy(tf.m_description, fdesc.c_str(), sizeof(tf.m_description));
|
||||||
tf.m_print_format = PF_DEC;
|
tf.m_print_format = PF_DEC;
|
||||||
if(ftype == "string")
|
if(ftype == "string")
|
||||||
|
@ -763,12 +796,19 @@ bool sinsp_plugin::resolve_dylib_symbols(void *handle, std::string &errstr)
|
||||||
|
|
||||||
const std::string &str = prop.asString();
|
const std::string &str = prop.asString();
|
||||||
|
|
||||||
// There might be other properties (e.g. "conversation" and "info", which are used by wireshark),
|
// "hidden" is used inside and outside libs. "info" and "conversation" are used outside libs.
|
||||||
// but the only one that is relevant to libs is "hidden".
|
|
||||||
if(str == "hidden")
|
if(str == "hidden")
|
||||||
{
|
{
|
||||||
tf.m_flags = (filtercheck_field_flags) ((int) tf.m_flags | (int) filtercheck_field_flags::EPF_TABLE_ONLY);
|
tf.m_flags = (filtercheck_field_flags) ((int) tf.m_flags | (int) filtercheck_field_flags::EPF_TABLE_ONLY);
|
||||||
}
|
}
|
||||||
|
else if(str == "info")
|
||||||
|
{
|
||||||
|
tf.m_flags = (filtercheck_field_flags) ((int) tf.m_flags | (int) filtercheck_field_flags::EPF_INFO);
|
||||||
|
}
|
||||||
|
else if(str == "conversation")
|
||||||
|
{
|
||||||
|
tf.m_flags = (filtercheck_field_flags) ((int) tf.m_flags | (int) filtercheck_field_flags::EPF_CONVERSATION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -866,7 +906,16 @@ void sinsp_plugin::validate_init_config_json_schema(std::string config, std::str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sinsp_source_plugin::sinsp_source_plugin()
|
void sinsp_plugin::destroy_handle(sinsp_plugin_handle handle) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
FreeLibrary(handle);
|
||||||
|
#else
|
||||||
|
dlclose(handle);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
sinsp_source_plugin::sinsp_source_plugin(sinsp_plugin_handle handle) :
|
||||||
|
sinsp_plugin(handle)
|
||||||
{
|
{
|
||||||
memset(&m_source_plugin_info, 0, sizeof(m_source_plugin_info));
|
memset(&m_source_plugin_info, 0, sizeof(m_source_plugin_info));
|
||||||
}
|
}
|
||||||
|
@ -997,9 +1046,9 @@ ss_plugin_t *sinsp_source_plugin::plugin_state()
|
||||||
return m_source_plugin_info.state;
|
return m_source_plugin_info.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sinsp_source_plugin::resolve_dylib_symbols(void *handle, std::string &errstr)
|
bool sinsp_source_plugin::resolve_dylib_symbols(std::string &errstr)
|
||||||
{
|
{
|
||||||
if (!sinsp_plugin::resolve_dylib_symbols(handle, errstr))
|
if (!sinsp_plugin::resolve_dylib_symbols(errstr))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1010,32 +1059,32 @@ bool sinsp_source_plugin::resolve_dylib_symbols(void *handle, std::string &errst
|
||||||
// down to libscap when reading/writing capture files).
|
// down to libscap when reading/writing capture files).
|
||||||
//
|
//
|
||||||
// Some functions are required and return false if not found.
|
// Some functions are required and return false if not found.
|
||||||
if((*(void **) (&(m_source_plugin_info.get_required_api_version)) = getsym(handle, "plugin_get_required_api_version", errstr)) == NULL ||
|
if((*(void **) (&(m_source_plugin_info.get_required_api_version)) = getsym(m_handle, "plugin_get_required_api_version", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.init)) = getsym(handle, "plugin_init", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.init)) = getsym(m_handle, "plugin_init", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.destroy)) = getsym(handle, "plugin_destroy", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.destroy)) = getsym(m_handle, "plugin_destroy", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.get_last_error)) = getsym(handle, "plugin_get_last_error", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.get_last_error)) = getsym(m_handle, "plugin_get_last_error", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.get_type)) = getsym(handle, "plugin_get_type", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.get_type)) = getsym(m_handle, "plugin_get_type", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.get_id)) = getsym(handle, "plugin_get_id", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.get_id)) = getsym(m_handle, "plugin_get_id", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.get_name)) = getsym(handle, "plugin_get_name", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.get_name)) = getsym(m_handle, "plugin_get_name", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.get_description)) = getsym(handle, "plugin_get_description", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.get_description)) = getsym(m_handle, "plugin_get_description", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.get_contact)) = getsym(handle, "plugin_get_contact", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.get_contact)) = getsym(m_handle, "plugin_get_contact", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.get_version)) = getsym(handle, "plugin_get_version", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.get_version)) = getsym(m_handle, "plugin_get_version", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.get_event_source)) = getsym(handle, "plugin_get_event_source", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.get_event_source)) = getsym(m_handle, "plugin_get_event_source", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.open)) = getsym(handle, "plugin_open", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.open)) = getsym(m_handle, "plugin_open", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.close)) = getsym(handle, "plugin_close", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.close)) = getsym(m_handle, "plugin_close", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.next_batch)) = getsym(handle, "plugin_next_batch", errstr)) == NULL ||
|
(*(void **) (&(m_source_plugin_info.next_batch)) = getsym(m_handle, "plugin_next_batch", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_source_plugin_info.event_to_string)) = getsym(handle, "plugin_event_to_string", errstr)) == NULL)
|
(*(void **) (&(m_source_plugin_info.event_to_string)) = getsym(m_handle, "plugin_event_to_string", errstr)) == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Others are not.
|
// Others are not.
|
||||||
(*(void **) (&m_source_plugin_info.get_fields)) = getsym(handle, "plugin_get_fields", errstr);
|
(*(void **) (&m_source_plugin_info.get_fields)) = getsym(m_handle, "plugin_get_fields", errstr);
|
||||||
(*(void **) (&m_source_plugin_info.get_progress)) = getsym(handle, "plugin_get_progress", errstr);
|
(*(void **) (&m_source_plugin_info.get_progress)) = getsym(m_handle, "plugin_get_progress", errstr);
|
||||||
(*(void **) (&m_source_plugin_info.event_to_string)) = getsym(handle, "plugin_event_to_string", errstr);
|
(*(void **) (&m_source_plugin_info.event_to_string)) = getsym(m_handle, "plugin_event_to_string", errstr);
|
||||||
(*(void **) (&m_source_plugin_info.extract_fields)) = getsym(handle, "plugin_extract_fields", errstr);
|
(*(void **) (&m_source_plugin_info.extract_fields)) = getsym(m_handle, "plugin_extract_fields", errstr);
|
||||||
(*(void **) (&m_source_plugin_info.list_open_params)) = getsym(handle, "plugin_list_open_params", errstr);
|
(*(void **) (&m_source_plugin_info.list_open_params)) = getsym(m_handle, "plugin_list_open_params", errstr);
|
||||||
(*(void **) (&m_source_plugin_info.get_init_schema)) = getsym(handle, "plugin_get_init_schema", errstr);
|
(*(void **) (&m_source_plugin_info.get_init_schema)) = getsym(m_handle, "plugin_get_init_schema", errstr);
|
||||||
|
|
||||||
m_id = m_source_plugin_info.get_id();
|
m_id = m_source_plugin_info.get_id();
|
||||||
m_event_source = str_from_alloc_charbuf(m_source_plugin_info.get_event_source());
|
m_event_source = str_from_alloc_charbuf(m_source_plugin_info.get_event_source());
|
||||||
|
@ -1043,7 +1092,8 @@ bool sinsp_source_plugin::resolve_dylib_symbols(void *handle, std::string &errst
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sinsp_extractor_plugin::sinsp_extractor_plugin()
|
sinsp_extractor_plugin::sinsp_extractor_plugin(sinsp_plugin_handle handle) :
|
||||||
|
sinsp_plugin(handle)
|
||||||
{
|
{
|
||||||
memset(&m_extractor_plugin_info, 0, sizeof(m_extractor_plugin_info));
|
memset(&m_extractor_plugin_info, 0, sizeof(m_extractor_plugin_info));
|
||||||
}
|
}
|
||||||
|
@ -1074,9 +1124,9 @@ ss_plugin_t *sinsp_extractor_plugin::plugin_state()
|
||||||
return m_extractor_plugin_info.state;
|
return m_extractor_plugin_info.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sinsp_extractor_plugin::resolve_dylib_symbols(void *handle, std::string &errstr)
|
bool sinsp_extractor_plugin::resolve_dylib_symbols(std::string &errstr)
|
||||||
{
|
{
|
||||||
if (!sinsp_plugin::resolve_dylib_symbols(handle, errstr))
|
if (!sinsp_plugin::resolve_dylib_symbols(errstr))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1087,24 +1137,24 @@ bool sinsp_extractor_plugin::resolve_dylib_symbols(void *handle, std::string &er
|
||||||
// down to libscap when reading/writing capture files).
|
// down to libscap when reading/writing capture files).
|
||||||
//
|
//
|
||||||
// Some functions are required and return false if not found.
|
// Some functions are required and return false if not found.
|
||||||
if((*(void **) (&(m_extractor_plugin_info.get_required_api_version)) = getsym(handle, "plugin_get_required_api_version", errstr)) == NULL ||
|
if((*(void **) (&(m_extractor_plugin_info.get_required_api_version)) = getsym(m_handle, "plugin_get_required_api_version", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_extractor_plugin_info.init)) = getsym(handle, "plugin_init", errstr)) == NULL ||
|
(*(void **) (&(m_extractor_plugin_info.init)) = getsym(m_handle, "plugin_init", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_extractor_plugin_info.destroy)) = getsym(handle, "plugin_destroy", errstr)) == NULL ||
|
(*(void **) (&(m_extractor_plugin_info.destroy)) = getsym(m_handle, "plugin_destroy", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_extractor_plugin_info.get_last_error)) = getsym(handle, "plugin_get_last_error", errstr)) == NULL ||
|
(*(void **) (&(m_extractor_plugin_info.get_last_error)) = getsym(m_handle, "plugin_get_last_error", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_extractor_plugin_info.get_type)) = getsym(handle, "plugin_get_type", errstr)) == NULL ||
|
(*(void **) (&(m_extractor_plugin_info.get_type)) = getsym(m_handle, "plugin_get_type", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_extractor_plugin_info.get_name)) = getsym(handle, "plugin_get_name", errstr)) == NULL ||
|
(*(void **) (&(m_extractor_plugin_info.get_name)) = getsym(m_handle, "plugin_get_name", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_extractor_plugin_info.get_description)) = getsym(handle, "plugin_get_description", errstr)) == NULL ||
|
(*(void **) (&(m_extractor_plugin_info.get_description)) = getsym(m_handle, "plugin_get_description", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_extractor_plugin_info.get_contact)) = getsym(handle, "plugin_get_contact", errstr)) == NULL ||
|
(*(void **) (&(m_extractor_plugin_info.get_contact)) = getsym(m_handle, "plugin_get_contact", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_extractor_plugin_info.get_version)) = getsym(handle, "plugin_get_version", errstr)) == NULL ||
|
(*(void **) (&(m_extractor_plugin_info.get_version)) = getsym(m_handle, "plugin_get_version", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_extractor_plugin_info.get_fields)) = getsym(handle, "plugin_get_fields", errstr)) == NULL ||
|
(*(void **) (&(m_extractor_plugin_info.get_fields)) = getsym(m_handle, "plugin_get_fields", errstr)) == NULL ||
|
||||||
(*(void **) (&(m_extractor_plugin_info.extract_fields)) = getsym(handle, "plugin_extract_fields", errstr)) == NULL)
|
(*(void **) (&(m_extractor_plugin_info.extract_fields)) = getsym(m_handle, "plugin_extract_fields", errstr)) == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Others are not.
|
// Others are not.
|
||||||
(*(void **) (&m_extractor_plugin_info.get_extract_event_sources)) = getsym(handle, "plugin_get_extract_event_sources", errstr);
|
(*(void **) (&m_extractor_plugin_info.get_extract_event_sources)) = getsym(m_handle, "plugin_get_extract_event_sources", errstr);
|
||||||
(*(void **) (&m_extractor_plugin_info.get_init_schema)) = getsym(handle, "plugin_get_init_schema", errstr);
|
(*(void **) (&m_extractor_plugin_info.get_init_schema)) = getsym(m_handle, "plugin_get_init_schema", errstr);
|
||||||
|
|
||||||
|
|
||||||
if (m_extractor_plugin_info.get_extract_event_sources != NULL)
|
if (m_extractor_plugin_info.get_extract_event_sources != NULL)
|
||||||
|
|
|
@ -28,6 +28,13 @@ limitations under the License.
|
||||||
|
|
||||||
#include "filter_check_list.h"
|
#include "filter_check_list.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
typedef HINSTANCE sinsp_plugin_handle;
|
||||||
|
#else
|
||||||
|
typedef void* sinsp_plugin_handle;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class sinsp_filter_check_plugin;
|
class sinsp_filter_check_plugin;
|
||||||
|
|
||||||
// Base class for source/extractor plugins. Can not be created directly.
|
// Base class for source/extractor plugins. Can not be created directly.
|
||||||
|
@ -94,14 +101,17 @@ public:
|
||||||
// Return a string with names/descriptions/etc of all plugins used by this inspector
|
// Return a string with names/descriptions/etc of all plugins used by this inspector
|
||||||
static std::list<sinsp_plugin::info> plugin_infos(sinsp *inspector);
|
static std::list<sinsp_plugin::info> plugin_infos(sinsp *inspector);
|
||||||
|
|
||||||
sinsp_plugin();
|
// Return whether a filesystem object is loaded
|
||||||
|
static bool is_plugin_loaded(std::string &filepath);
|
||||||
|
|
||||||
|
sinsp_plugin(sinsp_plugin_handle handle);
|
||||||
virtual ~sinsp_plugin();
|
virtual ~sinsp_plugin();
|
||||||
|
|
||||||
// Given a dynamic library handle, fill in common properties
|
// Given a dynamic library handle, fill in common properties
|
||||||
// (name/desc/etc) and required functions
|
// (name/desc/etc) and required functions
|
||||||
// (init/destroy/extract/etc).
|
// (init/destroy/extract/etc).
|
||||||
// Returns true on success, false + sets errstr on error.
|
// Returns true on success, false + sets errstr on error.
|
||||||
virtual bool resolve_dylib_symbols(void *handle, std::string &errstr);
|
virtual bool resolve_dylib_symbols(std::string &errstr);
|
||||||
|
|
||||||
bool init(const char* config);
|
bool init(const char* config);
|
||||||
void destroy();
|
void destroy();
|
||||||
|
@ -123,9 +133,11 @@ public:
|
||||||
std::string get_init_schema(ss_plugin_schema_type& schema_type);
|
std::string get_init_schema(ss_plugin_schema_type& schema_type);
|
||||||
void validate_init_config(const char* config);
|
void validate_init_config(const char* config);
|
||||||
|
|
||||||
|
sinsp_plugin_handle m_handle;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Helper function to resolve symbols
|
// Helper function to resolve symbols
|
||||||
static void* getsym(void* handle, const char* name, std::string &errstr);
|
static void* getsym(sinsp_plugin_handle handle, const char* name, std::string &errstr);
|
||||||
|
|
||||||
// Helper function to set a string from an allocated charbuf and free the charbuf.
|
// Helper function to set a string from an allocated charbuf and free the charbuf.
|
||||||
std::string str_from_alloc_charbuf(const char* charbuf);
|
std::string str_from_alloc_charbuf(const char* charbuf);
|
||||||
|
@ -165,6 +177,8 @@ private:
|
||||||
common_plugin_info m_plugin_info;
|
common_plugin_info m_plugin_info;
|
||||||
|
|
||||||
void validate_init_config_json_schema(std::string config, std::string &schema);
|
void validate_init_config_json_schema(std::string config, std::string &schema);
|
||||||
|
|
||||||
|
static void destroy_handle(sinsp_plugin_handle handle);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note that this doesn't have a next_batch() method, as event generation is
|
// Note that this doesn't have a next_batch() method, as event generation is
|
||||||
|
@ -178,10 +192,10 @@ public:
|
||||||
std::string desc;
|
std::string desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
sinsp_source_plugin();
|
sinsp_source_plugin(sinsp_plugin_handle handle);
|
||||||
virtual ~sinsp_source_plugin();
|
virtual ~sinsp_source_plugin();
|
||||||
|
|
||||||
bool resolve_dylib_symbols(void *handle, std::string &errstr) override;
|
bool resolve_dylib_symbols(std::string &errstr) override;
|
||||||
|
|
||||||
ss_plugin_type type() override { return TYPE_SOURCE_PLUGIN; };
|
ss_plugin_type type() override { return TYPE_SOURCE_PLUGIN; };
|
||||||
uint32_t id();
|
uint32_t id();
|
||||||
|
@ -214,10 +228,10 @@ private:
|
||||||
class sinsp_extractor_plugin : public sinsp_plugin
|
class sinsp_extractor_plugin : public sinsp_plugin
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sinsp_extractor_plugin();
|
sinsp_extractor_plugin(sinsp_plugin_handle handle);
|
||||||
virtual ~sinsp_extractor_plugin();
|
virtual ~sinsp_extractor_plugin();
|
||||||
|
|
||||||
bool resolve_dylib_symbols(void *handle, std::string &errstr) override;
|
bool resolve_dylib_symbols(std::string &errstr) override;
|
||||||
|
|
||||||
ss_plugin_type type() override { return TYPE_EXTRACTOR_PLUGIN; };
|
ss_plugin_type type() override { return TYPE_EXTRACTOR_PLUGIN; };
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2021 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 "procfs_utils.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "sinsp.h"
|
||||||
|
|
||||||
|
int libsinsp::procfs_utils::get_userns_root_uid(std::istream& uid_map)
|
||||||
|
{
|
||||||
|
std::string uid_map_line;
|
||||||
|
|
||||||
|
while(std::getline(uid_map, uid_map_line))
|
||||||
|
{
|
||||||
|
int src_uid, target_uid;
|
||||||
|
std::stringstream mapping(uid_map_line);
|
||||||
|
mapping >> src_uid;
|
||||||
|
|
||||||
|
// if the target uid we're looking for was anything other than 0,
|
||||||
|
// we'd have to check the length of the range as well, but since
|
||||||
|
// 0 is the lowest, we're good
|
||||||
|
if(src_uid != 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mapping >> target_uid;
|
||||||
|
|
||||||
|
return target_uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return libsinsp::procfs_utils::NO_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string libsinsp::procfs_utils::get_systemd_cgroup(std::istream& cgroups)
|
||||||
|
{
|
||||||
|
std::string cgroups_line;
|
||||||
|
|
||||||
|
while(std::getline(cgroups, cgroups_line))
|
||||||
|
{
|
||||||
|
size_t cgpos = cgroups_line.find(":name=systemd:");
|
||||||
|
if(cgpos == std::string::npos)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string systemd_cgroup = cgroups_line.substr(cgpos + strlen(":name=systemd:"), std::string::npos);
|
||||||
|
return systemd_cgroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <istream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace libsinsp {
|
||||||
|
namespace procfs_utils {
|
||||||
|
|
||||||
|
constexpr const int NO_MATCH = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parse /proc/<pid>/uid_map to find the uid that root in the userns maps to
|
||||||
|
* @param uid_map a stream with the contents of /proc/<pid>/uid_map
|
||||||
|
* @return the uid of the userns owner
|
||||||
|
*
|
||||||
|
* For unprivileged Podman containers at least, all processes are created
|
||||||
|
* in a child user namespace which maps uids inside the container to uids
|
||||||
|
* outside. The root user in the container is mapped to the uid that created
|
||||||
|
* the container (in the parent user namespace)
|
||||||
|
*/
|
||||||
|
int get_userns_root_uid(std::istream& uid_map);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the path of the `name=systemd` cgroup
|
||||||
|
* @param cgroups a stream with the contents of /proc/<pid>/cgroup
|
||||||
|
* @return the path of the `name=systemd` cgroup
|
||||||
|
*/
|
||||||
|
std::string get_systemd_cgroup(std::istream& cgroups);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,11 @@ const char* CONTAINER_ID_VALID_CHARACTERS = "0123456789abcdefABCDEF";
|
||||||
|
|
||||||
static_assert(REPORTED_CONTAINER_ID_LENGTH <= CONTAINER_ID_LENGTH, "Reported container ID length cannot be longer than actual length");
|
static_assert(REPORTED_CONTAINER_ID_LENGTH <= CONTAINER_ID_LENGTH, "Reported container ID length cannot be longer than actual length");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace libsinsp {
|
||||||
|
namespace runc {
|
||||||
|
|
||||||
// check if cgroup ends with <prefix><container_id><suffix>
|
// check if cgroup ends with <prefix><container_id><suffix>
|
||||||
// If true, set <container_id> to a truncated version of the id and return true.
|
// If true, set <container_id> to a truncated version of the id and return true.
|
||||||
// Otherwise return false and leave container_id unchanged
|
// Otherwise return false and leave container_id unchanged
|
||||||
|
@ -76,17 +81,13 @@ bool match_container_id(const std::string &cgroup, const libsinsp::runc::cgroup_
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
bool matches_runc_cgroups(const sinsp_threadinfo *tinfo, const cgroup_layout *layout, std::string &container_id, std::string &matching_cgroup)
|
||||||
|
|
||||||
namespace libsinsp {
|
|
||||||
namespace runc {
|
|
||||||
|
|
||||||
bool matches_runc_cgroups(const sinsp_threadinfo *tinfo, const cgroup_layout *layout, std::string &container_id)
|
|
||||||
{
|
{
|
||||||
for(const auto &it : tinfo->m_cgroups)
|
for(const auto &it : tinfo->m_cgroups)
|
||||||
{
|
{
|
||||||
if(match_container_id(it.second, layout, container_id))
|
if(match_container_id(it.second, layout, container_id))
|
||||||
{
|
{
|
||||||
|
matching_cgroup = it.second;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,22 +24,61 @@ class sinsp_threadinfo;
|
||||||
namespace libsinsp {
|
namespace libsinsp {
|
||||||
namespace runc {
|
namespace runc {
|
||||||
|
|
||||||
/// runc-based runtimes (Docker, containerd, CRI-O, probably others) use the same two cgroup layouts
|
/**
|
||||||
/// with slight variations:
|
* @brief A pattern to match cgroup paths against
|
||||||
/// - non-systemd layout uses cgroups ending with .../<prefix><container id>
|
*
|
||||||
/// - systemd layout uses .../<prefix><container id>.scope
|
* runc-based runtimes (Docker, containerd, CRI-O, probably others) use the same two cgroup layouts
|
||||||
/// where <container id> is always 64 hex digits (we report the first 12 as the container id).
|
* with slight variations:
|
||||||
/// For non-systemd only CRI-O seems to use /crio-<container id>, while for systemd layout
|
* - non-systemd layout uses cgroups ending with .../<prefix><container id>
|
||||||
/// while all known container engines use a prefix like "docker-", "crio-" or "containerd-cri-".
|
* - systemd layout uses .../<prefix><container id>.scope
|
||||||
/// We can encode all these variants with a simple list of (prefix, suffix) pairs
|
* where <container id> is always 64 hex digits (we report the first 12 as the container id).
|
||||||
/// (the last one must be a pair of null pointers to mark the end of the array)
|
* For non-systemd only CRI-O seems to use /crio-<container id>, while for systemd layout
|
||||||
|
* while all known container engines use a prefix like "docker-", "crio-" or "containerd-cri-".
|
||||||
|
* We can encode all these variants with a simple list of (prefix, suffix) pairs
|
||||||
|
* (the last one must be a pair of null pointers to mark the end of the array)
|
||||||
|
*/
|
||||||
struct cgroup_layout {
|
struct cgroup_layout {
|
||||||
const char* prefix;
|
const char* prefix;
|
||||||
const char* suffix;
|
const char* suffix;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// If any of the cgroups of the thread in `tinfo` matches the `layout`, set `container_id` to the found id
|
/**
|
||||||
/// and return true. Otherwise, return false and leave `container_id` unchanged
|
* @brief Check if `cgroup` ends with <prefix><64_hex_digits><suffix>
|
||||||
bool matches_runc_cgroups(const sinsp_threadinfo *tinfo, const cgroup_layout *layout, std::string &container_id);
|
* @param container_id output parameter
|
||||||
|
* @return true if `cgroup` matches the pattern
|
||||||
|
*
|
||||||
|
* If this function returns true, `container_id` will be set to
|
||||||
|
* the truncated hex string (first 12 digits). Otherwise, it will remain
|
||||||
|
* unchanged.
|
||||||
|
*/
|
||||||
|
bool match_one_container_id(const std::string &cgroup, const std::string &prefix, const std::string &suffix, std::string &container_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Match `cgroup` against a list of layouts using `match_one_container_id()`
|
||||||
|
* @param layout an array of (prefix, suffix) pairs
|
||||||
|
* @param container_id output parameter
|
||||||
|
* @return true if `cgroup` matches any of the patterns
|
||||||
|
*
|
||||||
|
* `layout` is an array terminated by an empty entry (prefix, suffix both empty)
|
||||||
|
*
|
||||||
|
* If this function returns true, `container_id` will be set to
|
||||||
|
* the truncated hex string (first 12 digits). Otherwise, it will remain
|
||||||
|
* unchanged.
|
||||||
|
*/
|
||||||
|
bool match_container_id(const std::string &cgroup, const libsinsp::runc::cgroup_layout *layout,
|
||||||
|
std::string &container_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Match all the cgroups of `tinfo` against a list of cgroup layouts
|
||||||
|
* @param layout an array of (prefix, suffix) pairs
|
||||||
|
* @param container_id output parameter
|
||||||
|
* @param matching_cgroup output parameter
|
||||||
|
* @return true if any of `tinfo`'s cgroups match any of the patterns
|
||||||
|
*
|
||||||
|
* If this function returns true, `container_id` will be set to
|
||||||
|
* the truncated hex string (first 12 digits). Otherwise, it will remain
|
||||||
|
* unchanged.
|
||||||
|
*/
|
||||||
|
bool matches_runc_cgroups(const sinsp_threadinfo *tinfo, const cgroup_layout *layout, std::string &container_id, std::string &matching_cgroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,6 @@ sinsp::sinsp(bool static_container, const std::string static_id, const std::stri
|
||||||
|
|
||||||
#ifdef HAS_FILTERING
|
#ifdef HAS_FILTERING
|
||||||
m_filter = NULL;
|
m_filter = NULL;
|
||||||
m_evttype_filter = NULL;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_fds_to_remove = new vector<int64_t>;
|
m_fds_to_remove = new vector<int64_t>;
|
||||||
|
@ -798,11 +797,6 @@ void sinsp::close()
|
||||||
m_filter = NULL;
|
m_filter = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_evttype_filter != NULL)
|
|
||||||
{
|
|
||||||
delete m_evttype_filter;
|
|
||||||
m_evttype_filter = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_ppm_sc_of_interest.clear();
|
m_ppm_sc_of_interest.clear();
|
||||||
|
@ -1314,11 +1308,13 @@ int32_t sinsp::next(OUT sinsp_evt **puevt)
|
||||||
"n_evts:%" PRIu64
|
"n_evts:%" PRIu64
|
||||||
" n_drops:%" PRIu64
|
" n_drops:%" PRIu64
|
||||||
" n_drops_buffer:%" PRIu64
|
" n_drops_buffer:%" PRIu64
|
||||||
|
" n_drops_scratch_map:%" PRIu64
|
||||||
" n_drops_pf:%" PRIu64
|
" n_drops_pf:%" PRIu64
|
||||||
" n_drops_bug:%" PRIu64,
|
" n_drops_bug:%" PRIu64,
|
||||||
stats.n_evts,
|
stats.n_evts,
|
||||||
stats.n_drops,
|
stats.n_drops,
|
||||||
stats.n_drops_buffer,
|
stats.n_drops_buffer,
|
||||||
|
stats.n_drops_scratch_map,
|
||||||
stats.n_drops_pf,
|
stats.n_drops_pf,
|
||||||
stats.n_drops_bug);
|
stats.n_drops_bug);
|
||||||
}
|
}
|
||||||
|
@ -1582,6 +1578,11 @@ void sinsp::set_cri_socket_path(const std::string& path)
|
||||||
m_container_manager.set_cri_socket_path(path);
|
m_container_manager.set_cri_socket_path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sinsp::add_cri_socket_path(const std::string& path)
|
||||||
|
{
|
||||||
|
m_container_manager.add_cri_socket_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
void sinsp::set_cri_timeout(int64_t timeout_ms)
|
void sinsp::set_cri_timeout(int64_t timeout_ms)
|
||||||
{
|
{
|
||||||
m_container_manager.set_cri_timeout(timeout_ms);
|
m_container_manager.set_cri_timeout(timeout_ms);
|
||||||
|
@ -1834,21 +1835,6 @@ const string sinsp::get_filter()
|
||||||
return m_filterstring;
|
return m_filterstring;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sinsp::add_evttype_filter(string &name,
|
|
||||||
set<uint32_t> &evttypes,
|
|
||||||
set<uint32_t> &syscalls,
|
|
||||||
set<string> &tags,
|
|
||||||
sinsp_filter *filter)
|
|
||||||
{
|
|
||||||
// Create the evttype filter if it doesn't exist.
|
|
||||||
if(m_evttype_filter == NULL)
|
|
||||||
{
|
|
||||||
m_evttype_filter = new sinsp_evttype_filter();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_evttype_filter->add(name, evttypes, syscalls, tags, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sinsp::run_filters_on_evt(sinsp_evt *evt)
|
bool sinsp::run_filters_on_evt(sinsp_evt *evt)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -1859,13 +1845,6 @@ bool sinsp::run_filters_on_evt(sinsp_evt *evt)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Then run the evttype filter, if there is one.
|
|
||||||
if(m_evttype_filter && m_evttype_filter->run(evt) == true)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2341,6 +2320,37 @@ void sinsp::init_k8s_client(string* api_server, string* ssl_cert, string* node_n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sinsp::validate_k8s_node_name()
|
||||||
|
{
|
||||||
|
if(!m_k8s_node_name || m_k8s_node_name->size() == 0)
|
||||||
|
{
|
||||||
|
g_logger.log("No k8s node name passed as argument. "
|
||||||
|
"This may result in performance penalty on large clusters", sinsp_logger::SEV_WARNING);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
const auto& state = m_k8s_client->get_state();
|
||||||
|
|
||||||
|
for(const auto& node : state.get_nodes())
|
||||||
|
{
|
||||||
|
if(!node.get_node_name().compare(*m_k8s_node_name))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found)
|
||||||
|
{
|
||||||
|
throw sinsp_exception("Failing to enrich events with Kubernetes metadata:"
|
||||||
|
"node name does not correspond to a node in the cluster");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_k8s_node_name_validated = true;
|
||||||
|
}
|
||||||
|
|
||||||
void sinsp::collect_k8s()
|
void sinsp::collect_k8s()
|
||||||
{
|
{
|
||||||
if(m_parser)
|
if(m_parser)
|
||||||
|
@ -2372,6 +2382,11 @@ void sinsp::collect_k8s()
|
||||||
delta = sinsp_utils::get_current_time_ns() - delta;
|
delta = sinsp_utils::get_current_time_ns() - delta;
|
||||||
g_logger.format(sinsp_logger::SEV_DEBUG, "Updating Kubernetes state took %" PRIu64 " ms", delta / 1000000LL);
|
g_logger.format(sinsp_logger::SEV_DEBUG, "Updating Kubernetes state took %" PRIu64 " ms", delta / 1000000LL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!m_k8s_node_name_validated)
|
||||||
|
{
|
||||||
|
validate_k8s_node_name();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2021 The Falco Authors.
|
Copyright (C) 2022 The Falco Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -366,12 +366,6 @@ public:
|
||||||
*/
|
*/
|
||||||
const string get_filter();
|
const string get_filter();
|
||||||
|
|
||||||
void add_evttype_filter(std::string &name,
|
|
||||||
std::set<uint32_t> &evttypes,
|
|
||||||
std::set<uint32_t> &syscalls,
|
|
||||||
std::set<std::string> &tags,
|
|
||||||
sinsp_filter* filter);
|
|
||||||
|
|
||||||
bool run_filters_on_evt(sinsp_evt *evt);
|
bool run_filters_on_evt(sinsp_evt *evt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -655,6 +649,38 @@ public:
|
||||||
return PLUGIN_API_VERSION_STR;
|
return PLUGIN_API_VERSION_STR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Returns the API version supported by the driver
|
||||||
|
*/
|
||||||
|
inline uint64_t get_driver_api_version() const
|
||||||
|
{
|
||||||
|
return scap_get_driver_api_version(m_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Returns the minimum API version required by the userspace library
|
||||||
|
*/
|
||||||
|
inline uint64_t get_scap_api_version() const
|
||||||
|
{
|
||||||
|
return SCAP_MINIMUM_DRIVER_API_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Returns the schema version supported by the driver
|
||||||
|
*/
|
||||||
|
inline uint64_t get_driver_schema_version() const
|
||||||
|
{
|
||||||
|
return scap_get_driver_schema_version(m_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Returns the minimum schema version required by the userspace library
|
||||||
|
*/
|
||||||
|
inline uint64_t get_scap_schema_version() const
|
||||||
|
{
|
||||||
|
return SCAP_MINIMUM_DRIVER_SCHEMA_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns true if truncated environments should be loaded from /proc
|
\brief Returns true if truncated environments should be loaded from /proc
|
||||||
*/
|
*/
|
||||||
|
@ -855,6 +881,7 @@ public:
|
||||||
void init_k8s_client(std::string* api_server, std::string* ssl_cert, std::string *node_name, bool verbose = false);
|
void init_k8s_client(std::string* api_server, std::string* ssl_cert, std::string *node_name, bool verbose = false);
|
||||||
void make_k8s_client();
|
void make_k8s_client();
|
||||||
k8s* get_k8s_client() const { return m_k8s_client; }
|
k8s* get_k8s_client() const { return m_k8s_client; }
|
||||||
|
void validate_k8s_node_name();
|
||||||
|
|
||||||
void init_mesos_client(std::string* api_server, bool verbose = false);
|
void init_mesos_client(std::string* api_server, bool verbose = false);
|
||||||
mesos* get_mesos_client() const { return m_mesos_client; }
|
mesos* get_mesos_client() const { return m_mesos_client; }
|
||||||
|
@ -960,7 +987,14 @@ public:
|
||||||
|
|
||||||
void set_statsd_port(uint16_t port);
|
void set_statsd_port(uint16_t port);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Reset list of crio socket paths currently stored, and set path as the only path.
|
||||||
|
*/
|
||||||
void set_cri_socket_path(const std::string& path);
|
void set_cri_socket_path(const std::string& path);
|
||||||
|
/*!
|
||||||
|
\brief Pushed a new path to the list of crio socket paths
|
||||||
|
*/
|
||||||
|
void add_cri_socket_path(const std::string &path);
|
||||||
void set_cri_timeout(int64_t timeout_ms);
|
void set_cri_timeout(int64_t timeout_ms);
|
||||||
void set_cri_async(bool async);
|
void set_cri_async(bool async);
|
||||||
void set_cri_delay(uint64_t delay_ms);
|
void set_cri_delay(uint64_t delay_ms);
|
||||||
|
@ -1109,6 +1143,7 @@ public:
|
||||||
std::string* m_k8s_api_server;
|
std::string* m_k8s_api_server;
|
||||||
std::string* m_k8s_api_cert;
|
std::string* m_k8s_api_cert;
|
||||||
std::string* m_k8s_node_name;
|
std::string* m_k8s_node_name;
|
||||||
|
bool m_k8s_node_name_validated = false;
|
||||||
#ifdef HAS_CAPTURE
|
#ifdef HAS_CAPTURE
|
||||||
std::shared_ptr<sinsp_ssl> m_k8s_ssl;
|
std::shared_ptr<sinsp_ssl> m_k8s_ssl;
|
||||||
std::shared_ptr<sinsp_bearer_token> m_k8s_bt;
|
std::shared_ptr<sinsp_bearer_token> m_k8s_bt;
|
||||||
|
@ -1146,7 +1181,6 @@ public:
|
||||||
#ifdef HAS_FILTERING
|
#ifdef HAS_FILTERING
|
||||||
uint64_t m_firstevent_ts;
|
uint64_t m_firstevent_ts;
|
||||||
sinsp_filter* m_filter;
|
sinsp_filter* m_filter;
|
||||||
sinsp_evttype_filter *m_evttype_filter;
|
|
||||||
std::string m_filterstring;
|
std::string m_filterstring;
|
||||||
#endif
|
#endif
|
||||||
unordered_set<uint32_t> m_ppm_sc_of_interest;
|
unordered_set<uint32_t> m_ppm_sc_of_interest;
|
||||||
|
|
|
@ -22,15 +22,22 @@ if(NOT MINIMAL_BUILD)
|
||||||
endif() # MINIMAL_BUILD
|
endif() # MINIMAL_BUILD
|
||||||
|
|
||||||
include_directories("..")
|
include_directories("..")
|
||||||
include_directories(${LIBSCAP_INCLUDE_DIR})
|
include_directories(${LIBSCAP_INCLUDE_DIR} ${LIBSCAP_DIR}/driver)
|
||||||
|
|
||||||
add_executable(unit-test-libsinsp
|
set(LIBSINSP_UNIT_TESTS_SOURCES
|
||||||
cgroup_list_counter.ut.cpp
|
cgroup_list_counter.ut.cpp
|
||||||
sinsp.ut.cpp
|
sinsp.ut.cpp
|
||||||
evttype_filter.ut.cpp
|
evttype_filter.ut.cpp
|
||||||
token_bucket.ut.cpp
|
token_bucket.ut.cpp
|
||||||
|
ppm_api_version.ut.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(NOT MINIMAL_BUILD)
|
||||||
|
list(APPEND LIBSINSP_UNIT_TESTS_SOURCES procfs_utils.ut.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(unit-test-libsinsp ${LIBSINSP_UNIT_TESTS_SOURCES})
|
||||||
|
|
||||||
target_link_libraries(unit-test-libsinsp
|
target_link_libraries(unit-test-libsinsp
|
||||||
"${GTEST_LIB}"
|
"${GTEST_LIB}"
|
||||||
"${GTEST_MAIN_LIB}"
|
"${GTEST_MAIN_LIB}"
|
||||||
|
|
|
@ -27,5 +27,6 @@ ExternalProject_Add(googletest
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND ""
|
BUILD_COMMAND ""
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
|
UPDATE_COMMAND ""
|
||||||
TEST_COMMAND ""
|
TEST_COMMAND ""
|
||||||
)
|
)
|
||||||
|
|
|
@ -91,8 +91,8 @@ protected:
|
||||||
FAIL() << "Expected event type "
|
FAIL() << "Expected event type "
|
||||||
<< etype
|
<< etype
|
||||||
<< " not found in actual set. "
|
<< " not found in actual set. "
|
||||||
<< "Expected: " << expected << " "
|
<< "Expected: " << testing::PrintToString(expected) << " "
|
||||||
<< " Actual: " << actual;
|
<< " Actual: " << testing::PrintToString(actual);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,8 +104,8 @@ protected:
|
||||||
FAIL() << "Actual evttypes had additional event type "
|
FAIL() << "Actual evttypes had additional event type "
|
||||||
<< etype
|
<< etype
|
||||||
<< " not found in expected set. "
|
<< " not found in expected set. "
|
||||||
<< "Expected: " << expected << " "
|
<< "Expected: " << testing::PrintToString(expected) << " "
|
||||||
<< " Actual: " << actual;
|
<< " Actual: " << testing::PrintToString(actual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2022 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.h>
|
||||||
|
#include <ppm_api_version.h>
|
||||||
|
|
||||||
|
TEST(api_version, unpack)
|
||||||
|
{
|
||||||
|
uint64_t ver1_2_3 = (1ULL << 44) | (2ULL << 24) | 3;
|
||||||
|
ASSERT_EQ(ver1_2_3, PPM_API_VERSION(1, 2, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(api_version, pack)
|
||||||
|
{
|
||||||
|
uint64_t ver1_2_3 = (1ULL << 44) | (2ULL << 24) | 3;
|
||||||
|
EXPECT_EQ(1u, PPM_API_VERSION_MAJOR(ver1_2_3));
|
||||||
|
EXPECT_EQ(2u, PPM_API_VERSION_MINOR(ver1_2_3));
|
||||||
|
EXPECT_EQ(3u, PPM_API_VERSION_PATCH(ver1_2_3));
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2021 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.h>
|
||||||
|
#include <procfs_utils.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace libsinsp::procfs_utils;
|
||||||
|
|
||||||
|
TEST(procfs_utils_test, get_userns_uid)
|
||||||
|
{
|
||||||
|
std::string uidmap = " 0 1000 0\n 1 1000000 1000\n";
|
||||||
|
std::stringstream s(uidmap);
|
||||||
|
|
||||||
|
ASSERT_EQ(get_userns_root_uid(s), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(procfs_utils_test, get_userns_uid_root)
|
||||||
|
{
|
||||||
|
std::string uidmap = " 0 0 0\n";
|
||||||
|
std::stringstream s(uidmap);
|
||||||
|
|
||||||
|
ASSERT_EQ(get_userns_root_uid(s), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(procfs_utils_test, get_systemd_cgroup)
|
||||||
|
{
|
||||||
|
std::string cgroups = "12:perf_event:/\n"
|
||||||
|
"11:memory:/user.slice/user-0.slice/session-10697.scope\n"
|
||||||
|
"10:cpuset:/\n"
|
||||||
|
"9:cpu,cpuacct:/user.slice/user-0.slice/session-10697.scope\n"
|
||||||
|
"8:hugetlb:/\n"
|
||||||
|
"7:freezer:/\n"
|
||||||
|
"6:rdma:/\n"
|
||||||
|
"5:devices:/user.slice/user-0.slice/session-10697.scope\n"
|
||||||
|
"4:pids:/user.slice/user-0.slice/session-10697.scope\n"
|
||||||
|
"3:blkio:/user.slice/user-0.slice/session-10697.scope\n"
|
||||||
|
"2:net_cls,net_prio:/\n"
|
||||||
|
"1:name=systemd:/user.slice/user-0.slice/session-10697.scope";
|
||||||
|
std::stringstream s(cgroups);
|
||||||
|
|
||||||
|
ASSERT_EQ(get_systemd_cgroup(s), "/user.slice/user-0.slice/session-10697.scope");
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "token_bucket.h"
|
#include "token_bucket.h"
|
||||||
#include <gtest.h>
|
#include <gtest.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
// token bucket default ctor
|
// token bucket default ctor
|
||||||
TEST(token_bucket, constructor)
|
TEST(token_bucket, constructor)
|
||||||
|
|
|
@ -949,16 +949,14 @@ void sinsp_threadinfo::traverse_parent_state(visitor_func_t &visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sinsp_threadinfo::populate_cmdline(string &cmdline, sinsp_threadinfo *tinfo)
|
void sinsp_threadinfo::populate_cmdline(string &cmdline, const sinsp_threadinfo *tinfo)
|
||||||
{
|
{
|
||||||
cmdline = tinfo->get_comm();
|
cmdline = tinfo->get_comm();
|
||||||
|
|
||||||
uint32_t j;
|
for (const auto& arg : tinfo->m_args)
|
||||||
uint32_t nargs = (uint32_t)tinfo->m_args.size();
|
|
||||||
|
|
||||||
for(j = 0; j < nargs; j++)
|
|
||||||
{
|
{
|
||||||
cmdline += " " + tinfo->m_args[j];
|
cmdline += " ";
|
||||||
|
cmdline += arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,7 +229,7 @@ public:
|
||||||
typedef std::function<bool (sinsp_threadinfo *)> visitor_func_t;
|
typedef std::function<bool (sinsp_threadinfo *)> visitor_func_t;
|
||||||
void traverse_parent_state(visitor_func_t &visitor);
|
void traverse_parent_state(visitor_func_t &visitor);
|
||||||
|
|
||||||
static void populate_cmdline(std::string &cmdline, sinsp_threadinfo *tinfo);
|
static void populate_cmdline(std::string &cmdline, const sinsp_threadinfo *tinfo);
|
||||||
|
|
||||||
// Return true if this thread is a part of a healthcheck,
|
// Return true if this thread is a part of a healthcheck,
|
||||||
// readiness probe, or liveness probe.
|
// readiness probe, or liveness probe.
|
||||||
|
|
|
@ -898,7 +898,7 @@ void sinsp_utils::bt(void)
|
||||||
|
|
||||||
bool sinsp_utils::find_first_env(std::string &out, const vector<std::string> &env, const vector<std::string> &keys)
|
bool sinsp_utils::find_first_env(std::string &out, const vector<std::string> &env, const vector<std::string> &keys)
|
||||||
{
|
{
|
||||||
for (const string key : keys)
|
for (const auto& key : keys)
|
||||||
{
|
{
|
||||||
for(const auto& env_var : env)
|
for(const auto& env_var : env)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue