From cfaa52f522e1368b4c05ca436a35d0bee8c6bc16 Mon Sep 17 00:00:00 2001 From: Kaizhe Huang Date: Wed, 12 Jun 2019 11:04:13 -0700 Subject: [PATCH 01/64] rule update: 1. Extend macro mkdir with syscall mkdirat (#337) 2. add placeholder for whitelist in rule Clear Log Activities (#632) Signed-off-by: kaizhe add docker.io/ to the trusted images list Signed-off-by: kaizhe rule update: add container.id and image in the rule output except those rules with "not container" in condition Signed-off-by: kaizhe Remove empty line Signed-off-by: Kaizhe Huang --- rules/falco_rules.yaml | 133 ++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 63 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 78859d39988..a29e4b689bc 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -59,7 +59,7 @@ - macro: rename condition: evt.type in (rename, renameat) - macro: mkdir - condition: evt.type = mkdir + condition: evt.type in (mkdir, mkdirat) - macro: remove condition: evt.type in (rmdir, unlink, unlinkat) @@ -348,7 +348,7 @@ - rule: Disallowed SSH Connection desc: Detect any new ssh connection to a host other than those in an allowed group of hosts condition: (inbound_outbound) and ssh_port and not allowed_ssh_hosts - output: Disallowed SSH Connection (command=%proc.cmdline connection=%fd.name user=%user.name) + output: Disallowed SSH Connection (command=%proc.cmdline connection=%fd.name user=%user.name container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [network, mitre_remote_service] @@ -379,7 +379,7 @@ ((fd.sip in (allowed_outbound_destination_ipaddrs)) or (fd.snet in (allowed_outbound_destination_networks)) or (fd.sip.name in (allowed_outbound_destination_domains))) - output: Disallowed outbound connection destination (command=%proc.cmdline connection=%fd.name user=%user.name) + output: Disallowed outbound connection destination (command=%proc.cmdline connection=%fd.name user=%user.name container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [network] @@ -402,7 +402,7 @@ ((fd.cip in (allowed_inbound_source_ipaddrs)) or (fd.cnet in (allowed_inbound_source_networks)) or (fd.cip.name in (allowed_inbound_source_domains))) - output: Disallowed inbound connection source (command=%proc.cmdline connection=%fd.name user=%user.name) + output: Disallowed inbound connection source (command=%proc.cmdline connection=%fd.name user=%user.name container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [network] @@ -440,7 +440,7 @@ fd.directory in (shell_config_directories)) and not proc.name in (shell_binaries) output: > - a shell configuration file has been modified (user=%user.name command=%proc.cmdline file=%fd.name) + a shell configuration file has been modified (user=%user.name command=%proc.cmdline file=%fd.name container_id=%container.id image=%container.image.repository) priority: WARNING tag: [file, mitre_persistence] @@ -462,7 +462,7 @@ fd.directory in (shell_config_directories)) and (not proc.name in (shell_binaries)) output: > - a shell configuration file was read by a non-shell program (user=%user.name command=%proc.cmdline file=%fd.name) + a shell configuration file was read by a non-shell program (user=%user.name command=%proc.cmdline file=%fd.name container_id=%container.id image=%container.image.repository) priority: WARNING tag: [file, mitre_discovery] @@ -906,7 +906,7 @@ condition: > open_write and access_repositories and not package_mgmt_procs output: > - Repository files get updated (user=%user.name command=%proc.cmdline file=%fd.name) + Repository files get updated (user=%user.name command=%proc.cmdline file=%fd.name container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [filesystem, mitre_persistence] @@ -921,7 +921,7 @@ and not python_running_ms_oms output: > File below a known binary directory opened for writing (user=%user.name - command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2]) + command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository) priority: ERROR tags: [filesystem, mitre_persistence] @@ -979,7 +979,7 @@ and not user_known_write_monitored_dir_conditions output: > File below a monitored directory opened for writing (user=%user.name - command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2]) + command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository) priority: ERROR tags: [filesystem, mitre_persistence] @@ -998,7 +998,7 @@ (not proc.name in (ssh_binaries))) output: > ssh-related file/directory read by non-ssh program (user=%user.name - command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline) + command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline container_id=%container.id image=%container.image.repository) priority: ERROR tags: [filesystem, mitre_discovery] @@ -1249,7 +1249,7 @@ - rule: Write below etc desc: an attempt to write to any file below /etc condition: write_etc_common - output: "File below /etc opened for writing (user=%user.name command=%proc.cmdline parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4])" + output: "File below /etc opened for writing (user=%user.name command=%proc.cmdline parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)" priority: ERROR tags: [filesystem, mitre_persistence] @@ -1329,7 +1329,7 @@ and not rancher_writing_root and not known_root_conditions and not user_known_write_root_conditions - output: "File below / or /root opened for writing (user=%user.name command=%proc.cmdline parent=%proc.pname file=%fd.name program=%proc.name)" + output: "File below / or /root opened for writing (user=%user.name command=%proc.cmdline parent=%proc.pname file=%fd.name program=%proc.name container_id=%container.id image=%container.image.repository)" priority: ERROR tags: [filesystem, mitre_persistence] @@ -1344,7 +1344,7 @@ condition: sensitive_files and open_read and server_procs and not proc_is_new and proc.name!="sshd" output: > Sensitive file opened for reading by trusted program after startup (user=%user.name - command=%proc.cmdline parent=%proc.pname file=%fd.name parent=%proc.pname gparent=%proc.aname[2]) + command=%proc.cmdline parent=%proc.pname file=%fd.name parent=%proc.pname gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository) priority: WARNING tags: [filesystem, mitre_credential_access] @@ -1394,7 +1394,7 @@ and not runuser_reading_pam output: > Sensitive file opened for reading by non-trusted program (user=%user.name program=%proc.name - command=%proc.cmdline file=%fd.name parent=%proc.pname gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]) + command=%proc.cmdline file=%fd.name parent=%proc.pname gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository) priority: WARNING tags: [filesystem, mitre_credential_access, mitre_discovery] @@ -1407,7 +1407,7 @@ and not ansible_running_python and not python_running_chef and not exe_running_docker_save - output: "Rpm database opened for writing by a non-rpm program (command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline)" + output: "Rpm database opened for writing by a non-rpm program (command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline container_id=%container.id image=%container.image.repository)" priority: ERROR tags: [filesystem, software_mgmt, mitre_persistence] @@ -1442,7 +1442,7 @@ and not postgres_running_wal_e output: > Database-related program spawned process other than itself (user=%user.name - program=%proc.cmdline parent=%proc.pname) + program=%proc.cmdline parent=%proc.pname container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [process, database, mitre_execution] @@ -1451,7 +1451,7 @@ condition: (bin_dir_rename) and modify and not package_mgmt_procs and not exe_running_docker_save output: > File below known binary directory renamed/removed (user=%user.name command=%proc.cmdline - pcmdline=%proc.pcmdline operation=%evt.type file=%fd.name %evt.args) + pcmdline=%proc.pcmdline operation=%evt.type file=%fd.name %evt.args container_id=%container.id image=%container.image.repository) priority: ERROR tags: [filesystem, mitre_persistence] @@ -1460,7 +1460,7 @@ condition: mkdir and bin_dir_mkdir and not package_mgmt_procs output: > Directory below known binary directory created (user=%user.name - command=%proc.cmdline directory=%evt.arg.path) + command=%proc.cmdline directory=%evt.arg.path container_id=%container.id image=%container.image.repository) priority: ERROR tags: [filesystem, mitre_persistence] @@ -1489,7 +1489,7 @@ and not rancher_network_manager output: > Namespace change (setns) by unexpected program (user=%user.name command=%proc.cmdline - parent=%proc.pname %container.info) + parent=%proc.pname %container.info container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [process] @@ -1635,35 +1635,37 @@ output: > Shell spawned by untrusted binary (user=%user.name shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3] - aname[4]=%proc.aname[4] aname[5]=%proc.aname[5] aname[6]=%proc.aname[6] aname[7]=%proc.aname[7]) + aname[4]=%proc.aname[4] aname[5]=%proc.aname[5] aname[6]=%proc.aname[6] aname[7]=%proc.aname[7] container_id=%container.id image=%container.image.repository) priority: DEBUG tags: [shell, mitre_execution] - macro: allowed_openshift_registry_root condition: > (container.image.repository startswith openshift3/ or + container.image.repository startswith registry.redhat.io/openshift3/ or container.image.repository startswith registry.access.redhat.com/openshift3/) # Source: https://docs.openshift.com/enterprise/3.2/install_config/install/disconnected_install.html - macro: openshift_image condition: > (allowed_openshift_registry_root and - (container.image.repository contains logging-deployment or - container.image.repository contains logging-elasticsearch or - container.image.repository contains logging-kibana or - container.image.repository contains logging-fluentd or - container.image.repository contains logging-auth-proxy or - container.image.repository contains metrics-deployer or - container.image.repository contains metrics-hawkular-metrics or - container.image.repository contains metrics-cassandra or - container.image.repository contains metrics-heapster or - container.image.repository contains ose-haproxy-router or - container.image.repository contains ose-deployer or - container.image.repository contains ose-sti-builder or - container.image.repository contains ose-docker-builder or - container.image.repository contains ose-pod or - container.image.repository contains ose-docker-registry or - container.image.repository contains image-inspector)) + (container.image.repository endswith /logging-deployment or + container.image.repository endswith /logging-elasticsearch or + container.image.repository endswith /logging-kibana or + container.image.repository endswith /logging-fluentd or + container.image.repository endswith /logging-auth-proxy or + container.image.repository endswith /metrics-deployer or + container.image.repository endswith /metrics-hawkular-metrics or + container.image.repository endswith /metrics-cassandra or + container.image.repository endswith /metrics-heapster or + container.image.repository endswith /ose-haproxy-router or + container.image.repository endswith /ose-deployer or + container.image.repository endswith /ose-sti-builder or + container.image.repository endswith /ose-docker-builder or + container.image.repository endswith /ose-pod or + container.image.repository endswith /ose-node or + container.image.repository endswith /ose-docker-registry or + container.image.repository endswith /image-inspector)) # These images are allowed both to run with --privileged and to mount # sensitive paths from the host filesystem. @@ -1687,10 +1689,10 @@ # In this file, it just takes one of the images in trusted_containers # and repeats it. - macro: user_trusted_containers - condition: (container.image.repository=sysdig/agent) + condition: (container.image.repository = docker.io/sysdig/agent) - list: sematext_images - items: [sematext/sematext-agent-docker, sematext/agent, sematext/logagent, + items: [docker.io/sematext/sematext-agent-docker, docker.io/sematext/agent, docker.io/sematext/logagent, registry.access.redhat.com/sematext/sematext-agent-docker, registry.access.redhat.com/sematext/agent, registry.access.redhat.com/sematext/logagent] @@ -1698,10 +1700,10 @@ # These container images are allowed to run with --privileged - list: falco_privileged_images items: [ - sysdig/agent, sysdig/falco, sysdig/sysdig, - gcr.io/google_containers/kube-proxy, calico/node, - rook/toolbox, cloudnativelabs/kube-router, mesosphere/mesos-slave, - docker/ucp-agent, sematext_images + docker.io/sysdig/agent, docker.io/sysdig/falco, docker.io/sysdig/sysdig, + gcr.io/google_containers/kube-proxy, docker.io/calico/node, + docker.io/rook/toolbox, docker.io/cloudnativelabs/kube-router, docker.io/mesosphere/mesos-slave, + docker.io/docker/ucp-agent, sematext_images ] - macro: falco_privileged_containers @@ -1719,8 +1721,7 @@ # In this file, it just takes one of the images in falco_privileged_images # and repeats it. - macro: user_privileged_containers - condition: (container.image.repository=sysdig/agent) - + condition: (container.image.repository = docker.io/sysdig/agent) - list: rancher_images items: [ @@ -1732,11 +1733,11 @@ # host filesystem. - list: falco_sensitive_mount_images items: [ - sysdig/agent, sysdig/falco, sysdig/sysdig, + docker.io/sysdig/agent, docker.io/sysdig/falco, docker.io/sysdig/sysdig, gcr.io/google_containers/hyperkube, - gcr.io/google_containers/kube-proxy, calico/node, - rook/toolbox, cloudnativelabs/kube-router, consul, - datadog/docker-dd-agent, datadog/agent, docker/ucp-agent, gliderlabs/logspout + gcr.io/google_containers/kube-proxy, docker.io/calico/node, + docker.io/rook/toolbox, docker.io/cloudnativelabs/kube-router, docker.io/consul, + docker.io/datadog/docker-dd-agent, docker.io/datadog/agent, docker.io/docker/ucp-agent, docker.io/gliderlabs/logspout ] - macro: falco_sensitive_mount_containers @@ -1756,7 +1757,7 @@ # In this file, it just takes one of the images in falco_sensitive_mount_images # and repeats it. - macro: user_sensitive_mount_containers - condition: (container.image.repository=sysdig/agent) + condition: (container.image.repository = docker.io/sysdig/agent) - rule: Launch Privileged Container desc: Detect the initial process started in a privileged container. Exceptions are made for known trusted images. @@ -1837,7 +1838,7 @@ - rule: System user interactive desc: an attempt to run interactive commands by a system (i.e. non-login) user condition: spawned_process and system_users and interactive - output: "System user ran an interactive command (user=%user.name command=%proc.cmdline)" + output: "System user ran an interactive command (user=%user.name command=%proc.cmdline container_id=%container.id image=%container.image.repository)" priority: INFO tags: [users, mitre_remote_access_tools] @@ -1849,7 +1850,7 @@ and container_entrypoint output: > A shell was spawned in a container with an attached terminal (user=%user.name %container.info - shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline terminal=%proc.tty) + shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline terminal=%proc.tty container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [container, shell, mitre_execution] @@ -1923,7 +1924,7 @@ and not login_doing_dns_lookup output: > Known system binary sent/received network traffic - (user=%user.name command=%proc.cmdline connection=%fd.name) + (user=%user.name command=%proc.cmdline connection=%fd.name container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [network, mitre_exfiltration] @@ -1949,7 +1950,7 @@ proc.env icontains HTTP_PROXY output: > Program run with disallowed HTTP_PROXY environment variable - (user=%user.name command=%proc.cmdline env=%proc.env parent=%proc.pname) + (user=%user.name command=%proc.cmdline env=%proc.env parent=%proc.pname container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [host, users] @@ -1972,7 +1973,7 @@ and interpreted_procs) output: > Interpreted program received/listened for network traffic - (user=%user.name command=%proc.cmdline connection=%fd.name) + (user=%user.name command=%proc.cmdline connection=%fd.name container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [network, mitre_exfiltration] @@ -1983,7 +1984,7 @@ and interpreted_procs) output: > Interpreted program performed outgoing network connection - (user=%user.name command=%proc.cmdline connection=%fd.name) + (user=%user.name command=%proc.cmdline connection=%fd.name container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [network, mitre_exfiltration] @@ -2024,7 +2025,7 @@ condition: (inbound_outbound) and do_unexpected_udp_check and fd.l4proto=udp and not expected_udp_traffic output: > Unexpected UDP Traffic Seen - (user=%user.name command=%proc.cmdline connection=%fd.name proto=%fd.l4proto evt=%evt.type %evt.args) + (user=%user.name command=%proc.cmdline connection=%fd.name proto=%fd.l4proto evt=%evt.type %evt.args container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [network, mitre_exfiltration] @@ -2084,7 +2085,7 @@ and not user_known_non_sudo_setuid_conditions output: > Unexpected setuid call by non-sudo, non-root program (user=%user.name cur_uid=%user.uid parent=%proc.pname - command=%proc.cmdline uid=%evt.arg.uid) + command=%proc.cmdline uid=%evt.arg.uid container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [users, mitre_privilege_escalation] @@ -2128,7 +2129,7 @@ and not proc.name in (dev_creation_binaries) and not fd.name in (allowed_dev_files) and not fd.name startswith /dev/tty - output: "File created below /dev by untrusted program (user=%user.name command=%proc.cmdline file=%fd.name)" + output: "File created below /dev by untrusted program (user=%user.name command=%proc.cmdline file=%fd.name container_id=%container.id image=%container.image.repository)" priority: ERROR tags: [filesystem, mitre_persistence] @@ -2189,7 +2190,7 @@ - rule: Unexpected K8s NodePort Connection desc: Detect attempts to use K8s NodePorts from a container condition: (inbound_outbound) and fd.sport >= 30000 and fd.sport <= 32767 and container and not nodeport_containers - output: Unexpected K8s NodePort Connection (command=%proc.cmdline connection=%fd.name) + output: Unexpected K8s NodePort Connection (command=%proc.cmdline connection=%fd.name container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [network, k8s, container, mitre_port_knocking] @@ -2299,12 +2300,19 @@ - macro: access_log_files condition: (fd.directory in (log_directories) or fd.filename in (log_files)) +# a placeholder for whitelist log files that could be cleared. Recommend the macro as (fd.name startswith "/var/log/app1*") +- macro: allowed_clear_log_files + condition: (never_true) + - rule: Clear Log Activities desc: Detect clearing of critical log files condition: > - open_write and access_log_files and evt.arg.flags contains "O_TRUNC" + open_write and + access_log_files and + evt.arg.flags contains "O_TRUNC" and + not allowed_clear_log_files output: > - Log files were tampered (user=%user.name command=%proc.cmdline file=%fd.name) + Log files were tampered (user=%user.name command=%proc.cmdline file=%fd.name container_id=%container.id image=%container.image.repository) priority: WARNING tags: [file, mitre_defense_evasion] @@ -2319,7 +2327,7 @@ desc: Detect process running to clear bulk data from disk condition: spawned_process and clear_data_procs output: > - Bulk data has been removed from disk (user=%user.name command=%proc.cmdline file=%fd.name) + Bulk data has been removed from disk (user=%user.name command=%proc.cmdline file=%fd.name container_id=%container.id image=%container.image.repository) priority: WARNING tags: [process, mitre_persistence] @@ -2387,7 +2395,6 @@ priority: NOTICE tags: [network, process, mitre_lateral_movement, mitre_exfiltration] - - rule: Create Symlink Over Sensitive Files desc: Detect symlink created over sensitive files condition: > From 2198147c354d4863ed03110125bab93c7b3844c1 Mon Sep 17 00:00:00 2001 From: Naoki Oketani Date: Sat, 15 Jun 2019 00:04:32 +0900 Subject: [PATCH 02/64] docs: remove extra words Signed-off-by: Naoki Oketani --- integrations/k8s-using-daemonset/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/k8s-using-daemonset/README.md b/integrations/k8s-using-daemonset/README.md index c971278b62c..f0e1e138be0 100644 --- a/integrations/k8s-using-daemonset/README.md +++ b/integrations/k8s-using-daemonset/README.md @@ -29,7 +29,7 @@ service/falco-service created k8s-using-daemonset$ ``` -The Daemon Set also relies on a Kubernetes ConfigMap to store the Falco configuration and make the configuration available to the Falco Pods. This allows you to manage custom configuration without rebuilding and redeploying the underlying Pods. In order to create the ConfigMap you'll need to first need to copy the required configuration from their location in this GitHub repo to the `k8s-with-rbac/falco-config/` directory (please note that you will need to create the /falco-config directory). Any modification of the configuration should be performed on these copies rather than the original files. +The Daemon Set also relies on a Kubernetes ConfigMap to store the Falco configuration and make the configuration available to the Falco Pods. This allows you to manage custom configuration without rebuilding and redeploying the underlying Pods. In order to create the ConfigMap you'll first need to copy the required configuration from their location in this GitHub repo to the `k8s-with-rbac/falco-config/` directory (please note that you will need to create the /falco-config directory). Any modification of the configuration should be performed on these copies rather than the original files. ``` k8s-using-daemonset$ mkdir -p k8s-with-rbac/falco-config From 5beddf5320324532832ff290b8a26b629ff6c6ad Mon Sep 17 00:00:00 2001 From: kaizhe Date: Mon, 17 Jun 2019 12:12:09 -0700 Subject: [PATCH 03/64] rule update: add back trusted_containers list for backport compatibility Signed-off-by: kaizhe --- rules/falco_rules.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index a29e4b689bc..a6823fa25be 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1677,6 +1677,10 @@ - list: trusted_images items: [] +# Backport compatibility +- list: trusted_containers + items: [] + # Add conditions to this macro (probably in a separate file, # overwriting this macro) to specify additional containers that are # trusted and therefore allowed to run privileged *and* with sensitive From 18960b01b0cf10fe42ab734d155c18b9ab0980d4 Mon Sep 17 00:00:00 2001 From: kaizhe Date: Mon, 17 Jun 2019 12:30:26 -0700 Subject: [PATCH 04/64] more comment Signed-off-by: kaizhe --- rules/falco_rules.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index a6823fa25be..6af25792d87 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1677,7 +1677,10 @@ - list: trusted_images items: [] -# Backport compatibility +# NOTE: This list is only provided for backwards compatibility with +# older local falco rules files that may have been appending to +# trusted_containers. To make customizations, it's better to add containers to +# user_trusted_containers, user_priivleged_containers or user_sensitive_mount_containers. - list: trusted_containers items: [] From 88ed98ce81cfedaff079e6b9403e9068737a8f97 Mon Sep 17 00:00:00 2001 From: kaizhe Date: Mon, 17 Jun 2019 12:35:28 -0700 Subject: [PATCH 05/64] update to macro Signed-off-by: kaizhe --- rules/falco_rules.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 6af25792d87..39d7ff9e12c 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1677,12 +1677,12 @@ - list: trusted_images items: [] -# NOTE: This list is only provided for backwards compatibility with +# NOTE: This macro is only provided for backwards compatibility with # older local falco rules files that may have been appending to -# trusted_containers. To make customizations, it's better to add containers to -# user_trusted_containers, user_priivleged_containers or user_sensitive_mount_containers. -- list: trusted_containers - items: [] +# trusted_images. To make customizations, it's better to add containers to +# user_trusted_containers, user_privileged_containers or user_sensitive_mount_containers. +- macro: trusted_containers + condition: (container.image.repository in (trusted_images)) # Add conditions to this macro (probably in a separate file, # overwriting this macro) to specify additional containers that are From 3f200c52b0dd5be159ae9bd607ce66feb7745670 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Wed, 19 Jun 2019 15:47:56 +0000 Subject: [PATCH 06/64] new: SYSDIG_DIR can be passed as cmake option Signed-off-by: Lorenzo Fontana Co-Authored-By: Leonardo Di Donato Signed-off-by: Lorenzo Fontana --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc22d703957..af7048f9a0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,8 @@ endif() set(CMD_MAKE make) -set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig") +option(SYSDIG_DIR “Set the path to the Sysdig source” “${PROJECT_SOURCE_DIR}/../sysdig”) + # make luaJIT work on OS X if(APPLE) set(CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000") From 147ec6073c98276149ed71bfb0a0d8c9724f397c Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Thu, 20 Jun 2019 06:36:28 +0000 Subject: [PATCH 07/64] fix: SYSDIG_DIR not as an option but as a set Signed-off-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index af7048f9a0e..41e9f5ad1c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,10 @@ endif() set(CMD_MAKE make) -option(SYSDIG_DIR “Set the path to the Sysdig source” “${PROJECT_SOURCE_DIR}/../sysdig”) +if(NOT SYSDIG_DIR) + set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig") +endif() + # make luaJIT work on OS X if(APPLE) From 1d7c6c335610bb0697e20adc1880fcad5665d9c1 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Thu, 20 Jun 2019 12:04:59 +0000 Subject: [PATCH 08/64] update: fields checksum Signed-off-by: Lorenzo Fontana Co-Authored-By: Leonardo Di Donato --- userspace/engine/falco_engine_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/userspace/engine/falco_engine_version.h b/userspace/engine/falco_engine_version.h index 7dc9b169307..d9b14b15f13 100644 --- a/userspace/engine/falco_engine_version.h +++ b/userspace/engine/falco_engine_version.h @@ -24,4 +24,4 @@ limitations under the License. // This is the result of running "falco --list -N | sha256sum" and // represents the fields supported by this version of falco. It's used // at build time to detect a changed set of fields. -#define FALCO_FIELDS_CHECKSUM "fb82780f268b91fb888876e6ac1142b5acca08e05b3a82c4b1b524ca88fa83d9" +#define FALCO_FIELDS_CHECKSUM "9b5557ec8f16f5606a1544573b152d211d5212f653ee039146836a17266ff449" From d158d9980074ea478afd91400ccb2c708d9b8bb5 Mon Sep 17 00:00:00 2001 From: kaizhe Date: Wed, 19 Jun 2019 14:43:07 -0700 Subject: [PATCH 09/64] rule update: add exception for rule change thread namespace Signed-off-by: kaizhe --- rules/falco_rules.yaml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 39d7ff9e12c..d05d7ed272b 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -159,7 +159,7 @@ items: [docker, dockerd, exe, docker-compose, docker-entrypoi, docker-runc-cur, docker-current, dockerd-current] - list: k8s_binaries - items: [hyperkube, skydns, kube2sky, exechealthz, weave-net, loopback, bridge, openshift-sdn] + items: [hyperkube, skydns, kube2sky, exechealthz, weave-net, loopback, bridge, openshift-sdn, openshift] - list: lxd_binaries items: [lxd, lxcfs] @@ -243,7 +243,7 @@ # A canonical set of processes that run other programs with different # privileges or as a different user. - list: userexec_binaries - items: [sudo, su, suexec, critical-stack] + items: [sudo, su, suexec, critical-stack, dzdo] - list: known_setuid_binaries items: [ @@ -1470,6 +1470,12 @@ - list: user_known_change_thread_namespace_binaries items: [] +- list: network_plugin_binaries + items: [aws-cni, azure-vnet] + +- macro: calico_node + condition: (container.image.repository endswith calico/node and proc.name=calico-node) + - rule: Change thread namespace desc: > an attempt to change a program/thread\'s namespace (commonly done @@ -1477,7 +1483,7 @@ condition: > evt.type = setns and not proc.name in (docker_binaries, k8s_binaries, lxd_binaries, sysdigcloud_binaries, - sysdig, nsenter, calico, oci-umount) + sysdig, nsenter, calico, oci-umount, network_plugin_binaries) and not proc.name in (user_known_change_thread_namespace_binaries) and not proc.name startswith "runc" and not proc.cmdline startswith "containerd" @@ -1487,6 +1493,7 @@ and not kubelet_running_loopback and not rancher_agent and not rancher_network_manager + and not calico_node output: > Namespace change (setns) by unexpected program (user=%user.name command=%proc.cmdline parent=%proc.pname %container.info container_id=%container.id image=%container.image.repository) From 03310800edbdf12dfaf0b7b8b274a180c781e2ed Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Mon, 17 Jun 2019 14:10:19 +0000 Subject: [PATCH 10/64] update: ignore lyaml Co-authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b28c617fcab..f2178ccce77 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ test/results*.json.* userspace/falco/lua/re.lua userspace/falco/lua/lpeg.so +userspace/engine/lua/lyaml +userspace/engine/lua/lyaml.lua docker/event-generator/event_generator docker/event-generator/mysqld From e1655be243795c3d95fb458ff60e63995e35812f Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Mon, 17 Jun 2019 14:11:56 +0000 Subject: [PATCH 11/64] build: refine cmake rule for grpc and curl Co-authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41e9f5ad1c6..06db9f49bd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -308,7 +308,7 @@ else() URL "http://s3.amazonaws.com/download.draios.com/dependencies/curl-7.61.0.tar.bz2" URL_MD5 "31d0a9f48dc796a7db351898a1e5058a" # END CHANGE for CVE-2017-8816, CVE-2017-8817, CVE-2017-8818, CVE-2018-1000007 - CONFIGURE_COMMAND ./configure ${CURL_SSL_OPTION} --disable-shared --enable-optimize --disable-curldebug --disable-rt --enable-http --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-sspi --disable-ntlm-wb --disable-tls-srp --without-winssl --without-darwinssl --without-polarssl --without-cyassl --without-nss --without-axtls --without-ca-path --without-ca-bundle --without-libmetalink --without-librtmp --without-winidn --without-libidn --without-nghttp2 --without-libssh2 --disable-threaded-resolver + CONFIGURE_COMMAND ./configure ${CURL_SSL_OPTION} --disable-shared --enable-optimize --disable-curldebug --disable-rt --enable-http --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-sspi --disable-ntlm-wb --disable-tls-srp --without-winssl --without-darwinssl --without-polarssl --without-cyassl --without-nss --without-axtls --without-ca-path --without-ca-bundle --without-libmetalink --without-librtmp --without-winidn --without-libidn2 --without-libpsl --without-nghttp2 --without-libssh2 --disable-threaded-resolver BUILD_COMMAND ${CMD_MAKE} BUILD_IN_SOURCE 1 INSTALL_COMMAND "") @@ -590,7 +590,7 @@ else() URL_MD5 "2fc42c182a0ed1b48ad77397f76bb3bc" CONFIGURE_COMMAND "" # TODO what if using system openssl, protobuf or cares? - BUILD_COMMAND HAS_SYSTEM_ZLIB=false LDFLAGS=-static PATH=${PROTOC_DIR}:$ENV{PATH} PKG_CONFIG_PATH=${OPENSSL_BUNDLE_DIR}:${PROTOBUF_SRC}:${CARES_SRC} make grpc_cpp_plugin static_cxx static_c + BUILD_COMMAND sh -c "CFLAGS=-Wno-implicit-fallthrough CXXFLAGS=\"-Wno-ignored-qualifiers -Wno-stringop-truncation\" HAS_SYSTEM_ZLIB=false LDFLAGS=-static PATH=${PROTOC_DIR}:$ENV{PATH} PKG_CONFIG_PATH=${OPENSSL_BUNDLE_DIR}:${PROTOBUF_SRC}:${CARES_SRC} make grpc_cpp_plugin static_cxx static_c" BUILD_IN_SOURCE 1 BUILD_BYPRODUCTS ${GRPC_LIB} ${GRPCPP_LIB} # TODO s390x support From 29251f20787a2ebbff3d651ddf3986bceeca8454 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Tue, 18 Jun 2019 12:46:33 +0000 Subject: [PATCH 12/64] build: disable brotli for curl Signed-off-by: Lorenzo Fontana Co-Authored-By: Leonardo Di Donato --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06db9f49bd1..c4b13f42e1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -308,7 +308,7 @@ else() URL "http://s3.amazonaws.com/download.draios.com/dependencies/curl-7.61.0.tar.bz2" URL_MD5 "31d0a9f48dc796a7db351898a1e5058a" # END CHANGE for CVE-2017-8816, CVE-2017-8817, CVE-2017-8818, CVE-2018-1000007 - CONFIGURE_COMMAND ./configure ${CURL_SSL_OPTION} --disable-shared --enable-optimize --disable-curldebug --disable-rt --enable-http --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-sspi --disable-ntlm-wb --disable-tls-srp --without-winssl --without-darwinssl --without-polarssl --without-cyassl --without-nss --without-axtls --without-ca-path --without-ca-bundle --without-libmetalink --without-librtmp --without-winidn --without-libidn2 --without-libpsl --without-nghttp2 --without-libssh2 --disable-threaded-resolver + CONFIGURE_COMMAND ./configure ${CURL_SSL_OPTION} --disable-shared --enable-optimize --disable-curldebug --disable-rt --enable-http --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-sspi --disable-ntlm-wb --disable-tls-srp --without-winssl --without-darwinssl --without-polarssl --without-cyassl --without-nss --without-axtls --without-ca-path --without-ca-bundle --without-libmetalink --without-librtmp --without-winidn --without-libidn2 --without-libpsl --without-nghttp2 --without-libssh2 --disable-threaded-resolver --without-brotli BUILD_COMMAND ${CMD_MAKE} BUILD_IN_SOURCE 1 INSTALL_COMMAND "") From 02d5c167cea60fe696c53381cf2fba34f16e619c Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Wed, 19 Jun 2019 15:44:46 +0000 Subject: [PATCH 13/64] build: lyaml paths from vars Signed-off-by: Lorenzo Fontana Co-Authored-By: Leonardo Di Donato --- CMakeLists.txt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c4b13f42e1a..088c0c089df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,7 +79,6 @@ if(NOT SYSDIG_DIR) set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig") endif() - # make luaJIT work on OS X if(APPLE) set(CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000") @@ -382,7 +381,6 @@ endif() # Libyaml # option(USE_BUNDLED_LIBYAML "Enable building of the bundled libyaml" ${USE_BUNDLED_DEPS}) - if(NOT USE_BUNDLED_LIBYAML) # Note: to distinguish libyaml.a and yaml.a we specify a full # file name here, so you'll have to arrange for static @@ -402,6 +400,7 @@ else() endif() set(LIBYAML_SRC "${PROJECT_BINARY_DIR}/libyaml-prefix/src/libyaml/src") + set(LIBYAML_INCLUDE "${PROJECT_BINARY_DIR}/libyaml-prefix/src/libyaml/include") set(LIBYAML_LIB "${LIBYAML_SRC}/.libs/libyaml.a") message(STATUS "Using bundled libyaml in '${LIBYAML_SRC}'") ExternalProject_Add(libyaml @@ -417,7 +416,6 @@ endif() # lyaml # option(USE_BUNDLED_LYAML "Enable building of the bundled lyaml" ${USE_BUNDLED_DEPS}) - if(NOT USE_BUNDLED_LYAML) # Note: to distinguish libyaml.a and yaml.a we specify a full # file name here, so you'll have to arrange for static @@ -439,14 +437,15 @@ else() if(USE_BUNDLED_LIBYAML) list(APPEND LYAML_DEPENDENCIES "libyaml") endif() + ExternalProject_Add(lyaml DEPENDS ${LYAML_DEPENDENCIES} URL "http://s3.amazonaws.com/download.draios.com/dependencies/lyaml-release-v6.0.tar.gz" - URL_MD5 "dc3494689a0dce7cf44e7a99c72b1f30" - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - CONFIGURE_COMMAND ./configure --enable-static LIBS=-L../../../libyaml-prefix/src/libyaml/src/.libs CFLAGS=-I../../../libyaml-prefix/src/libyaml/include CPPFLAGS=-I../../../libyaml-prefix/src/libyaml/include LUA_INCLUDE=-I../../../luajit-prefix/src/luajit/src LUA=../../../luajit-prefix/src/luajit/src/luajit - INSTALL_COMMAND sh -c "cp -R ${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/lib/* ${PROJECT_SOURCE_DIR}/userspace/engine/lua") + URL_MD5 "dc3494689a0dce7cf44e7a99c72b1f30" + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND ./configure --enable-static LIBS=-L${LIBYAML_SRC}/.libs CFLAGS=-I${LIBYAML_INCLUDE} CPPFLAGS=-I${LIBYAML_INCLUDE} LUA_INCLUDE=-I${LUAJIT_INCLUDE} LUA=${LUAJIT_SRC}/luajit + INSTALL_COMMAND sh -c "cp -R ${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/lib/* ${PROJECT_SOURCE_DIR}/userspace/engine/lua") endif() option(USE_BUNDLED_TBB "Enable building of the bundled tbb" ${USE_BUNDLED_DEPS}) From 68340944b1c96b18cce1edfc332b63e3611bb2b1 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Fri, 21 Jun 2019 14:02:55 +0000 Subject: [PATCH 14/64] new: use sysdig modules to build libscap Signed-off-by: Lorenzo Fontana Co-Authored-By: Leonardo Di Donato --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 088c0c089df..cabe1118ec4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -606,8 +606,13 @@ add_subdirectory(test) add_subdirectory(rules) add_subdirectory(docker) +# Add path for custom CMake modules used to build dependencies from Sysdig (libscap, libsinsp) +list(APPEND CMAKE_MODULE_PATH + "${SYSDIG_DIR}/cmake/modules") + if(CMAKE_SYSTEM_NAME MATCHES "Linux") add_subdirectory("${SYSDIG_DIR}/driver" "${PROJECT_BINARY_DIR}/driver") + include(FindMakedev) endif() add_subdirectory("${SYSDIG_DIR}/userspace/libscap" "${PROJECT_BINARY_DIR}/userspace/libscap") add_subdirectory("${SYSDIG_DIR}/userspace/libsinsp" "${PROJECT_BINARY_DIR}/userspace/libsinsp") From acae9dd9f11e6627eb56884aa2d51e0bb4c7a4b5 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Tue, 25 Jun 2019 10:32:24 +0000 Subject: [PATCH 15/64] new: cmake modules for catch2 Signed-off-by: Lorenzo Fontana Co-authored-by: Leonardo Di Donato --- cmake/modules/Catch.cmake | 175 ++++++++++++++++++++++++++++++ cmake/modules/CatchAddTests.cmake | 78 +++++++++++++ cmake/modules/FindCatch.cmake | 17 +++ 3 files changed, 270 insertions(+) create mode 100644 cmake/modules/Catch.cmake create mode 100644 cmake/modules/CatchAddTests.cmake create mode 100644 cmake/modules/FindCatch.cmake diff --git a/cmake/modules/Catch.cmake b/cmake/modules/Catch.cmake new file mode 100644 index 00000000000..486e323318c --- /dev/null +++ b/cmake/modules/Catch.cmake @@ -0,0 +1,175 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +Catch +----- + +This module defines a function to help use the Catch test framework. + +The :command:`catch_discover_tests` discovers tests by asking the compiled test +executable to enumerate its tests. This does not require CMake to be re-run +when tests change. However, it may not work in a cross-compiling environment, +and setting test properties is less convenient. + +This command is intended to replace use of :command:`add_test` to register +tests, and will create a separate CTest test for each Catch test case. Note +that this is in some cases less efficient, as common set-up and tear-down logic +cannot be shared by multiple test cases executing in the same instance. +However, it provides more fine-grained pass/fail information to CTest, which is +usually considered as more beneficial. By default, the CTest test name is the +same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``. + +.. command:: catch_discover_tests + + Automatically add tests with CTest by querying the compiled test executable + for available tests:: + + catch_discover_tests(target + [TEST_SPEC arg1...] + [EXTRA_ARGS arg1...] + [WORKING_DIRECTORY dir] + [TEST_PREFIX prefix] + [TEST_SUFFIX suffix] + [PROPERTIES name1 value1...] + [TEST_LIST var] + ) + + ``catch_discover_tests`` sets up a post-build command on the test executable + that generates the list of tests by parsing the output from running the test + with the ``--list-test-names-only`` argument. This ensures that the full + list of tests is obtained. Since test discovery occurs at build time, it is + not necessary to re-run CMake when the list of tests changes. + However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set + in order to function in a cross-compiling environment. + + Additionally, setting properties on tests is somewhat less convenient, since + the tests are not available at CMake time. Additional test properties may be + assigned to the set of tests as a whole using the ``PROPERTIES`` option. If + more fine-grained test control is needed, custom content may be provided + through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES` + directory property. The set of discovered tests is made accessible to such a + script via the ``_TESTS`` variable. + + The options are: + + ``target`` + Specifies the Catch executable, which must be a known CMake executable + target. CMake will substitute the location of the built executable when + running the test. + + ``TEST_SPEC arg1...`` + Specifies test cases, wildcarded test cases, tags and tag expressions to + pass to the Catch executable with the ``--list-test-names-only`` argument. + + ``EXTRA_ARGS arg1...`` + Any extra arguments to pass on the command line to each test case. + + ``WORKING_DIRECTORY dir`` + Specifies the directory in which to run the discovered test cases. If this + option is not provided, the current binary directory is used. + + ``TEST_PREFIX prefix`` + Specifies a ``prefix`` to be prepended to the name of each discovered test + case. This can be useful when the same test executable is being used in + multiple calls to ``catch_discover_tests()`` but with different + ``TEST_SPEC`` or ``EXTRA_ARGS``. + + ``TEST_SUFFIX suffix`` + Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of + every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may + be specified. + + ``PROPERTIES name1 value1...`` + Specifies additional properties to be set on all tests discovered by this + invocation of ``catch_discover_tests``. + + ``TEST_LIST var`` + Make the list of tests available in the variable ``var``, rather than the + default ``_TESTS``. This can be useful when the same test + executable is being used in multiple calls to ``catch_discover_tests()``. + Note that this variable is only available in CTest. + +#]=======================================================================] + +#------------------------------------------------------------------------------ +function(catch_discover_tests TARGET) + cmake_parse_arguments( + "" + "" + "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST" + "TEST_SPEC;EXTRA_ARGS;PROPERTIES" + ${ARGN} + ) + + if(NOT _WORKING_DIRECTORY) + set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + endif() + if(NOT _TEST_LIST) + set(_TEST_LIST ${TARGET}_TESTS) + endif() + + ## Generate a unique name based on the extra arguments + string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS}") + string(SUBSTRING ${args_hash} 0 7 args_hash) + + # Define rule to generate test list for aforementioned test executable + set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake") + set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake") + get_property(crosscompiling_emulator + TARGET ${TARGET} + PROPERTY CROSSCOMPILING_EMULATOR + ) + add_custom_command( + TARGET ${TARGET} POST_BUILD + BYPRODUCTS "${ctest_tests_file}" + COMMAND "${CMAKE_COMMAND}" + -D "TEST_TARGET=${TARGET}" + -D "TEST_EXECUTABLE=$" + -D "TEST_EXECUTOR=${crosscompiling_emulator}" + -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" + -D "TEST_SPEC=${_TEST_SPEC}" + -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" + -D "TEST_PROPERTIES=${_PROPERTIES}" + -D "TEST_PREFIX=${_TEST_PREFIX}" + -D "TEST_SUFFIX=${_TEST_SUFFIX}" + -D "TEST_LIST=${_TEST_LIST}" + -D "CTEST_FILE=${ctest_tests_file}" + -P "${_CATCH_DISCOVER_TESTS_SCRIPT}" + VERBATIM + ) + + file(WRITE "${ctest_include_file}" + "if(EXISTS \"${ctest_tests_file}\")\n" + " include(\"${ctest_tests_file}\")\n" + "else()\n" + " add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n" + "endif()\n" + ) + + if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0") + # Add discovered tests to directory TEST_INCLUDE_FILES + set_property(DIRECTORY + APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}" + ) + else() + # Add discovered tests as directory TEST_INCLUDE_FILE if possible + get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET) + if (NOT ${test_include_file_set}) + set_property(DIRECTORY + PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}" + ) + else() + message(FATAL_ERROR + "Cannot set more than one TEST_INCLUDE_FILE" + ) + endif() + endif() + +endfunction() + +############################################################################### + +set(_CATCH_DISCOVER_TESTS_SCRIPT + ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake +) diff --git a/cmake/modules/CatchAddTests.cmake b/cmake/modules/CatchAddTests.cmake new file mode 100644 index 00000000000..2220ce3ac6b --- /dev/null +++ b/cmake/modules/CatchAddTests.cmake @@ -0,0 +1,78 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +set(prefix "${TEST_PREFIX}") +set(suffix "${TEST_SUFFIX}") +set(spec ${TEST_SPEC}) +set(extra_args ${TEST_EXTRA_ARGS}) +set(properties ${TEST_PROPERTIES}) +set(script) +set(suite) +set(tests) + +function(add_command NAME) + set(_args "") + foreach(_arg ${ARGN}) + if(_arg MATCHES "[^-./:a-zA-Z0-9_]") + set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument + else() + set(_args "${_args} ${_arg}") + endif() + endforeach() + set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE) +endfunction() + +# Run test executable to get list of available tests +if(NOT EXISTS "${TEST_EXECUTABLE}") + message(FATAL_ERROR + "Specified test executable '${TEST_EXECUTABLE}' does not exist" + ) +endif() +execute_process( + COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only + OUTPUT_VARIABLE output + RESULT_VARIABLE result +) +# Catch --list-test-names-only reports the number of tests, so 0 is... surprising +if(${result} EQUAL 0) + message(WARNING + "Test executable '${TEST_EXECUTABLE}' contains no tests!\n" + ) +elseif(${result} LESS 0) + message(FATAL_ERROR + "Error running test executable '${TEST_EXECUTABLE}':\n" + " Result: ${result}\n" + " Output: ${output}\n" + ) +endif() + +string(REPLACE "\n" ";" output "${output}") + +# Parse output +foreach(line ${output}) + set(test ${line}) + # use escape commas to handle properly test cases with commans inside the name + string(REPLACE "," "\\," test_name ${test}) + # ...and add to script + add_command(add_test + "${prefix}${test}${suffix}" + ${TEST_EXECUTOR} + "${TEST_EXECUTABLE}" + "${test_name}" + ${extra_args} + ) + add_command(set_tests_properties + "${prefix}${test}${suffix}" + PROPERTIES + WORKING_DIRECTORY "${TEST_WORKING_DIR}" + ${properties} + ) + list(APPEND tests "${prefix}${test}${suffix}") +endforeach() + +# Create a list of all discovered tests, which users may use to e.g. set +# properties on the tests +add_command(set ${TEST_LIST} ${tests}) + +# Write CTest script +file(WRITE "${CTEST_FILE}" "${script}") diff --git a/cmake/modules/FindCatch.cmake b/cmake/modules/FindCatch.cmake new file mode 100644 index 00000000000..fa920767da0 --- /dev/null +++ b/cmake/modules/FindCatch.cmake @@ -0,0 +1,17 @@ + +include(ExternalProject) +set(CATCH_EXTERNAL_URL + URL https://github.com/catchorg/Catch2/archive/v2.9.1.tar.gz) + #URL_HASH MD5=2080f4696579351d9323b3b5a8c3c71b) +ExternalProject_Add(catch2 + PREFIX ${CMAKE_BINARY_DIR}/catch2-prefix + ${CATCH_EXTERNAL_URL} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/catch2-prefix/src/catch2/single_include/catch2/catch.hpp + ${CMAKE_BINARY_DIR}/catch2-prefix/include/catch.hpp +) +add_library(catch INTERFACE) +add_dependencies(catch catch2) +target_include_directories(catch INTERFACE ${CMAKE_BINARY_DIR}/catch2-prefix/include) + From 18b66330ec209872c9204f1563ff244c751dbe14 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Tue, 25 Jun 2019 10:33:38 +0000 Subject: [PATCH 16/64] new: tests cmake setup Signed-off-by: Lorenzo Fontana Co-authored-by: Leonardo Di Donato --- tests/CMakeLists.txt | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/CMakeLists.txt diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 00000000000..64ff0aa88df --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,24 @@ +set(FALCO_TESTS_SOURCES + TestBase.cpp) + +set(FALCO_TESTED_LIBRARIES + falco_engine) + +option(FALCO_BUILD_TESTS "Determines whether to build tests." OFF) + +if(FALCO_BUILD_TESTS) + enable_testing() + if(NOT TARGET catch) + include(FindCatch) + endif() + + add_executable(falco_test ${FALCO_TESTS_SOURCES}) + + target_link_libraries(falco_test PUBLIC ${FALCO_TESTED_LIBRARIES} catch) + + include(CTest) + include(Catch) + catch_discover_tests(falco_test) + + add_custom_target(tests COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS falco_test) +endif() From 026f6866e352f9fb59ff7a2e43ebe942b5b37f6a Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Tue, 25 Jun 2019 10:34:34 +0000 Subject: [PATCH 17/64] new: attach tests to main cmake and base test Signed-off-by: Lorenzo Fontana Co-authored-by: Leonardo Di Donato --- CMakeLists.txt | 5 +++++ tests/TestBase.cpp | 5 +++++ userspace/engine/CMakeLists.txt | 5 ++++- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 tests/TestBase.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cabe1118ec4..5c36ded022e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -610,6 +610,10 @@ add_subdirectory(docker) list(APPEND CMAKE_MODULE_PATH "${SYSDIG_DIR}/cmake/modules") +# Add path for custom CMake modules +list(APPEND CMAKE_MODULE_PATH + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") + if(CMAKE_SYSTEM_NAME MATCHES "Linux") add_subdirectory("${SYSDIG_DIR}/driver" "${PROJECT_BINARY_DIR}/driver") include(FindMakedev) @@ -624,6 +628,7 @@ set(FALCO_BIN_DIR bin) add_subdirectory(scripts) add_subdirectory(userspace/engine) add_subdirectory(userspace/falco) +add_subdirectory(tests) set(CPACK_PACKAGE_NAME "${PACKAGE_NAME}") diff --git a/tests/TestBase.cpp b/tests/TestBase.cpp new file mode 100644 index 00000000000..0e2d84d101a --- /dev/null +++ b/tests/TestBase.cpp @@ -0,0 +1,5 @@ +#define CATCH_CONFIG_MAIN +#include + +TEST_CASE( "1: All test cases reside in other .cpp files (empty)", "[multi-file:1]" ) { +} diff --git a/userspace/engine/CMakeLists.txt b/userspace/engine/CMakeLists.txt index 820643ced8f..ef7bc25dce9 100644 --- a/userspace/engine/CMakeLists.txt +++ b/userspace/engine/CMakeLists.txt @@ -24,7 +24,7 @@ include_directories("${NJSON_INCLUDE}") include_directories("${CURL_INCLUDE_DIR}") include_directories("${TBB_INCLUDE_DIR}") -add_library(falco_engine STATIC +set(FALCO_ENGINE_SOURCE_FILES rules.cpp falco_common.cpp falco_engine.cpp @@ -33,6 +33,8 @@ add_library(falco_engine STATIC token_bucket.cpp formats.cpp) +add_library(falco_engine STATIC ${FALCO_ENGINE_SOURCE_FILES}) + target_include_directories(falco_engine PUBLIC "${LUAJIT_INCLUDE}" "${NJSON_INCLUDE}" @@ -43,6 +45,7 @@ target_link_libraries(falco_engine "${LPEG_LIB}" "${LYAML_LIB}" "${LIBYAML_LIB}") +# --coverage) # todo: enable only if coverage enabled configure_file(config_falco_engine.h.in config_falco_engine.h) From 6e92988425f31c5125de35c6c010f26ac35c66d7 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Tue, 25 Jun 2019 10:55:21 +0000 Subject: [PATCH 18/64] docs: licensing info in test files Signed-off-by: Lorenzo Fontana Co-authored-by: Leonardo Di Donato --- cmake/modules/FindCatch.cmake | 23 ++++++++++++++++++++--- tests/CMakeLists.txt | 20 +++++++++++++++++++- tests/TestBase.cpp | 17 +++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/cmake/modules/FindCatch.cmake b/cmake/modules/FindCatch.cmake index fa920767da0..88f18149f89 100644 --- a/cmake/modules/FindCatch.cmake +++ b/cmake/modules/FindCatch.cmake @@ -1,8 +1,25 @@ - +# +# Copyright (C) 2016-2019 Draios Inc dba Sysdig. +# +# This file is part of falco . +# +# 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(ExternalProject) + set(CATCH_EXTERNAL_URL - URL https://github.com/catchorg/Catch2/archive/v2.9.1.tar.gz) - #URL_HASH MD5=2080f4696579351d9323b3b5a8c3c71b) + URL https://github.com/catchorg/Catch2/archive/v2.9.1.tar.gz + URL_HASH MD5=4980778888fed635bf191d8a86f9f89c) ExternalProject_Add(catch2 PREFIX ${CMAKE_BINARY_DIR}/catch2-prefix ${CATCH_EXTERNAL_URL} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 64ff0aa88df..4d8672957a6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,23 @@ +# +# Copyright (C) 2016-2019 Draios Inc dba Sysdig. +# +# This file is part of falco . +# +# 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. +# set(FALCO_TESTS_SOURCES - TestBase.cpp) + TestBase.cpp + engine/TestEngineProva.cpp) set(FALCO_TESTED_LIBRARIES falco_engine) diff --git a/tests/TestBase.cpp b/tests/TestBase.cpp index 0e2d84d101a..a485d2fe84e 100644 --- a/tests/TestBase.cpp +++ b/tests/TestBase.cpp @@ -1,3 +1,20 @@ +/* +Copyright (C) 2016-2019 Draios Inc dba Sysdig. + +This file is part of falco. + +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. +*/ #define CATCH_CONFIG_MAIN #include From adabae4f63d63dadc20a1fcb18a6578fb2d846a5 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Tue, 25 Jun 2019 11:07:04 +0000 Subject: [PATCH 19/64] update: build unit tests in travis Signed-off-by: Lorenzo Fontana Co-Authored-By: Leonardo Di Donato --- .travis.yml | 1 + tests/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fb38328e504..b01446885e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,7 @@ script: - cd build - docker run --user $(id -u):$(id -g) -v /etc/passwd:/etc/passwd:ro -e MAKE_JOBS=4 -v $TRAVIS_BUILD_DIR/..:/source -v $TRAVIS_BUILD_DIR/build:/build falcosecurity/falco-builder cmake - docker run --user $(id -u):$(id -g) -v /etc/passwd:/etc/passwd:ro -e MAKE_JOBS=4 -v $TRAVIS_BUILD_DIR/..:/source -v $TRAVIS_BUILD_DIR/build:/build falcosecurity/falco-builder package + - docker run --user $(id -u):$(id -g) -v /etc/passwd:/etc/passwd:ro -e MAKE_JOBS=1 -v $TRAVIS_BUILD_DIR/..:/source -v $TRAVIS_BUILD_DIR/build:/build falcosecurity/falco-builder tests - docker run -v /boot:/boot:ro -v /var/run/docker.sock:/var/run/docker.sock -v /etc/passwd:/etc/passwd:ro -e MAKE_JOBS=4 -v $TRAVIS_BUILD_DIR/..:/source -v $TRAVIS_BUILD_DIR/build:/build falcosecurity/falco-tester notifications: webhooks: diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4d8672957a6..19d80d050f1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,7 +22,7 @@ set(FALCO_TESTS_SOURCES set(FALCO_TESTED_LIBRARIES falco_engine) -option(FALCO_BUILD_TESTS "Determines whether to build tests." OFF) +option(FALCO_BUILD_TESTS "Determines whether to build tests." ON) if(FALCO_BUILD_TESTS) enable_testing() From c2ac1d36222ef33ebfd34729cc90d96259c86dc6 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Tue, 25 Jun 2019 11:10:31 +0000 Subject: [PATCH 20/64] chore: remove typo Signed-off-by: Lorenzo Fontana Co-Authored-By: Leonardo Di Donato --- userspace/engine/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/userspace/engine/CMakeLists.txt b/userspace/engine/CMakeLists.txt index ef7bc25dce9..2dbf3b50923 100644 --- a/userspace/engine/CMakeLists.txt +++ b/userspace/engine/CMakeLists.txt @@ -45,7 +45,6 @@ target_link_libraries(falco_engine "${LPEG_LIB}" "${LYAML_LIB}" "${LIBYAML_LIB}") -# --coverage) # todo: enable only if coverage enabled configure_file(config_falco_engine.h.in config_falco_engine.h) From 4174822617637973998d201221e4a5cae2aa2ef3 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Tue, 25 Jun 2019 12:58:38 +0000 Subject: [PATCH 21/64] fix: remove example file from cmake tests Signed-off-by: Lorenzo Fontana Co-authored-by: Leonardo Di Donato --- tests/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 19d80d050f1..2fe7892cc12 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,8 +16,7 @@ # limitations under the License. # set(FALCO_TESTS_SOURCES - TestBase.cpp - engine/TestEngineProva.cpp) + TestBase.cpp) set(FALCO_TESTED_LIBRARIES falco_engine) From 93537ccaea51f25e8e7f4c63402699ec02db7086 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Tue, 25 Jun 2019 13:41:12 +0000 Subject: [PATCH 22/64] update: test files should use the naming convention Signed-off-by: Lorenzo Fontana --- tests/CMakeLists.txt | 2 +- tests/{TestBase.cpp => test_base.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{TestBase.cpp => test_base.cpp} (100%) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2fe7892cc12..91ea35d366a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,7 +16,7 @@ # limitations under the License. # set(FALCO_TESTS_SOURCES - TestBase.cpp) + test_base.cpp) set(FALCO_TESTED_LIBRARIES falco_engine) diff --git a/tests/TestBase.cpp b/tests/test_base.cpp similarity index 100% rename from tests/TestBase.cpp rename to tests/test_base.cpp From f4fea8441c7660eb59311fc08030acef051ec75a Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Tue, 25 Jun 2019 14:53:15 +0000 Subject: [PATCH 23/64] new: initial clang format file This coding convention's solely goal is to approximately match the current code style. It MUST not be intended in any other way until a real and definitive coding convention is put in. Co-authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- .clang-format | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000000..e22175e5629 --- /dev/null +++ b/.clang-format @@ -0,0 +1,10 @@ +# This coding convention's solely goal is to approximately match the current code style. +# It MUST not be intended in any other way until a real and definitive coding convention is put in. +--- +BreakBeforeBraces: GNU +ColumnLimit: 0 +IndentWidth: 4 +Language: Cpp +SpaceBeforeParens: Never +Standard: Auto +UseTab: Always \ No newline at end of file From 8ed33a04fd64727230734726c86373b74f93f267 Mon Sep 17 00:00:00 2001 From: kaizhe Date: Fri, 21 Jun 2019 10:34:51 -0700 Subject: [PATCH 24/64] rule update: add placeholder for rules write below root/etc Signed-off-by: kaizhe --- rules/falco_rules.yaml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index d05d7ed272b..48711283733 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1148,6 +1148,10 @@ - macro: user_known_write_etc_conditions condition: proc.name=confd +# This is a placeholder for user to extend the whitelist for write below etc rule +- macro: user_know_write_below_etc_activities + condition: (never_true) + - macro: write_etc_common condition: > etc_dir and evt.dir = < and open_write @@ -1245,6 +1249,7 @@ and not checkpoint_writing_state and not jboss_in_container_writing_passwd and not etcd_manager_updating_dns + and not user_know_write_below_etc_activities - rule: Write below etc desc: an attempt to write to any file below /etc @@ -1308,6 +1313,10 @@ - macro: user_known_write_root_conditions condition: fd.name=/root/.bash_history +# This is a placeholder for user to extend the whitelist for write below root rule +- macro: user_known_write_below_root_activities + condition: (never_true) + - rule: Write below root desc: an attempt to write to any file directly below / or /root condition: > @@ -1329,6 +1338,7 @@ and not rancher_writing_root and not known_root_conditions and not user_known_write_root_conditions + and not user_known_write_below_root_activities output: "File below / or /root opened for writing (user=%user.name command=%proc.cmdline parent=%proc.pname file=%fd.name program=%proc.name container_id=%container.id image=%container.image.repository)" priority: ERROR tags: [filesystem, mitre_persistence] @@ -1470,12 +1480,18 @@ - list: user_known_change_thread_namespace_binaries items: [] +- macro: user_know_change_thread_namespace_activities + condition: (never_true) + - list: network_plugin_binaries items: [aws-cni, azure-vnet] - macro: calico_node condition: (container.image.repository endswith calico/node and proc.name=calico-node) +- macro: weaveworks_scope + condition: (container.image.repository endswith weaveworks/scope and proc.name=scope) + - rule: Change thread namespace desc: > an attempt to change a program/thread\'s namespace (commonly done @@ -1494,6 +1510,8 @@ and not rancher_agent and not rancher_network_manager and not calico_node + and not weaveworks_scope + and not user_know_change_thread_namespace_activities output: > Namespace change (setns) by unexpected program (user=%user.name command=%proc.cmdline parent=%proc.pname %container.info container_id=%container.id image=%container.image.repository) @@ -1703,7 +1721,7 @@ # In this file, it just takes one of the images in trusted_containers # and repeats it. - macro: user_trusted_containers - condition: (container.image.repository = docker.io/sysdig/agent) + condition: (container.image.repository endswith sysdig/agent) - list: sematext_images items: [docker.io/sematext/sematext-agent-docker, docker.io/sematext/agent, docker.io/sematext/logagent, @@ -1735,7 +1753,7 @@ # In this file, it just takes one of the images in falco_privileged_images # and repeats it. - macro: user_privileged_containers - condition: (container.image.repository = docker.io/sysdig/agent) + condition: (container.image.repository endswith sysdig/agent) - list: rancher_images items: [ From c12052e03d15879ed74655be0bb17594e69dbf29 Mon Sep 17 00:00:00 2001 From: kaizhe Date: Fri, 21 Jun 2019 10:41:56 -0700 Subject: [PATCH 25/64] add openshift image to whitelist Signed-off-by: kaizhe --- rules/falco_rules.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 48711283733..495f28d4bb0 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1690,6 +1690,7 @@ container.image.repository endswith /ose-pod or container.image.repository endswith /ose-node or container.image.repository endswith /ose-docker-registry or + container.image.repository endswith /prometheus-node-exporter or container.image.repository endswith /image-inspector)) # These images are allowed both to run with --privileged and to mount From 6ce17d6fcbd5638a83670b45aa86a474964e984b Mon Sep 17 00:00:00 2001 From: kaizhe Date: Fri, 21 Jun 2019 15:49:02 -0700 Subject: [PATCH 26/64] add rfc_1918_address macro Signed-off-by: kaizhe --- rules/falco_rules.yaml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 495f28d4bb0..438f7b44d17 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -311,13 +311,17 @@ (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8") and (evt.rawres >= 0 or evt.res = EINPROGRESS)) +# RFC1918 addresses were assigned for private network usage +- list: rfc_1918_addresses + items: ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"] + - macro: outbound condition: > (((evt.type = connect and evt.dir=<) or (evt.type in (sendto,sendmsg) and evt.dir=< and fd.l4proto != tcp and fd.connected=false and fd.name_changed=true)) and (fd.typechar = 4 or fd.typechar = 6) and - (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8") and + (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and (not fd.snet in rfc_1918_addresses) and (evt.rawres >= 0 or evt.res = EINPROGRESS)) # Very similar to inbound/outbound, but combines the tests together @@ -1149,7 +1153,7 @@ condition: proc.name=confd # This is a placeholder for user to extend the whitelist for write below etc rule -- macro: user_know_write_below_etc_activities +- macro: user_known_write_below_etc_activities condition: (never_true) - macro: write_etc_common @@ -1249,7 +1253,7 @@ and not checkpoint_writing_state and not jboss_in_container_writing_passwd and not etcd_manager_updating_dns - and not user_know_write_below_etc_activities + and not user_known_write_below_etc_activities - rule: Write below etc desc: an attempt to write to any file below /etc @@ -1480,7 +1484,7 @@ - list: user_known_change_thread_namespace_binaries items: [] -- macro: user_know_change_thread_namespace_activities +- macro: user_known_change_thread_namespace_activities condition: (never_true) - list: network_plugin_binaries @@ -1511,7 +1515,7 @@ and not rancher_network_manager and not calico_node and not weaveworks_scope - and not user_know_change_thread_namespace_activities + and not user_known_change_thread_namespace_activities output: > Namespace change (setns) by unexpected program (user=%user.name command=%proc.cmdline parent=%proc.pname %container.info container_id=%container.id image=%container.image.repository) From 16bd8919abcbe60584308d7e6ad1a7c43fc4b006 Mon Sep 17 00:00:00 2001 From: kaizhe Date: Sat, 29 Jun 2019 06:55:17 +0800 Subject: [PATCH 27/64] rule update: fix syntax error Signed-off-by: kaizhe --- rules/falco_rules.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 438f7b44d17..b4a86528421 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -313,7 +313,7 @@ # RFC1918 addresses were assigned for private network usage - list: rfc_1918_addresses - items: ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"] + items: ['"10.0.0.0/8"', '"172.16.0.0/12"', '"192.168.0.0/16"'] - macro: outbound condition: > @@ -321,7 +321,7 @@ (evt.type in (sendto,sendmsg) and evt.dir=< and fd.l4proto != tcp and fd.connected=false and fd.name_changed=true)) and (fd.typechar = 4 or fd.typechar = 6) and - (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and (not fd.snet in rfc_1918_addresses) and + (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and not fd.snet in (rfc_1918_addresses)) and (evt.rawres >= 0 or evt.res = EINPROGRESS)) # Very similar to inbound/outbound, but combines the tests together From 48f2b1d08a4a09ea11b4e3bcd2eeacb2fe786581 Mon Sep 17 00:00:00 2001 From: Leo Di Donato Date: Mon, 1 Jul 2019 12:10:24 +0200 Subject: [PATCH 28/64] fix(.github): kind/rule-* rather thant kind/rule/* Signed-off-by: leodidonato@gmail.com --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d3ab3c5bff0..90b5891bbe3 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -19,8 +19,8 @@ > If contributing rules or changes to rules, please make sure to uncomment the appropriate kind -> /kind rule/update -> /kind rule/create +> /kind rule-update +> /kind rule-create **Any specific area of the project related to this PR?** From fade4241206200cba559ca5be057a7750f79fb8f Mon Sep 17 00:00:00 2001 From: Leo Di Donato Date: Mon, 1 Jul 2019 12:37:03 +0200 Subject: [PATCH 29/64] update(.github): PR template Some refinements and improvements to the GitHub PR template. Co-authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- .github/PULL_REQUEST_TEMPLATE.md | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 90b5891bbe3..63896a4417e 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,48 +7,66 @@ --> **What type of PR is this?** -> Uncomment only one ` /kind <>` line, hit enter to put that in a new line, and remove leading whitespaces from that line: -> + +> Uncomment one (or more) `/kind <>` lines: + > /kind bug + > /kind cleanup + > /kind design + > /kind documentation + > /kind failing-test + > /kind feature + > /kind flaky-test -> If contributing rules or changes to rules, please make sure to uncomment the appropriate kind +> If contributing rules or changes to rules, please make sure to also uncomment one of the following line: > /kind rule-update + > /kind rule-create **Any specific area of the project related to this PR?** +> Uncomment one (or more) `/area <>` lines: + > /area engine + > /area rules + > /area deployment + > /area integrations + > /area examples **What this PR does / why we need it**: **Which issue(s) this PR fixes**: + + Fixes # **Special notes for your reviewer**: **Does this PR introduce a user-facing change?**: + + ```release-note ``` From 8a745b73a3cf77681852b29f2a07b7c12ab398a5 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Tue, 25 Jun 2019 16:16:52 +0000 Subject: [PATCH 30/64] build: use sysdig directory variable for userspace engine build Co-Authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- userspace/engine/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/userspace/engine/CMakeLists.txt b/userspace/engine/CMakeLists.txt index 2dbf3b50923..550399a4c98 100644 --- a/userspace/engine/CMakeLists.txt +++ b/userspace/engine/CMakeLists.txt @@ -15,9 +15,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # -include_directories("${PROJECT_SOURCE_DIR}/../sysdig/userspace/libsinsp/third-party/jsoncpp") -include_directories("${PROJECT_SOURCE_DIR}/../sysdig/userspace/libscap") -include_directories("${PROJECT_SOURCE_DIR}/../sysdig/userspace/libsinsp") +include_directories("${SYSDIG_DIR}/userspace/libsinsp/third-party/jsoncpp") +include_directories("${SYSDIG_DIR}/userspace/libscap") +include_directories("${SYSDIG_DIR}/userspace/libsinsp") include_directories("${PROJECT_BINARY_DIR}/userspace/engine") include_directories("${LUAJIT_INCLUDE}") include_directories("${NJSON_INCLUDE}") From 11838548df05f17965998f830db86327992c4b61 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Tue, 25 Jun 2019 16:17:56 +0000 Subject: [PATCH 31/64] build: includes for tests Co-Authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- tests/CMakeLists.txt | 19 ++++++++-- tests/engine/test_ruleset.cpp | 67 +++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 tests/engine/test_ruleset.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 91ea35d366a..1e0e370b56e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,7 +16,8 @@ # limitations under the License. # set(FALCO_TESTS_SOURCES - test_base.cpp) + test_base.cpp + engine/test_ruleset.cpp) set(FALCO_TESTED_LIBRARIES falco_engine) @@ -31,11 +32,23 @@ if(FALCO_BUILD_TESTS) add_executable(falco_test ${FALCO_TESTS_SOURCES}) - target_link_libraries(falco_test PUBLIC ${FALCO_TESTED_LIBRARIES} catch) + target_link_libraries(falco_test PUBLIC ${FALCO_TESTED_LIBRARIES} catch) + target_include_directories(falco_test PUBLIC + "${SYSDIG_DIR}/userspace/libsinsp/third-party/jsoncpp" + "${SYSDIG_DIR}/userspace/libscap" + "${SYSDIG_DIR}/userspace/libsinsp" + "${LUAJIT_INCLUDE}" + "${NJSON_INCLUDE}" + "${CURL_INCLUDE_DIR}" + "${TBB_INCLUDE_DIR}" + "${LUAJIT_INCLUDE}" + "${NJSON_INCLUDE}" + "${PROJECT_SOURCE_DIR}/userspace/engine" + ) include(CTest) include(Catch) catch_discover_tests(falco_test) - add_custom_target(tests COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS falco_test) + add_custom_target(tests COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS falco_test) endif() diff --git a/tests/engine/test_ruleset.cpp b/tests/engine/test_ruleset.cpp new file mode 100644 index 00000000000..024b8106be4 --- /dev/null +++ b/tests/engine/test_ruleset.cpp @@ -0,0 +1,67 @@ +/* +Copyright (C) 2016-2019 Draios Inc dba Sysdig. + +This file is part of falco. + +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 +#include "ruleset.h" + +TEST_CASE("vectors can be sized and resized", "[vector]") +{ + auto rs = new falco_ruleset(); + + SECTION("adding ...") + { + std::string s = "string"; + std::set tagset = {"a", "b", "c"}; + std::set evtset = {1, 2, 3}; + rs->add(s, tagset, evtset, nullptr); + } + + // std::vector v(5); + + // REQUIRE(v.size() == 5); + // REQUIRE(v.capacity() >= 5); + + // SECTION("resizing bigger changes size and capacity") + // { + // v.resize(10); + + // REQUIRE(v.size() == 10); + // REQUIRE(v.capacity() >= 10); + // } + // SECTION("resizing smaller changes size but not capacity") + // { + // v.resize(0); + + // REQUIRE(v.size() == 0); + // REQUIRE(v.capacity() >= 5); + // } + // SECTION("reserving bigger changes capacity but not size") + // { + // v.reserve(10); + + // REQUIRE(v.size() == 5); + // REQUIRE(v.capacity() >= 10); + // } + // SECTION("reserving smaller does not change size or capacity") + // { + // v.reserve(0); + + // REQUIRE(v.size() == 5); + // REQUIRE(v.capacity() >= 5); + // } +} From 815f5d8714e9d59d02e98173bd3838acf6c6bb0d Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Wed, 26 Jun 2019 12:52:31 +0000 Subject: [PATCH 32/64] new: test token bucket Co-authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- tests/CMakeLists.txt | 2 +- tests/engine/test_ruleset.cpp | 67 ------------------------- tests/engine/test_token_bucket.cpp | 78 ++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 68 deletions(-) delete mode 100644 tests/engine/test_ruleset.cpp create mode 100644 tests/engine/test_token_bucket.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1e0e370b56e..2cd30967c18 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,7 +17,7 @@ # set(FALCO_TESTS_SOURCES test_base.cpp - engine/test_ruleset.cpp) + engine/test_token_bucket.cpp) set(FALCO_TESTED_LIBRARIES falco_engine) diff --git a/tests/engine/test_ruleset.cpp b/tests/engine/test_ruleset.cpp deleted file mode 100644 index 024b8106be4..00000000000 --- a/tests/engine/test_ruleset.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright (C) 2016-2019 Draios Inc dba Sysdig. - -This file is part of falco. - -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 -#include "ruleset.h" - -TEST_CASE("vectors can be sized and resized", "[vector]") -{ - auto rs = new falco_ruleset(); - - SECTION("adding ...") - { - std::string s = "string"; - std::set tagset = {"a", "b", "c"}; - std::set evtset = {1, 2, 3}; - rs->add(s, tagset, evtset, nullptr); - } - - // std::vector v(5); - - // REQUIRE(v.size() == 5); - // REQUIRE(v.capacity() >= 5); - - // SECTION("resizing bigger changes size and capacity") - // { - // v.resize(10); - - // REQUIRE(v.size() == 10); - // REQUIRE(v.capacity() >= 10); - // } - // SECTION("resizing smaller changes size but not capacity") - // { - // v.resize(0); - - // REQUIRE(v.size() == 0); - // REQUIRE(v.capacity() >= 5); - // } - // SECTION("reserving bigger changes capacity but not size") - // { - // v.reserve(10); - - // REQUIRE(v.size() == 5); - // REQUIRE(v.capacity() >= 10); - // } - // SECTION("reserving smaller does not change size or capacity") - // { - // v.reserve(0); - - // REQUIRE(v.size() == 5); - // REQUIRE(v.capacity() >= 5); - // } -} diff --git a/tests/engine/test_token_bucket.cpp b/tests/engine/test_token_bucket.cpp new file mode 100644 index 00000000000..553b1599495 --- /dev/null +++ b/tests/engine/test_token_bucket.cpp @@ -0,0 +1,78 @@ +/* +Copyright (C) 2016-2019 Draios Inc dba Sysdig. + +This file is part of falco. + +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 "token_bucket.h" +#include + +using namespace Catch::literals; + +TEST_CASE("token bucket ctor", "[token_bucket]") +{ +} + +TEST_CASE("token bucket init", "[token_bucket]") +{ + auto tb = new token_bucket(); + + SECTION("at specific time") + { + auto max = 2.0; + uint64_t now = 1; + tb->init(1.0, max, now); + REQUIRE(tb->get_last_seen() == now); + REQUIRE(tb->get_tokens() == max); + } + + SECTION("at current time") + { + // auto max = 2.0; + // tb->init(1.0, max, 0); + // REQUIRE(tb->get_last_seen() == ); + // REQUIRE(tb->get_tokens() == max); + } +} + +TEST_CASE("token bucket claim", "[token_bucket]") +{ + auto tb = new token_bucket(); + tb->init(2.0, 10.0, 1); + + SECTION("...") + { + bool claimed = tb->claim(5.0, 1000000001); + REQUIRE(tb->get_last_seen() == 1000000001); + REQUIRE(tb->get_tokens() == 5.0_a); + REQUIRE(claimed); + + SECTION("xxx") + { + bool claimed = tb->claim(7.0, 2000000001); + REQUIRE(tb->get_last_seen() == 2000000001); + REQUIRE(tb->get_tokens() == 0.0_a); + REQUIRE(claimed); + + SECTION(";;;") + { + bool claimed = tb->claim(3.0, 3000000001); + REQUIRE(tb->get_last_seen() == 3000000001); + REQUIRE(tb->get_tokens() == 2.0_a); + REQUIRE_FALSE(claimed); + } + } + } +} \ No newline at end of file From fcc587e806ebf27a7f672ce2cb9c943b0da6abaf Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Thu, 27 Jun 2019 10:32:22 +0000 Subject: [PATCH 33/64] new: cmake format config file Co-Authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- .cmake-format | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 .cmake-format diff --git a/.cmake-format b/.cmake-format new file mode 100644 index 00000000000..e6484a15e30 --- /dev/null +++ b/.cmake-format @@ -0,0 +1,119 @@ +# -------------------------- +# General Formatting Options +# -------------------------- +# How wide to allow formatted cmake files +line_width = 80 + +# How many spaces to tab for indent +tab_size = 2 + +# If arglists are longer than this, break them always +max_subargs_per_line = 3 + +# If true, separate flow control names from their parentheses with a space +separate_ctrl_name_with_space = False + +# If true, separate function names from parentheses with a space +separate_fn_name_with_space = False + +# If a statement is wrapped to more than one line, than dangle the closing +# parenthesis on it's own line +dangle_parens = False + +# If the statement spelling length (including space and parenthesis is larger +# than the tab width by more than this amoung, then force reject un-nested +# layouts. +max_prefix_chars = 2 + +# If a candidate layout is wrapped horizontally but it exceeds this many lines, +# then reject the layout. +max_lines_hwrap = 2 + +# What style line endings to use in the output. +line_ending = 'unix' + +# Format command names consistently as 'lower' or 'upper' case +command_case = 'canonical' + +# Format keywords consistently as 'lower' or 'upper' case +keyword_case = 'unchanged' + +# Specify structure for custom cmake functions +additional_commands = { + "pkg_find": { + "kwargs": { + "PKG": "*" + } + } +} + +# A list of command names which should always be wrapped +always_wrap = [] + +# Specify the order of wrapping algorithms during successive reflow attempts +algorithm_order = [0, 1, 2, 3, 4] + +# If true, the argument lists which are known to be sortable will be sorted +# lexicographicall +enable_sort = True + +# If true, the parsers may infer whether or not an argument list is sortable +# (without annotation). +autosort = False + +# If a comment line starts with at least this many consecutive hash characters, +# then don't lstrip() them off. This allows for lazy hash rulers where the first +# hash char is not separated by space +hashruler_min_length = 10 + +# A dictionary containing any per-command configuration overrides. Currently +# only `command_case` is supported. +per_command = {} + + +# -------------------------- +# Comment Formatting Options +# -------------------------- +# What character to use for bulleted lists +bullet_char = '*' + +# What character to use as punctuation after numerals in an enumerated list +enum_char = '.' + +# enable comment markup parsing and reflow +enable_markup = True + +# If comment markup is enabled, don't reflow the first comment block in each +# listfile. Use this to preserve formatting of your copyright/license +# statements. +first_comment_is_literal = False + +# If comment markup is enabled, don't reflow any comment block which matches +# this (regex) pattern. Default is `None` (disabled). +literal_comment_pattern = None + +# Regular expression to match preformat fences in comments +# default=r'^\s*([`~]{3}[`~]*)(.*)$' +fence_pattern = '^\\s*([`~]{3}[`~]*)(.*)$' + +# Regular expression to match rulers in comments +# default=r'^\s*[^\w\s]{3}.*[^\w\s]{3}$' +ruler_pattern = '^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$' + +# If true, then insert a space between the first hash char and remaining hash +# chars in a hash ruler, and normalize it's length to fill the column +canonicalize_hashrulers = True + + +# --------------------------------- +# Miscellaneous Options +# --------------------------------- +# If true, emit the unicode byte-order mark (BOM) at the start of the file +emit_byteorder_mark = False + +# Specify the encoding of the input file. Defaults to utf-8. +input_encoding = 'utf-8' + +# Specify the encoding of the output file. Defaults to utf-8. Note that cmake +# only claims to support utf-8 so be careful when using anything else +output_encoding = 'utf-8' \ No newline at end of file From 3a1c0ea916ffd1426f8172ecd429e9ce3ee0be05 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Thu, 27 Jun 2019 10:33:15 +0000 Subject: [PATCH 34/64] build: download fakeit mocking library (cmake) Co-Authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- cmake/modules/DownloadFakeIt.cmake | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 cmake/modules/DownloadFakeIt.cmake diff --git a/cmake/modules/DownloadFakeIt.cmake b/cmake/modules/DownloadFakeIt.cmake new file mode 100644 index 00000000000..16067a148be --- /dev/null +++ b/cmake/modules/DownloadFakeIt.cmake @@ -0,0 +1,39 @@ +# +# Copyright (C) 2016-2019 Draios Inc dba Sysdig. +# +# This file is part of falco . +# +# 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(ExternalProject) + +set(FAKEIT_INCLUDE ${CMAKE_BINARY_DIR}/fakeit-prefix/include) + +set(FAKEIT_EXTERNAL_URL + URL + https://github.com/eranpeer/fakeit/archive/2.0.5.tar.gz + URL_HASH + MD5=d3d21b909cebaea5b780af5500bf384e) + +ExternalProject_Add( + fakeit-external + PREFIX ${CMAKE_BINARY_DIR}/fakeit-prefix + ${FAKEIT_EXTERNAL_URL} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND + ${CMAKE_COMMAND} + -E + copy + ${CMAKE_BINARY_DIR}/fakeit-prefix/src/fakeit-external/single_header/catch/fakeit.hpp + ${FAKEIT_INCLUDE}/fakeit.hpp) From 1a0cf69b03272028190603a6f30335c9431b2ad7 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Thu, 27 Jun 2019 10:33:50 +0000 Subject: [PATCH 35/64] chore: cmakes formatting Co-Authored-By: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- CMakeCPackOptions.cmake | 44 +- CMakeLists.txt | 1042 +++++++++++++++++------------ cmake/modules/Catch.cmake | 111 +-- cmake/modules/CatchAddTests.cmake | 61 +- cmake/modules/DownloadCatch.cmake | 39 ++ cmake/modules/FindCatch.cmake | 34 - tests/CMakeLists.txt | 72 +- 7 files changed, 809 insertions(+), 594 deletions(-) create mode 100644 cmake/modules/DownloadCatch.cmake delete mode 100644 cmake/modules/FindCatch.cmake diff --git a/CMakeCPackOptions.cmake b/CMakeCPackOptions.cmake index ec32740cdeb..74150018d6d 100644 --- a/CMakeCPackOptions.cmake +++ b/CMakeCPackOptions.cmake @@ -3,29 +3,45 @@ # # This file is part of falco . # -# 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 +# 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 +# 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. +# 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. # if(CPACK_GENERATOR MATCHES "DEB") - list(APPEND CPACK_INSTALL_COMMANDS "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/init.d/") - list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/debian/falco _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/init.d") + list( + APPEND + CPACK_INSTALL_COMMANDS + "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/init.d/" + ) + list( + APPEND + CPACK_INSTALL_COMMANDS + "cp scripts/debian/falco _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/init.d" + ) endif() if(CPACK_GENERATOR MATCHES "RPM") - list(APPEND CPACK_INSTALL_COMMANDS "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/rc.d/init.d/") - list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/rpm/falco _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/rc.d/init.d") + list( + APPEND + CPACK_INSTALL_COMMANDS + "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/rc.d/init.d/" + ) + list( + APPEND + CPACK_INSTALL_COMMANDS + "cp scripts/rpm/falco _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/rc.d/init.d" + ) endif() if(CPACK_GENERATOR MATCHES "TGZ") - set(CPACK_SET_DESTDIR "ON") - set(CPACK_STRIP_FILES "OFF") + set(CPACK_SET_DESTDIR "ON") + set(CPACK_STRIP_FILES "OFF") endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c36ded022e..263778d2e12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,17 +3,17 @@ # # This file is part of falco . # -# 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 +# 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 +# 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. +# 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. # cmake_minimum_required(VERSION 2.8.2) @@ -22,26 +22,30 @@ project(falco) option(BUILD_WARNINGS_AS_ERRORS "Enable building with -Wextra -Werror flags") if(NOT DEFINED FALCO_VERSION) - set(FALCO_VERSION "0.1.1dev") + set(FALCO_VERSION "0.1.1dev") endif() if(NOT DEFINED FALCO_ETC_DIR) - set(FALCO_ETC_DIR "/etc/falco") + set(FALCO_ETC_DIR "/etc/falco") endif() if(NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE Release) + set(CMAKE_BUILD_TYPE Release) endif() if(NOT DRAIOS_DEBUG_FLAGS) - set(DRAIOS_DEBUG_FLAGS "-D_DEBUG") + set(DRAIOS_DEBUG_FLAGS "-D_DEBUG") endif() set(CMAKE_COMMON_FLAGS "-Wall -ggdb ${DRAIOS_FEATURE_FLAGS}") if(BUILD_WARNINGS_AS_ERRORS) - set(CMAKE_SUPPRESSED_WARNINGS "-Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-type-limits -Wno-implicit-fallthrough -Wno-format-truncation") - set(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wextra -Werror ${CMAKE_SUPPRESSED_WARNINGS}") + set( + CMAKE_SUPPRESSED_WARNINGS + "-Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-type-limits -Wno-implicit-fallthrough -Wno-format-truncation" + ) + set(CMAKE_COMMON_FLAGS + "${CMAKE_COMMON_FLAGS} -Wextra -Werror ${CMAKE_SUPPRESSED_WARNINGS}") endif() set(CMAKE_C_FLAGS "${CMAKE_COMMON_FLAGS}") @@ -56,65 +60,70 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O3 -fno-strict-aliasing -DNDEBUG") add_definitions(-DPLATFORM_NAME="${CMAKE_SYSTEM_NAME}") add_definitions(-DK8S_DISABLE_THREAD) if(CMAKE_SYSTEM_NAME MATCHES "Linux") - add_definitions(-DHAS_CAPTURE) + add_definitions(-DHAS_CAPTURE) endif() if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(KBUILD_FLAGS "${DRAIOS_DEBUG_FLAGS} ${DRAIOS_FEATURE_FLAGS}") + set(KBUILD_FLAGS "${DRAIOS_DEBUG_FLAGS} ${DRAIOS_FEATURE_FLAGS}") else() - set(KBUILD_FLAGS "${DRAIOS_FEATURE_FLAGS}") + set(KBUILD_FLAGS "${DRAIOS_FEATURE_FLAGS}") endif() set(PACKAGE_NAME "falco") set(PROBE_VERSION "${FALCO_VERSION}") set(PROBE_NAME "falco-probe") set(PROBE_DEVICE_NAME "falco") -if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX /usr CACHE PATH "Default install path" FORCE) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX /usr CACHE PATH "Default install path" FORCE) endif() set(CMD_MAKE make) if(NOT SYSDIG_DIR) - set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig") + set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig") endif() # make luaJIT work on OS X if(APPLE) - set(CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000") + set(CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000") endif() include(ExternalProject) -option(USE_BUNDLED_DEPS "Enable bundled dependencies instead of using the system ones" ON) +option(USE_BUNDLED_DEPS + "Enable bundled dependencies instead of using the system ones" ON) # # zlib # -option(USE_BUNDLED_ZLIB "Enable building of the bundled zlib" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_ZLIB "Enable building of the bundled zlib" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_ZLIB) - find_path(ZLIB_INCLUDE zlib.h PATH_SUFFIXES zlib) - find_library(ZLIB_LIB NAMES z) - if(ZLIB_INCLUDE AND ZLIB_LIB) - message(STATUS "Found zlib: include: ${ZLIB_INCLUDE}, lib: ${ZLIB_LIB}") - else() - message(FATAL_ERROR "Couldn't find system zlib") - endif() + find_path(ZLIB_INCLUDE zlib.h PATH_SUFFIXES zlib) + find_library(ZLIB_LIB NAMES z) + if(ZLIB_INCLUDE AND ZLIB_LIB) + message(STATUS "Found zlib: include: ${ZLIB_INCLUDE}, lib: ${ZLIB_LIB}") + else() + message(FATAL_ERROR "Couldn't find system zlib") + endif() else() - set(ZLIB_SRC "${PROJECT_BINARY_DIR}/zlib-prefix/src/zlib") - message(STATUS "Using bundled zlib in '${ZLIB_SRC}'") - set(ZLIB_INCLUDE "${ZLIB_SRC}") - set(ZLIB_LIB "${ZLIB_SRC}/libz.a") - ExternalProject_Add(zlib - # START CHANGE for CVE-2016-9840, CVE-2016-9841, CVE-2016-9842, CVE-2016-9843 - URL "http://s3.amazonaws.com/download.draios.com/dependencies/zlib-1.2.11.tar.gz" - URL_MD5 "1c9f62f0778697a09d36121ead88e08e" - # END CHANGE for CVE-2016-9840, CVE-2016-9841, CVE-2016-9842, CVE-2016-9843 - CONFIGURE_COMMAND "./configure" - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(ZLIB_SRC "${PROJECT_BINARY_DIR}/zlib-prefix/src/zlib") + message(STATUS "Using bundled zlib in '${ZLIB_SRC}'") + set(ZLIB_INCLUDE "${ZLIB_SRC}") + set(ZLIB_LIB "${ZLIB_SRC}/libz.a") + ExternalProject_Add( + zlib + # START CHANGE for CVE-2016-9840, CVE-2016-9841, CVE-2016-9842, + # CVE-2016-9843 + URL + "http://s3.amazonaws.com/download.draios.com/dependencies/zlib-1.2.11.tar.gz" + URL_MD5 "1c9f62f0778697a09d36121ead88e08e" + # END CHANGE for CVE-2016-9840, CVE-2016-9841, CVE-2016-9842, CVE-2016-9843 + CONFIGURE_COMMAND "./configure" + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # @@ -122,26 +131,38 @@ endif() # option(USE_BUNDLED_JQ "Enable building of the bundled jq" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_JQ) - find_path(JQ_INCLUDE jq.h PATH_SUFFIXES jq) - find_library(JQ_LIB NAMES jq) - if(JQ_INCLUDE AND JQ_LIB) - message(STATUS "Found jq: include: ${JQ_INCLUDE}, lib: ${JQ_LIB}") - else() - message(FATAL_ERROR "Couldn't find system jq") - endif() + find_path(JQ_INCLUDE jq.h PATH_SUFFIXES jq) + find_library(JQ_LIB NAMES jq) + if(JQ_INCLUDE AND JQ_LIB) + message(STATUS "Found jq: include: ${JQ_INCLUDE}, lib: ${JQ_LIB}") + else() + message(FATAL_ERROR "Couldn't find system jq") + endif() else() - set(JQ_SRC "${PROJECT_BINARY_DIR}/jq-prefix/src/jq") - message(STATUS "Using bundled jq in '${JQ_SRC}'") - set(JQ_INCLUDE "${JQ_SRC}") - set(JQ_LIB "${JQ_SRC}/.libs/libjq.a") - ExternalProject_Add(jq - URL "http://s3.amazonaws.com/download.draios.com/dependencies/jq-1.5.tar.gz" - URL_MD5 "0933532b086bd8b6a41c1b162b1731f9" - CONFIGURE_COMMAND ./configure --disable-maintainer-mode --enable-all-static --disable-dependency-tracking - BUILD_COMMAND ${CMD_MAKE} LDFLAGS=-all-static - BUILD_IN_SOURCE 1 - PATCH_COMMAND wget -O jq-1.5-fix-tokenadd.patch https://github.com/stedolan/jq/commit/8eb1367ca44e772963e704a700ef72ae2e12babd.patch && patch -i jq-1.5-fix-tokenadd.patch - INSTALL_COMMAND "") + set(JQ_SRC "${PROJECT_BINARY_DIR}/jq-prefix/src/jq") + message(STATUS "Using bundled jq in '${JQ_SRC}'") + set(JQ_INCLUDE "${JQ_SRC}") + set(JQ_LIB "${JQ_SRC}/.libs/libjq.a") + ExternalProject_Add( + jq + URL "http://s3.amazonaws.com/download.draios.com/dependencies/jq-1.5.tar.gz" + URL_MD5 "0933532b086bd8b6a41c1b162b1731f9" + CONFIGURE_COMMAND ./configure + --disable-maintainer-mode + --enable-all-static + --disable-dependency-tracking + BUILD_COMMAND ${CMD_MAKE} LDFLAGS=-all-static + BUILD_IN_SOURCE 1 + PATCH_COMMAND + wget + -O + jq-1.5-fix-tokenadd.patch + https://github.com/stedolan/jq/commit/8eb1367ca44e772963e704a700ef72ae2e12babd.patch + && + patch + -i + jq-1.5-fix-tokenadd.patch + INSTALL_COMMAND "") endif() set(JSONCPP_SRC "${SYSDIG_DIR}/userspace/libsinsp/third-party/jsoncpp") @@ -151,27 +172,28 @@ set(JSONCPP_LIB_SRC "${JSONCPP_SRC}/jsoncpp.cpp") # # nlohmann-json # -option(USE_BUNDLED_NJSON "Enable building of the bundled nlohmann-json" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_NJSON "Enable building of the bundled nlohmann-json" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_NJSON) - find_path(NJSON_INCLUDE json.hpp PATH_SUFFIXES nlohmann) - if(NJSON_INCLUDE) - message(STATUS "Found nlohmann-json: include: ${NJSON_INCLUDE}") - else() - message(FATAL_ERROR "Couldn't find system nlohmann-json") - endif() + find_path(NJSON_INCLUDE json.hpp PATH_SUFFIXES nlohmann) + if(NJSON_INCLUDE) + message(STATUS "Found nlohmann-json: include: ${NJSON_INCLUDE}") + else() + message(FATAL_ERROR "Couldn't find system nlohmann-json") + endif() else() - # No distinction needed for windows. The implementation is - # solely in json.hpp. - set(NJSON_SRC "${PROJECT_BINARY_DIR}/njson-prefix/src/njson") - message(STATUS "Using bundled nlohmann-json in '${NJSON_SRC}'") - set(NJSON_INCLUDE "${NJSON_SRC}/single_include") - ExternalProject_Add(njson - URL "http://download.draios.com/dependencies/njson-3.3.0.tar.gz" - URL_MD5 "e26760e848656a5da400662e6c5d999a" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "") + # No distinction needed for windows. The implementation is solely in json.hpp. + set(NJSON_SRC "${PROJECT_BINARY_DIR}/njson-prefix/src/njson") + message(STATUS "Using bundled nlohmann-json in '${NJSON_SRC}'") + set(NJSON_INCLUDE "${NJSON_SRC}/single_include") + ExternalProject_Add( + njson + URL "http://download.draios.com/dependencies/njson-3.3.0.tar.gz" + URL_MD5 "e26760e848656a5da400662e6c5d999a" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "") endif() # @@ -179,24 +201,37 @@ endif() # # we pull this in because libsinsp won't build without it -option(USE_BUNDLED_NCURSES "Enable building of the bundled ncurses" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_NCURSES "Enable building of the bundled ncurses" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_NCURSES) - set(CURSES_NEED_NCURSES TRUE) - find_package(Curses REQUIRED) - message(STATUS "Found ncurses: include: ${CURSES_INCLUDE_DIR}, lib: ${CURSES_LIBRARIES}") + set(CURSES_NEED_NCURSES TRUE) + find_package(Curses REQUIRED) + message( + STATUS + "Found ncurses: include: ${CURSES_INCLUDE_DIR}, lib: ${CURSES_LIBRARIES}") else() - set(CURSES_BUNDLE_DIR "${PROJECT_BINARY_DIR}/ncurses-prefix/src/ncurses") - set(CURSES_INCLUDE_DIR "${CURSES_BUNDLE_DIR}/include/") - set(CURSES_LIBRARIES "${CURSES_BUNDLE_DIR}/lib/libncurses.a") - message(STATUS "Using bundled ncurses in '${CURSES_BUNDLE_DIR}'") - ExternalProject_Add(ncurses - URL "http://s3.amazonaws.com/download.draios.com/dependencies/ncurses-6.0-20150725.tgz" - URL_MD5 "32b8913312e738d707ae68da439ca1f4" - CONFIGURE_COMMAND ./configure --without-cxx --without-cxx-binding --without-ada --without-manpages --without-progs --without-tests --with-terminfo-dirs=/etc/terminfo:/lib/terminfo:/usr/share/terminfo - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(CURSES_BUNDLE_DIR "${PROJECT_BINARY_DIR}/ncurses-prefix/src/ncurses") + set(CURSES_INCLUDE_DIR "${CURSES_BUNDLE_DIR}/include/") + set(CURSES_LIBRARIES "${CURSES_BUNDLE_DIR}/lib/libncurses.a") + message(STATUS "Using bundled ncurses in '${CURSES_BUNDLE_DIR}'") + ExternalProject_Add( + ncurses + URL + "http://s3.amazonaws.com/download.draios.com/dependencies/ncurses-6.0-20150725.tgz" + URL_MD5 "32b8913312e738d707ae68da439ca1f4" + CONFIGURE_COMMAND + ./configure + --without-cxx + --without-cxx-binding + --without-ada + --without-manpages + --without-progs + --without-tests + --with-terminfo-dirs=/etc/terminfo:/lib/terminfo:/usr/share/terminfo + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # @@ -205,421 +240,559 @@ endif() option(USE_BUNDLED_B64 "Enable building of the bundled b64" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_B64) - find_path(B64_INCLUDE NAMES b64/encode.h) - find_library(B64_LIB NAMES b64) - if(B64_INCLUDE AND B64_LIB) - message(STATUS "Found b64: include: ${B64_INCLUDE}, lib: ${B64_LIB}") - else() - message(FATAL_ERROR "Couldn't find system b64") - endif() + find_path(B64_INCLUDE NAMES b64/encode.h) + find_library(B64_LIB NAMES b64) + if(B64_INCLUDE AND B64_LIB) + message(STATUS "Found b64: include: ${B64_INCLUDE}, lib: ${B64_LIB}") + else() + message(FATAL_ERROR "Couldn't find system b64") + endif() else() - set(B64_SRC "${PROJECT_BINARY_DIR}/b64-prefix/src/b64") - message(STATUS "Using bundled b64 in '${B64_SRC}'") - set(B64_INCLUDE "${B64_SRC}/include") - set(B64_LIB "${B64_SRC}/src/libb64.a") - ExternalProject_Add(b64 - URL "http://s3.amazonaws.com/download.draios.com/dependencies/libb64-1.2.src.zip" - URL_MD5 "a609809408327117e2c643bed91b76c5" - CONFIGURE_COMMAND "" - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(B64_SRC "${PROJECT_BINARY_DIR}/b64-prefix/src/b64") + message(STATUS "Using bundled b64 in '${B64_SRC}'") + set(B64_INCLUDE "${B64_SRC}/include") + set(B64_LIB "${B64_SRC}/src/libb64.a") + ExternalProject_Add( + b64 + URL + "http://s3.amazonaws.com/download.draios.com/dependencies/libb64-1.2.src.zip" + URL_MD5 "a609809408327117e2c643bed91b76c5" + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # # yamlcpp # -option(USE_BUNDLED_YAMLCPP "Enable building of the bundled yamlcpp" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_YAMLCPP "Enable building of the bundled yamlcpp" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_YAMLCPP) - find_path(YAMLCPP_INCLUDE_DIR NAMES yaml-cpp/yaml.h) - find_library(YAMLCPP_LIB NAMES yaml-cpp) - if(YAMLCPP_INCLUDE_DIR AND YAMLCPP_LIB) - message(STATUS "Found yamlcpp: include: ${YAMLCPP_INCLUDE_DIR}, lib: ${YAMLCPP_LIB}") - else() - message(FATAL_ERROR "Couldn't find system yamlcpp") - endif() + find_path(YAMLCPP_INCLUDE_DIR NAMES yaml-cpp/yaml.h) + find_library(YAMLCPP_LIB NAMES yaml-cpp) + if(YAMLCPP_INCLUDE_DIR AND YAMLCPP_LIB) + message( + STATUS + "Found yamlcpp: include: ${YAMLCPP_INCLUDE_DIR}, lib: ${YAMLCPP_LIB}") + else() + message(FATAL_ERROR "Couldn't find system yamlcpp") + endif() else() - set(YAMLCPP_SRC "${PROJECT_BINARY_DIR}/yamlcpp-prefix/src/yamlcpp") - message(STATUS "Using bundled yaml-cpp in '${YAMLCPP_SRC}'") - set(YAMLCPP_LIB "${YAMLCPP_SRC}/libyaml-cpp.a") - set(YAMLCPP_INCLUDE_DIR "${YAMLCPP_SRC}/include") - ExternalProject_Add(yamlcpp - URL "https://s3.amazonaws.com/download.draios.com/dependencies/yaml-cpp-yaml-cpp-0.6.2.tar.gz" - URL_MD5 "5b943e9af0060d0811148b037449ef82" - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(YAMLCPP_SRC "${PROJECT_BINARY_DIR}/yamlcpp-prefix/src/yamlcpp") + message(STATUS "Using bundled yaml-cpp in '${YAMLCPP_SRC}'") + set(YAMLCPP_LIB "${YAMLCPP_SRC}/libyaml-cpp.a") + set(YAMLCPP_INCLUDE_DIR "${YAMLCPP_SRC}/include") + ExternalProject_Add( + yamlcpp + URL + "https://s3.amazonaws.com/download.draios.com/dependencies/yaml-cpp-yaml-cpp-0.6.2.tar.gz" + URL_MD5 "5b943e9af0060d0811148b037449ef82" + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # # OpenSSL # -option(USE_BUNDLED_OPENSSL "Enable building of the bundled OpenSSL" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_OPENSSL "Enable building of the bundled OpenSSL" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_OPENSSL) - find_package(OpenSSL REQUIRED) - message(STATUS "Found OpenSSL: include: ${OPENSSL_INCLUDE_DIR}, lib: ${OPENSSL_LIBRARIES}") + find_package(OpenSSL REQUIRED) + message( + STATUS + "Found OpenSSL: include: ${OPENSSL_INCLUDE_DIR}, lib: ${OPENSSL_LIBRARIES}" + ) else() - set(OPENSSL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl") - set(OPENSSL_INSTALL_DIR "${OPENSSL_BUNDLE_DIR}/target") - set(OPENSSL_INCLUDE_DIR "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl/include") - set(OPENSSL_LIBRARY_SSL "${OPENSSL_INSTALL_DIR}/lib/libssl.a") - set(OPENSSL_LIBRARY_CRYPTO "${OPENSSL_INSTALL_DIR}/lib/libcrypto.a") - - message(STATUS "Using bundled openssl in '${OPENSSL_BUNDLE_DIR}'") - - ExternalProject_Add(openssl - # START CHANGE for CVE-2017-3735, CVE-2017-3731, CVE-2017-3737, CVE-2017-3738, CVE-2017-3736 - URL "http://s3.amazonaws.com/download.draios.com/dependencies/openssl-1.0.2n.tar.gz" - URL_MD5 "13bdc1b1d1ff39b6fd42a255e74676a4" - # END CHANGE for CVE-2017-3735, CVE-2017-3731, CVE-2017-3737, CVE-2017-3738, CVE-2017-3736 - CONFIGURE_COMMAND ./config shared --prefix=${OPENSSL_INSTALL_DIR} - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND ${CMD_MAKE} install) + set(OPENSSL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl") + set(OPENSSL_INSTALL_DIR "${OPENSSL_BUNDLE_DIR}/target") + set(OPENSSL_INCLUDE_DIR + "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl/include") + set(OPENSSL_LIBRARY_SSL "${OPENSSL_INSTALL_DIR}/lib/libssl.a") + set(OPENSSL_LIBRARY_CRYPTO "${OPENSSL_INSTALL_DIR}/lib/libcrypto.a") + + message(STATUS "Using bundled openssl in '${OPENSSL_BUNDLE_DIR}'") + + ExternalProject_Add( + openssl + # START CHANGE for CVE-2017-3735, CVE-2017-3731, CVE-2017-3737, + # CVE-2017-3738, CVE-2017-3736 + URL + "http://s3.amazonaws.com/download.draios.com/dependencies/openssl-1.0.2n.tar.gz" + URL_MD5 "13bdc1b1d1ff39b6fd42a255e74676a4" + # END CHANGE for CVE-2017-3735, CVE-2017-3731, CVE-2017-3737, CVE-2017-3738, + # CVE-2017-3736 + CONFIGURE_COMMAND ./config shared --prefix=${OPENSSL_INSTALL_DIR} + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND ${CMD_MAKE} install) endif() # # libcurl # -option(USE_BUNDLED_CURL "Enable building of the bundled curl" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_CURL "Enable building of the bundled curl" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_CURL) - find_package(CURL REQUIRED) - message(STATUS "Found CURL: include: ${CURL_INCLUDE_DIR}, lib: ${CURL_LIBRARIES}") + find_package(CURL REQUIRED) + message( + STATUS "Found CURL: include: ${CURL_INCLUDE_DIR}, lib: ${CURL_LIBRARIES}") else() - set(CURL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/curl-prefix/src/curl") - set(CURL_INCLUDE_DIR "${CURL_BUNDLE_DIR}/include/") - set(CURL_LIBRARIES "${CURL_BUNDLE_DIR}/lib/.libs/libcurl.a") - - if(NOT USE_BUNDLED_OPENSSL) - set(CURL_SSL_OPTION "--with-ssl") - else() - set(CURL_SSL_OPTION "--with-ssl=${OPENSSL_INSTALL_DIR}") - message(STATUS "Using bundled curl in '${CURL_BUNDLE_DIR}'") - message(STATUS "Using SSL for curl in '${CURL_SSL_OPTION}'") - endif() - - ExternalProject_Add(curl - DEPENDS openssl - # START CHANGE for CVE-2017-8816, CVE-2017-8817, CVE-2017-8818, CVE-2018-1000007 - URL "http://s3.amazonaws.com/download.draios.com/dependencies/curl-7.61.0.tar.bz2" - URL_MD5 "31d0a9f48dc796a7db351898a1e5058a" - # END CHANGE for CVE-2017-8816, CVE-2017-8817, CVE-2017-8818, CVE-2018-1000007 - CONFIGURE_COMMAND ./configure ${CURL_SSL_OPTION} --disable-shared --enable-optimize --disable-curldebug --disable-rt --enable-http --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-sspi --disable-ntlm-wb --disable-tls-srp --without-winssl --without-darwinssl --without-polarssl --without-cyassl --without-nss --without-axtls --without-ca-path --without-ca-bundle --without-libmetalink --without-librtmp --without-winidn --without-libidn2 --without-libpsl --without-nghttp2 --without-libssh2 --disable-threaded-resolver --without-brotli - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(CURL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/curl-prefix/src/curl") + set(CURL_INCLUDE_DIR "${CURL_BUNDLE_DIR}/include/") + set(CURL_LIBRARIES "${CURL_BUNDLE_DIR}/lib/.libs/libcurl.a") + + if(NOT USE_BUNDLED_OPENSSL) + set(CURL_SSL_OPTION "--with-ssl") + else() + set(CURL_SSL_OPTION "--with-ssl=${OPENSSL_INSTALL_DIR}") + message(STATUS "Using bundled curl in '${CURL_BUNDLE_DIR}'") + message(STATUS "Using SSL for curl in '${CURL_SSL_OPTION}'") + endif() + + ExternalProject_Add( + curl + DEPENDS openssl + # START CHANGE for CVE-2017-8816, CVE-2017-8817, CVE-2017-8818, + # CVE-2018-1000007 + URL + "http://s3.amazonaws.com/download.draios.com/dependencies/curl-7.61.0.tar.bz2" + URL_MD5 "31d0a9f48dc796a7db351898a1e5058a" + # END CHANGE for CVE-2017-8816, CVE-2017-8817, CVE-2017-8818, + # CVE-2018-1000007 + CONFIGURE_COMMAND ./configure + ${CURL_SSL_OPTION} + --disable-shared + --enable-optimize + --disable-curldebug + --disable-rt + --enable-http + --disable-ftp + --disable-file + --disable-ldap + --disable-ldaps + --disable-rtsp + --disable-telnet + --disable-tftp + --disable-pop3 + --disable-imap + --disable-smb + --disable-smtp + --disable-gopher + --disable-sspi + --disable-ntlm-wb + --disable-tls-srp + --without-winssl + --without-darwinssl + --without-polarssl + --without-cyassl + --without-nss + --without-axtls + --without-ca-path + --without-ca-bundle + --without-libmetalink + --without-librtmp + --without-winidn + --without-libidn2 + --without-libpsl + --without-nghttp2 + --without-libssh2 + --disable-threaded-resolver + --without-brotli + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # # LuaJIT # -option(USE_BUNDLED_LUAJIT "Enable building of the bundled LuaJIT" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_LUAJIT "Enable building of the bundled LuaJIT" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_LUAJIT) - find_path(LUAJIT_INCLUDE luajit.h PATH_SUFFIXES luajit-2.0 luajit) - find_library(LUAJIT_LIB NAMES luajit luajit-5.1) - if(LUAJIT_INCLUDE AND LUAJIT_LIB) - message(STATUS "Found LuaJIT: include: ${LUAJIT_INCLUDE}, lib: ${LUAJIT_LIB}") - else() - # alternatively try stock Lua - find_package(Lua51) - set(LUAJIT_LIB ${LUA_LIBRARY}) - set(LUAJIT_INCLUDE ${LUA_INCLUDE_DIR}) - - if(NOT ${LUA51_FOUND}) - message(FATAL_ERROR "Couldn't find system LuaJIT or Lua") - endif() - endif() + find_path(LUAJIT_INCLUDE luajit.h PATH_SUFFIXES luajit-2.0 luajit) + find_library(LUAJIT_LIB NAMES luajit luajit-5.1) + if(LUAJIT_INCLUDE AND LUAJIT_LIB) + message( + STATUS "Found LuaJIT: include: ${LUAJIT_INCLUDE}, lib: ${LUAJIT_LIB}") + else() + # alternatively try stock Lua + find_package(Lua51) + set(LUAJIT_LIB ${LUA_LIBRARY}) + set(LUAJIT_INCLUDE ${LUA_INCLUDE_DIR}) + + if(NOT ${LUA51_FOUND}) + message(FATAL_ERROR "Couldn't find system LuaJIT or Lua") + endif() + endif() else() - set(LUAJIT_SRC "${PROJECT_BINARY_DIR}/luajit-prefix/src/luajit/src") - message(STATUS "Using bundled LuaJIT in '${LUAJIT_SRC}'") - set(LUAJIT_INCLUDE "${LUAJIT_SRC}") - set(LUAJIT_LIB "${LUAJIT_SRC}/libluajit.a") - ExternalProject_Add(luajit - URL "http://s3.amazonaws.com/download.draios.com/dependencies/LuaJIT-2.0.3.tar.gz" - URL_MD5 "f14e9104be513913810cd59c8c658dc0" - CONFIGURE_COMMAND "" - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(LUAJIT_SRC "${PROJECT_BINARY_DIR}/luajit-prefix/src/luajit/src") + message(STATUS "Using bundled LuaJIT in '${LUAJIT_SRC}'") + set(LUAJIT_INCLUDE "${LUAJIT_SRC}") + set(LUAJIT_LIB "${LUAJIT_SRC}/libluajit.a") + ExternalProject_Add( + luajit + URL + "http://s3.amazonaws.com/download.draios.com/dependencies/LuaJIT-2.0.3.tar.gz" + URL_MD5 "f14e9104be513913810cd59c8c658dc0" + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # # Lpeg # -option(USE_BUNDLED_LPEG "Enable building of the bundled lpeg" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_LPEG "Enable building of the bundled lpeg" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_LPEG) - find_library(LPEG_LIB NAMES lpeg.a) - if(LPEG_LIB) - message(STATUS "Found lpeg: lib: ${LPEG_LIB}") - else() - message(FATAL_ERROR "Couldn't find system lpeg") - endif() + find_library(LPEG_LIB NAMES lpeg.a) + if(LPEG_LIB) + message(STATUS "Found lpeg: lib: ${LPEG_LIB}") + else() + message(FATAL_ERROR "Couldn't find system lpeg") + endif() else() - set(LPEG_SRC "${PROJECT_BINARY_DIR}/lpeg-prefix/src/lpeg") - set(LPEG_LIB "${PROJECT_BINARY_DIR}/lpeg-prefix/src/lpeg/build/lpeg.a") - message(STATUS "Using bundled lpeg in '${LPEG_SRC}'") - set(LPEG_DEPENDENCIES "") - if(USE_BUNDLED_LUAJIT) - list(APPEND LPEG_DEPENDENCIES "luajit") - endif() - ExternalProject_Add(lpeg - DEPENDS ${LPEG_DEPENDENCIES} - URL "http://s3.amazonaws.com/download.draios.com/dependencies/lpeg-1.0.0.tar.gz" - URL_MD5 "0aec64ccd13996202ad0c099e2877ece" - BUILD_COMMAND LUA_INCLUDE=${LUAJIT_INCLUDE} "${PROJECT_SOURCE_DIR}/scripts/build-lpeg.sh" "${LPEG_SRC}/build" - BUILD_IN_SOURCE 1 - CONFIGURE_COMMAND "" - INSTALL_COMMAND "") + set(LPEG_SRC "${PROJECT_BINARY_DIR}/lpeg-prefix/src/lpeg") + set(LPEG_LIB "${PROJECT_BINARY_DIR}/lpeg-prefix/src/lpeg/build/lpeg.a") + message(STATUS "Using bundled lpeg in '${LPEG_SRC}'") + set(LPEG_DEPENDENCIES "") + if(USE_BUNDLED_LUAJIT) + list(APPEND LPEG_DEPENDENCIES "luajit") + endif() + ExternalProject_Add( + lpeg + DEPENDS ${LPEG_DEPENDENCIES} + URL + "http://s3.amazonaws.com/download.draios.com/dependencies/lpeg-1.0.0.tar.gz" + URL_MD5 "0aec64ccd13996202ad0c099e2877ece" + BUILD_COMMAND LUA_INCLUDE=${LUAJIT_INCLUDE} + "${PROJECT_SOURCE_DIR}/scripts/build-lpeg.sh" + "${LPEG_SRC}/build" + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + INSTALL_COMMAND "") endif() # # Libyaml # -option(USE_BUNDLED_LIBYAML "Enable building of the bundled libyaml" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_LIBYAML "Enable building of the bundled libyaml" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_LIBYAML) - # Note: to distinguish libyaml.a and yaml.a we specify a full - # file name here, so you'll have to arrange for static - # libraries being available. - find_library(LIBYAML_LIB NAMES libyaml.a) - if(LIBYAML_LIB) - message(STATUS "Found libyaml: lib: ${LIBYAML_LIB}") - else() - message(FATAL_ERROR "Couldn't find system libyaml") - endif() + # Note: to distinguish libyaml.a and yaml.a we specify a full file name here, + # so you'll have to arrange for static libraries being available. + find_library(LIBYAML_LIB NAMES libyaml.a) + if(LIBYAML_LIB) + message(STATUS "Found libyaml: lib: ${LIBYAML_LIB}") + else() + message(FATAL_ERROR "Couldn't find system libyaml") + endif() else() - find_path(AUTORECONF_BIN NAMES autoreconf) - if(AUTORECONF_BIN) - message(STATUS "Found autoreconf: ${AUTORECONF_BIN}") - else() - message(FATAL_ERROR "Couldn't find system autoreconf. Please install autoreconf before continuing or use system libyaml") - endif() - - set(LIBYAML_SRC "${PROJECT_BINARY_DIR}/libyaml-prefix/src/libyaml/src") - set(LIBYAML_INCLUDE "${PROJECT_BINARY_DIR}/libyaml-prefix/src/libyaml/include") - set(LIBYAML_LIB "${LIBYAML_SRC}/.libs/libyaml.a") - message(STATUS "Using bundled libyaml in '${LIBYAML_SRC}'") - ExternalProject_Add(libyaml - URL "http://s3.amazonaws.com/download.draios.com/dependencies/libyaml-0.1.4.tar.gz" - URL_MD5 "4a4bced818da0b9ae7fc8ebc690792a7" - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - CONFIGURE_COMMAND ./bootstrap && ./configure - INSTALL_COMMAND "") + find_path(AUTORECONF_BIN NAMES autoreconf) + if(AUTORECONF_BIN) + message(STATUS "Found autoreconf: ${AUTORECONF_BIN}") + else() + message( + FATAL_ERROR + "Couldn't find system autoreconf. Please install autoreconf before continuing or use system libyaml" + ) + endif() + + set(LIBYAML_SRC "${PROJECT_BINARY_DIR}/libyaml-prefix/src/libyaml/src") + set(LIBYAML_INCLUDE + "${PROJECT_BINARY_DIR}/libyaml-prefix/src/libyaml/include") + set(LIBYAML_LIB "${LIBYAML_SRC}/.libs/libyaml.a") + message(STATUS "Using bundled libyaml in '${LIBYAML_SRC}'") + ExternalProject_Add( + libyaml + URL + "http://s3.amazonaws.com/download.draios.com/dependencies/libyaml-0.1.4.tar.gz" + URL_MD5 "4a4bced818da0b9ae7fc8ebc690792a7" + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND ./bootstrap && ./configure + INSTALL_COMMAND "") endif() # # lyaml # -option(USE_BUNDLED_LYAML "Enable building of the bundled lyaml" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_LYAML "Enable building of the bundled lyaml" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_LYAML) - # Note: to distinguish libyaml.a and yaml.a we specify a full - # file name here, so you'll have to arrange for static - # libraries being available. - find_library(LYAML_LIB NAMES yaml.a) - if(LYAML_LIB) - message(STATUS "Found lyaml: lib: ${LYAML_LIB}") - else() - message(FATAL_ERROR "Couldn't find system lyaml") - endif() + # Note: to distinguish libyaml.a and yaml.a we specify a full file name here, + # so you'll have to arrange for static libraries being available. + find_library(LYAML_LIB NAMES yaml.a) + if(LYAML_LIB) + message(STATUS "Found lyaml: lib: ${LYAML_LIB}") + else() + message(FATAL_ERROR "Couldn't find system lyaml") + endif() else() - set(LYAML_SRC "${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/ext/yaml") - set(LYAML_LIB "${LYAML_SRC}/.libs/yaml.a") - message(STATUS "Using bundled lyaml in '${LYAML_SRC}'") - set(LYAML_DEPENDENCIES "") - if(USE_BUNDLED_LUAJIT) - list(APPEND LYAML_DEPENDENCIES "luajit") - endif() - if(USE_BUNDLED_LIBYAML) - list(APPEND LYAML_DEPENDENCIES "libyaml") - endif() - - ExternalProject_Add(lyaml - DEPENDS ${LYAML_DEPENDENCIES} - URL "http://s3.amazonaws.com/download.draios.com/dependencies/lyaml-release-v6.0.tar.gz" - URL_MD5 "dc3494689a0dce7cf44e7a99c72b1f30" - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - CONFIGURE_COMMAND ./configure --enable-static LIBS=-L${LIBYAML_SRC}/.libs CFLAGS=-I${LIBYAML_INCLUDE} CPPFLAGS=-I${LIBYAML_INCLUDE} LUA_INCLUDE=-I${LUAJIT_INCLUDE} LUA=${LUAJIT_SRC}/luajit - INSTALL_COMMAND sh -c "cp -R ${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/lib/* ${PROJECT_SOURCE_DIR}/userspace/engine/lua") + set(LYAML_SRC "${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/ext/yaml") + set(LYAML_LIB "${LYAML_SRC}/.libs/yaml.a") + message(STATUS "Using bundled lyaml in '${LYAML_SRC}'") + set(LYAML_DEPENDENCIES "") + if(USE_BUNDLED_LUAJIT) + list(APPEND LYAML_DEPENDENCIES "luajit") + endif() + if(USE_BUNDLED_LIBYAML) + list(APPEND LYAML_DEPENDENCIES "libyaml") + endif() + + ExternalProject_Add( + lyaml + DEPENDS ${LYAML_DEPENDENCIES} + URL + "http://s3.amazonaws.com/download.draios.com/dependencies/lyaml-release-v6.0.tar.gz" + URL_MD5 "dc3494689a0dce7cf44e7a99c72b1f30" + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND ./configure + --enable-static + LIBS=-L${LIBYAML_SRC}/.libs + CFLAGS=-I${LIBYAML_INCLUDE} + CPPFLAGS=-I${LIBYAML_INCLUDE} + LUA_INCLUDE=-I${LUAJIT_INCLUDE} + LUA=${LUAJIT_SRC}/luajit + INSTALL_COMMAND + sh -c + "cp -R ${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/lib/* ${PROJECT_SOURCE_DIR}/userspace/engine/lua" + ) endif() option(USE_BUNDLED_TBB "Enable building of the bundled tbb" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_TBB) - find_path(TBB_INCLUDE_DIR tbb.h PATH_SUFFIXES tbb) - find_library(TBB_LIB NAMES tbb) - if(TBB_INCLUDE_DIR AND TBB_LIB) - message(STATUS "Found tbb: include: ${TBB_INCLUDE_DIR}, lib: ${TBB_LIB}") - else() - message(FATAL_ERROR "Couldn't find system tbb") - endif() + find_path(TBB_INCLUDE_DIR tbb.h PATH_SUFFIXES tbb) + find_library(TBB_LIB NAMES tbb) + if(TBB_INCLUDE_DIR AND TBB_LIB) + message(STATUS "Found tbb: include: ${TBB_INCLUDE_DIR}, lib: ${TBB_LIB}") + else() + message(FATAL_ERROR "Couldn't find system tbb") + endif() else() - set(TBB_SRC "${PROJECT_BINARY_DIR}/tbb-prefix/src/tbb") - - message(STATUS "Using bundled tbb in '${TBB_SRC}'") - - set(TBB_INCLUDE_DIR "${TBB_SRC}/include/") - set(TBB_LIB "${TBB_SRC}/build/lib_release/libtbb.a") - ExternalProject_Add(tbb - URL "http://s3.amazonaws.com/download.draios.com/dependencies/tbb-2018_U5.tar.gz" - URL_MD5 "ff3ae09f8c23892fbc3008c39f78288f" - CONFIGURE_COMMAND "" - BUILD_COMMAND ${CMD_MAKE} tbb_build_dir=${TBB_SRC}/build tbb_build_prefix=lib extra_inc=big_iron.inc - BUILD_IN_SOURCE 1 - BUILD_BYPRODUCTS ${TBB_LIB} - INSTALL_COMMAND "") + set(TBB_SRC "${PROJECT_BINARY_DIR}/tbb-prefix/src/tbb") + + message(STATUS "Using bundled tbb in '${TBB_SRC}'") + + set(TBB_INCLUDE_DIR "${TBB_SRC}/include/") + set(TBB_LIB "${TBB_SRC}/build/lib_release/libtbb.a") + ExternalProject_Add( + tbb + URL + "http://s3.amazonaws.com/download.draios.com/dependencies/tbb-2018_U5.tar.gz" + URL_MD5 "ff3ae09f8c23892fbc3008c39f78288f" + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMD_MAKE} + tbb_build_dir=${TBB_SRC}/build + tbb_build_prefix=lib + extra_inc=big_iron.inc + BUILD_IN_SOURCE 1 + BUILD_BYPRODUCTS ${TBB_LIB} + INSTALL_COMMAND "") endif() # # civetweb # -option(USE_BUNDLED_CIVETWEB "Enable building of the bundled civetweb" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_CIVETWEB "Enable building of the bundled civetweb" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_CIVETWEB) - find_library(CIVETWEB_LIB NAMES civetweb) - if(CIVETWEB_LIB) - message(STATUS "Found civetweb: lib: ${CIVETWEB_LIB}") - else() - message(FATAL_ERROR "Couldn't find system civetweb") - endif() + find_library(CIVETWEB_LIB NAMES civetweb) + if(CIVETWEB_LIB) + message(STATUS "Found civetweb: lib: ${CIVETWEB_LIB}") + else() + message(FATAL_ERROR "Couldn't find system civetweb") + endif() else() - set(CIVETWEB_SRC "${PROJECT_BINARY_DIR}/civetweb-prefix/src/civetweb/") - set(CIVETWEB_LIB "${CIVETWEB_SRC}/install/lib/libcivetweb.a") - set(CIVETWEB_INCLUDE_DIR "${CIVETWEB_SRC}/install/include") - message(STATUS "Using bundled civetweb in '${CIVETWEB_SRC}'") - set(CIVETWEB_DEPENDENCIES "") - if(USE_BUNDLED_OPENSSL) - list(APPEND CIVETWEB_DEPENDENCIES "openssl") - endif() - ExternalProject_Add(civetweb - DEPENDS ${CIVETWEB_DEPENDENCIES} - URL "http://s3.amazonaws.com/download.draios.com/dependencies/civetweb-1.11.tar.gz" - URL_MD5 "b6d2175650a27924bccb747cbe084cd4" - CONFIGURE_COMMAND ${CMAKE_COMMAND} -E make_directory ${CIVETWEB_SRC}/install/lib - COMMAND ${CMAKE_COMMAND} -E make_directory ${CIVETWEB_SRC}/install/include - BUILD_IN_SOURCE 1 - BUILD_COMMAND ${CMD_MAKE} COPT="-DNO_FILES" WITH_CPP=1 - INSTALL_COMMAND ${CMD_MAKE} install-lib install-headers PREFIX=${CIVETWEB_SRC}/install WITH_CPP=1) + set(CIVETWEB_SRC "${PROJECT_BINARY_DIR}/civetweb-prefix/src/civetweb/") + set(CIVETWEB_LIB "${CIVETWEB_SRC}/install/lib/libcivetweb.a") + set(CIVETWEB_INCLUDE_DIR "${CIVETWEB_SRC}/install/include") + message(STATUS "Using bundled civetweb in '${CIVETWEB_SRC}'") + set(CIVETWEB_DEPENDENCIES "") + if(USE_BUNDLED_OPENSSL) + list(APPEND CIVETWEB_DEPENDENCIES "openssl") + endif() + ExternalProject_Add( + civetweb + DEPENDS ${CIVETWEB_DEPENDENCIES} + URL + "http://s3.amazonaws.com/download.draios.com/dependencies/civetweb-1.11.tar.gz" + URL_MD5 "b6d2175650a27924bccb747cbe084cd4" + CONFIGURE_COMMAND ${CMAKE_COMMAND} + -E + make_directory + ${CIVETWEB_SRC}/install/lib + COMMAND ${CMAKE_COMMAND} + -E + make_directory + ${CIVETWEB_SRC}/install/include + BUILD_IN_SOURCE 1 + BUILD_COMMAND ${CMD_MAKE} COPT="-DNO_FILES" WITH_CPP=1 + INSTALL_COMMAND ${CMD_MAKE} + install-lib + install-headers + PREFIX=${CIVETWEB_SRC}/install + WITH_CPP=1) endif() -option(USE_BUNDLED_CARES "Enable building of the bundled c-ares" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_CARES "Enable building of the bundled c-ares" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_CARES) - find_path(CARES_INCLUDE NAMES cares/ares.h) - find_library(CARES_LIB NAMES libcares.a) - if(CARES_INCLUDE AND CARES_LIB) - message(STATUS "Found c-ares: include: ${CARES_INCLUDE}, lib: ${CARES_LIB}") - else() - message(FATAL_ERROR "Couldn't find system c-ares") - endif() + find_path(CARES_INCLUDE NAMES cares/ares.h) + find_library(CARES_LIB NAMES libcares.a) + if(CARES_INCLUDE AND CARES_LIB) + message(STATUS "Found c-ares: include: ${CARES_INCLUDE}, lib: ${CARES_LIB}") + else() + message(FATAL_ERROR "Couldn't find system c-ares") + endif() else() - set(CARES_SRC "${PROJECT_BINARY_DIR}/c-ares-prefix/src/c-ares") - message(STATUS "Using bundled c-ares in '${CARES_SRC}'") - set(CARES_INCLUDE "${CARES_SRC}/target/include") - set(CARES_LIB "${CARES_SRC}/target/lib/libcares.a") - ExternalProject_Add(c-ares - URL "https://download.sysdig.com/dependencies/c-ares-1.13.0.tar.gz" - URL_MD5 "d2e010b43537794d8bedfb562ae6bba2" - CONFIGURE_COMMAND ./configure --prefix=${CARES_SRC}/target - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - BUILD_BYPRODUCTS ${CARES_INCLUDE} ${CARES_LIB} - INSTALL_COMMAND ${CMD_MAKE} install) + set(CARES_SRC "${PROJECT_BINARY_DIR}/c-ares-prefix/src/c-ares") + message(STATUS "Using bundled c-ares in '${CARES_SRC}'") + set(CARES_INCLUDE "${CARES_SRC}/target/include") + set(CARES_LIB "${CARES_SRC}/target/lib/libcares.a") + ExternalProject_Add( + c-ares + URL "https://download.sysdig.com/dependencies/c-ares-1.13.0.tar.gz" + URL_MD5 "d2e010b43537794d8bedfb562ae6bba2" + CONFIGURE_COMMAND ./configure --prefix=${CARES_SRC}/target + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + BUILD_BYPRODUCTS ${CARES_INCLUDE} ${CARES_LIB} + INSTALL_COMMAND ${CMD_MAKE} install) endif() -option(USE_BUNDLED_PROTOBUF "Enable building of the bundled protobuf" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_PROTOBUF "Enable building of the bundled protobuf" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_PROTOBUF) - find_program(PROTOC NAMES protoc) - find_path(PROTOBUF_INCLUDE NAMES google/protobuf/message.h) - find_library(PROTOBUF_LIB NAMES libprotobuf.a) - if(PROTOC AND PROTOBUF_INCLUDE AND PROTOBUF_LIB) - message(STATUS "Found protobuf: compiler: ${PROTOC}, include: ${PROTOBUF_INCLUDE}, lib: ${PROTOBUF_LIB}") - else() - message(FATAL_ERROR "Couldn't find system protobuf") - endif() + find_program(PROTOC NAMES protoc) + find_path(PROTOBUF_INCLUDE NAMES google/protobuf/message.h) + find_library(PROTOBUF_LIB NAMES libprotobuf.a) + if(PROTOC AND PROTOBUF_INCLUDE AND PROTOBUF_LIB) + message( + STATUS + "Found protobuf: compiler: ${PROTOC}, include: ${PROTOBUF_INCLUDE}, lib: ${PROTOBUF_LIB}" + ) + else() + message(FATAL_ERROR "Couldn't find system protobuf") + endif() else() - set(PROTOBUF_SRC "${PROJECT_BINARY_DIR}/protobuf-prefix/src/protobuf") - message(STATUS "Using bundled protobuf in '${PROTOBUF_SRC}'") - set(PROTOC "${PROTOBUF_SRC}/target/bin/protoc") - set(PROTOBUF_INCLUDE "${PROTOBUF_SRC}/target/include") - set(PROTOBUF_LIB "${PROTOBUF_SRC}/target/lib/libprotobuf.a") - ExternalProject_Add(protobuf - DEPENDS openssl zlib - URL "https://github.com/google/protobuf/releases/download/v3.5.0/protobuf-cpp-3.5.0.tar.gz" - URL_MD5 "e4ba8284a407712168593e79e6555eb2" - # TODO what if using system zlib? - CONFIGURE_COMMAND /usr/bin/env CPPFLAGS=-I${ZLIB_INCLUDE} LDFLAGS=-L${ZLIB_SRC} ./configure --with-zlib --prefix=${PROTOBUF_SRC}/target - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - BUILD_BYPRODUCTS ${PROTOC} ${PROTOBUF_INCLUDE} ${PROTOBUF_LIB} - # TODO s390x support - INSTALL_COMMAND make install) + set(PROTOBUF_SRC "${PROJECT_BINARY_DIR}/protobuf-prefix/src/protobuf") + message(STATUS "Using bundled protobuf in '${PROTOBUF_SRC}'") + set(PROTOC "${PROTOBUF_SRC}/target/bin/protoc") + set(PROTOBUF_INCLUDE "${PROTOBUF_SRC}/target/include") + set(PROTOBUF_LIB "${PROTOBUF_SRC}/target/lib/libprotobuf.a") + ExternalProject_Add( + protobuf + DEPENDS openssl zlib + URL + "https://github.com/google/protobuf/releases/download/v3.5.0/protobuf-cpp-3.5.0.tar.gz" + URL_MD5 "e4ba8284a407712168593e79e6555eb2" + # TODO what if using system zlib? + CONFIGURE_COMMAND /usr/bin/env + CPPFLAGS=-I${ZLIB_INCLUDE} + LDFLAGS=-L${ZLIB_SRC} + ./configure + --with-zlib + --prefix=${PROTOBUF_SRC}/target + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + BUILD_BYPRODUCTS ${PROTOC} ${PROTOBUF_INCLUDE} ${PROTOBUF_LIB} + # TODO s390x support + INSTALL_COMMAND make install) endif() -option(USE_BUNDLED_GRPC "Enable building of the bundled grpc" ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_GRPC "Enable building of the bundled grpc" + ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_GRPC) - find_path(GRPC_INCLUDE grpc++/impl/codegen/rpc_method.h) - find_library(GRPC_LIB NAMES libgrpc_unsecure.a) - find_library(GRPCPP_LIB NAMES libgrpc++_unsecure.a) - if(GRPC_INCLUDE AND GRPC_LIB AND GRPCPP_LIB) - message(STATUS "Found grpc: include: ${GRPC_INCLUDE}, C lib: ${GRPC_LIB}, C++ lib: ${GRPC_PP_LIB}") - else() - message(FATAL_ERROR "Couldn't find system grpc") - endif() - find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin) - if(NOT GRPC_CPP_PLUGIN) - message(FATAL_ERROR "System grpc_cpp_plugin not found") - endif() + find_path(GRPC_INCLUDE grpc++/impl/codegen/rpc_method.h) + find_library(GRPC_LIB NAMES libgrpc_unsecure.a) + find_library(GRPCPP_LIB NAMES libgrpc++_unsecure.a) + if(GRPC_INCLUDE AND GRPC_LIB AND GRPCPP_LIB) + message( + STATUS + "Found grpc: include: ${GRPC_INCLUDE}, C lib: ${GRPC_LIB}, C++ lib: ${GRPC_PP_LIB}" + ) + else() + message(FATAL_ERROR "Couldn't find system grpc") + endif() + find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin) + if(NOT GRPC_CPP_PLUGIN) + message(FATAL_ERROR "System grpc_cpp_plugin not found") + endif() else() - set(GRPC_SRC "${PROJECT_BINARY_DIR}/grpc-prefix/src/grpc") - message(STATUS "Using bundled grpc in '${GRPC_SRC}'") - set(GRPC_INCLUDE "${GRPC_SRC}/include") - set(GRPC_LIB "${GRPC_SRC}/libs/opt/libgrpc_unsecure.a") - set(GRPCPP_LIB "${GRPC_SRC}/libs/opt/libgrpc++_unsecure.a") - set(GRPC_CPP_PLUGIN "${GRPC_SRC}/bins/opt/grpc_cpp_plugin") - - get_filename_component(PROTOC_DIR ${PROTOC} DIRECTORY) - - ExternalProject_Add(grpc - DEPENDS protobuf zlib c-ares - URL "http://download.draios.com/dependencies/grpc-1.8.1.tar.gz" - URL_MD5 "2fc42c182a0ed1b48ad77397f76bb3bc" - CONFIGURE_COMMAND "" - # TODO what if using system openssl, protobuf or cares? - BUILD_COMMAND sh -c "CFLAGS=-Wno-implicit-fallthrough CXXFLAGS=\"-Wno-ignored-qualifiers -Wno-stringop-truncation\" HAS_SYSTEM_ZLIB=false LDFLAGS=-static PATH=${PROTOC_DIR}:$ENV{PATH} PKG_CONFIG_PATH=${OPENSSL_BUNDLE_DIR}:${PROTOBUF_SRC}:${CARES_SRC} make grpc_cpp_plugin static_cxx static_c" - BUILD_IN_SOURCE 1 - BUILD_BYPRODUCTS ${GRPC_LIB} ${GRPCPP_LIB} - # TODO s390x support - # TODO what if using system zlib - PATCH_COMMAND rm -rf third_party/zlib && ln -s ${ZLIB_SRC} third_party/zlib && wget https://download.sysdig.com/dependencies/grpc-1.1.4-Makefile.patch && patch < grpc-1.1.4-Makefile.patch - INSTALL_COMMAND "") + set(GRPC_SRC "${PROJECT_BINARY_DIR}/grpc-prefix/src/grpc") + message(STATUS "Using bundled grpc in '${GRPC_SRC}'") + set(GRPC_INCLUDE "${GRPC_SRC}/include") + set(GRPC_LIB "${GRPC_SRC}/libs/opt/libgrpc_unsecure.a") + set(GRPCPP_LIB "${GRPC_SRC}/libs/opt/libgrpc++_unsecure.a") + set(GRPC_CPP_PLUGIN "${GRPC_SRC}/bins/opt/grpc_cpp_plugin") + + get_filename_component(PROTOC_DIR ${PROTOC} DIRECTORY) + + ExternalProject_Add( + grpc + DEPENDS protobuf zlib c-ares + URL "http://download.draios.com/dependencies/grpc-1.8.1.tar.gz" + URL_MD5 "2fc42c182a0ed1b48ad77397f76bb3bc" + CONFIGURE_COMMAND "" + # TODO what if using system openssl, protobuf or cares? + BUILD_COMMAND + sh -c + "CFLAGS=-Wno-implicit-fallthrough CXXFLAGS=\"-Wno-ignored-qualifiers -Wno-stringop-truncation\" HAS_SYSTEM_ZLIB=false LDFLAGS=-static PATH=${PROTOC_DIR}:$ENV{PATH} PKG_CONFIG_PATH=${OPENSSL_BUNDLE_DIR}:${PROTOBUF_SRC}:${CARES_SRC} make grpc_cpp_plugin static_cxx static_c" + BUILD_IN_SOURCE 1 + BUILD_BYPRODUCTS ${GRPC_LIB} ${GRPCPP_LIB} + # TODO s390x support + # TODO what if using system zlib + PATCH_COMMAND + rm + -rf + third_party/zlib + && + ln + -s + ${ZLIB_SRC} + third_party/zlib + && + wget + https://download.sysdig.com/dependencies/grpc-1.1.4-Makefile.patch + && + patch + < + grpc-1.1.4-Makefile.patch + INSTALL_COMMAND "") endif() - -install(FILES falco.yaml - DESTINATION "${FALCO_ETC_DIR}") +install(FILES falco.yaml DESTINATION "${FALCO_ETC_DIR}") add_subdirectory(test) add_subdirectory(rules) add_subdirectory(docker) -# Add path for custom CMake modules used to build dependencies from Sysdig (libscap, libsinsp) -list(APPEND CMAKE_MODULE_PATH - "${SYSDIG_DIR}/cmake/modules") +# Add path for custom CMake modules used to build dependencies from Sysdig +# (libscap, libsinsp) +list(APPEND CMAKE_MODULE_PATH "${SYSDIG_DIR}/cmake/modules") # Add path for custom CMake modules -list(APPEND CMAKE_MODULE_PATH - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") if(CMAKE_SYSTEM_NAME MATCHES "Linux") - add_subdirectory("${SYSDIG_DIR}/driver" "${PROJECT_BINARY_DIR}/driver") - include(FindMakedev) + add_subdirectory("${SYSDIG_DIR}/driver" "${PROJECT_BINARY_DIR}/driver") + include(FindMakedev) endif() -add_subdirectory("${SYSDIG_DIR}/userspace/libscap" "${PROJECT_BINARY_DIR}/userspace/libscap") -add_subdirectory("${SYSDIG_DIR}/userspace/libsinsp" "${PROJECT_BINARY_DIR}/userspace/libsinsp") +add_subdirectory("${SYSDIG_DIR}/userspace/libscap" + "${PROJECT_BINARY_DIR}/userspace/libscap") +add_subdirectory("${SYSDIG_DIR}/userspace/libsinsp" + "${PROJECT_BINARY_DIR}/userspace/libsinsp") set(FALCO_SINSP_LIBRARY sinsp) set(FALCO_SHARE_DIR share/falco) @@ -630,13 +803,15 @@ add_subdirectory(userspace/engine) add_subdirectory(userspace/falco) add_subdirectory(tests) - set(CPACK_PACKAGE_NAME "${PACKAGE_NAME}") set(CPACK_PACKAGE_VENDOR "Sysdig Inc.") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "falco, a system-level activity monitoring tool") -set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/scripts/description.txt") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "falco, a system-level activity monitoring tool") +set(CPACK_PACKAGE_DESCRIPTION_FILE + "${PROJECT_SOURCE_DIR}/scripts/description.txt") set(CPACK_PACKAGE_VERSION "${FALCO_VERSION}") -set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_PROCESSOR}") +set(CPACK_PACKAGE_FILE_NAME + "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_PROCESSOR}") set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_SOURCE_DIR}/CMakeCPackOptions.cmake") set(CPACK_STRIP_FILES "ON") set(CPACK_PACKAGE_RELOCATABLE "OFF") @@ -647,15 +822,30 @@ set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Sysdig ") set(CPACK_DEBIAN_PACKAGE_SECTION "utils") set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://www.sysdig.org") set(CPACK_DEBIAN_PACKAGE_DEPENDS "dkms (>= 2.1.0.0)") -set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_BINARY_DIR}/scripts/debian/postinst;${CMAKE_BINARY_DIR}/scripts/debian/prerm;${PROJECT_SOURCE_DIR}/scripts/debian/postrm;${PROJECT_SOURCE_DIR}/cpack/debian/conffiles") +set( + CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA + "${CMAKE_BINARY_DIR}/scripts/debian/postinst;${CMAKE_BINARY_DIR}/scripts/debian/prerm;${PROJECT_SOURCE_DIR}/scripts/debian/postrm;${PROJECT_SOURCE_DIR}/cpack/debian/conffiles" + ) set(CPACK_RPM_PACKAGE_LICENSE "Apache v2.0") set(CPACK_RPM_PACKAGE_URL "http://www.sysdig.org") set(CPACK_RPM_PACKAGE_REQUIRES "dkms, gcc, make, kernel-devel, perl") -set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/scripts/rpm/postinstall") -set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/scripts/rpm/preuninstall") -set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/scripts/rpm/postuninstall") -set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /usr/src /usr/share/man /usr/share/man/man8 /etc /usr /usr/bin /usr/share /etc/rc.d /etc/rc.d/init.d ) +set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE + "${PROJECT_SOURCE_DIR}/scripts/rpm/postinstall") +set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE + "${PROJECT_SOURCE_DIR}/scripts/rpm/preuninstall") +set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE + "${PROJECT_SOURCE_DIR}/scripts/rpm/postuninstall") +set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION + /usr/src + /usr/share/man + /usr/share/man/man8 + /etc + /usr + /usr/bin + /usr/share + /etc/rc.d + /etc/rc.d/init.d) set(CPACK_RPM_PACKAGE_RELOCATABLE "OFF") include(CPack) diff --git a/cmake/modules/Catch.cmake b/cmake/modules/Catch.cmake index 486e323318c..2ee56e631d8 100644 --- a/cmake/modules/Catch.cmake +++ b/cmake/modules/Catch.cmake @@ -92,15 +92,13 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``. #]=======================================================================] -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ function(catch_discover_tests TARGET) - cmake_parse_arguments( - "" - "" - "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST" - "TEST_SPEC;EXTRA_ARGS;PROPERTIES" - ${ARGN} - ) + cmake_parse_arguments("" + "" + "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST" + "TEST_SPEC;EXTRA_ARGS;PROPERTIES" + ${ARGN}) if(NOT _WORKING_DIRECTORY) set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") @@ -109,67 +107,78 @@ function(catch_discover_tests TARGET) set(_TEST_LIST ${TARGET}_TESTS) endif() - ## Generate a unique name based on the extra arguments + # Generate a unique name based on the extra arguments string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS}") - string(SUBSTRING ${args_hash} 0 7 args_hash) + string(SUBSTRING ${args_hash} + 0 + 7 + args_hash) # Define rule to generate test list for aforementioned test executable - set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake") - set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake") + set(ctest_include_file + "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake") + set(ctest_tests_file + "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake") get_property(crosscompiling_emulator - TARGET ${TARGET} - PROPERTY CROSSCOMPILING_EMULATOR - ) - add_custom_command( - TARGET ${TARGET} POST_BUILD - BYPRODUCTS "${ctest_tests_file}" - COMMAND "${CMAKE_COMMAND}" - -D "TEST_TARGET=${TARGET}" - -D "TEST_EXECUTABLE=$" - -D "TEST_EXECUTOR=${crosscompiling_emulator}" - -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" - -D "TEST_SPEC=${_TEST_SPEC}" - -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" - -D "TEST_PROPERTIES=${_PROPERTIES}" - -D "TEST_PREFIX=${_TEST_PREFIX}" - -D "TEST_SUFFIX=${_TEST_SUFFIX}" - -D "TEST_LIST=${_TEST_LIST}" - -D "CTEST_FILE=${ctest_tests_file}" - -P "${_CATCH_DISCOVER_TESTS_SCRIPT}" - VERBATIM - ) - - file(WRITE "${ctest_include_file}" + TARGET ${TARGET} + PROPERTY CROSSCOMPILING_EMULATOR) + add_custom_command(TARGET + ${TARGET} + POST_BUILD + BYPRODUCTS + "${ctest_tests_file}" + COMMAND "${CMAKE_COMMAND}" + -D + "TEST_TARGET=${TARGET}" + -D + "TEST_EXECUTABLE=$" + -D + "TEST_EXECUTOR=${crosscompiling_emulator}" + -D + "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" + -D + "TEST_SPEC=${_TEST_SPEC}" + -D + "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" + -D + "TEST_PROPERTIES=${_PROPERTIES}" + -D + "TEST_PREFIX=${_TEST_PREFIX}" + -D + "TEST_SUFFIX=${_TEST_SUFFIX}" + -D + "TEST_LIST=${_TEST_LIST}" + -D + "CTEST_FILE=${ctest_tests_file}" + -P + "${_CATCH_DISCOVER_TESTS_SCRIPT}" + VERBATIM) + + file( + WRITE "${ctest_include_file}" "if(EXISTS \"${ctest_tests_file}\")\n" " include(\"${ctest_tests_file}\")\n" "else()\n" " add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n" - "endif()\n" - ) + "endif()\n") - if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0") + if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0") # Add discovered tests to directory TEST_INCLUDE_FILES set_property(DIRECTORY - APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}" - ) + APPEND + PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}") else() # Add discovered tests as directory TEST_INCLUDE_FILE if possible get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET) - if (NOT ${test_include_file_set}) - set_property(DIRECTORY - PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}" - ) + if(NOT ${test_include_file_set}) + set_property(DIRECTORY PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}") else() - message(FATAL_ERROR - "Cannot set more than one TEST_INCLUDE_FILE" - ) + message(FATAL_ERROR "Cannot set more than one TEST_INCLUDE_FILE") endif() endif() endfunction() -############################################################################### +# ############################################################################## -set(_CATCH_DISCOVER_TESTS_SCRIPT - ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake -) +set(_CATCH_DISCOVER_TESTS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake) diff --git a/cmake/modules/CatchAddTests.cmake b/cmake/modules/CatchAddTests.cmake index 2220ce3ac6b..05f2d1bd024 100644 --- a/cmake/modules/CatchAddTests.cmake +++ b/cmake/modules/CatchAddTests.cmake @@ -24,49 +24,50 @@ endfunction() # Run test executable to get list of available tests if(NOT EXISTS "${TEST_EXECUTABLE}") - message(FATAL_ERROR - "Specified test executable '${TEST_EXECUTABLE}' does not exist" - ) + message( + FATAL_ERROR "Specified test executable '${TEST_EXECUTABLE}' does not exist") endif() -execute_process( - COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only - OUTPUT_VARIABLE output - RESULT_VARIABLE result -) -# Catch --list-test-names-only reports the number of tests, so 0 is... surprising +execute_process(COMMAND ${TEST_EXECUTOR} + "${TEST_EXECUTABLE}" + ${spec} + --list-test-names-only + OUTPUT_VARIABLE output + RESULT_VARIABLE result) +# Catch --list-test-names-only reports the number of tests, so 0 is... +# surprising if(${result} EQUAL 0) - message(WARNING - "Test executable '${TEST_EXECUTABLE}' contains no tests!\n" - ) + message(WARNING "Test executable '${TEST_EXECUTABLE}' contains no tests!\n") elseif(${result} LESS 0) - message(FATAL_ERROR - "Error running test executable '${TEST_EXECUTABLE}':\n" - " Result: ${result}\n" - " Output: ${output}\n" - ) + message(FATAL_ERROR "Error running test executable '${TEST_EXECUTABLE}':\n" + " Result: ${result}\n" " Output: ${output}\n") endif() -string(REPLACE "\n" ";" output "${output}") +string(REPLACE "\n" + ";" + output + "${output}") # Parse output foreach(line ${output}) set(test ${line}) # use escape commas to handle properly test cases with commans inside the name - string(REPLACE "," "\\," test_name ${test}) + string(REPLACE "," + "\\," + test_name + ${test}) # ...and add to script add_command(add_test - "${prefix}${test}${suffix}" - ${TEST_EXECUTOR} - "${TEST_EXECUTABLE}" - "${test_name}" - ${extra_args} - ) + "${prefix}${test}${suffix}" + ${TEST_EXECUTOR} + "${TEST_EXECUTABLE}" + "${test_name}" + ${extra_args}) add_command(set_tests_properties - "${prefix}${test}${suffix}" - PROPERTIES - WORKING_DIRECTORY "${TEST_WORKING_DIR}" - ${properties} - ) + "${prefix}${test}${suffix}" + PROPERTIES + WORKING_DIRECTORY + "${TEST_WORKING_DIR}" + ${properties}) list(APPEND tests "${prefix}${test}${suffix}") endforeach() diff --git a/cmake/modules/DownloadCatch.cmake b/cmake/modules/DownloadCatch.cmake new file mode 100644 index 00000000000..f1583b74d2a --- /dev/null +++ b/cmake/modules/DownloadCatch.cmake @@ -0,0 +1,39 @@ +# +# Copyright (C) 2016-2019 Draios Inc dba Sysdig. +# +# This file is part of falco . +# +# 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(ExternalProject) + +set(CATCH2_INCLUDE ${CMAKE_BINARY_DIR}/catch2-prefix/include) + +set(CATCH_EXTERNAL_URL + URL + https://github.com/catchorg/catch2/archive/v2.9.1.tar.gz + URL_HASH + MD5=4980778888fed635bf191d8a86f9f89c) + +ExternalProject_Add( + catch2 + PREFIX ${CMAKE_BINARY_DIR}/catch2-prefix + ${CATCH_EXTERNAL_URL} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND + ${CMAKE_COMMAND} + -E + copy + ${CMAKE_BINARY_DIR}/catch2-prefix/src/catch2/single_include/catch2/catch.hpp + ${CATCH2_INCLUDE}/catch.hpp) diff --git a/cmake/modules/FindCatch.cmake b/cmake/modules/FindCatch.cmake deleted file mode 100644 index 88f18149f89..00000000000 --- a/cmake/modules/FindCatch.cmake +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (C) 2016-2019 Draios Inc dba Sysdig. -# -# This file is part of falco . -# -# 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(ExternalProject) - -set(CATCH_EXTERNAL_URL - URL https://github.com/catchorg/Catch2/archive/v2.9.1.tar.gz - URL_HASH MD5=4980778888fed635bf191d8a86f9f89c) -ExternalProject_Add(catch2 - PREFIX ${CMAKE_BINARY_DIR}/catch2-prefix - ${CATCH_EXTERNAL_URL} - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/catch2-prefix/src/catch2/single_include/catch2/catch.hpp - ${CMAKE_BINARY_DIR}/catch2-prefix/include/catch.hpp -) -add_library(catch INTERFACE) -add_dependencies(catch catch2) -target_include_directories(catch INTERFACE ${CMAKE_BINARY_DIR}/catch2-prefix/include) - diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2cd30967c18..5919f5115c9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,52 +3,46 @@ # # This file is part of falco . # -# 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 +# 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 +# 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. +# 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. # -set(FALCO_TESTS_SOURCES - test_base.cpp - engine/test_token_bucket.cpp) +set(FALCO_TESTS_SOURCES test_base.cpp engine/test_token_bucket.cpp) -set(FALCO_TESTED_LIBRARIES - falco_engine) +set(FALCO_TESTED_LIBRARIES falco_engine) option(FALCO_BUILD_TESTS "Determines whether to build tests." ON) if(FALCO_BUILD_TESTS) - enable_testing() - if(NOT TARGET catch) - include(FindCatch) - endif() - - add_executable(falco_test ${FALCO_TESTS_SOURCES}) - - target_link_libraries(falco_test PUBLIC ${FALCO_TESTED_LIBRARIES} catch) - target_include_directories(falco_test PUBLIC - "${SYSDIG_DIR}/userspace/libsinsp/third-party/jsoncpp" - "${SYSDIG_DIR}/userspace/libscap" - "${SYSDIG_DIR}/userspace/libsinsp" - "${LUAJIT_INCLUDE}" - "${NJSON_INCLUDE}" - "${CURL_INCLUDE_DIR}" - "${TBB_INCLUDE_DIR}" - "${LUAJIT_INCLUDE}" - "${NJSON_INCLUDE}" - "${PROJECT_SOURCE_DIR}/userspace/engine" - ) - - include(CTest) - include(Catch) - catch_discover_tests(falco_test) - - add_custom_target(tests COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS falco_test) + enable_testing() + if(NOT TARGET catch) + include(DownloadCatch) + endif() + + if(NOT TARGET fakeit) + include(DownloadFakeIt) + endif() + + add_executable(falco_test ${FALCO_TESTS_SOURCES}) + + target_link_libraries(falco_test PUBLIC ${FALCO_TESTED_LIBRARIES}) + target_include_directories( + falco_test + PUBLIC "${CATCH2_INCLUDE}" + "${FAKEIT_INCLUDE}" + "${PROJECT_SOURCE_DIR}/userspace/engine") + + include(CTest) + include(Catch) + catch_discover_tests(falco_test) + + add_custom_target(tests COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS falco_test) endif() From a09f71b457c0e2065ded72ed959e4c9f169634da Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Thu, 27 Jun 2019 10:34:47 +0000 Subject: [PATCH 36/64] new: dependency inject the timer for token bucket Co-Authored-By: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- userspace/engine/token_bucket.cpp | 64 +++++++++--------- userspace/engine/token_bucket.h | 106 ++++++++++++++++-------------- 2 files changed, 86 insertions(+), 84 deletions(-) diff --git a/userspace/engine/token_bucket.cpp b/userspace/engine/token_bucket.cpp index ec6025de05c..6dd7ea00cab 100644 --- a/userspace/engine/token_bucket.cpp +++ b/userspace/engine/token_bucket.cpp @@ -18,14 +18,20 @@ limitations under the License. */ #include +#include #include -#include "utils.h" #include "token_bucket.h" +#include "utils.h" + +token_bucket::token_bucket() : token_bucket(sinsp_utils::get_current_time_ns) +{ +} -token_bucket::token_bucket() +token_bucket::token_bucket(std::function timer) { - init(1, 1); + m_timer = timer; + init(1, 1); } token_bucket::~token_bucket() @@ -34,59 +40,51 @@ token_bucket::~token_bucket() void token_bucket::init(double rate, double max_tokens, uint64_t now) { - m_rate = rate; - m_max_tokens = max_tokens; - m_tokens = max_tokens; - - if(now == 0) - { - now = sinsp_utils::get_current_time_ns(); - } - - m_last_seen = now; + m_rate = rate; + m_max_tokens = max_tokens; + m_tokens = max_tokens; + m_last_seen = now == 0 ? m_timer() : now; } bool token_bucket::claim() { - uint64_t now = sinsp_utils::get_current_time_ns(); - - return claim(1, now); + return claim(1, m_timer()); } bool token_bucket::claim(double tokens, uint64_t now) { - double tokens_gained = m_rate * ((now - m_last_seen) / (1000000000.0)); - m_last_seen = now; + double tokens_gained = m_rate * ((now - m_last_seen) / (1000000000.0)); + m_last_seen = now; - m_tokens += tokens_gained; + m_tokens += tokens_gained; - // - // Cap at max_tokens - // - if(m_tokens > m_max_tokens) + // + // Cap at max_tokens + // + if(m_tokens > m_max_tokens) { - m_tokens = m_max_tokens; + m_tokens = m_max_tokens; } - // - // If m_tokens is < tokens, can't claim. - // - if(m_tokens < tokens) + // + // If m_tokens is < tokens, can't claim. + // + if(m_tokens < tokens) { - return false; + return false; } - m_tokens -= tokens; + m_tokens -= tokens; - return true; + return true; } double token_bucket::get_tokens() { - return m_tokens; + return m_tokens; } uint64_t token_bucket::get_last_seen() { - return m_last_seen; + return m_last_seen; } diff --git a/userspace/engine/token_bucket.h b/userspace/engine/token_bucket.h index bb36b3f6b40..03c4790ea56 100644 --- a/userspace/engine/token_bucket.h +++ b/userspace/engine/token_bucket.h @@ -20,59 +20,63 @@ limitations under the License. #pragma once #include +#include + +using token_timer = std::function; // A simple token bucket that accumulates tokens at a fixed rate and allows // for limited bursting in the form of "banked" tokens. class token_bucket { -public: - token_bucket(); - virtual ~token_bucket(); - - // - // Initialize the token bucket and start accumulating tokens - // - void init(double rate, double max_tokens, uint64_t now = 0); - - // - // Try to claim tokens tokens from the token bucket, using a - // timestamp of now. Returns true if the tokens could be - // claimed. Also updates internal metrics. - // - bool claim(double tokens, uint64_t now); - - // Simpler version of claim that claims a single token and - // uses the current time for now - bool claim(); - - // Return the current number of tokens available - double get_tokens(); - - // Return the last time someone tried to claim a token. - uint64_t get_last_seen(); - -private: - - // - // The number of tokens generated per second. - // - double m_rate; - - // - // The maximum number of tokens that can be banked for future - // claim()s. - // - double m_max_tokens; - - // - // The current number of tokens - // - double m_tokens; - - // - // The last time claim() was called (or the object was created). - // Nanoseconds since the epoch. - // - uint64_t m_last_seen; -}; - + public: + token_bucket(); + token_bucket(std::function timer); + virtual ~token_bucket(); + + // + // Initialize the token bucket and start accumulating tokens + // + void init(double rate, double max_tokens, uint64_t now = 0); + + // + // Try to claim tokens tokens from the token bucket, using a + // timestamp of now. Returns true if the tokens could be + // claimed. Also updates internal metrics. + // + bool claim(double tokens, uint64_t now); + + // Simpler version of claim that claims a single token and + // uses the current time for now + bool claim(); + + // Return the current number of tokens available + double get_tokens(); + + // Return the last time someone tried to claim a token. + uint64_t get_last_seen(); + + private: + std::function m_timer; + + // + // The number of tokens generated per second. + // + double m_rate; + + // + // The maximum number of tokens that can be banked for future + // claim()s. + // + double m_max_tokens; + + // + // The current number of tokens + // + double m_tokens; + + // + // The last time claim() was called (or the object was created). + // Nanoseconds since the epoch. + // + uint64_t m_last_seen; +}; \ No newline at end of file From 71b2fe6e149e2ab6e723c73120ca0cfd040a4618 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Thu, 27 Jun 2019 10:35:17 +0000 Subject: [PATCH 37/64] update: token bucket tests Co-authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- tests/engine/test_token_bucket.cpp | 41 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/tests/engine/test_token_bucket.cpp b/tests/engine/test_token_bucket.cpp index 553b1599495..412c996b535 100644 --- a/tests/engine/test_token_bucket.cpp +++ b/tests/engine/test_token_bucket.cpp @@ -21,15 +21,13 @@ limitations under the License. using namespace Catch::literals; -TEST_CASE("token bucket ctor", "[token_bucket]") -{ -} - -TEST_CASE("token bucket init", "[token_bucket]") +TEST_CASE("token bucket default ctor", "[token_bucket]") { auto tb = new token_bucket(); - SECTION("at specific time") + REQUIRE(tb->get_tokens() == 1); + + SECTION("initialising with specific time, rate 2 tokens/sec") { auto max = 2.0; uint64_t now = 1; @@ -37,38 +35,39 @@ TEST_CASE("token bucket init", "[token_bucket]") REQUIRE(tb->get_last_seen() == now); REQUIRE(tb->get_tokens() == max); } +} - SECTION("at current time") - { - // auto max = 2.0; - // tb->init(1.0, max, 0); - // REQUIRE(tb->get_last_seen() == ); - // REQUIRE(tb->get_tokens() == max); - } +TEST_CASE("token bucket ctor with custom timer", "[token_bucket]") +{ + auto t = []() -> uint64_t { return 22; }; + auto tb = new token_bucket(t); + + REQUIRE(tb->get_tokens() == 1); + REQUIRE(tb->get_last_seen() == 22); } -TEST_CASE("token bucket claim", "[token_bucket]") +TEST_CASE("token bucket with 2 tokens/sec rate, max 10 tokens", "[token_bucket]") { auto tb = new token_bucket(); - tb->init(2.0, 10.0, 1); + tb->init(2.0, 10, 1); - SECTION("...") + SECTION("claiming 5 tokens") { - bool claimed = tb->claim(5.0, 1000000001); + bool claimed = tb->claim(5, 1000000001); REQUIRE(tb->get_last_seen() == 1000000001); REQUIRE(tb->get_tokens() == 5.0_a); REQUIRE(claimed); - SECTION("xxx") + SECTION("claiming all the 7 remaining tokens") { - bool claimed = tb->claim(7.0, 2000000001); + bool claimed = tb->claim(7, 2000000001); REQUIRE(tb->get_last_seen() == 2000000001); REQUIRE(tb->get_tokens() == 0.0_a); REQUIRE(claimed); - SECTION(";;;") + SECTION("claiming 1 token more than the 2 available fails") { - bool claimed = tb->claim(3.0, 3000000001); + bool claimed = tb->claim(3, 3000000001); REQUIRE(tb->get_last_seen() == 3000000001); REQUIRE(tb->get_tokens() == 2.0_a); REQUIRE_FALSE(claimed); From 583be9ce226c49824ca186dda34393a88da9402c Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Thu, 27 Jun 2019 10:55:50 +0000 Subject: [PATCH 38/64] udpate: catch2 tests config Co-Authored-By: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- tests/test_base.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_base.cpp b/tests/test_base.cpp index a485d2fe84e..8048b15ffec 100644 --- a/tests/test_base.cpp +++ b/tests/test_base.cpp @@ -16,7 +16,9 @@ See the License for the specific language governing permissions and limitations under the License. */ #define CATCH_CONFIG_MAIN +#define CATCH_CONFIG_CONSOLE_WIDTH 300 #include -TEST_CASE( "1: All test cases reside in other .cpp files (empty)", "[multi-file:1]" ) { +TEST_CASE("all test cases reside in other .cpp files (empty)", "[multi-file:1]") +{ } From 9bc28951ad34b0cefe4d3c949c9fbaed872d5339 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Mon, 1 Jul 2019 10:11:27 +0000 Subject: [PATCH 39/64] update: revert formatting Co-authored-by: Leonardo Di Donato Signed-off-by: Lorenzo Fontana --- .cmake-format | 119 ---- CMakeCPackOptions.cmake | 44 +- CMakeLists.txt | 1042 ++++++++++++----------------- cmake/modules/Catch.cmake | 111 ++- cmake/modules/CatchAddTests.cmake | 61 +- cmake/modules/FindCatch.cmake | 34 + 6 files changed, 555 insertions(+), 856 deletions(-) delete mode 100644 .cmake-format create mode 100644 cmake/modules/FindCatch.cmake diff --git a/.cmake-format b/.cmake-format deleted file mode 100644 index e6484a15e30..00000000000 --- a/.cmake-format +++ /dev/null @@ -1,119 +0,0 @@ -# -------------------------- -# General Formatting Options -# -------------------------- -# How wide to allow formatted cmake files -line_width = 80 - -# How many spaces to tab for indent -tab_size = 2 - -# If arglists are longer than this, break them always -max_subargs_per_line = 3 - -# If true, separate flow control names from their parentheses with a space -separate_ctrl_name_with_space = False - -# If true, separate function names from parentheses with a space -separate_fn_name_with_space = False - -# If a statement is wrapped to more than one line, than dangle the closing -# parenthesis on it's own line -dangle_parens = False - -# If the statement spelling length (including space and parenthesis is larger -# than the tab width by more than this amoung, then force reject un-nested -# layouts. -max_prefix_chars = 2 - -# If a candidate layout is wrapped horizontally but it exceeds this many lines, -# then reject the layout. -max_lines_hwrap = 2 - -# What style line endings to use in the output. -line_ending = 'unix' - -# Format command names consistently as 'lower' or 'upper' case -command_case = 'canonical' - -# Format keywords consistently as 'lower' or 'upper' case -keyword_case = 'unchanged' - -# Specify structure for custom cmake functions -additional_commands = { - "pkg_find": { - "kwargs": { - "PKG": "*" - } - } -} - -# A list of command names which should always be wrapped -always_wrap = [] - -# Specify the order of wrapping algorithms during successive reflow attempts -algorithm_order = [0, 1, 2, 3, 4] - -# If true, the argument lists which are known to be sortable will be sorted -# lexicographicall -enable_sort = True - -# If true, the parsers may infer whether or not an argument list is sortable -# (without annotation). -autosort = False - -# If a comment line starts with at least this many consecutive hash characters, -# then don't lstrip() them off. This allows for lazy hash rulers where the first -# hash char is not separated by space -hashruler_min_length = 10 - -# A dictionary containing any per-command configuration overrides. Currently -# only `command_case` is supported. -per_command = {} - - -# -------------------------- -# Comment Formatting Options -# -------------------------- -# What character to use for bulleted lists -bullet_char = '*' - -# What character to use as punctuation after numerals in an enumerated list -enum_char = '.' - -# enable comment markup parsing and reflow -enable_markup = True - -# If comment markup is enabled, don't reflow the first comment block in each -# listfile. Use this to preserve formatting of your copyright/license -# statements. -first_comment_is_literal = False - -# If comment markup is enabled, don't reflow any comment block which matches -# this (regex) pattern. Default is `None` (disabled). -literal_comment_pattern = None - -# Regular expression to match preformat fences in comments -# default=r'^\s*([`~]{3}[`~]*)(.*)$' -fence_pattern = '^\\s*([`~]{3}[`~]*)(.*)$' - -# Regular expression to match rulers in comments -# default=r'^\s*[^\w\s]{3}.*[^\w\s]{3}$' -ruler_pattern = '^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$' - -# If true, then insert a space between the first hash char and remaining hash -# chars in a hash ruler, and normalize it's length to fill the column -canonicalize_hashrulers = True - - -# --------------------------------- -# Miscellaneous Options -# --------------------------------- -# If true, emit the unicode byte-order mark (BOM) at the start of the file -emit_byteorder_mark = False - -# Specify the encoding of the input file. Defaults to utf-8. -input_encoding = 'utf-8' - -# Specify the encoding of the output file. Defaults to utf-8. Note that cmake -# only claims to support utf-8 so be careful when using anything else -output_encoding = 'utf-8' \ No newline at end of file diff --git a/CMakeCPackOptions.cmake b/CMakeCPackOptions.cmake index 74150018d6d..ec32740cdeb 100644 --- a/CMakeCPackOptions.cmake +++ b/CMakeCPackOptions.cmake @@ -3,45 +3,29 @@ # # This file is part of falco . # -# 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 +# 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 +# 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. +# 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. # if(CPACK_GENERATOR MATCHES "DEB") - list( - APPEND - CPACK_INSTALL_COMMANDS - "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/init.d/" - ) - list( - APPEND - CPACK_INSTALL_COMMANDS - "cp scripts/debian/falco _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/init.d" - ) + list(APPEND CPACK_INSTALL_COMMANDS "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/init.d/") + list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/debian/falco _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/init.d") endif() if(CPACK_GENERATOR MATCHES "RPM") - list( - APPEND - CPACK_INSTALL_COMMANDS - "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/rc.d/init.d/" - ) - list( - APPEND - CPACK_INSTALL_COMMANDS - "cp scripts/rpm/falco _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/rc.d/init.d" - ) + list(APPEND CPACK_INSTALL_COMMANDS "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/rc.d/init.d/") + list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/rpm/falco _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/rc.d/init.d") endif() if(CPACK_GENERATOR MATCHES "TGZ") - set(CPACK_SET_DESTDIR "ON") - set(CPACK_STRIP_FILES "OFF") + set(CPACK_SET_DESTDIR "ON") + set(CPACK_STRIP_FILES "OFF") endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 263778d2e12..5c36ded022e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,17 +3,17 @@ # # This file is part of falco . # -# 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 +# 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 +# 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. +# 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. # cmake_minimum_required(VERSION 2.8.2) @@ -22,30 +22,26 @@ project(falco) option(BUILD_WARNINGS_AS_ERRORS "Enable building with -Wextra -Werror flags") if(NOT DEFINED FALCO_VERSION) - set(FALCO_VERSION "0.1.1dev") + set(FALCO_VERSION "0.1.1dev") endif() if(NOT DEFINED FALCO_ETC_DIR) - set(FALCO_ETC_DIR "/etc/falco") + set(FALCO_ETC_DIR "/etc/falco") endif() if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) + SET(CMAKE_BUILD_TYPE Release) endif() if(NOT DRAIOS_DEBUG_FLAGS) - set(DRAIOS_DEBUG_FLAGS "-D_DEBUG") + set(DRAIOS_DEBUG_FLAGS "-D_DEBUG") endif() set(CMAKE_COMMON_FLAGS "-Wall -ggdb ${DRAIOS_FEATURE_FLAGS}") if(BUILD_WARNINGS_AS_ERRORS) - set( - CMAKE_SUPPRESSED_WARNINGS - "-Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-type-limits -Wno-implicit-fallthrough -Wno-format-truncation" - ) - set(CMAKE_COMMON_FLAGS - "${CMAKE_COMMON_FLAGS} -Wextra -Werror ${CMAKE_SUPPRESSED_WARNINGS}") + set(CMAKE_SUPPRESSED_WARNINGS "-Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-type-limits -Wno-implicit-fallthrough -Wno-format-truncation") + set(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wextra -Werror ${CMAKE_SUPPRESSED_WARNINGS}") endif() set(CMAKE_C_FLAGS "${CMAKE_COMMON_FLAGS}") @@ -60,70 +56,65 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O3 -fno-strict-aliasing -DNDEBUG") add_definitions(-DPLATFORM_NAME="${CMAKE_SYSTEM_NAME}") add_definitions(-DK8S_DISABLE_THREAD) if(CMAKE_SYSTEM_NAME MATCHES "Linux") - add_definitions(-DHAS_CAPTURE) + add_definitions(-DHAS_CAPTURE) endif() if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(KBUILD_FLAGS "${DRAIOS_DEBUG_FLAGS} ${DRAIOS_FEATURE_FLAGS}") + set(KBUILD_FLAGS "${DRAIOS_DEBUG_FLAGS} ${DRAIOS_FEATURE_FLAGS}") else() - set(KBUILD_FLAGS "${DRAIOS_FEATURE_FLAGS}") + set(KBUILD_FLAGS "${DRAIOS_FEATURE_FLAGS}") endif() set(PACKAGE_NAME "falco") set(PROBE_VERSION "${FALCO_VERSION}") set(PROBE_NAME "falco-probe") set(PROBE_DEVICE_NAME "falco") -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX /usr CACHE PATH "Default install path" FORCE) +if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX /usr CACHE PATH "Default install path" FORCE) endif() set(CMD_MAKE make) if(NOT SYSDIG_DIR) - set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig") + set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig") endif() # make luaJIT work on OS X if(APPLE) - set(CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000") + set(CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000") endif() include(ExternalProject) -option(USE_BUNDLED_DEPS - "Enable bundled dependencies instead of using the system ones" ON) +option(USE_BUNDLED_DEPS "Enable bundled dependencies instead of using the system ones" ON) # # zlib # -option(USE_BUNDLED_ZLIB "Enable building of the bundled zlib" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_ZLIB "Enable building of the bundled zlib" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_ZLIB) - find_path(ZLIB_INCLUDE zlib.h PATH_SUFFIXES zlib) - find_library(ZLIB_LIB NAMES z) - if(ZLIB_INCLUDE AND ZLIB_LIB) - message(STATUS "Found zlib: include: ${ZLIB_INCLUDE}, lib: ${ZLIB_LIB}") - else() - message(FATAL_ERROR "Couldn't find system zlib") - endif() + find_path(ZLIB_INCLUDE zlib.h PATH_SUFFIXES zlib) + find_library(ZLIB_LIB NAMES z) + if(ZLIB_INCLUDE AND ZLIB_LIB) + message(STATUS "Found zlib: include: ${ZLIB_INCLUDE}, lib: ${ZLIB_LIB}") + else() + message(FATAL_ERROR "Couldn't find system zlib") + endif() else() - set(ZLIB_SRC "${PROJECT_BINARY_DIR}/zlib-prefix/src/zlib") - message(STATUS "Using bundled zlib in '${ZLIB_SRC}'") - set(ZLIB_INCLUDE "${ZLIB_SRC}") - set(ZLIB_LIB "${ZLIB_SRC}/libz.a") - ExternalProject_Add( - zlib - # START CHANGE for CVE-2016-9840, CVE-2016-9841, CVE-2016-9842, - # CVE-2016-9843 - URL - "http://s3.amazonaws.com/download.draios.com/dependencies/zlib-1.2.11.tar.gz" - URL_MD5 "1c9f62f0778697a09d36121ead88e08e" - # END CHANGE for CVE-2016-9840, CVE-2016-9841, CVE-2016-9842, CVE-2016-9843 - CONFIGURE_COMMAND "./configure" - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(ZLIB_SRC "${PROJECT_BINARY_DIR}/zlib-prefix/src/zlib") + message(STATUS "Using bundled zlib in '${ZLIB_SRC}'") + set(ZLIB_INCLUDE "${ZLIB_SRC}") + set(ZLIB_LIB "${ZLIB_SRC}/libz.a") + ExternalProject_Add(zlib + # START CHANGE for CVE-2016-9840, CVE-2016-9841, CVE-2016-9842, CVE-2016-9843 + URL "http://s3.amazonaws.com/download.draios.com/dependencies/zlib-1.2.11.tar.gz" + URL_MD5 "1c9f62f0778697a09d36121ead88e08e" + # END CHANGE for CVE-2016-9840, CVE-2016-9841, CVE-2016-9842, CVE-2016-9843 + CONFIGURE_COMMAND "./configure" + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # @@ -131,38 +122,26 @@ endif() # option(USE_BUNDLED_JQ "Enable building of the bundled jq" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_JQ) - find_path(JQ_INCLUDE jq.h PATH_SUFFIXES jq) - find_library(JQ_LIB NAMES jq) - if(JQ_INCLUDE AND JQ_LIB) - message(STATUS "Found jq: include: ${JQ_INCLUDE}, lib: ${JQ_LIB}") - else() - message(FATAL_ERROR "Couldn't find system jq") - endif() + find_path(JQ_INCLUDE jq.h PATH_SUFFIXES jq) + find_library(JQ_LIB NAMES jq) + if(JQ_INCLUDE AND JQ_LIB) + message(STATUS "Found jq: include: ${JQ_INCLUDE}, lib: ${JQ_LIB}") + else() + message(FATAL_ERROR "Couldn't find system jq") + endif() else() - set(JQ_SRC "${PROJECT_BINARY_DIR}/jq-prefix/src/jq") - message(STATUS "Using bundled jq in '${JQ_SRC}'") - set(JQ_INCLUDE "${JQ_SRC}") - set(JQ_LIB "${JQ_SRC}/.libs/libjq.a") - ExternalProject_Add( - jq - URL "http://s3.amazonaws.com/download.draios.com/dependencies/jq-1.5.tar.gz" - URL_MD5 "0933532b086bd8b6a41c1b162b1731f9" - CONFIGURE_COMMAND ./configure - --disable-maintainer-mode - --enable-all-static - --disable-dependency-tracking - BUILD_COMMAND ${CMD_MAKE} LDFLAGS=-all-static - BUILD_IN_SOURCE 1 - PATCH_COMMAND - wget - -O - jq-1.5-fix-tokenadd.patch - https://github.com/stedolan/jq/commit/8eb1367ca44e772963e704a700ef72ae2e12babd.patch - && - patch - -i - jq-1.5-fix-tokenadd.patch - INSTALL_COMMAND "") + set(JQ_SRC "${PROJECT_BINARY_DIR}/jq-prefix/src/jq") + message(STATUS "Using bundled jq in '${JQ_SRC}'") + set(JQ_INCLUDE "${JQ_SRC}") + set(JQ_LIB "${JQ_SRC}/.libs/libjq.a") + ExternalProject_Add(jq + URL "http://s3.amazonaws.com/download.draios.com/dependencies/jq-1.5.tar.gz" + URL_MD5 "0933532b086bd8b6a41c1b162b1731f9" + CONFIGURE_COMMAND ./configure --disable-maintainer-mode --enable-all-static --disable-dependency-tracking + BUILD_COMMAND ${CMD_MAKE} LDFLAGS=-all-static + BUILD_IN_SOURCE 1 + PATCH_COMMAND wget -O jq-1.5-fix-tokenadd.patch https://github.com/stedolan/jq/commit/8eb1367ca44e772963e704a700ef72ae2e12babd.patch && patch -i jq-1.5-fix-tokenadd.patch + INSTALL_COMMAND "") endif() set(JSONCPP_SRC "${SYSDIG_DIR}/userspace/libsinsp/third-party/jsoncpp") @@ -172,28 +151,27 @@ set(JSONCPP_LIB_SRC "${JSONCPP_SRC}/jsoncpp.cpp") # # nlohmann-json # -option(USE_BUNDLED_NJSON "Enable building of the bundled nlohmann-json" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_NJSON "Enable building of the bundled nlohmann-json" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_NJSON) - find_path(NJSON_INCLUDE json.hpp PATH_SUFFIXES nlohmann) - if(NJSON_INCLUDE) - message(STATUS "Found nlohmann-json: include: ${NJSON_INCLUDE}") - else() - message(FATAL_ERROR "Couldn't find system nlohmann-json") - endif() + find_path(NJSON_INCLUDE json.hpp PATH_SUFFIXES nlohmann) + if(NJSON_INCLUDE) + message(STATUS "Found nlohmann-json: include: ${NJSON_INCLUDE}") + else() + message(FATAL_ERROR "Couldn't find system nlohmann-json") + endif() else() - # No distinction needed for windows. The implementation is solely in json.hpp. - set(NJSON_SRC "${PROJECT_BINARY_DIR}/njson-prefix/src/njson") - message(STATUS "Using bundled nlohmann-json in '${NJSON_SRC}'") - set(NJSON_INCLUDE "${NJSON_SRC}/single_include") - ExternalProject_Add( - njson - URL "http://download.draios.com/dependencies/njson-3.3.0.tar.gz" - URL_MD5 "e26760e848656a5da400662e6c5d999a" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "") + # No distinction needed for windows. The implementation is + # solely in json.hpp. + set(NJSON_SRC "${PROJECT_BINARY_DIR}/njson-prefix/src/njson") + message(STATUS "Using bundled nlohmann-json in '${NJSON_SRC}'") + set(NJSON_INCLUDE "${NJSON_SRC}/single_include") + ExternalProject_Add(njson + URL "http://download.draios.com/dependencies/njson-3.3.0.tar.gz" + URL_MD5 "e26760e848656a5da400662e6c5d999a" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "") endif() # @@ -201,37 +179,24 @@ endif() # # we pull this in because libsinsp won't build without it -option(USE_BUNDLED_NCURSES "Enable building of the bundled ncurses" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_NCURSES "Enable building of the bundled ncurses" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_NCURSES) - set(CURSES_NEED_NCURSES TRUE) - find_package(Curses REQUIRED) - message( - STATUS - "Found ncurses: include: ${CURSES_INCLUDE_DIR}, lib: ${CURSES_LIBRARIES}") + set(CURSES_NEED_NCURSES TRUE) + find_package(Curses REQUIRED) + message(STATUS "Found ncurses: include: ${CURSES_INCLUDE_DIR}, lib: ${CURSES_LIBRARIES}") else() - set(CURSES_BUNDLE_DIR "${PROJECT_BINARY_DIR}/ncurses-prefix/src/ncurses") - set(CURSES_INCLUDE_DIR "${CURSES_BUNDLE_DIR}/include/") - set(CURSES_LIBRARIES "${CURSES_BUNDLE_DIR}/lib/libncurses.a") - message(STATUS "Using bundled ncurses in '${CURSES_BUNDLE_DIR}'") - ExternalProject_Add( - ncurses - URL - "http://s3.amazonaws.com/download.draios.com/dependencies/ncurses-6.0-20150725.tgz" - URL_MD5 "32b8913312e738d707ae68da439ca1f4" - CONFIGURE_COMMAND - ./configure - --without-cxx - --without-cxx-binding - --without-ada - --without-manpages - --without-progs - --without-tests - --with-terminfo-dirs=/etc/terminfo:/lib/terminfo:/usr/share/terminfo - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(CURSES_BUNDLE_DIR "${PROJECT_BINARY_DIR}/ncurses-prefix/src/ncurses") + set(CURSES_INCLUDE_DIR "${CURSES_BUNDLE_DIR}/include/") + set(CURSES_LIBRARIES "${CURSES_BUNDLE_DIR}/lib/libncurses.a") + message(STATUS "Using bundled ncurses in '${CURSES_BUNDLE_DIR}'") + ExternalProject_Add(ncurses + URL "http://s3.amazonaws.com/download.draios.com/dependencies/ncurses-6.0-20150725.tgz" + URL_MD5 "32b8913312e738d707ae68da439ca1f4" + CONFIGURE_COMMAND ./configure --without-cxx --without-cxx-binding --without-ada --without-manpages --without-progs --without-tests --with-terminfo-dirs=/etc/terminfo:/lib/terminfo:/usr/share/terminfo + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # @@ -240,559 +205,421 @@ endif() option(USE_BUNDLED_B64 "Enable building of the bundled b64" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_B64) - find_path(B64_INCLUDE NAMES b64/encode.h) - find_library(B64_LIB NAMES b64) - if(B64_INCLUDE AND B64_LIB) - message(STATUS "Found b64: include: ${B64_INCLUDE}, lib: ${B64_LIB}") - else() - message(FATAL_ERROR "Couldn't find system b64") - endif() + find_path(B64_INCLUDE NAMES b64/encode.h) + find_library(B64_LIB NAMES b64) + if(B64_INCLUDE AND B64_LIB) + message(STATUS "Found b64: include: ${B64_INCLUDE}, lib: ${B64_LIB}") + else() + message(FATAL_ERROR "Couldn't find system b64") + endif() else() - set(B64_SRC "${PROJECT_BINARY_DIR}/b64-prefix/src/b64") - message(STATUS "Using bundled b64 in '${B64_SRC}'") - set(B64_INCLUDE "${B64_SRC}/include") - set(B64_LIB "${B64_SRC}/src/libb64.a") - ExternalProject_Add( - b64 - URL - "http://s3.amazonaws.com/download.draios.com/dependencies/libb64-1.2.src.zip" - URL_MD5 "a609809408327117e2c643bed91b76c5" - CONFIGURE_COMMAND "" - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(B64_SRC "${PROJECT_BINARY_DIR}/b64-prefix/src/b64") + message(STATUS "Using bundled b64 in '${B64_SRC}'") + set(B64_INCLUDE "${B64_SRC}/include") + set(B64_LIB "${B64_SRC}/src/libb64.a") + ExternalProject_Add(b64 + URL "http://s3.amazonaws.com/download.draios.com/dependencies/libb64-1.2.src.zip" + URL_MD5 "a609809408327117e2c643bed91b76c5" + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # # yamlcpp # -option(USE_BUNDLED_YAMLCPP "Enable building of the bundled yamlcpp" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_YAMLCPP "Enable building of the bundled yamlcpp" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_YAMLCPP) - find_path(YAMLCPP_INCLUDE_DIR NAMES yaml-cpp/yaml.h) - find_library(YAMLCPP_LIB NAMES yaml-cpp) - if(YAMLCPP_INCLUDE_DIR AND YAMLCPP_LIB) - message( - STATUS - "Found yamlcpp: include: ${YAMLCPP_INCLUDE_DIR}, lib: ${YAMLCPP_LIB}") - else() - message(FATAL_ERROR "Couldn't find system yamlcpp") - endif() + find_path(YAMLCPP_INCLUDE_DIR NAMES yaml-cpp/yaml.h) + find_library(YAMLCPP_LIB NAMES yaml-cpp) + if(YAMLCPP_INCLUDE_DIR AND YAMLCPP_LIB) + message(STATUS "Found yamlcpp: include: ${YAMLCPP_INCLUDE_DIR}, lib: ${YAMLCPP_LIB}") + else() + message(FATAL_ERROR "Couldn't find system yamlcpp") + endif() else() - set(YAMLCPP_SRC "${PROJECT_BINARY_DIR}/yamlcpp-prefix/src/yamlcpp") - message(STATUS "Using bundled yaml-cpp in '${YAMLCPP_SRC}'") - set(YAMLCPP_LIB "${YAMLCPP_SRC}/libyaml-cpp.a") - set(YAMLCPP_INCLUDE_DIR "${YAMLCPP_SRC}/include") - ExternalProject_Add( - yamlcpp - URL - "https://s3.amazonaws.com/download.draios.com/dependencies/yaml-cpp-yaml-cpp-0.6.2.tar.gz" - URL_MD5 "5b943e9af0060d0811148b037449ef82" - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(YAMLCPP_SRC "${PROJECT_BINARY_DIR}/yamlcpp-prefix/src/yamlcpp") + message(STATUS "Using bundled yaml-cpp in '${YAMLCPP_SRC}'") + set(YAMLCPP_LIB "${YAMLCPP_SRC}/libyaml-cpp.a") + set(YAMLCPP_INCLUDE_DIR "${YAMLCPP_SRC}/include") + ExternalProject_Add(yamlcpp + URL "https://s3.amazonaws.com/download.draios.com/dependencies/yaml-cpp-yaml-cpp-0.6.2.tar.gz" + URL_MD5 "5b943e9af0060d0811148b037449ef82" + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # # OpenSSL # -option(USE_BUNDLED_OPENSSL "Enable building of the bundled OpenSSL" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_OPENSSL "Enable building of the bundled OpenSSL" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_OPENSSL) - find_package(OpenSSL REQUIRED) - message( - STATUS - "Found OpenSSL: include: ${OPENSSL_INCLUDE_DIR}, lib: ${OPENSSL_LIBRARIES}" - ) + find_package(OpenSSL REQUIRED) + message(STATUS "Found OpenSSL: include: ${OPENSSL_INCLUDE_DIR}, lib: ${OPENSSL_LIBRARIES}") else() - set(OPENSSL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl") - set(OPENSSL_INSTALL_DIR "${OPENSSL_BUNDLE_DIR}/target") - set(OPENSSL_INCLUDE_DIR - "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl/include") - set(OPENSSL_LIBRARY_SSL "${OPENSSL_INSTALL_DIR}/lib/libssl.a") - set(OPENSSL_LIBRARY_CRYPTO "${OPENSSL_INSTALL_DIR}/lib/libcrypto.a") - - message(STATUS "Using bundled openssl in '${OPENSSL_BUNDLE_DIR}'") - - ExternalProject_Add( - openssl - # START CHANGE for CVE-2017-3735, CVE-2017-3731, CVE-2017-3737, - # CVE-2017-3738, CVE-2017-3736 - URL - "http://s3.amazonaws.com/download.draios.com/dependencies/openssl-1.0.2n.tar.gz" - URL_MD5 "13bdc1b1d1ff39b6fd42a255e74676a4" - # END CHANGE for CVE-2017-3735, CVE-2017-3731, CVE-2017-3737, CVE-2017-3738, - # CVE-2017-3736 - CONFIGURE_COMMAND ./config shared --prefix=${OPENSSL_INSTALL_DIR} - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND ${CMD_MAKE} install) + set(OPENSSL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl") + set(OPENSSL_INSTALL_DIR "${OPENSSL_BUNDLE_DIR}/target") + set(OPENSSL_INCLUDE_DIR "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl/include") + set(OPENSSL_LIBRARY_SSL "${OPENSSL_INSTALL_DIR}/lib/libssl.a") + set(OPENSSL_LIBRARY_CRYPTO "${OPENSSL_INSTALL_DIR}/lib/libcrypto.a") + + message(STATUS "Using bundled openssl in '${OPENSSL_BUNDLE_DIR}'") + + ExternalProject_Add(openssl + # START CHANGE for CVE-2017-3735, CVE-2017-3731, CVE-2017-3737, CVE-2017-3738, CVE-2017-3736 + URL "http://s3.amazonaws.com/download.draios.com/dependencies/openssl-1.0.2n.tar.gz" + URL_MD5 "13bdc1b1d1ff39b6fd42a255e74676a4" + # END CHANGE for CVE-2017-3735, CVE-2017-3731, CVE-2017-3737, CVE-2017-3738, CVE-2017-3736 + CONFIGURE_COMMAND ./config shared --prefix=${OPENSSL_INSTALL_DIR} + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND ${CMD_MAKE} install) endif() # # libcurl # -option(USE_BUNDLED_CURL "Enable building of the bundled curl" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_CURL "Enable building of the bundled curl" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_CURL) - find_package(CURL REQUIRED) - message( - STATUS "Found CURL: include: ${CURL_INCLUDE_DIR}, lib: ${CURL_LIBRARIES}") + find_package(CURL REQUIRED) + message(STATUS "Found CURL: include: ${CURL_INCLUDE_DIR}, lib: ${CURL_LIBRARIES}") else() - set(CURL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/curl-prefix/src/curl") - set(CURL_INCLUDE_DIR "${CURL_BUNDLE_DIR}/include/") - set(CURL_LIBRARIES "${CURL_BUNDLE_DIR}/lib/.libs/libcurl.a") - - if(NOT USE_BUNDLED_OPENSSL) - set(CURL_SSL_OPTION "--with-ssl") - else() - set(CURL_SSL_OPTION "--with-ssl=${OPENSSL_INSTALL_DIR}") - message(STATUS "Using bundled curl in '${CURL_BUNDLE_DIR}'") - message(STATUS "Using SSL for curl in '${CURL_SSL_OPTION}'") - endif() - - ExternalProject_Add( - curl - DEPENDS openssl - # START CHANGE for CVE-2017-8816, CVE-2017-8817, CVE-2017-8818, - # CVE-2018-1000007 - URL - "http://s3.amazonaws.com/download.draios.com/dependencies/curl-7.61.0.tar.bz2" - URL_MD5 "31d0a9f48dc796a7db351898a1e5058a" - # END CHANGE for CVE-2017-8816, CVE-2017-8817, CVE-2017-8818, - # CVE-2018-1000007 - CONFIGURE_COMMAND ./configure - ${CURL_SSL_OPTION} - --disable-shared - --enable-optimize - --disable-curldebug - --disable-rt - --enable-http - --disable-ftp - --disable-file - --disable-ldap - --disable-ldaps - --disable-rtsp - --disable-telnet - --disable-tftp - --disable-pop3 - --disable-imap - --disable-smb - --disable-smtp - --disable-gopher - --disable-sspi - --disable-ntlm-wb - --disable-tls-srp - --without-winssl - --without-darwinssl - --without-polarssl - --without-cyassl - --without-nss - --without-axtls - --without-ca-path - --without-ca-bundle - --without-libmetalink - --without-librtmp - --without-winidn - --without-libidn2 - --without-libpsl - --without-nghttp2 - --without-libssh2 - --disable-threaded-resolver - --without-brotli - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(CURL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/curl-prefix/src/curl") + set(CURL_INCLUDE_DIR "${CURL_BUNDLE_DIR}/include/") + set(CURL_LIBRARIES "${CURL_BUNDLE_DIR}/lib/.libs/libcurl.a") + + if(NOT USE_BUNDLED_OPENSSL) + set(CURL_SSL_OPTION "--with-ssl") + else() + set(CURL_SSL_OPTION "--with-ssl=${OPENSSL_INSTALL_DIR}") + message(STATUS "Using bundled curl in '${CURL_BUNDLE_DIR}'") + message(STATUS "Using SSL for curl in '${CURL_SSL_OPTION}'") + endif() + + ExternalProject_Add(curl + DEPENDS openssl + # START CHANGE for CVE-2017-8816, CVE-2017-8817, CVE-2017-8818, CVE-2018-1000007 + URL "http://s3.amazonaws.com/download.draios.com/dependencies/curl-7.61.0.tar.bz2" + URL_MD5 "31d0a9f48dc796a7db351898a1e5058a" + # END CHANGE for CVE-2017-8816, CVE-2017-8817, CVE-2017-8818, CVE-2018-1000007 + CONFIGURE_COMMAND ./configure ${CURL_SSL_OPTION} --disable-shared --enable-optimize --disable-curldebug --disable-rt --enable-http --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-sspi --disable-ntlm-wb --disable-tls-srp --without-winssl --without-darwinssl --without-polarssl --without-cyassl --without-nss --without-axtls --without-ca-path --without-ca-bundle --without-libmetalink --without-librtmp --without-winidn --without-libidn2 --without-libpsl --without-nghttp2 --without-libssh2 --disable-threaded-resolver --without-brotli + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # # LuaJIT # -option(USE_BUNDLED_LUAJIT "Enable building of the bundled LuaJIT" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_LUAJIT "Enable building of the bundled LuaJIT" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_LUAJIT) - find_path(LUAJIT_INCLUDE luajit.h PATH_SUFFIXES luajit-2.0 luajit) - find_library(LUAJIT_LIB NAMES luajit luajit-5.1) - if(LUAJIT_INCLUDE AND LUAJIT_LIB) - message( - STATUS "Found LuaJIT: include: ${LUAJIT_INCLUDE}, lib: ${LUAJIT_LIB}") - else() - # alternatively try stock Lua - find_package(Lua51) - set(LUAJIT_LIB ${LUA_LIBRARY}) - set(LUAJIT_INCLUDE ${LUA_INCLUDE_DIR}) - - if(NOT ${LUA51_FOUND}) - message(FATAL_ERROR "Couldn't find system LuaJIT or Lua") - endif() - endif() + find_path(LUAJIT_INCLUDE luajit.h PATH_SUFFIXES luajit-2.0 luajit) + find_library(LUAJIT_LIB NAMES luajit luajit-5.1) + if(LUAJIT_INCLUDE AND LUAJIT_LIB) + message(STATUS "Found LuaJIT: include: ${LUAJIT_INCLUDE}, lib: ${LUAJIT_LIB}") + else() + # alternatively try stock Lua + find_package(Lua51) + set(LUAJIT_LIB ${LUA_LIBRARY}) + set(LUAJIT_INCLUDE ${LUA_INCLUDE_DIR}) + + if(NOT ${LUA51_FOUND}) + message(FATAL_ERROR "Couldn't find system LuaJIT or Lua") + endif() + endif() else() - set(LUAJIT_SRC "${PROJECT_BINARY_DIR}/luajit-prefix/src/luajit/src") - message(STATUS "Using bundled LuaJIT in '${LUAJIT_SRC}'") - set(LUAJIT_INCLUDE "${LUAJIT_SRC}") - set(LUAJIT_LIB "${LUAJIT_SRC}/libluajit.a") - ExternalProject_Add( - luajit - URL - "http://s3.amazonaws.com/download.draios.com/dependencies/LuaJIT-2.0.3.tar.gz" - URL_MD5 "f14e9104be513913810cd59c8c658dc0" - CONFIGURE_COMMAND "" - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - INSTALL_COMMAND "") + set(LUAJIT_SRC "${PROJECT_BINARY_DIR}/luajit-prefix/src/luajit/src") + message(STATUS "Using bundled LuaJIT in '${LUAJIT_SRC}'") + set(LUAJIT_INCLUDE "${LUAJIT_SRC}") + set(LUAJIT_LIB "${LUAJIT_SRC}/libluajit.a") + ExternalProject_Add(luajit + URL "http://s3.amazonaws.com/download.draios.com/dependencies/LuaJIT-2.0.3.tar.gz" + URL_MD5 "f14e9104be513913810cd59c8c658dc0" + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "") endif() # # Lpeg # -option(USE_BUNDLED_LPEG "Enable building of the bundled lpeg" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_LPEG "Enable building of the bundled lpeg" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_LPEG) - find_library(LPEG_LIB NAMES lpeg.a) - if(LPEG_LIB) - message(STATUS "Found lpeg: lib: ${LPEG_LIB}") - else() - message(FATAL_ERROR "Couldn't find system lpeg") - endif() + find_library(LPEG_LIB NAMES lpeg.a) + if(LPEG_LIB) + message(STATUS "Found lpeg: lib: ${LPEG_LIB}") + else() + message(FATAL_ERROR "Couldn't find system lpeg") + endif() else() - set(LPEG_SRC "${PROJECT_BINARY_DIR}/lpeg-prefix/src/lpeg") - set(LPEG_LIB "${PROJECT_BINARY_DIR}/lpeg-prefix/src/lpeg/build/lpeg.a") - message(STATUS "Using bundled lpeg in '${LPEG_SRC}'") - set(LPEG_DEPENDENCIES "") - if(USE_BUNDLED_LUAJIT) - list(APPEND LPEG_DEPENDENCIES "luajit") - endif() - ExternalProject_Add( - lpeg - DEPENDS ${LPEG_DEPENDENCIES} - URL - "http://s3.amazonaws.com/download.draios.com/dependencies/lpeg-1.0.0.tar.gz" - URL_MD5 "0aec64ccd13996202ad0c099e2877ece" - BUILD_COMMAND LUA_INCLUDE=${LUAJIT_INCLUDE} - "${PROJECT_SOURCE_DIR}/scripts/build-lpeg.sh" - "${LPEG_SRC}/build" - BUILD_IN_SOURCE 1 - CONFIGURE_COMMAND "" - INSTALL_COMMAND "") + set(LPEG_SRC "${PROJECT_BINARY_DIR}/lpeg-prefix/src/lpeg") + set(LPEG_LIB "${PROJECT_BINARY_DIR}/lpeg-prefix/src/lpeg/build/lpeg.a") + message(STATUS "Using bundled lpeg in '${LPEG_SRC}'") + set(LPEG_DEPENDENCIES "") + if(USE_BUNDLED_LUAJIT) + list(APPEND LPEG_DEPENDENCIES "luajit") + endif() + ExternalProject_Add(lpeg + DEPENDS ${LPEG_DEPENDENCIES} + URL "http://s3.amazonaws.com/download.draios.com/dependencies/lpeg-1.0.0.tar.gz" + URL_MD5 "0aec64ccd13996202ad0c099e2877ece" + BUILD_COMMAND LUA_INCLUDE=${LUAJIT_INCLUDE} "${PROJECT_SOURCE_DIR}/scripts/build-lpeg.sh" "${LPEG_SRC}/build" + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + INSTALL_COMMAND "") endif() # # Libyaml # -option(USE_BUNDLED_LIBYAML "Enable building of the bundled libyaml" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_LIBYAML "Enable building of the bundled libyaml" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_LIBYAML) - # Note: to distinguish libyaml.a and yaml.a we specify a full file name here, - # so you'll have to arrange for static libraries being available. - find_library(LIBYAML_LIB NAMES libyaml.a) - if(LIBYAML_LIB) - message(STATUS "Found libyaml: lib: ${LIBYAML_LIB}") - else() - message(FATAL_ERROR "Couldn't find system libyaml") - endif() + # Note: to distinguish libyaml.a and yaml.a we specify a full + # file name here, so you'll have to arrange for static + # libraries being available. + find_library(LIBYAML_LIB NAMES libyaml.a) + if(LIBYAML_LIB) + message(STATUS "Found libyaml: lib: ${LIBYAML_LIB}") + else() + message(FATAL_ERROR "Couldn't find system libyaml") + endif() else() - find_path(AUTORECONF_BIN NAMES autoreconf) - if(AUTORECONF_BIN) - message(STATUS "Found autoreconf: ${AUTORECONF_BIN}") - else() - message( - FATAL_ERROR - "Couldn't find system autoreconf. Please install autoreconf before continuing or use system libyaml" - ) - endif() - - set(LIBYAML_SRC "${PROJECT_BINARY_DIR}/libyaml-prefix/src/libyaml/src") - set(LIBYAML_INCLUDE - "${PROJECT_BINARY_DIR}/libyaml-prefix/src/libyaml/include") - set(LIBYAML_LIB "${LIBYAML_SRC}/.libs/libyaml.a") - message(STATUS "Using bundled libyaml in '${LIBYAML_SRC}'") - ExternalProject_Add( - libyaml - URL - "http://s3.amazonaws.com/download.draios.com/dependencies/libyaml-0.1.4.tar.gz" - URL_MD5 "4a4bced818da0b9ae7fc8ebc690792a7" - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - CONFIGURE_COMMAND ./bootstrap && ./configure - INSTALL_COMMAND "") + find_path(AUTORECONF_BIN NAMES autoreconf) + if(AUTORECONF_BIN) + message(STATUS "Found autoreconf: ${AUTORECONF_BIN}") + else() + message(FATAL_ERROR "Couldn't find system autoreconf. Please install autoreconf before continuing or use system libyaml") + endif() + + set(LIBYAML_SRC "${PROJECT_BINARY_DIR}/libyaml-prefix/src/libyaml/src") + set(LIBYAML_INCLUDE "${PROJECT_BINARY_DIR}/libyaml-prefix/src/libyaml/include") + set(LIBYAML_LIB "${LIBYAML_SRC}/.libs/libyaml.a") + message(STATUS "Using bundled libyaml in '${LIBYAML_SRC}'") + ExternalProject_Add(libyaml + URL "http://s3.amazonaws.com/download.draios.com/dependencies/libyaml-0.1.4.tar.gz" + URL_MD5 "4a4bced818da0b9ae7fc8ebc690792a7" + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND ./bootstrap && ./configure + INSTALL_COMMAND "") endif() # # lyaml # -option(USE_BUNDLED_LYAML "Enable building of the bundled lyaml" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_LYAML "Enable building of the bundled lyaml" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_LYAML) - # Note: to distinguish libyaml.a and yaml.a we specify a full file name here, - # so you'll have to arrange for static libraries being available. - find_library(LYAML_LIB NAMES yaml.a) - if(LYAML_LIB) - message(STATUS "Found lyaml: lib: ${LYAML_LIB}") - else() - message(FATAL_ERROR "Couldn't find system lyaml") - endif() + # Note: to distinguish libyaml.a and yaml.a we specify a full + # file name here, so you'll have to arrange for static + # libraries being available. + find_library(LYAML_LIB NAMES yaml.a) + if(LYAML_LIB) + message(STATUS "Found lyaml: lib: ${LYAML_LIB}") + else() + message(FATAL_ERROR "Couldn't find system lyaml") + endif() else() - set(LYAML_SRC "${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/ext/yaml") - set(LYAML_LIB "${LYAML_SRC}/.libs/yaml.a") - message(STATUS "Using bundled lyaml in '${LYAML_SRC}'") - set(LYAML_DEPENDENCIES "") - if(USE_BUNDLED_LUAJIT) - list(APPEND LYAML_DEPENDENCIES "luajit") - endif() - if(USE_BUNDLED_LIBYAML) - list(APPEND LYAML_DEPENDENCIES "libyaml") - endif() - - ExternalProject_Add( - lyaml - DEPENDS ${LYAML_DEPENDENCIES} - URL - "http://s3.amazonaws.com/download.draios.com/dependencies/lyaml-release-v6.0.tar.gz" - URL_MD5 "dc3494689a0dce7cf44e7a99c72b1f30" - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - CONFIGURE_COMMAND ./configure - --enable-static - LIBS=-L${LIBYAML_SRC}/.libs - CFLAGS=-I${LIBYAML_INCLUDE} - CPPFLAGS=-I${LIBYAML_INCLUDE} - LUA_INCLUDE=-I${LUAJIT_INCLUDE} - LUA=${LUAJIT_SRC}/luajit - INSTALL_COMMAND - sh -c - "cp -R ${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/lib/* ${PROJECT_SOURCE_DIR}/userspace/engine/lua" - ) + set(LYAML_SRC "${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/ext/yaml") + set(LYAML_LIB "${LYAML_SRC}/.libs/yaml.a") + message(STATUS "Using bundled lyaml in '${LYAML_SRC}'") + set(LYAML_DEPENDENCIES "") + if(USE_BUNDLED_LUAJIT) + list(APPEND LYAML_DEPENDENCIES "luajit") + endif() + if(USE_BUNDLED_LIBYAML) + list(APPEND LYAML_DEPENDENCIES "libyaml") + endif() + + ExternalProject_Add(lyaml + DEPENDS ${LYAML_DEPENDENCIES} + URL "http://s3.amazonaws.com/download.draios.com/dependencies/lyaml-release-v6.0.tar.gz" + URL_MD5 "dc3494689a0dce7cf44e7a99c72b1f30" + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND ./configure --enable-static LIBS=-L${LIBYAML_SRC}/.libs CFLAGS=-I${LIBYAML_INCLUDE} CPPFLAGS=-I${LIBYAML_INCLUDE} LUA_INCLUDE=-I${LUAJIT_INCLUDE} LUA=${LUAJIT_SRC}/luajit + INSTALL_COMMAND sh -c "cp -R ${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/lib/* ${PROJECT_SOURCE_DIR}/userspace/engine/lua") endif() option(USE_BUNDLED_TBB "Enable building of the bundled tbb" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_TBB) - find_path(TBB_INCLUDE_DIR tbb.h PATH_SUFFIXES tbb) - find_library(TBB_LIB NAMES tbb) - if(TBB_INCLUDE_DIR AND TBB_LIB) - message(STATUS "Found tbb: include: ${TBB_INCLUDE_DIR}, lib: ${TBB_LIB}") - else() - message(FATAL_ERROR "Couldn't find system tbb") - endif() + find_path(TBB_INCLUDE_DIR tbb.h PATH_SUFFIXES tbb) + find_library(TBB_LIB NAMES tbb) + if(TBB_INCLUDE_DIR AND TBB_LIB) + message(STATUS "Found tbb: include: ${TBB_INCLUDE_DIR}, lib: ${TBB_LIB}") + else() + message(FATAL_ERROR "Couldn't find system tbb") + endif() else() - set(TBB_SRC "${PROJECT_BINARY_DIR}/tbb-prefix/src/tbb") - - message(STATUS "Using bundled tbb in '${TBB_SRC}'") - - set(TBB_INCLUDE_DIR "${TBB_SRC}/include/") - set(TBB_LIB "${TBB_SRC}/build/lib_release/libtbb.a") - ExternalProject_Add( - tbb - URL - "http://s3.amazonaws.com/download.draios.com/dependencies/tbb-2018_U5.tar.gz" - URL_MD5 "ff3ae09f8c23892fbc3008c39f78288f" - CONFIGURE_COMMAND "" - BUILD_COMMAND ${CMD_MAKE} - tbb_build_dir=${TBB_SRC}/build - tbb_build_prefix=lib - extra_inc=big_iron.inc - BUILD_IN_SOURCE 1 - BUILD_BYPRODUCTS ${TBB_LIB} - INSTALL_COMMAND "") + set(TBB_SRC "${PROJECT_BINARY_DIR}/tbb-prefix/src/tbb") + + message(STATUS "Using bundled tbb in '${TBB_SRC}'") + + set(TBB_INCLUDE_DIR "${TBB_SRC}/include/") + set(TBB_LIB "${TBB_SRC}/build/lib_release/libtbb.a") + ExternalProject_Add(tbb + URL "http://s3.amazonaws.com/download.draios.com/dependencies/tbb-2018_U5.tar.gz" + URL_MD5 "ff3ae09f8c23892fbc3008c39f78288f" + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMD_MAKE} tbb_build_dir=${TBB_SRC}/build tbb_build_prefix=lib extra_inc=big_iron.inc + BUILD_IN_SOURCE 1 + BUILD_BYPRODUCTS ${TBB_LIB} + INSTALL_COMMAND "") endif() # # civetweb # -option(USE_BUNDLED_CIVETWEB "Enable building of the bundled civetweb" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_CIVETWEB "Enable building of the bundled civetweb" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_CIVETWEB) - find_library(CIVETWEB_LIB NAMES civetweb) - if(CIVETWEB_LIB) - message(STATUS "Found civetweb: lib: ${CIVETWEB_LIB}") - else() - message(FATAL_ERROR "Couldn't find system civetweb") - endif() + find_library(CIVETWEB_LIB NAMES civetweb) + if(CIVETWEB_LIB) + message(STATUS "Found civetweb: lib: ${CIVETWEB_LIB}") + else() + message(FATAL_ERROR "Couldn't find system civetweb") + endif() else() - set(CIVETWEB_SRC "${PROJECT_BINARY_DIR}/civetweb-prefix/src/civetweb/") - set(CIVETWEB_LIB "${CIVETWEB_SRC}/install/lib/libcivetweb.a") - set(CIVETWEB_INCLUDE_DIR "${CIVETWEB_SRC}/install/include") - message(STATUS "Using bundled civetweb in '${CIVETWEB_SRC}'") - set(CIVETWEB_DEPENDENCIES "") - if(USE_BUNDLED_OPENSSL) - list(APPEND CIVETWEB_DEPENDENCIES "openssl") - endif() - ExternalProject_Add( - civetweb - DEPENDS ${CIVETWEB_DEPENDENCIES} - URL - "http://s3.amazonaws.com/download.draios.com/dependencies/civetweb-1.11.tar.gz" - URL_MD5 "b6d2175650a27924bccb747cbe084cd4" - CONFIGURE_COMMAND ${CMAKE_COMMAND} - -E - make_directory - ${CIVETWEB_SRC}/install/lib - COMMAND ${CMAKE_COMMAND} - -E - make_directory - ${CIVETWEB_SRC}/install/include - BUILD_IN_SOURCE 1 - BUILD_COMMAND ${CMD_MAKE} COPT="-DNO_FILES" WITH_CPP=1 - INSTALL_COMMAND ${CMD_MAKE} - install-lib - install-headers - PREFIX=${CIVETWEB_SRC}/install - WITH_CPP=1) + set(CIVETWEB_SRC "${PROJECT_BINARY_DIR}/civetweb-prefix/src/civetweb/") + set(CIVETWEB_LIB "${CIVETWEB_SRC}/install/lib/libcivetweb.a") + set(CIVETWEB_INCLUDE_DIR "${CIVETWEB_SRC}/install/include") + message(STATUS "Using bundled civetweb in '${CIVETWEB_SRC}'") + set(CIVETWEB_DEPENDENCIES "") + if(USE_BUNDLED_OPENSSL) + list(APPEND CIVETWEB_DEPENDENCIES "openssl") + endif() + ExternalProject_Add(civetweb + DEPENDS ${CIVETWEB_DEPENDENCIES} + URL "http://s3.amazonaws.com/download.draios.com/dependencies/civetweb-1.11.tar.gz" + URL_MD5 "b6d2175650a27924bccb747cbe084cd4" + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E make_directory ${CIVETWEB_SRC}/install/lib + COMMAND ${CMAKE_COMMAND} -E make_directory ${CIVETWEB_SRC}/install/include + BUILD_IN_SOURCE 1 + BUILD_COMMAND ${CMD_MAKE} COPT="-DNO_FILES" WITH_CPP=1 + INSTALL_COMMAND ${CMD_MAKE} install-lib install-headers PREFIX=${CIVETWEB_SRC}/install WITH_CPP=1) endif() -option(USE_BUNDLED_CARES "Enable building of the bundled c-ares" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_CARES "Enable building of the bundled c-ares" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_CARES) - find_path(CARES_INCLUDE NAMES cares/ares.h) - find_library(CARES_LIB NAMES libcares.a) - if(CARES_INCLUDE AND CARES_LIB) - message(STATUS "Found c-ares: include: ${CARES_INCLUDE}, lib: ${CARES_LIB}") - else() - message(FATAL_ERROR "Couldn't find system c-ares") - endif() + find_path(CARES_INCLUDE NAMES cares/ares.h) + find_library(CARES_LIB NAMES libcares.a) + if(CARES_INCLUDE AND CARES_LIB) + message(STATUS "Found c-ares: include: ${CARES_INCLUDE}, lib: ${CARES_LIB}") + else() + message(FATAL_ERROR "Couldn't find system c-ares") + endif() else() - set(CARES_SRC "${PROJECT_BINARY_DIR}/c-ares-prefix/src/c-ares") - message(STATUS "Using bundled c-ares in '${CARES_SRC}'") - set(CARES_INCLUDE "${CARES_SRC}/target/include") - set(CARES_LIB "${CARES_SRC}/target/lib/libcares.a") - ExternalProject_Add( - c-ares - URL "https://download.sysdig.com/dependencies/c-ares-1.13.0.tar.gz" - URL_MD5 "d2e010b43537794d8bedfb562ae6bba2" - CONFIGURE_COMMAND ./configure --prefix=${CARES_SRC}/target - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - BUILD_BYPRODUCTS ${CARES_INCLUDE} ${CARES_LIB} - INSTALL_COMMAND ${CMD_MAKE} install) + set(CARES_SRC "${PROJECT_BINARY_DIR}/c-ares-prefix/src/c-ares") + message(STATUS "Using bundled c-ares in '${CARES_SRC}'") + set(CARES_INCLUDE "${CARES_SRC}/target/include") + set(CARES_LIB "${CARES_SRC}/target/lib/libcares.a") + ExternalProject_Add(c-ares + URL "https://download.sysdig.com/dependencies/c-ares-1.13.0.tar.gz" + URL_MD5 "d2e010b43537794d8bedfb562ae6bba2" + CONFIGURE_COMMAND ./configure --prefix=${CARES_SRC}/target + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + BUILD_BYPRODUCTS ${CARES_INCLUDE} ${CARES_LIB} + INSTALL_COMMAND ${CMD_MAKE} install) endif() -option(USE_BUNDLED_PROTOBUF "Enable building of the bundled protobuf" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_PROTOBUF "Enable building of the bundled protobuf" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_PROTOBUF) - find_program(PROTOC NAMES protoc) - find_path(PROTOBUF_INCLUDE NAMES google/protobuf/message.h) - find_library(PROTOBUF_LIB NAMES libprotobuf.a) - if(PROTOC AND PROTOBUF_INCLUDE AND PROTOBUF_LIB) - message( - STATUS - "Found protobuf: compiler: ${PROTOC}, include: ${PROTOBUF_INCLUDE}, lib: ${PROTOBUF_LIB}" - ) - else() - message(FATAL_ERROR "Couldn't find system protobuf") - endif() + find_program(PROTOC NAMES protoc) + find_path(PROTOBUF_INCLUDE NAMES google/protobuf/message.h) + find_library(PROTOBUF_LIB NAMES libprotobuf.a) + if(PROTOC AND PROTOBUF_INCLUDE AND PROTOBUF_LIB) + message(STATUS "Found protobuf: compiler: ${PROTOC}, include: ${PROTOBUF_INCLUDE}, lib: ${PROTOBUF_LIB}") + else() + message(FATAL_ERROR "Couldn't find system protobuf") + endif() else() - set(PROTOBUF_SRC "${PROJECT_BINARY_DIR}/protobuf-prefix/src/protobuf") - message(STATUS "Using bundled protobuf in '${PROTOBUF_SRC}'") - set(PROTOC "${PROTOBUF_SRC}/target/bin/protoc") - set(PROTOBUF_INCLUDE "${PROTOBUF_SRC}/target/include") - set(PROTOBUF_LIB "${PROTOBUF_SRC}/target/lib/libprotobuf.a") - ExternalProject_Add( - protobuf - DEPENDS openssl zlib - URL - "https://github.com/google/protobuf/releases/download/v3.5.0/protobuf-cpp-3.5.0.tar.gz" - URL_MD5 "e4ba8284a407712168593e79e6555eb2" - # TODO what if using system zlib? - CONFIGURE_COMMAND /usr/bin/env - CPPFLAGS=-I${ZLIB_INCLUDE} - LDFLAGS=-L${ZLIB_SRC} - ./configure - --with-zlib - --prefix=${PROTOBUF_SRC}/target - BUILD_COMMAND ${CMD_MAKE} - BUILD_IN_SOURCE 1 - BUILD_BYPRODUCTS ${PROTOC} ${PROTOBUF_INCLUDE} ${PROTOBUF_LIB} - # TODO s390x support - INSTALL_COMMAND make install) + set(PROTOBUF_SRC "${PROJECT_BINARY_DIR}/protobuf-prefix/src/protobuf") + message(STATUS "Using bundled protobuf in '${PROTOBUF_SRC}'") + set(PROTOC "${PROTOBUF_SRC}/target/bin/protoc") + set(PROTOBUF_INCLUDE "${PROTOBUF_SRC}/target/include") + set(PROTOBUF_LIB "${PROTOBUF_SRC}/target/lib/libprotobuf.a") + ExternalProject_Add(protobuf + DEPENDS openssl zlib + URL "https://github.com/google/protobuf/releases/download/v3.5.0/protobuf-cpp-3.5.0.tar.gz" + URL_MD5 "e4ba8284a407712168593e79e6555eb2" + # TODO what if using system zlib? + CONFIGURE_COMMAND /usr/bin/env CPPFLAGS=-I${ZLIB_INCLUDE} LDFLAGS=-L${ZLIB_SRC} ./configure --with-zlib --prefix=${PROTOBUF_SRC}/target + BUILD_COMMAND ${CMD_MAKE} + BUILD_IN_SOURCE 1 + BUILD_BYPRODUCTS ${PROTOC} ${PROTOBUF_INCLUDE} ${PROTOBUF_LIB} + # TODO s390x support + INSTALL_COMMAND make install) endif() -option(USE_BUNDLED_GRPC "Enable building of the bundled grpc" - ${USE_BUNDLED_DEPS}) +option(USE_BUNDLED_GRPC "Enable building of the bundled grpc" ${USE_BUNDLED_DEPS}) if(NOT USE_BUNDLED_GRPC) - find_path(GRPC_INCLUDE grpc++/impl/codegen/rpc_method.h) - find_library(GRPC_LIB NAMES libgrpc_unsecure.a) - find_library(GRPCPP_LIB NAMES libgrpc++_unsecure.a) - if(GRPC_INCLUDE AND GRPC_LIB AND GRPCPP_LIB) - message( - STATUS - "Found grpc: include: ${GRPC_INCLUDE}, C lib: ${GRPC_LIB}, C++ lib: ${GRPC_PP_LIB}" - ) - else() - message(FATAL_ERROR "Couldn't find system grpc") - endif() - find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin) - if(NOT GRPC_CPP_PLUGIN) - message(FATAL_ERROR "System grpc_cpp_plugin not found") - endif() + find_path(GRPC_INCLUDE grpc++/impl/codegen/rpc_method.h) + find_library(GRPC_LIB NAMES libgrpc_unsecure.a) + find_library(GRPCPP_LIB NAMES libgrpc++_unsecure.a) + if(GRPC_INCLUDE AND GRPC_LIB AND GRPCPP_LIB) + message(STATUS "Found grpc: include: ${GRPC_INCLUDE}, C lib: ${GRPC_LIB}, C++ lib: ${GRPC_PP_LIB}") + else() + message(FATAL_ERROR "Couldn't find system grpc") + endif() + find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin) + if(NOT GRPC_CPP_PLUGIN) + message(FATAL_ERROR "System grpc_cpp_plugin not found") + endif() else() - set(GRPC_SRC "${PROJECT_BINARY_DIR}/grpc-prefix/src/grpc") - message(STATUS "Using bundled grpc in '${GRPC_SRC}'") - set(GRPC_INCLUDE "${GRPC_SRC}/include") - set(GRPC_LIB "${GRPC_SRC}/libs/opt/libgrpc_unsecure.a") - set(GRPCPP_LIB "${GRPC_SRC}/libs/opt/libgrpc++_unsecure.a") - set(GRPC_CPP_PLUGIN "${GRPC_SRC}/bins/opt/grpc_cpp_plugin") - - get_filename_component(PROTOC_DIR ${PROTOC} DIRECTORY) - - ExternalProject_Add( - grpc - DEPENDS protobuf zlib c-ares - URL "http://download.draios.com/dependencies/grpc-1.8.1.tar.gz" - URL_MD5 "2fc42c182a0ed1b48ad77397f76bb3bc" - CONFIGURE_COMMAND "" - # TODO what if using system openssl, protobuf or cares? - BUILD_COMMAND - sh -c - "CFLAGS=-Wno-implicit-fallthrough CXXFLAGS=\"-Wno-ignored-qualifiers -Wno-stringop-truncation\" HAS_SYSTEM_ZLIB=false LDFLAGS=-static PATH=${PROTOC_DIR}:$ENV{PATH} PKG_CONFIG_PATH=${OPENSSL_BUNDLE_DIR}:${PROTOBUF_SRC}:${CARES_SRC} make grpc_cpp_plugin static_cxx static_c" - BUILD_IN_SOURCE 1 - BUILD_BYPRODUCTS ${GRPC_LIB} ${GRPCPP_LIB} - # TODO s390x support - # TODO what if using system zlib - PATCH_COMMAND - rm - -rf - third_party/zlib - && - ln - -s - ${ZLIB_SRC} - third_party/zlib - && - wget - https://download.sysdig.com/dependencies/grpc-1.1.4-Makefile.patch - && - patch - < - grpc-1.1.4-Makefile.patch - INSTALL_COMMAND "") + set(GRPC_SRC "${PROJECT_BINARY_DIR}/grpc-prefix/src/grpc") + message(STATUS "Using bundled grpc in '${GRPC_SRC}'") + set(GRPC_INCLUDE "${GRPC_SRC}/include") + set(GRPC_LIB "${GRPC_SRC}/libs/opt/libgrpc_unsecure.a") + set(GRPCPP_LIB "${GRPC_SRC}/libs/opt/libgrpc++_unsecure.a") + set(GRPC_CPP_PLUGIN "${GRPC_SRC}/bins/opt/grpc_cpp_plugin") + + get_filename_component(PROTOC_DIR ${PROTOC} DIRECTORY) + + ExternalProject_Add(grpc + DEPENDS protobuf zlib c-ares + URL "http://download.draios.com/dependencies/grpc-1.8.1.tar.gz" + URL_MD5 "2fc42c182a0ed1b48ad77397f76bb3bc" + CONFIGURE_COMMAND "" + # TODO what if using system openssl, protobuf or cares? + BUILD_COMMAND sh -c "CFLAGS=-Wno-implicit-fallthrough CXXFLAGS=\"-Wno-ignored-qualifiers -Wno-stringop-truncation\" HAS_SYSTEM_ZLIB=false LDFLAGS=-static PATH=${PROTOC_DIR}:$ENV{PATH} PKG_CONFIG_PATH=${OPENSSL_BUNDLE_DIR}:${PROTOBUF_SRC}:${CARES_SRC} make grpc_cpp_plugin static_cxx static_c" + BUILD_IN_SOURCE 1 + BUILD_BYPRODUCTS ${GRPC_LIB} ${GRPCPP_LIB} + # TODO s390x support + # TODO what if using system zlib + PATCH_COMMAND rm -rf third_party/zlib && ln -s ${ZLIB_SRC} third_party/zlib && wget https://download.sysdig.com/dependencies/grpc-1.1.4-Makefile.patch && patch < grpc-1.1.4-Makefile.patch + INSTALL_COMMAND "") endif() -install(FILES falco.yaml DESTINATION "${FALCO_ETC_DIR}") + +install(FILES falco.yaml + DESTINATION "${FALCO_ETC_DIR}") add_subdirectory(test) add_subdirectory(rules) add_subdirectory(docker) -# Add path for custom CMake modules used to build dependencies from Sysdig -# (libscap, libsinsp) -list(APPEND CMAKE_MODULE_PATH "${SYSDIG_DIR}/cmake/modules") +# Add path for custom CMake modules used to build dependencies from Sysdig (libscap, libsinsp) +list(APPEND CMAKE_MODULE_PATH + "${SYSDIG_DIR}/cmake/modules") # Add path for custom CMake modules -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") +list(APPEND CMAKE_MODULE_PATH + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") if(CMAKE_SYSTEM_NAME MATCHES "Linux") - add_subdirectory("${SYSDIG_DIR}/driver" "${PROJECT_BINARY_DIR}/driver") - include(FindMakedev) + add_subdirectory("${SYSDIG_DIR}/driver" "${PROJECT_BINARY_DIR}/driver") + include(FindMakedev) endif() -add_subdirectory("${SYSDIG_DIR}/userspace/libscap" - "${PROJECT_BINARY_DIR}/userspace/libscap") -add_subdirectory("${SYSDIG_DIR}/userspace/libsinsp" - "${PROJECT_BINARY_DIR}/userspace/libsinsp") +add_subdirectory("${SYSDIG_DIR}/userspace/libscap" "${PROJECT_BINARY_DIR}/userspace/libscap") +add_subdirectory("${SYSDIG_DIR}/userspace/libsinsp" "${PROJECT_BINARY_DIR}/userspace/libsinsp") set(FALCO_SINSP_LIBRARY sinsp) set(FALCO_SHARE_DIR share/falco) @@ -803,15 +630,13 @@ add_subdirectory(userspace/engine) add_subdirectory(userspace/falco) add_subdirectory(tests) + set(CPACK_PACKAGE_NAME "${PACKAGE_NAME}") set(CPACK_PACKAGE_VENDOR "Sysdig Inc.") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY - "falco, a system-level activity monitoring tool") -set(CPACK_PACKAGE_DESCRIPTION_FILE - "${PROJECT_SOURCE_DIR}/scripts/description.txt") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "falco, a system-level activity monitoring tool") +set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/scripts/description.txt") set(CPACK_PACKAGE_VERSION "${FALCO_VERSION}") -set(CPACK_PACKAGE_FILE_NAME - "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_PROCESSOR}") +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_PROCESSOR}") set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_SOURCE_DIR}/CMakeCPackOptions.cmake") set(CPACK_STRIP_FILES "ON") set(CPACK_PACKAGE_RELOCATABLE "OFF") @@ -822,30 +647,15 @@ set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Sysdig ") set(CPACK_DEBIAN_PACKAGE_SECTION "utils") set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://www.sysdig.org") set(CPACK_DEBIAN_PACKAGE_DEPENDS "dkms (>= 2.1.0.0)") -set( - CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA - "${CMAKE_BINARY_DIR}/scripts/debian/postinst;${CMAKE_BINARY_DIR}/scripts/debian/prerm;${PROJECT_SOURCE_DIR}/scripts/debian/postrm;${PROJECT_SOURCE_DIR}/cpack/debian/conffiles" - ) +set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_BINARY_DIR}/scripts/debian/postinst;${CMAKE_BINARY_DIR}/scripts/debian/prerm;${PROJECT_SOURCE_DIR}/scripts/debian/postrm;${PROJECT_SOURCE_DIR}/cpack/debian/conffiles") set(CPACK_RPM_PACKAGE_LICENSE "Apache v2.0") set(CPACK_RPM_PACKAGE_URL "http://www.sysdig.org") set(CPACK_RPM_PACKAGE_REQUIRES "dkms, gcc, make, kernel-devel, perl") -set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE - "${PROJECT_SOURCE_DIR}/scripts/rpm/postinstall") -set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE - "${PROJECT_SOURCE_DIR}/scripts/rpm/preuninstall") -set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE - "${PROJECT_SOURCE_DIR}/scripts/rpm/postuninstall") -set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION - /usr/src - /usr/share/man - /usr/share/man/man8 - /etc - /usr - /usr/bin - /usr/share - /etc/rc.d - /etc/rc.d/init.d) +set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/scripts/rpm/postinstall") +set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/scripts/rpm/preuninstall") +set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/scripts/rpm/postuninstall") +set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /usr/src /usr/share/man /usr/share/man/man8 /etc /usr /usr/bin /usr/share /etc/rc.d /etc/rc.d/init.d ) set(CPACK_RPM_PACKAGE_RELOCATABLE "OFF") include(CPack) diff --git a/cmake/modules/Catch.cmake b/cmake/modules/Catch.cmake index 2ee56e631d8..486e323318c 100644 --- a/cmake/modules/Catch.cmake +++ b/cmake/modules/Catch.cmake @@ -92,13 +92,15 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``. #]=======================================================================] -# ------------------------------------------------------------------------------ +#------------------------------------------------------------------------------ function(catch_discover_tests TARGET) - cmake_parse_arguments("" - "" - "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST" - "TEST_SPEC;EXTRA_ARGS;PROPERTIES" - ${ARGN}) + cmake_parse_arguments( + "" + "" + "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST" + "TEST_SPEC;EXTRA_ARGS;PROPERTIES" + ${ARGN} + ) if(NOT _WORKING_DIRECTORY) set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") @@ -107,78 +109,67 @@ function(catch_discover_tests TARGET) set(_TEST_LIST ${TARGET}_TESTS) endif() - # Generate a unique name based on the extra arguments + ## Generate a unique name based on the extra arguments string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS}") - string(SUBSTRING ${args_hash} - 0 - 7 - args_hash) + string(SUBSTRING ${args_hash} 0 7 args_hash) # Define rule to generate test list for aforementioned test executable - set(ctest_include_file - "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake") - set(ctest_tests_file - "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake") + set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake") + set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake") get_property(crosscompiling_emulator - TARGET ${TARGET} - PROPERTY CROSSCOMPILING_EMULATOR) - add_custom_command(TARGET - ${TARGET} - POST_BUILD - BYPRODUCTS - "${ctest_tests_file}" - COMMAND "${CMAKE_COMMAND}" - -D - "TEST_TARGET=${TARGET}" - -D - "TEST_EXECUTABLE=$" - -D - "TEST_EXECUTOR=${crosscompiling_emulator}" - -D - "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" - -D - "TEST_SPEC=${_TEST_SPEC}" - -D - "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" - -D - "TEST_PROPERTIES=${_PROPERTIES}" - -D - "TEST_PREFIX=${_TEST_PREFIX}" - -D - "TEST_SUFFIX=${_TEST_SUFFIX}" - -D - "TEST_LIST=${_TEST_LIST}" - -D - "CTEST_FILE=${ctest_tests_file}" - -P - "${_CATCH_DISCOVER_TESTS_SCRIPT}" - VERBATIM) - - file( - WRITE "${ctest_include_file}" + TARGET ${TARGET} + PROPERTY CROSSCOMPILING_EMULATOR + ) + add_custom_command( + TARGET ${TARGET} POST_BUILD + BYPRODUCTS "${ctest_tests_file}" + COMMAND "${CMAKE_COMMAND}" + -D "TEST_TARGET=${TARGET}" + -D "TEST_EXECUTABLE=$" + -D "TEST_EXECUTOR=${crosscompiling_emulator}" + -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" + -D "TEST_SPEC=${_TEST_SPEC}" + -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" + -D "TEST_PROPERTIES=${_PROPERTIES}" + -D "TEST_PREFIX=${_TEST_PREFIX}" + -D "TEST_SUFFIX=${_TEST_SUFFIX}" + -D "TEST_LIST=${_TEST_LIST}" + -D "CTEST_FILE=${ctest_tests_file}" + -P "${_CATCH_DISCOVER_TESTS_SCRIPT}" + VERBATIM + ) + + file(WRITE "${ctest_include_file}" "if(EXISTS \"${ctest_tests_file}\")\n" " include(\"${ctest_tests_file}\")\n" "else()\n" " add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n" - "endif()\n") + "endif()\n" + ) - if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0") + if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0") # Add discovered tests to directory TEST_INCLUDE_FILES set_property(DIRECTORY - APPEND - PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}") + APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}" + ) else() # Add discovered tests as directory TEST_INCLUDE_FILE if possible get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET) - if(NOT ${test_include_file_set}) - set_property(DIRECTORY PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}") + if (NOT ${test_include_file_set}) + set_property(DIRECTORY + PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}" + ) else() - message(FATAL_ERROR "Cannot set more than one TEST_INCLUDE_FILE") + message(FATAL_ERROR + "Cannot set more than one TEST_INCLUDE_FILE" + ) endif() endif() endfunction() -# ############################################################################## +############################################################################### -set(_CATCH_DISCOVER_TESTS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake) +set(_CATCH_DISCOVER_TESTS_SCRIPT + ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake +) diff --git a/cmake/modules/CatchAddTests.cmake b/cmake/modules/CatchAddTests.cmake index 05f2d1bd024..2220ce3ac6b 100644 --- a/cmake/modules/CatchAddTests.cmake +++ b/cmake/modules/CatchAddTests.cmake @@ -24,50 +24,49 @@ endfunction() # Run test executable to get list of available tests if(NOT EXISTS "${TEST_EXECUTABLE}") - message( - FATAL_ERROR "Specified test executable '${TEST_EXECUTABLE}' does not exist") + message(FATAL_ERROR + "Specified test executable '${TEST_EXECUTABLE}' does not exist" + ) endif() -execute_process(COMMAND ${TEST_EXECUTOR} - "${TEST_EXECUTABLE}" - ${spec} - --list-test-names-only - OUTPUT_VARIABLE output - RESULT_VARIABLE result) -# Catch --list-test-names-only reports the number of tests, so 0 is... -# surprising +execute_process( + COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only + OUTPUT_VARIABLE output + RESULT_VARIABLE result +) +# Catch --list-test-names-only reports the number of tests, so 0 is... surprising if(${result} EQUAL 0) - message(WARNING "Test executable '${TEST_EXECUTABLE}' contains no tests!\n") + message(WARNING + "Test executable '${TEST_EXECUTABLE}' contains no tests!\n" + ) elseif(${result} LESS 0) - message(FATAL_ERROR "Error running test executable '${TEST_EXECUTABLE}':\n" - " Result: ${result}\n" " Output: ${output}\n") + message(FATAL_ERROR + "Error running test executable '${TEST_EXECUTABLE}':\n" + " Result: ${result}\n" + " Output: ${output}\n" + ) endif() -string(REPLACE "\n" - ";" - output - "${output}") +string(REPLACE "\n" ";" output "${output}") # Parse output foreach(line ${output}) set(test ${line}) # use escape commas to handle properly test cases with commans inside the name - string(REPLACE "," - "\\," - test_name - ${test}) + string(REPLACE "," "\\," test_name ${test}) # ...and add to script add_command(add_test - "${prefix}${test}${suffix}" - ${TEST_EXECUTOR} - "${TEST_EXECUTABLE}" - "${test_name}" - ${extra_args}) + "${prefix}${test}${suffix}" + ${TEST_EXECUTOR} + "${TEST_EXECUTABLE}" + "${test_name}" + ${extra_args} + ) add_command(set_tests_properties - "${prefix}${test}${suffix}" - PROPERTIES - WORKING_DIRECTORY - "${TEST_WORKING_DIR}" - ${properties}) + "${prefix}${test}${suffix}" + PROPERTIES + WORKING_DIRECTORY "${TEST_WORKING_DIR}" + ${properties} + ) list(APPEND tests "${prefix}${test}${suffix}") endforeach() diff --git a/cmake/modules/FindCatch.cmake b/cmake/modules/FindCatch.cmake new file mode 100644 index 00000000000..88f18149f89 --- /dev/null +++ b/cmake/modules/FindCatch.cmake @@ -0,0 +1,34 @@ +# +# Copyright (C) 2016-2019 Draios Inc dba Sysdig. +# +# This file is part of falco . +# +# 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(ExternalProject) + +set(CATCH_EXTERNAL_URL + URL https://github.com/catchorg/Catch2/archive/v2.9.1.tar.gz + URL_HASH MD5=4980778888fed635bf191d8a86f9f89c) +ExternalProject_Add(catch2 + PREFIX ${CMAKE_BINARY_DIR}/catch2-prefix + ${CATCH_EXTERNAL_URL} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/catch2-prefix/src/catch2/single_include/catch2/catch.hpp + ${CMAKE_BINARY_DIR}/catch2-prefix/include/catch.hpp +) +add_library(catch INTERFACE) +add_dependencies(catch catch2) +target_include_directories(catch INTERFACE ${CMAKE_BINARY_DIR}/catch2-prefix/include) + From 08454dfa5385333cec57d26ee7fe483be01f2285 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Tue, 2 Jul 2019 11:32:58 +0000 Subject: [PATCH 40/64] new: test token bucket declaration triggers the default init Co-Authored-By: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- tests/engine/test_token_bucket.cpp | 8 +++++++- userspace/engine/token_bucket.h | 4 +--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/engine/test_token_bucket.cpp b/tests/engine/test_token_bucket.cpp index 412c996b535..01893027cb0 100644 --- a/tests/engine/test_token_bucket.cpp +++ b/tests/engine/test_token_bucket.cpp @@ -74,4 +74,10 @@ TEST_CASE("token bucket with 2 tokens/sec rate, max 10 tokens", "[token_bucket]" } } } -} \ No newline at end of file +} + +TEST_CASE("token bucket default initialization", "[token_bucket]") +{ + token_bucket tb; + REQUIRE(tb.get_tokens() == 1); +} diff --git a/userspace/engine/token_bucket.h b/userspace/engine/token_bucket.h index 03c4790ea56..1dd60c26ea0 100644 --- a/userspace/engine/token_bucket.h +++ b/userspace/engine/token_bucket.h @@ -22,8 +22,6 @@ limitations under the License. #include #include -using token_timer = std::function; - // A simple token bucket that accumulates tokens at a fixed rate and allows // for limited bursting in the form of "banked" tokens. class token_bucket @@ -79,4 +77,4 @@ class token_bucket // Nanoseconds since the epoch. // uint64_t m_last_seen; -}; \ No newline at end of file +}; From 5fdf658d0ec961f6d61065315d1771e84523a340 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Tue, 2 Jul 2019 11:34:26 +0000 Subject: [PATCH 41/64] fix(userspace): correct include directories Co-Authored-By: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- userspace/engine/CMakeLists.txt | 17 +++++++---------- userspace/falco/CMakeLists.txt | 24 +++++++++--------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/userspace/engine/CMakeLists.txt b/userspace/engine/CMakeLists.txt index 550399a4c98..af63c76330a 100644 --- a/userspace/engine/CMakeLists.txt +++ b/userspace/engine/CMakeLists.txt @@ -14,15 +14,6 @@ # 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_directories("${SYSDIG_DIR}/userspace/libsinsp/third-party/jsoncpp") -include_directories("${SYSDIG_DIR}/userspace/libscap") -include_directories("${SYSDIG_DIR}/userspace/libsinsp") -include_directories("${PROJECT_BINARY_DIR}/userspace/engine") -include_directories("${LUAJIT_INCLUDE}") -include_directories("${NJSON_INCLUDE}") -include_directories("${CURL_INCLUDE_DIR}") -include_directories("${TBB_INCLUDE_DIR}") set(FALCO_ENGINE_SOURCE_FILES rules.cpp @@ -38,7 +29,13 @@ add_library(falco_engine STATIC ${FALCO_ENGINE_SOURCE_FILES}) target_include_directories(falco_engine PUBLIC "${LUAJIT_INCLUDE}" "${NJSON_INCLUDE}" - "${PROJECT_BINARY_DIR}/userspace/engine") + "${CURL_INCLUDE_DIR}" + "${TBB_INCLUDE_DIR}" + "${SYSDIG_DIR}/userspace/libsinsp/third-party/jsoncpp" + "${SYSDIG_DIR}/userspace/libscap" + "${SYSDIG_DIR}/userspace/libsinsp" + "${PROJECT_BINARY_DIR}/userspace/engine" + ) target_link_libraries(falco_engine "${FALCO_SINSP_LIBRARY}" diff --git a/userspace/falco/CMakeLists.txt b/userspace/falco/CMakeLists.txt index 81b79825db7..7f14fd929e4 100644 --- a/userspace/falco/CMakeLists.txt +++ b/userspace/falco/CMakeLists.txt @@ -15,21 +15,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # -include_directories("${PROJECT_SOURCE_DIR}/../sysdig/userspace/libsinsp/third-party/jsoncpp") -include_directories("${LUAJIT_INCLUDE}") - -include_directories("${PROJECT_SOURCE_DIR}/../sysdig/userspace/libscap") -include_directories("${PROJECT_SOURCE_DIR}/../sysdig/userspace/libsinsp") -include_directories("${PROJECT_SOURCE_DIR}/../sysdig/userspace/sysdig") -include_directories("${PROJECT_SOURCE_DIR}/userspace/engine") -include_directories("${PROJECT_BINARY_DIR}/userspace/falco") -include_directories("${PROJECT_BINARY_DIR}/driver/src") -include_directories("${CURL_INCLUDE_DIR}") -include_directories("${TBB_INCLUDE_DIR}") -include_directories("${NJSON_INCLUDE}") -include_directories("${YAMLCPP_INCLUDE_DIR}") -include_directories("${CIVETWEB_INCLUDE_DIR}") -include_directories("${DRAIOS_DEPENDENCIES_DIR}/yaml-${DRAIOS_YAML_VERSION}/target/include") configure_file("${PROJECT_SOURCE_DIR}/../sysdig/userspace/sysdig/config_sysdig.h.in" config_sysdig.h) @@ -43,6 +28,15 @@ add_executable(falco "${PROJECT_SOURCE_DIR}/../sysdig/userspace/sysdig/fields_info.cpp" webserver.cpp) +target_include_directories(falco PUBLIC + "${SYSDIG_DIR}/userspace/sysdig" + "${PROJECT_SOURCE_DIR}/userspace/engine" + "${PROJECT_BINARY_DIR}/userspace/falco" + "${PROJECT_BINARY_DIR}/driver/src" + "${YAMLCPP_INCLUDE_DIR}" + "${CIVETWEB_INCLUDE_DIR}" + "${DRAIOS_DEPENDENCIES_DIR}/yaml-${DRAIOS_YAML_VERSION}/target/include") + target_link_libraries(falco falco_engine sinsp) target_link_libraries(falco "${LIBYAML_LIB}" From b2ef08fd30931b6788b100941f7269aa07430297 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Tue, 2 Jul 2019 16:36:20 +0000 Subject: [PATCH 42/64] chore: clang format following the current style Signed-off-by: Lorenzo Fontana Co-authored-by: Leonardo Di Donato --- .clang-format | 20 ++++-- tests/engine/test_token_bucket.cpp | 82 +++++++++++------------ userspace/engine/token_bucket.cpp | 51 ++++++++------- userspace/engine/token_bucket.h | 102 ++++++++++++++--------------- 4 files changed, 131 insertions(+), 124 deletions(-) diff --git a/.clang-format b/.clang-format index e22175e5629..2e074ae1f4b 100644 --- a/.clang-format +++ b/.clang-format @@ -1,10 +1,16 @@ -# This coding convention's solely goal is to approximately match the current code style. -# It MUST not be intended in any other way until a real and definitive coding convention is put in. --- -BreakBeforeBraces: GNU -ColumnLimit: 0 -IndentWidth: 4 Language: Cpp +BasedOnStyle: LLVM +AccessModifierOffset: -8 +BreakBeforeBraces: Allman +BreakConstructorInitializers: AfterColon +ColumnLimit: 0 +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 +DerivePointerAlignment: true +IndentWidth: 8 +SortIncludes: false +SpaceAfterTemplateKeyword: false +SpaceBeforeCtorInitializerColon: false SpaceBeforeParens: Never -Standard: Auto -UseTab: Always \ No newline at end of file +UseTab: Always diff --git a/tests/engine/test_token_bucket.cpp b/tests/engine/test_token_bucket.cpp index 01893027cb0..a907d85c577 100644 --- a/tests/engine/test_token_bucket.cpp +++ b/tests/engine/test_token_bucket.cpp @@ -23,61 +23,61 @@ using namespace Catch::literals; TEST_CASE("token bucket default ctor", "[token_bucket]") { - auto tb = new token_bucket(); - - REQUIRE(tb->get_tokens() == 1); - - SECTION("initialising with specific time, rate 2 tokens/sec") - { - auto max = 2.0; - uint64_t now = 1; - tb->init(1.0, max, now); - REQUIRE(tb->get_last_seen() == now); - REQUIRE(tb->get_tokens() == max); - } + auto tb = new token_bucket(); + + REQUIRE(tb->get_tokens() == 1); + + SECTION("initialising with specific time, rate 2 tokens/sec") + { + auto max = 2.0; + uint64_t now = 1; + tb->init(1.0, max, now); + REQUIRE(tb->get_last_seen() == now); + REQUIRE(tb->get_tokens() == max); + } } TEST_CASE("token bucket ctor with custom timer", "[token_bucket]") { - auto t = []() -> uint64_t { return 22; }; - auto tb = new token_bucket(t); + auto t = []() -> uint64_t { return 22; }; + auto tb = new token_bucket(t); - REQUIRE(tb->get_tokens() == 1); - REQUIRE(tb->get_last_seen() == 22); + REQUIRE(tb->get_tokens() == 1); + REQUIRE(tb->get_last_seen() == 22); } TEST_CASE("token bucket with 2 tokens/sec rate, max 10 tokens", "[token_bucket]") { - auto tb = new token_bucket(); - tb->init(2.0, 10, 1); - - SECTION("claiming 5 tokens") - { - bool claimed = tb->claim(5, 1000000001); - REQUIRE(tb->get_last_seen() == 1000000001); - REQUIRE(tb->get_tokens() == 5.0_a); - REQUIRE(claimed); + auto tb = new token_bucket(); + tb->init(2.0, 10, 1); - SECTION("claiming all the 7 remaining tokens") + SECTION("claiming 5 tokens") { - bool claimed = tb->claim(7, 2000000001); - REQUIRE(tb->get_last_seen() == 2000000001); - REQUIRE(tb->get_tokens() == 0.0_a); - REQUIRE(claimed); - - SECTION("claiming 1 token more than the 2 available fails") - { - bool claimed = tb->claim(3, 3000000001); - REQUIRE(tb->get_last_seen() == 3000000001); - REQUIRE(tb->get_tokens() == 2.0_a); - REQUIRE_FALSE(claimed); - } + bool claimed = tb->claim(5, 1000000001); + REQUIRE(tb->get_last_seen() == 1000000001); + REQUIRE(tb->get_tokens() == 5.0_a); + REQUIRE(claimed); + + SECTION("claiming all the 7 remaining tokens") + { + bool claimed = tb->claim(7, 2000000001); + REQUIRE(tb->get_last_seen() == 2000000001); + REQUIRE(tb->get_tokens() == 0.0_a); + REQUIRE(claimed); + + SECTION("claiming 1 token more than the 2 available fails") + { + bool claimed = tb->claim(3, 3000000001); + REQUIRE(tb->get_last_seen() == 3000000001); + REQUIRE(tb->get_tokens() == 2.0_a); + REQUIRE_FALSE(claimed); + } + } } - } } TEST_CASE("token bucket default initialization", "[token_bucket]") { - token_bucket tb; - REQUIRE(tb.get_tokens() == 1); + token_bucket tb; + REQUIRE(tb.get_tokens() == 1); } diff --git a/userspace/engine/token_bucket.cpp b/userspace/engine/token_bucket.cpp index 6dd7ea00cab..0cc749a76a4 100644 --- a/userspace/engine/token_bucket.cpp +++ b/userspace/engine/token_bucket.cpp @@ -24,14 +24,15 @@ limitations under the License. #include "token_bucket.h" #include "utils.h" -token_bucket::token_bucket() : token_bucket(sinsp_utils::get_current_time_ns) +token_bucket::token_bucket(): + token_bucket(sinsp_utils::get_current_time_ns) { } token_bucket::token_bucket(std::function timer) { - m_timer = timer; - init(1, 1); + m_timer = timer; + init(1, 1); } token_bucket::~token_bucket() @@ -40,51 +41,51 @@ token_bucket::~token_bucket() void token_bucket::init(double rate, double max_tokens, uint64_t now) { - m_rate = rate; - m_max_tokens = max_tokens; - m_tokens = max_tokens; - m_last_seen = now == 0 ? m_timer() : now; + m_rate = rate; + m_max_tokens = max_tokens; + m_tokens = max_tokens; + m_last_seen = now == 0 ? m_timer() : now; } bool token_bucket::claim() { - return claim(1, m_timer()); + return claim(1, m_timer()); } bool token_bucket::claim(double tokens, uint64_t now) { - double tokens_gained = m_rate * ((now - m_last_seen) / (1000000000.0)); - m_last_seen = now; + double tokens_gained = m_rate * ((now - m_last_seen) / (1000000000.0)); + m_last_seen = now; - m_tokens += tokens_gained; + m_tokens += tokens_gained; - // - // Cap at max_tokens - // - if(m_tokens > m_max_tokens) + // + // Cap at max_tokens + // + if(m_tokens > m_max_tokens) { - m_tokens = m_max_tokens; + m_tokens = m_max_tokens; } - // - // If m_tokens is < tokens, can't claim. - // - if(m_tokens < tokens) + // + // If m_tokens is < tokens, can't claim. + // + if(m_tokens < tokens) { - return false; + return false; } - m_tokens -= tokens; + m_tokens -= tokens; - return true; + return true; } double token_bucket::get_tokens() { - return m_tokens; + return m_tokens; } uint64_t token_bucket::get_last_seen() { - return m_last_seen; + return m_last_seen; } diff --git a/userspace/engine/token_bucket.h b/userspace/engine/token_bucket.h index 1dd60c26ea0..731a38c77f8 100644 --- a/userspace/engine/token_bucket.h +++ b/userspace/engine/token_bucket.h @@ -26,55 +26,55 @@ limitations under the License. // for limited bursting in the form of "banked" tokens. class token_bucket { - public: - token_bucket(); - token_bucket(std::function timer); - virtual ~token_bucket(); - - // - // Initialize the token bucket and start accumulating tokens - // - void init(double rate, double max_tokens, uint64_t now = 0); - - // - // Try to claim tokens tokens from the token bucket, using a - // timestamp of now. Returns true if the tokens could be - // claimed. Also updates internal metrics. - // - bool claim(double tokens, uint64_t now); - - // Simpler version of claim that claims a single token and - // uses the current time for now - bool claim(); - - // Return the current number of tokens available - double get_tokens(); - - // Return the last time someone tried to claim a token. - uint64_t get_last_seen(); - - private: - std::function m_timer; - - // - // The number of tokens generated per second. - // - double m_rate; - - // - // The maximum number of tokens that can be banked for future - // claim()s. - // - double m_max_tokens; - - // - // The current number of tokens - // - double m_tokens; - - // - // The last time claim() was called (or the object was created). - // Nanoseconds since the epoch. - // - uint64_t m_last_seen; +public: + token_bucket(); + token_bucket(std::function timer); + virtual ~token_bucket(); + + // + // Initialize the token bucket and start accumulating tokens + // + void init(double rate, double max_tokens, uint64_t now = 0); + + // + // Try to claim tokens tokens from the token bucket, using a + // timestamp of now. Returns true if the tokens could be + // claimed. Also updates internal metrics. + // + bool claim(double tokens, uint64_t now); + + // Simpler version of claim that claims a single token and + // uses the current time for now + bool claim(); + + // Return the current number of tokens available + double get_tokens(); + + // Return the last time someone tried to claim a token. + uint64_t get_last_seen(); + +private: + std::function m_timer; + + // + // The number of tokens generated per second. + // + double m_rate; + + // + // The maximum number of tokens that can be banked for future + // claim()s. + // + double m_max_tokens; + + // + // The current number of tokens + // + double m_tokens; + + // + // The last time claim() was called (or the object was created). + // Nanoseconds since the epoch. + // + uint64_t m_last_seen; }; From e688ab7d0a88ca9dc678a0c3c4aa7821f6f4961d Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Tue, 2 Jul 2019 16:19:22 +0000 Subject: [PATCH 43/64] chore: remove find catch from cmake files Signed-off-by: Lorenzo Fontana Co-authored-by: Leonardo Di Donato --- cmake/modules/FindCatch.cmake | 34 ---------------------------------- 1 file changed, 34 deletions(-) delete mode 100644 cmake/modules/FindCatch.cmake diff --git a/cmake/modules/FindCatch.cmake b/cmake/modules/FindCatch.cmake deleted file mode 100644 index 88f18149f89..00000000000 --- a/cmake/modules/FindCatch.cmake +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (C) 2016-2019 Draios Inc dba Sysdig. -# -# This file is part of falco . -# -# 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(ExternalProject) - -set(CATCH_EXTERNAL_URL - URL https://github.com/catchorg/Catch2/archive/v2.9.1.tar.gz - URL_HASH MD5=4980778888fed635bf191d8a86f9f89c) -ExternalProject_Add(catch2 - PREFIX ${CMAKE_BINARY_DIR}/catch2-prefix - ${CATCH_EXTERNAL_URL} - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/catch2-prefix/src/catch2/single_include/catch2/catch.hpp - ${CMAKE_BINARY_DIR}/catch2-prefix/include/catch.hpp -) -add_library(catch INTERFACE) -add_dependencies(catch catch2) -target_include_directories(catch INTERFACE ${CMAKE_BINARY_DIR}/catch2-prefix/include) - From 19c12042f4b039022dbee7bfd3261f70de08b5e0 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Wed, 3 Jul 2019 10:05:45 +0000 Subject: [PATCH 44/64] update: sysdig dir gate in subdirectories Signed-off-by: Lorenzo Fontana Co-authored-by: Leonardo Di Donato --- scripts/CMakeLists.txt | 4 ++++ tests/CMakeLists.txt | 1 + userspace/engine/CMakeLists.txt | 4 ++++ userspace/falco/CMakeLists.txt | 9 ++++++--- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index c76f99176dd..fbec666c409 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -18,6 +18,10 @@ configure_file(debian/postinst.in debian/postinst) configure_file(debian/prerm.in debian/prerm) +if(NOT SYSDIG_DIR) + set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig") +endif() + file(COPY "${PROJECT_SOURCE_DIR}/scripts/debian/falco" DESTINATION "${PROJECT_BINARY_DIR}/scripts/debian") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5919f5115c9..c0a6ab77109 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -40,6 +40,7 @@ if(FALCO_BUILD_TESTS) "${FAKEIT_INCLUDE}" "${PROJECT_SOURCE_DIR}/userspace/engine") + include(CMakeParseArguments) include(CTest) include(Catch) catch_discover_tests(falco_test) diff --git a/userspace/engine/CMakeLists.txt b/userspace/engine/CMakeLists.txt index af63c76330a..99d2ebe25c2 100644 --- a/userspace/engine/CMakeLists.txt +++ b/userspace/engine/CMakeLists.txt @@ -15,6 +15,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +if(NOT SYSDIG_DIR) + set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig") +endif() + set(FALCO_ENGINE_SOURCE_FILES rules.cpp falco_common.cpp diff --git a/userspace/falco/CMakeLists.txt b/userspace/falco/CMakeLists.txt index 7f14fd929e4..fb5b5355fa8 100644 --- a/userspace/falco/CMakeLists.txt +++ b/userspace/falco/CMakeLists.txt @@ -15,8 +15,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # +if(NOT SYSDIG_DIR) + set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig") +endif() -configure_file("${PROJECT_SOURCE_DIR}/../sysdig/userspace/sysdig/config_sysdig.h.in" config_sysdig.h) +configure_file("${SYSDIG_DIR}/userspace/sysdig/config_sysdig.h.in" config_sysdig.h) add_executable(falco configuration.cpp @@ -25,7 +28,7 @@ add_executable(falco event_drops.cpp statsfilewriter.cpp falco.cpp - "${PROJECT_SOURCE_DIR}/../sysdig/userspace/sysdig/fields_info.cpp" + "${SYSDIG_DIR}/userspace/sysdig/fields_info.cpp" webserver.cpp) target_include_directories(falco PUBLIC @@ -39,7 +42,7 @@ target_include_directories(falco PUBLIC target_link_libraries(falco falco_engine sinsp) target_link_libraries(falco - "${LIBYAML_LIB}" + "${LIBYAML_LIB}" "${YAMLCPP_LIB}" "${CIVETWEB_LIB}") From c1035ce4de6fd83901525f21d2d24c097acf96e7 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Thu, 27 Jun 2019 16:18:51 -0700 Subject: [PATCH 45/64] Make field index information public Json-related filtercheck fields supported indexing with brackets, but when looking at the field descriptions you couldn't tell if a field allowed an index, required an index, or did not allow an index. This information was available, but it was a part of the protected aliases map within the class. Move this to the public field information so it can be used outside the class. Also add m_ prefixes for member names, now that the struct isn't trivial. Signed-off-by: Mark Stemm --- userspace/engine/falco_engine.cpp | 12 +-- userspace/engine/json_evt.cpp | 124 ++++++++++++++++++------------ userspace/engine/json_evt.h | 51 ++++++------ 3 files changed, 107 insertions(+), 80 deletions(-) diff --git a/userspace/engine/falco_engine.cpp b/userspace/engine/falco_engine.cpp index 93e9c6dc564..dc8673b7f2e 100644 --- a/userspace/engine/falco_engine.cpp +++ b/userspace/engine/falco_engine.cpp @@ -93,21 +93,21 @@ void falco_engine::list_fields(bool names_only) if(!names_only) { printf("\n----------------------\n"); - printf("Field Class: %s (%s)\n\n", chk_field.name.c_str(), chk_field.desc.c_str()); + printf("Field Class: %s (%s)\n\n", chk_field.m_name.c_str(), chk_field.m_desc.c_str()); } - for(auto &field : chk_field.fields) + for(auto &field : chk_field.m_fields) { uint32_t l, m; - printf("%s", field.name.c_str()); + printf("%s", field.m_name.c_str()); if(names_only) { printf("\n"); continue; } - uint32_t namelen = field.name.size(); + uint32_t namelen = field.m_name.size(); if(namelen >= DESCRIPTION_TEXT_START) { @@ -120,7 +120,7 @@ void falco_engine::list_fields(bool names_only) printf(" "); } - size_t desclen = field.desc.size(); + size_t desclen = field.m_desc.size(); for(l = 0; l < desclen; l++) { @@ -134,7 +134,7 @@ void falco_engine::list_fields(bool names_only) } } - printf("%c", field.desc.at(l)); + printf("%c", field.m_desc.at(l)); } printf("\n"); diff --git a/userspace/engine/json_evt.cpp b/userspace/engine/json_evt.cpp index 7adc4d953a2..f45875c728c 100644 --- a/userspace/engine/json_evt.cpp +++ b/userspace/engine/json_evt.cpp @@ -70,33 +70,54 @@ std::string json_event_filter_check::json_as_string(const json &j) } } -json_event_filter_check::alias::alias() +json_event_filter_check::field_info::field_info() : m_idx_mode(IDX_NONE), m_idx_type(IDX_NUMERIC) { } -json_event_filter_check::alias::alias(nlohmann::json::json_pointer ptr) - : m_jptr(ptr), m_format(def_format), +json_event_filter_check::field_info::field_info(std::string name, + std::string desc) + : m_name(name), m_desc(desc), m_idx_mode(IDX_NONE), m_idx_type(IDX_NUMERIC) { } -json_event_filter_check::alias::alias(nlohmann::json::json_pointer ptr, - format_t format) - : m_jptr(ptr), m_format(format), - m_idx_mode(IDX_NONE), m_idx_type(IDX_NUMERIC) +json_event_filter_check::field_info::field_info(std::string name, + std::string desc, + index_mode mode) + : m_name(name), m_desc(desc), + m_idx_mode(mode), m_idx_type(IDX_NUMERIC) { } -json_event_filter_check::alias::alias(nlohmann::json::json_pointer ptr, - format_t format, - index_mode mode, - index_type itype) - : m_jptr(ptr), m_format(format), +json_event_filter_check::field_info::field_info(std::string name, + std::string desc, + index_mode mode, + index_type itype) + : m_name(name), m_desc(desc), m_idx_mode(mode), m_idx_type(itype) { } +json_event_filter_check::field_info::~field_info() +{ +} + +json_event_filter_check::alias::alias() +{ +} + +json_event_filter_check::alias::alias(nlohmann::json::json_pointer ptr) + : m_jptr(ptr), m_format(def_format) +{ +} + +json_event_filter_check::alias::alias(nlohmann::json::json_pointer ptr, + format_t format) + : m_jptr(ptr), m_format(format) +{ +} + json_event_filter_check::alias::~alias() { } @@ -118,18 +139,25 @@ int32_t json_event_filter_check::parse_field_name(const char *str, bool alloc_st size_t idx_len = 0; - for(auto &pair : m_aliases) + for(auto &info : m_info.m_fields) { + if(m_aliases.find(info.m_name) == m_aliases.end()) + { + throw falco_exception("Could not find alias for field name " + info.m_name); + } + + auto &al = m_aliases[info.m_name]; + // What follows the match must not be alphanumeric or a dot - if(strncmp(pair.first.c_str(), str, pair.first.size()) == 0 && - !isalnum((int) str[pair.first.size()]) && - str[pair.first.size()] != '.' && - pair.first.size() > match_len) + if(strncmp(info.m_name.c_str(), str, info.m_name.size()) == 0 && + !isalnum((int) str[info.m_name.size()]) && + str[info.m_name.size()] != '.' && + info.m_name.size() > match_len) { - m_jptr = pair.second.m_jptr; - m_field = pair.first; - m_format = pair.second.m_format; - match_len = pair.first.size(); + m_jptr = al.m_jptr; + m_field = info.m_name; + m_format = al.m_format; + match_len = info.m_name.size(); const char *start = str + m_field.size(); @@ -147,18 +175,18 @@ int32_t json_event_filter_check::parse_field_name(const char *str, bool alloc_st idx_len = (end - start + 2); } - if(m_idx.empty() && pair.second.m_idx_mode == alias::IDX_REQUIRED) + if(m_idx.empty() && info.m_idx_mode == IDX_REQUIRED) { throw falco_exception(string("When parsing filtercheck ") + string(str) + string(": ") + m_field + string(" requires an index but none provided")); } - if(!m_idx.empty() && pair.second.m_idx_mode == alias::IDX_NONE) + if(!m_idx.empty() && info.m_idx_mode == IDX_NONE) { throw falco_exception(string("When parsing filtercheck ") + string(str) + string(": ") + m_field + string(" forbids an index but one provided")); } if(!m_idx.empty() && - pair.second.m_idx_type == alias::IDX_NUMERIC && + info.m_idx_type == IDX_NUMERIC && m_idx.find_first_not_of("0123456789") != string::npos) { throw falco_exception(string("When parsing filtercheck ") + string(str) + string(": ") + m_field + string(" requires a numeric index")); @@ -291,7 +319,7 @@ jevt_filter_check::jevt_filter_check() {s_jevt_time_field, "json event timestamp as a string that includes the nanosecond part"}, {s_jevt_time_iso_8601_field, "json event timestamp in ISO 8601 format, including nanoseconds and time zone offset (in UTC)"}, {s_jevt_rawtime_field, "absolute event timestamp, i.e. nanoseconds from epoch."}, - {s_jevt_value_field, "General way to access single property from json object. The syntax is []. The property is returned as a string"}, + {s_jevt_value_field, "General way to access single property from json object. The syntax is []. The property is returned as a string", IDX_REQUIRED, IDX_KEY}, {s_jevt_obj_field, "The entire json object, stringified"} }}; } @@ -603,36 +631,34 @@ k8s_audit_filter_check::k8s_audit_filter_check() {"ka.impuser.name", "The impersonated user name"}, {"ka.verb", "The action being performed"}, {"ka.uri", "The request URI as sent from client to server"}, - {"ka.uri.param", "The value of a given query parameter in the uri (e.g. when uri=/foo?key=val, ka.uri.param[key] is val)."}, + {"ka.uri.param", "The value of a given query parameter in the uri (e.g. when uri=/foo?key=val, ka.uri.param[key] is val).", IDX_REQUIRED, IDX_KEY}, {"ka.target.name", "The target object name"}, {"ka.target.namespace", "The target object namespace"}, {"ka.target.resource", "The target object resource"}, {"ka.target.subresource", "The target object subresource"}, {"ka.req.binding.subjects", "When the request object refers to a cluster role binding, the subject (e.g. account/users) being linked by the binding"}, - {"ka.req.binding.subject.has_name", "When the request object refers to a cluster role binding, return true if a subject with the provided name exists"}, + {"ka.req.binding.subject.has_name", "When the request object refers to a cluster role binding, return true if a subject with the provided name exists", IDX_REQUIRED, IDX_KEY}, {"ka.req.binding.role", "When the request object refers to a cluster role binding, the role being linked by the binding"}, {"ka.req.configmap.name", "If the request object refers to a configmap, the configmap name"}, {"ka.req.configmap.obj", "If the request object refers to a configmap, the entire configmap object"}, - {"ka.req.container.image", "When the request object refers to a container, the container's images. Can be indexed (e.g. ka.req.container.image[0]). Without any index, returns the first image"}, - {"ka.req.container.image.repository", "The same as req.container.image, but only the repository part (e.g. sysdig/falco)"}, + {"ka.req.container.image", "When the request object refers to a container, the container's images. Can be indexed (e.g. ka.req.container.image[0]). Without any index, returns the first image", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.container.image.repository", "The same as req.container.image, but only the repository part (e.g. sysdig/falco)", IDX_ALLOWED, IDX_NUMERIC}, {"ka.req.container.host_network", "When the request object refers to a container, the value of the hostNetwork flag."}, - {"ka.req.container.privileged", "When the request object refers to a container, whether or not any container is run privileged. With an index, return whether or not the ith container is run privileged."}, + {"ka.req.container.privileged", "When the request object refers to a container, whether or not any container is run privileged. With an index, return whether or not the ith container is run privileged.", IDX_ALLOWED, IDX_NUMERIC}, {"ka.req.role.rules", "When the request object refers to a role/cluster role, the rules associated with the role"}, - {"ka.req.role.rules.apiGroups", "When the request object refers to a role/cluster role, the api groups associated with the role's rules. With an index, return only the api groups from the ith rule. Without an index, return all api groups concatenated"}, - {"ka.req.role.rules.nonResourceURLs", "When the request object refers to a role/cluster role, the non resource urls associated with the role's rules. With an index, return only the non resource urls from the ith rule. Without an index, return all non resource urls concatenated"}, - {"ka.req.role.rules.verbs", "When the request object refers to a role/cluster role, the verbs associated with the role's rules. With an index, return only the verbs from the ith rule. Without an index, return all verbs concatenated"}, - {"ka.req.role.rules.resources", "When the request object refers to a role/cluster role, the resources associated with the role's rules. With an index, return only the resources from the ith rule. Without an index, return all resources concatenated"}, + {"ka.req.role.rules.apiGroups", "When the request object refers to a role/cluster role, the api groups associated with the role's rules. With an index, return only the api groups from the ith rule. Without an index, return all api groups concatenated", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.role.rules.nonResourceURLs", "When the request object refers to a role/cluster role, the non resource urls associated with the role's rules. With an index, return only the non resource urls from the ith rule. Without an index, return all non resource urls concatenated", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.role.rules.verbs", "When the request object refers to a role/cluster role, the verbs associated with the role's rules. With an index, return only the verbs from the ith rule. Without an index, return all verbs concatenated", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.role.rules.resources", "When the request object refers to a role/cluster role, the resources associated with the role's rules. With an index, return only the resources from the ith rule. Without an index, return all resources concatenated", IDX_ALLOWED, IDX_NUMERIC}, {"ka.req.service.type", "When the request object refers to a service, the service type"}, - {"ka.req.service.ports", "When the request object refers to a service, the service's ports. Can be indexed (e.g. ka.req.service.ports[0]). Without any index, returns all ports"}, - {"ka.req.volume.hostpath", "If the request object contains volume definitions, whether or not a hostPath volume exists that mounts the specified path from the host (...hostpath[/etc]=true if a volume mounts /etc from the host). The index can be a glob, in which case all volumes are considered to find any path matching the specified glob (...hostpath[/usr/*] would match either /usr/local or /usr/bin)"}, + {"ka.req.service.ports", "When the request object refers to a service, the service's ports. Can be indexed (e.g. ka.req.service.ports[0]). Without any index, returns all ports", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.volume.hostpath", "If the request object contains volume definitions, whether or not a hostPath volume exists that mounts the specified path from the host (...hostpath[/etc]=true if a volume mounts /etc from the host). The index can be a glob, in which case all volumes are considered to find any path matching the specified glob (...hostpath[/usr/*] would match either /usr/local or /usr/bin)", IDX_REQUIRED, IDX_KEY}, {"ka.resp.name", "The response object name"}, {"ka.response.code", "The response code"}, {"ka.response.reason", "The response reason (usually present only for failures)"} }}; { - using a = alias; - m_aliases = { {"ka.auditid", {"/auditID"_json_pointer}}, {"ka.stage", {"/stage"_json_pointer}}, @@ -643,28 +669,28 @@ k8s_audit_filter_check::k8s_audit_filter_check() {"ka.impuser.name", {"/impersonatedUser/username"_json_pointer}}, {"ka.verb", {"/verb"_json_pointer}}, {"ka.uri", {"/requestURI"_json_pointer}}, - {"ka.uri.param", {"/requestURI"_json_pointer, index_query_param, a::IDX_REQUIRED, a::IDX_KEY}}, + {"ka.uri.param", {"/requestURI"_json_pointer, index_query_param}}, {"ka.target.name", {"/objectRef/name"_json_pointer}}, {"ka.target.namespace", {"/objectRef/namespace"_json_pointer}}, {"ka.target.resource", {"/objectRef/resource"_json_pointer}}, {"ka.target.subresource", {"/objectRef/subresource"_json_pointer}}, {"ka.req.binding.subjects", {"/requestObject/subjects"_json_pointer}}, - {"ka.req.binding.subject.has_name", {"/requestObject/subjects"_json_pointer, index_has_name, a::IDX_REQUIRED, a::IDX_KEY}}, + {"ka.req.binding.subject.has_name", {"/requestObject/subjects"_json_pointer, index_has_name}}, {"ka.req.binding.role", {"/requestObject/roleRef/name"_json_pointer}}, {"ka.req.configmap.name", {"/objectRef/name"_json_pointer}}, {"ka.req.configmap.obj", {"/requestObject/data"_json_pointer}}, - {"ka.req.container.image", {"/requestObject/spec/containers"_json_pointer, index_image, a::IDX_ALLOWED, a::IDX_NUMERIC}}, - {"ka.req.container.image.repository", {"/requestObject/spec/containers"_json_pointer, index_image, a::IDX_ALLOWED, a::IDX_NUMERIC}}, + {"ka.req.container.image", {"/requestObject/spec/containers"_json_pointer, index_image}}, + {"ka.req.container.image.repository", {"/requestObject/spec/containers"_json_pointer, index_image}}, {"ka.req.container.host_network", {"/requestObject/spec/hostNetwork"_json_pointer}}, - {"ka.req.container.privileged", {"/requestObject/spec/containers"_json_pointer, index_privileged, a::IDX_ALLOWED, a::IDX_NUMERIC}}, + {"ka.req.container.privileged", {"/requestObject/spec/containers"_json_pointer, index_privileged}}, {"ka.req.role.rules", {"/requestObject/rules"_json_pointer}}, - {"ka.req.role.rules.apiGroups", {"/requestObject/rules"_json_pointer, index_select, a::IDX_ALLOWED, a::IDX_NUMERIC}}, - {"ka.req.role.rules.nonResourceURLs", {"/requestObject/rules"_json_pointer, index_select, a::IDX_ALLOWED, a::IDX_NUMERIC}}, - {"ka.req.role.rules.resources", {"/requestObject/rules"_json_pointer, index_select, a::IDX_ALLOWED, a::IDX_NUMERIC}}, - {"ka.req.role.rules.verbs", {"/requestObject/rules"_json_pointer, index_select, a::IDX_ALLOWED, a::IDX_NUMERIC}}, + {"ka.req.role.rules.apiGroups", {"/requestObject/rules"_json_pointer, index_select}}, + {"ka.req.role.rules.nonResourceURLs", {"/requestObject/rules"_json_pointer, index_select}}, + {"ka.req.role.rules.resources", {"/requestObject/rules"_json_pointer, index_select}}, + {"ka.req.role.rules.verbs", {"/requestObject/rules"_json_pointer, index_select}}, {"ka.req.service.type", {"/requestObject/spec/type"_json_pointer}}, - {"ka.req.service.ports", {"/requestObject/spec/ports"_json_pointer, index_generic, a::IDX_ALLOWED, a::IDX_NUMERIC}}, - {"ka.req.volume.hostpath", {"/requestObject/spec/volumes"_json_pointer, check_hostpath_vols, a::IDX_REQUIRED, a::IDX_KEY}}, + {"ka.req.service.ports", {"/requestObject/spec/ports"_json_pointer, index_generic}}, + {"ka.req.volume.hostpath", {"/requestObject/spec/volumes"_json_pointer, check_hostpath_vols}}, {"ka.resp.name", {"/responseObject/metadata/name"_json_pointer}}, {"ka.response.code", {"/responseStatus/code"_json_pointer}}, {"ka.response.reason", {"/responseStatus/reason"_json_pointer}} diff --git a/userspace/engine/json_evt.h b/userspace/engine/json_evt.h index e04d73fda70..b4ad05733a5 100644 --- a/userspace/engine/json_evt.h +++ b/userspace/engine/json_evt.h @@ -62,19 +62,40 @@ class json_event : public gen_event class json_event_filter_check : public gen_event_filter_check { public: + enum index_mode { + IDX_REQUIRED, + IDX_ALLOWED, + IDX_NONE + }; + + enum index_type { + IDX_KEY, + IDX_NUMERIC + }; // A struct describing a single filtercheck field ("ka.user") struct field_info { - std::string name; - std::string desc; + std::string m_name; + std::string m_desc; + + index_mode m_idx_mode; + index_type m_idx_type; + // The variants allow for brace-initialization either + // with just the name/desc or additionally with index + // information + field_info(); + field_info(std::string name, std::string desc); + field_info(std::string name, std::string desc, index_mode mode); + field_info(std::string name, std::string desc, index_mode mode, index_type itype); + virtual ~field_info(); }; // A struct describing a group of filtercheck fields ("ka") struct check_info { - std::string name; - std::string desc; + std::string m_name; + std::string m_desc; - std::list fields; + std::list m_fields; }; json_event_filter_check(); @@ -115,28 +136,12 @@ class json_event_filter_check : public gen_event_filter_check typedef std::function format_t; struct alias { - - // Whether this alias requires an index, allows an - // index, or should not have an index. - enum index_mode { - IDX_REQUIRED, - IDX_ALLOWED, - IDX_NONE - }; - - enum index_type { - IDX_KEY, - IDX_NUMERIC - }; - // The variants allow for brace-initialization either // with just the pointer or with both the pointer and // a format function. alias(); alias(nlohmann::json::json_pointer ptr); alias(nlohmann::json::json_pointer ptr, format_t format); - alias(nlohmann::json::json_pointer ptr, format_t format, index_mode mode); - alias(nlohmann::json::json_pointer ptr, format_t format, index_mode mode, index_type itype); virtual ~alias(); // A json pointer used to extract a referenced value @@ -149,10 +154,6 @@ class json_event_filter_check : public gen_event_filter_check // indexing, searches, etc.) or string reformatting to // trim unnecessary parts of the value. format_t m_format; - - index_mode m_idx_mode; - - index_type m_idx_type; }; // This map defines the aliases defined by this filter check From 047f12d0f6e965a566f2c73122334d5105ee06cb Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Thu, 27 Jun 2019 16:38:09 -0700 Subject: [PATCH 46/64] More efficient searches for defined filters Instead of iterating over the entire list of filters and doing pattern matches against each defined filter, perform table lookups. For filters that take arguments e.g. proc.aname[3] or evt.arg.xxx, split the filtercheck string on bracket/dot and check the values against a table. There are now two tables of defined filters: defined_arg_filters and defined_noarg_filters. Each filter is put into a table depending on whether the filter takes an argument or not. Signed-off-by: Mark Stemm --- userspace/engine/lua/rule_loader.lua | 30 +++++++++-- userspace/engine/rules.cpp | 74 +++++++++++++++++++--------- userspace/engine/rules.h | 3 +- 3 files changed, 78 insertions(+), 29 deletions(-) diff --git a/userspace/engine/lua/rule_loader.lua b/userspace/engine/lua/rule_loader.lua index 055dddf466a..4f045b98bd7 100644 --- a/userspace/engine/lua/rule_loader.lua +++ b/userspace/engine/lua/rule_loader.lua @@ -433,10 +433,32 @@ function load_rules(sinsp_lua_parser, for filter, _ in pairs(filters) do found = false - for pat, _ in pairs(defined_filters) do - if string.match(filter, pat) ~= nil then - found = true - break + if defined_noarg_filters[filter] ~= nil then + found = true + else + bracket_idx = string.find(filter, "[", 1, true) + + if bracket_idx ~= nil then + subfilter = string.sub(filter, 1, bracket_idx-1) + + if defined_arg_filters[subfilter] ~= nil then + found = true + end + end + + if not found then + dot_idx = string.find(filter, ".", 1, true) + + while dot_idx ~= nil do + subfilter = string.sub(filter, 1, dot_idx-1) + + if defined_arg_filters[subfilter] ~= nil then + found = true + break + end + + dot_idx = string.find(filter, ".", dot_idx+1, true) + end end end diff --git a/userspace/engine/rules.cpp b/userspace/engine/rules.cpp index c8c45ef8867..140fc8803fa 100644 --- a/userspace/engine/rules.cpp +++ b/userspace/engine/rules.cpp @@ -323,12 +323,12 @@ void falco_rules::load_rules(const string &rules_content, lua_setglobal(m_ls, m_lua_ignored_syscalls.c_str()); - // Create a table containing all filtercheck names. - lua_newtable(m_ls); - vector fc_plugins; sinsp::get_filtercheck_fields_info(&fc_plugins); + set no_argument_filters; + set argument_filters; + for(uint32_t j = 0; j < fc_plugins.size(); j++) { const filter_check_info* fci = fc_plugins[j]; @@ -350,45 +350,71 @@ void falco_rules::load_rules(const string &rules_content, // Some filters can work with or without an argument std::set flexible_filters = { - "^proc.aname", - "^proc.apid" + "proc.aname", + "proc.apid" }; - std::list fields; - std::string field_base = string("^") + fld->m_name; - if(fld->m_flags & EPF_REQUIRES_ARGUMENT || - flexible_filters.find(field_base) != flexible_filters.end()) + flexible_filters.find(fld->m_name) != flexible_filters.end()) { - fields.push_back(field_base + "[%[%.]"); + argument_filters.insert(fld->m_name); } if(!(fld->m_flags & EPF_REQUIRES_ARGUMENT) || - flexible_filters.find(field_base) != flexible_filters.end()) - { - fields.push_back(field_base + "$"); - } - - for(auto &field : fields) + flexible_filters.find(fld->m_name) != flexible_filters.end()) { - lua_pushstring(m_ls, field.c_str()); - lua_pushnumber(m_ls, 1); - lua_settable(m_ls, -3); + no_argument_filters.insert(fld->m_name); } } } for(auto &chk_field : m_engine->json_factory().get_fields()) { - for(auto &field : chk_field.fields) + for(auto &field : chk_field.m_fields) { - lua_pushstring(m_ls, field.name.c_str()); - lua_pushnumber(m_ls, 1); - lua_settable(m_ls, -3); + switch(field.m_idx_mode) + { + case json_event_filter_check::IDX_REQUIRED: + argument_filters.insert(field.m_name); + break; + case json_event_filter_check::IDX_ALLOWED: + argument_filters.insert(field.m_name); + no_argument_filters.insert(field.m_name); + break; + case json_event_filter_check::IDX_NONE: + no_argument_filters.insert(field.m_name); + break; + default: + break; + } } } - lua_setglobal(m_ls, m_lua_defined_filters.c_str()); + // Create tables containing all filtercheck + // names. They are split into names that require + // arguments and ones that do not. + + lua_newtable(m_ls); + + for(auto &field : argument_filters) + { + lua_pushstring(m_ls, field.c_str()); + lua_pushnumber(m_ls, 1); + lua_settable(m_ls, -3); + } + + lua_setglobal(m_ls, m_lua_defined_arg_filters.c_str()); + + lua_newtable(m_ls); + + for(auto &field : no_argument_filters) + { + lua_pushstring(m_ls, field.c_str()); + lua_pushnumber(m_ls, 1); + lua_settable(m_ls, -3); + } + + lua_setglobal(m_ls, m_lua_defined_noarg_filters.c_str()); lua_pushlightuserdata(m_ls, m_sinsp_lua_parser); lua_pushlightuserdata(m_ls, m_json_lua_parser); diff --git a/userspace/engine/rules.h b/userspace/engine/rules.h index 47fb454a075..02037b176f8 100644 --- a/userspace/engine/rules.h +++ b/userspace/engine/rules.h @@ -67,7 +67,8 @@ class falco_rules string m_lua_load_rules = "load_rules"; string m_lua_ignored_syscalls = "ignored_syscalls"; string m_lua_ignored_events = "ignored_events"; - string m_lua_defined_filters = "defined_filters"; + string m_lua_defined_arg_filters = "defined_arg_filters"; + string m_lua_defined_noarg_filters = "defined_noarg_filters"; string m_lua_events = "events"; string m_lua_syscalls = "syscalls"; string m_lua_describe_rule = "describe_rule"; From 0e4f2ec17c2db3cea852b67bb53a3d0f6001b936 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Thu, 27 Jun 2019 16:59:16 -0700 Subject: [PATCH 47/64] Skip unnecessary string cleanups We shouldn't need to clean up strings via a cleanup function and don't need to do it via a bunch of string.gsub() functions. Signed-off-by: Mark Stemm --- userspace/engine/lua/parser.lua | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/userspace/engine/lua/parser.lua b/userspace/engine/lua/parser.lua index 5cd951c5a86..bd96b4d4a68 100644 --- a/userspace/engine/lua/parser.lua +++ b/userspace/engine/lua/parser.lua @@ -152,22 +152,6 @@ local function rel (left, sep, right) return left * sep * right / function(e1, op, e2) return { type = "BinaryRelOp", operator = op, left = e1, right = e2 } end end -local function fix_str (str) - str = string.gsub(str, "\\a", "\a") - str = string.gsub(str, "\\b", "\b") - str = string.gsub(str, "\\f", "\f") - str = string.gsub(str, "\\n", "\n") - str = string.gsub(str, "\\r", "\r") - str = string.gsub(str, "\\t", "\t") - str = string.gsub(str, "\\v", "\v") - str = string.gsub(str, "\\\n", "\n") - str = string.gsub(str, "\\\r", "\n") - str = string.gsub(str, "\\'", "'") - str = string.gsub(str, '\\"', '"') - str = string.gsub(str, '\\\\', '\\') - return str -end - -- grammar @@ -243,7 +227,7 @@ local G = { (digit^1 * V"Expo"); Number = C(V"Hex" + V"Float" + V"Int") / function (n) return tonumber(n) end; - String = (P'"' * C(((P'\\' * P(1)) + (P(1) - P'"'))^0) * P'"' + P"'" * C(((P"\\" * P(1)) + (P(1) - P"'"))^0) * P"'") / function (s) return fix_str(s) end; + String = (P'"' * C(((P'\\' * P(1)) + (P(1) - P'"'))^0) * P'"' + P"'" * C(((P"\\" * P(1)) + (P(1) - P"'"))^0) * P"'"); BareString = C(((P(1) - S' (),='))^1); OrOp = kw("or") / "or"; From 52a44c171cc4c76f1c2bb73667e1376c23c6be20 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 28 Jun 2019 17:10:42 -0700 Subject: [PATCH 48/64] Look up priorities using a table This is faster than iteration + string case changes. Signed-off-by: Mark Stemm --- userspace/engine/lua/rule_loader.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/userspace/engine/lua/rule_loader.lua b/userspace/engine/lua/rule_loader.lua index 4f045b98bd7..a98b27bc624 100644 --- a/userspace/engine/lua/rule_loader.lua +++ b/userspace/engine/lua/rule_loader.lua @@ -59,17 +59,13 @@ function map(f, arr) return res end -priorities = {"Emergency", "Alert", "Critical", "Error", "Warning", "Notice", "Informational", "Debug"} -local function priority_num_for(s) - s = string.lower(s) - for i,v in ipairs(priorities) do - if (string.find(string.lower(v), "^"..s)) then - return i - 1 -- (numbers start at 0, lua indices start at 1) - end - end - error("Invalid priority level: "..s) -end +-- Permissive for case and for common abbreviations. +priorities = { + Emergency=0, Alert=1, Critical=2, Error=3, Warning=4, Notice=5, Informational=5, Debug=7, + EMERGENCY=0, ALERT=1, CRITICAL=2, ERROR=3, WARNING=4, NOTICE=5, INFORMATIONAL=5, DEBUG=7, + INFO=5 +} --[[ Take a filter AST and set it up in the libsinsp runtime, using the filter API. @@ -336,7 +332,11 @@ function load_rules(sinsp_lua_parser, end -- Convert the priority-as-string to a priority-as-number now - v['priority_num'] = priority_num_for(v['priority']) + v['priority_num'] = priorities[v['priority']] + + if v['priority_num'] == nil then + error("Invalid priority level: "..v['priority']) + end if v['priority_num'] <= min_priority then -- Note that we can overwrite rules, but the rules are still From 7501c3cb5d736cc72c5ec51bc03e129d37fd488b Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 28 Jun 2019 17:11:39 -0700 Subject: [PATCH 49/64] Expand lists without using regsub To speed up list expansion, instead of using regexes to replace a list name with its contents, do string searches followed by examining the preceding/following characters for the proper delimiter. Signed-off-by: Mark Stemm --- userspace/engine/lua/compiler.lua | 33 ++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/userspace/engine/lua/compiler.lua b/userspace/engine/lua/compiler.lua index 07b39c8933b..9a39cf7d925 100644 --- a/userspace/engine/lua/compiler.lua +++ b/userspace/engine/lua/compiler.lua @@ -152,16 +152,35 @@ end function compiler.expand_lists_in(source, list_defs) for name, def in pairs(list_defs) do - local begin_name_pat = "^("..name..")([%s(),=])" - local mid_name_pat = "([%s(),=])("..name..")([%s(),=])" - local end_name_pat = "([%s(),=])("..name..")$" - source, subcount1 = string.gsub(source, begin_name_pat, table.concat(def.items, ", ").."%2") - source, subcount2 = string.gsub(source, mid_name_pat, "%1"..table.concat(def.items, ", ").."%3") - source, subcount3 = string.gsub(source, end_name_pat, "%1"..table.concat(def.items, ", ")) + local bpos = string.find(source, name, 1, true) - if (subcount1 + subcount2 + subcount3) > 0 then + while bpos ~= nil do def.used = true + + local epos = bpos + string.len(name) + + -- The characters surrounding the name must be delimiters of beginning/end of string + if (bpos == 1 or string.match(string.sub(source, bpos-1, bpos-1), "[%s(),=]")) and (epos > string.len(source) or string.match(string.sub(source, epos, epos), "[%s(),=]")) then + new_source = "" + + if bpos > 1 then + new_source = new_source..string.sub(source, 1, bpos-1) + end + + sub = table.concat(def.items, ", ") + + new_source = new_source..sub + + if epos <= string.len(source) then + new_source = new_source..string.sub(source, epos, string.len(source)) + end + + source = new_source + bpos = bpos + (string.len(sub)-string.len(name)) + end + + bpos = string.find(source, name, bpos+1, true) end end From bf19d8c8816f4a809ba3ecff9a9fc24c9c0c718a Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Mon, 8 Jul 2019 12:52:36 +0000 Subject: [PATCH 50/64] chore: format json_evt in preparation to add fields Signed-off-by: Lorenzo Fontana Co-authored-by: Leonardo Di Donato --- userspace/engine/json_evt.cpp | 224 +++++++++++++++++----------------- 1 file changed, 113 insertions(+), 111 deletions(-) diff --git a/userspace/engine/json_evt.cpp b/userspace/engine/json_evt.cpp index f45875c728c..a40ab0ba649 100644 --- a/userspace/engine/json_evt.cpp +++ b/userspace/engine/json_evt.cpp @@ -19,8 +19,8 @@ limitations under the License. #include -#include "utils.h" #include "uri.h" +#include "utils.h" #include "falco_common.h" #include "json_evt.h" @@ -30,7 +30,6 @@ using namespace std; json_event::json_event() { - } json_event::~json_event() @@ -60,7 +59,7 @@ std::string json_event_filter_check::def_format(const json &j, std::string &fiel std::string json_event_filter_check::json_as_string(const json &j) { - if (j.type() == json::value_t::string) + if(j.type() == json::value_t::string) { return j; } @@ -70,32 +69,35 @@ std::string json_event_filter_check::json_as_string(const json &j) } } -json_event_filter_check::field_info::field_info() - : m_idx_mode(IDX_NONE), m_idx_type(IDX_NUMERIC) +json_event_filter_check::field_info::field_info(): + m_idx_mode(IDX_NONE), m_idx_type(IDX_NUMERIC) { } json_event_filter_check::field_info::field_info(std::string name, - std::string desc) - : m_name(name), m_desc(desc), - m_idx_mode(IDX_NONE), m_idx_type(IDX_NUMERIC) + std::string desc): + m_name(name), + m_desc(desc), + m_idx_mode(IDX_NONE), m_idx_type(IDX_NUMERIC) { } json_event_filter_check::field_info::field_info(std::string name, std::string desc, - index_mode mode) - : m_name(name), m_desc(desc), - m_idx_mode(mode), m_idx_type(IDX_NUMERIC) + index_mode mode): + m_name(name), + m_desc(desc), + m_idx_mode(mode), m_idx_type(IDX_NUMERIC) { } json_event_filter_check::field_info::field_info(std::string name, std::string desc, index_mode mode, - index_type itype) - : m_name(name), m_desc(desc), - m_idx_mode(mode), m_idx_type(itype) + index_type itype): + m_name(name), + m_desc(desc), + m_idx_mode(mode), m_idx_type(itype) { } @@ -107,14 +109,15 @@ json_event_filter_check::alias::alias() { } -json_event_filter_check::alias::alias(nlohmann::json::json_pointer ptr) - : m_jptr(ptr), m_format(def_format) +json_event_filter_check::alias::alias(nlohmann::json::json_pointer ptr): + m_jptr(ptr), m_format(def_format) { } json_event_filter_check::alias::alias(nlohmann::json::json_pointer ptr, - format_t format) - : m_jptr(ptr), m_format(format) + format_t format): + m_jptr(ptr), + m_format(format) { } @@ -122,8 +125,8 @@ json_event_filter_check::alias::~alias() { } -json_event_filter_check::json_event_filter_check() - : m_format(def_format) +json_event_filter_check::json_event_filter_check(): + m_format(def_format) { } @@ -150,7 +153,7 @@ int32_t json_event_filter_check::parse_field_name(const char *str, bool alloc_st // What follows the match must not be alphanumeric or a dot if(strncmp(info.m_name.c_str(), str, info.m_name.size()) == 0 && - !isalnum((int) str[info.m_name.size()]) && + !isalnum((int)str[info.m_name.size()]) && str[info.m_name.size()] != '.' && info.m_name.size() > match_len) { @@ -169,7 +172,7 @@ int32_t json_event_filter_check::parse_field_name(const char *str, bool alloc_st if(end != NULL) { - m_idx = string(start, end-start); + m_idx = string(start, end - start); } idx_len = (end - start + 2); @@ -197,14 +200,14 @@ int32_t json_event_filter_check::parse_field_name(const char *str, bool alloc_st return match_len + idx_len; } -void json_event_filter_check::add_filter_value(const char* str, uint32_t len, uint32_t i) +void json_event_filter_check::add_filter_value(const char *str, uint32_t len, uint32_t i) { m_values.push_back(string(str)); } bool json_event_filter_check::compare(gen_event *evt) { - json_event *jevt = (json_event *) evt; + json_event *jevt = (json_event *)evt; std::string value = extract(jevt); @@ -225,7 +228,7 @@ bool json_event_filter_check::compare(gen_event *evt) case CO_IN: for(auto &val : m_values) { - if (value == val) + if(value == val) { return true; } @@ -268,11 +271,12 @@ json_event_filter_check::check_info &json_event_filter_check::get_fields() return m_info; } -uint8_t* json_event_filter_check::extract(gen_event *evt, uint32_t* len, bool sanitize_strings) +uint8_t *json_event_filter_check::extract(gen_event *evt, uint32_t *len, bool sanitize_strings) { - json_event *jevt = (json_event *) evt; + json_event *jevt = (json_event *)evt; - try { + try + { const json &j = jevt->jevt().at(m_jptr); // Only format when the value was actually found in @@ -286,7 +290,7 @@ uint8_t* json_event_filter_check::extract(gen_event *evt, uint32_t* len, bool sa *len = m_tstr.size(); - return (uint8_t *) m_tstr.c_str(); + return (uint8_t *)m_tstr.c_str(); } std::string json_event_filter_check::extract(json_event *evt) @@ -299,7 +303,7 @@ std::string json_event_filter_check::extract(json_event *evt) if(res != NULL) { - ret.assign((const char *) res, len); + ret.assign((const char *)res, len); } return ret; @@ -315,18 +319,15 @@ jevt_filter_check::jevt_filter_check() { m_info = {"jevt", "generic ways to access json events", - { - {s_jevt_time_field, "json event timestamp as a string that includes the nanosecond part"}, - {s_jevt_time_iso_8601_field, "json event timestamp in ISO 8601 format, including nanoseconds and time zone offset (in UTC)"}, - {s_jevt_rawtime_field, "absolute event timestamp, i.e. nanoseconds from epoch."}, - {s_jevt_value_field, "General way to access single property from json object. The syntax is []. The property is returned as a string", IDX_REQUIRED, IDX_KEY}, - {s_jevt_obj_field, "The entire json object, stringified"} - }}; + {{s_jevt_time_field, "json event timestamp as a string that includes the nanosecond part"}, + {s_jevt_time_iso_8601_field, "json event timestamp in ISO 8601 format, including nanoseconds and time zone offset (in UTC)"}, + {s_jevt_rawtime_field, "absolute event timestamp, i.e. nanoseconds from epoch."}, + {s_jevt_value_field, "General way to access single property from json object. The syntax is []. The property is returned as a string", IDX_REQUIRED, IDX_KEY}, + {s_jevt_obj_field, "The entire json object, stringified"}}}; } jevt_filter_check::~jevt_filter_check() { - } int32_t jevt_filter_check::parse_field_name(const char *str, bool alloc_state, bool needed_for_filtering) @@ -360,55 +361,56 @@ int32_t jevt_filter_check::parse_field_name(const char *str, bool alloc_state, b const char *end; // What follows must be [] - if (*(str + s_jevt_value_field.size()) != '[' || - ((end = strchr(str + 1, ']')) == NULL)) + if(*(str + s_jevt_value_field.size()) != '[' || + ((end = strchr(str + 1, ']')) == NULL)) { throw falco_exception(string("Could not parse filtercheck field \"") + str + "\". Did not have expected format with 'jevt.value[]'"); } - try { - m_jptr = json::json_pointer(string(str + (s_jevt_value_field.size()+1), (end-str-(s_jevt_value_field.size()+1)))); + try + { + m_jptr = json::json_pointer(string(str + (s_jevt_value_field.size() + 1), (end - str - (s_jevt_value_field.size() + 1)))); } - catch (json::parse_error& e) + catch(json::parse_error &e) { throw falco_exception(string("Could not parse filtercheck field \"") + str + "\". Invalid json selector (" + e.what() + ")"); } // The +1 accounts for the closing ']' - m_field = string(str, end-str + 1); + m_field = string(str, end - str + 1); return (end - str + 1); } return 0; } -uint8_t* jevt_filter_check::extract(gen_event *evt, uint32_t* len, bool sanitize_stings) +uint8_t *jevt_filter_check::extract(gen_event *evt, uint32_t *len, bool sanitize_stings) { if(m_field == s_jevt_rawtime_field) { m_tstr = to_string(evt->get_ts()); *len = m_tstr.size(); - return (uint8_t *) m_tstr.c_str(); + return (uint8_t *)m_tstr.c_str(); } else if(m_field == s_jevt_time_field) { sinsp_utils::ts_to_string(evt->get_ts(), &m_tstr, false, true); *len = m_tstr.size(); - return (uint8_t *) m_tstr.c_str(); + return (uint8_t *)m_tstr.c_str(); } else if(m_field == s_jevt_time_iso_8601_field) { sinsp_utils::ts_to_iso_8601(evt->get_ts(), &m_tstr); *len = m_tstr.size(); - return (uint8_t *) m_tstr.c_str(); + return (uint8_t *)m_tstr.c_str(); } else if(m_field == s_jevt_obj_field) { - json_event *jevt = (json_event *) evt; + json_event *jevt = (json_event *)evt; m_tstr = jevt->jevt().dump(); *len = m_tstr.size(); - return (uint8_t *) m_tstr.c_str(); + return (uint8_t *)m_tstr.c_str(); } return json_event_filter_check::extract(evt, len, sanitize_stings); @@ -418,7 +420,7 @@ json_event_filter_check *jevt_filter_check::allocate_new() { jevt_filter_check *chk = new jevt_filter_check(); - return (json_event_filter_check *) chk; + return (json_event_filter_check *)chk; } std::string k8s_audit_filter_check::index_image(const json &j, std::string &field, std::string &idx) @@ -427,8 +429,9 @@ std::string k8s_audit_filter_check::index_image(const json &j, std::string &fiel string image; - try { - image = j[idx_num].at("image"); + try + { + image = j[idx_num].at("image"); } catch(json::out_of_range &e) { @@ -470,7 +473,6 @@ std::string k8s_audit_filter_check::index_has_name(const json &j, std::string &f return string("false"); } - std::string k8s_audit_filter_check::index_query_param(const json &j, std::string &field, std::string &idx) { string uri = j; @@ -489,7 +491,7 @@ std::string k8s_audit_filter_check::index_query_param(const json &j, std::string { std::vector param_parts = sinsp_split(part, '='); - if(param_parts.size() == 2 && uri::decode(param_parts[0], true)==idx) + if(param_parts.size() == 2 && uri::decode(param_parts[0], true) == idx) { return uri::decode(param_parts[1]); } @@ -498,7 +500,6 @@ std::string k8s_audit_filter_check::index_query_param(const json &j, std::string return string(""); } - std::string k8s_audit_filter_check::index_generic(const json &j, std::string &field, std::string &idx) { json item; @@ -511,7 +512,8 @@ std::string k8s_audit_filter_check::index_generic(const json &j, std::string &fi { uint64_t idx_num = (idx.empty() ? 0 : stoi(idx)); - try { + try + { item = j[idx_num]; } catch(json::out_of_range &e) @@ -529,7 +531,7 @@ std::string k8s_audit_filter_check::index_select(const json &j, std::string &fie // Use the suffix of the field to determine which property to // select from each object. - std::string prop = field.substr(field.find_last_of(".")+1); + std::string prop = field.substr(field.find_last_of(".") + 1); std::string ret; @@ -542,7 +544,8 @@ std::string k8s_audit_filter_check::index_select(const json &j, std::string &fie ret += " "; } - try { + try + { ret += json_event_filter_check::json_as_string(obj.at(prop)); } catch(json::out_of_range &e) @@ -553,7 +556,8 @@ std::string k8s_audit_filter_check::index_select(const json &j, std::string &fie } else { - try { + try + { ret = j[stoi(idx)].at(prop); } catch(json::out_of_range &e) @@ -573,7 +577,8 @@ std::string k8s_audit_filter_check::index_privileged(const json &j, std::string if(!idx.empty()) { - try { + try + { privileged = j[stoi(idx)].at(jpriv); } catch(json::out_of_range &e) @@ -584,7 +589,8 @@ std::string k8s_audit_filter_check::index_privileged(const json &j, std::string { for(auto &container : j) { - try { + try + { if(container.at(jpriv)) { privileged = true; @@ -621,42 +627,40 @@ k8s_audit_filter_check::k8s_audit_filter_check() { m_info = {"ka", "Access K8s Audit Log Events", - { - {"ka.auditid", "The unique id of the audit event"}, - {"ka.stage", "Stage of the request (e.g. RequestReceived, ResponseComplete, etc.)"}, - {"ka.auth.decision", "The authorization decision"}, - {"ka.auth.reason", "The authorization reason"}, - {"ka.user.name", "The user name performing the request"}, - {"ka.user.groups", "The groups to which the user belongs"}, - {"ka.impuser.name", "The impersonated user name"}, - {"ka.verb", "The action being performed"}, - {"ka.uri", "The request URI as sent from client to server"}, - {"ka.uri.param", "The value of a given query parameter in the uri (e.g. when uri=/foo?key=val, ka.uri.param[key] is val).", IDX_REQUIRED, IDX_KEY}, - {"ka.target.name", "The target object name"}, - {"ka.target.namespace", "The target object namespace"}, - {"ka.target.resource", "The target object resource"}, - {"ka.target.subresource", "The target object subresource"}, - {"ka.req.binding.subjects", "When the request object refers to a cluster role binding, the subject (e.g. account/users) being linked by the binding"}, - {"ka.req.binding.subject.has_name", "When the request object refers to a cluster role binding, return true if a subject with the provided name exists", IDX_REQUIRED, IDX_KEY}, - {"ka.req.binding.role", "When the request object refers to a cluster role binding, the role being linked by the binding"}, - {"ka.req.configmap.name", "If the request object refers to a configmap, the configmap name"}, - {"ka.req.configmap.obj", "If the request object refers to a configmap, the entire configmap object"}, - {"ka.req.container.image", "When the request object refers to a container, the container's images. Can be indexed (e.g. ka.req.container.image[0]). Without any index, returns the first image", IDX_ALLOWED, IDX_NUMERIC}, - {"ka.req.container.image.repository", "The same as req.container.image, but only the repository part (e.g. sysdig/falco)", IDX_ALLOWED, IDX_NUMERIC}, - {"ka.req.container.host_network", "When the request object refers to a container, the value of the hostNetwork flag."}, - {"ka.req.container.privileged", "When the request object refers to a container, whether or not any container is run privileged. With an index, return whether or not the ith container is run privileged.", IDX_ALLOWED, IDX_NUMERIC}, - {"ka.req.role.rules", "When the request object refers to a role/cluster role, the rules associated with the role"}, - {"ka.req.role.rules.apiGroups", "When the request object refers to a role/cluster role, the api groups associated with the role's rules. With an index, return only the api groups from the ith rule. Without an index, return all api groups concatenated", IDX_ALLOWED, IDX_NUMERIC}, - {"ka.req.role.rules.nonResourceURLs", "When the request object refers to a role/cluster role, the non resource urls associated with the role's rules. With an index, return only the non resource urls from the ith rule. Without an index, return all non resource urls concatenated", IDX_ALLOWED, IDX_NUMERIC}, - {"ka.req.role.rules.verbs", "When the request object refers to a role/cluster role, the verbs associated with the role's rules. With an index, return only the verbs from the ith rule. Without an index, return all verbs concatenated", IDX_ALLOWED, IDX_NUMERIC}, - {"ka.req.role.rules.resources", "When the request object refers to a role/cluster role, the resources associated with the role's rules. With an index, return only the resources from the ith rule. Without an index, return all resources concatenated", IDX_ALLOWED, IDX_NUMERIC}, - {"ka.req.service.type", "When the request object refers to a service, the service type"}, - {"ka.req.service.ports", "When the request object refers to a service, the service's ports. Can be indexed (e.g. ka.req.service.ports[0]). Without any index, returns all ports", IDX_ALLOWED, IDX_NUMERIC}, - {"ka.req.volume.hostpath", "If the request object contains volume definitions, whether or not a hostPath volume exists that mounts the specified path from the host (...hostpath[/etc]=true if a volume mounts /etc from the host). The index can be a glob, in which case all volumes are considered to find any path matching the specified glob (...hostpath[/usr/*] would match either /usr/local or /usr/bin)", IDX_REQUIRED, IDX_KEY}, - {"ka.resp.name", "The response object name"}, - {"ka.response.code", "The response code"}, - {"ka.response.reason", "The response reason (usually present only for failures)"} - }}; + {{"ka.auditid", "The unique id of the audit event"}, + {"ka.stage", "Stage of the request (e.g. RequestReceived, ResponseComplete, etc.)"}, + {"ka.auth.decision", "The authorization decision"}, + {"ka.auth.reason", "The authorization reason"}, + {"ka.user.name", "The user name performing the request"}, + {"ka.user.groups", "The groups to which the user belongs"}, + {"ka.impuser.name", "The impersonated user name"}, + {"ka.verb", "The action being performed"}, + {"ka.uri", "The request URI as sent from client to server"}, + {"ka.uri.param", "The value of a given query parameter in the uri (e.g. when uri=/foo?key=val, ka.uri.param[key] is val).", IDX_REQUIRED, IDX_KEY}, + {"ka.target.name", "The target object name"}, + {"ka.target.namespace", "The target object namespace"}, + {"ka.target.resource", "The target object resource"}, + {"ka.target.subresource", "The target object subresource"}, + {"ka.req.binding.subjects", "When the request object refers to a cluster role binding, the subject (e.g. account/users) being linked by the binding"}, + {"ka.req.binding.subject.has_name", "When the request object refers to a cluster role binding, return true if a subject with the provided name exists", IDX_REQUIRED, IDX_KEY}, + {"ka.req.binding.role", "When the request object refers to a cluster role binding, the role being linked by the binding"}, + {"ka.req.configmap.name", "If the request object refers to a configmap, the configmap name"}, + {"ka.req.configmap.obj", "If the request object refers to a configmap, the entire configmap object"}, + {"ka.req.container.image", "When the request object refers to a container, the container's images. Can be indexed (e.g. ka.req.container.image[0]). Without any index, returns the first image", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.container.image.repository", "The same as req.container.image, but only the repository part (e.g. sysdig/falco)", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.container.host_network", "When the request object refers to a container, the value of the hostNetwork flag."}, + {"ka.req.container.privileged", "When the request object refers to a container, whether or not any container is run privileged. With an index, return whether or not the ith container is run privileged.", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.role.rules", "When the request object refers to a role/cluster role, the rules associated with the role"}, + {"ka.req.role.rules.apiGroups", "When the request object refers to a role/cluster role, the api groups associated with the role's rules. With an index, return only the api groups from the ith rule. Without an index, return all api groups concatenated", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.role.rules.nonResourceURLs", "When the request object refers to a role/cluster role, the non resource urls associated with the role's rules. With an index, return only the non resource urls from the ith rule. Without an index, return all non resource urls concatenated", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.role.rules.verbs", "When the request object refers to a role/cluster role, the verbs associated with the role's rules. With an index, return only the verbs from the ith rule. Without an index, return all verbs concatenated", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.role.rules.resources", "When the request object refers to a role/cluster role, the resources associated with the role's rules. With an index, return only the resources from the ith rule. Without an index, return all resources concatenated", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.service.type", "When the request object refers to a service, the service type"}, + {"ka.req.service.ports", "When the request object refers to a service, the service's ports. Can be indexed (e.g. ka.req.service.ports[0]). Without any index, returns all ports", IDX_ALLOWED, IDX_NUMERIC}, + {"ka.req.volume.hostpath", "If the request object contains volume definitions, whether or not a hostPath volume exists that mounts the specified path from the host (...hostpath[/etc]=true if a volume mounts /etc from the host). The index can be a glob, in which case all volumes are considered to find any path matching the specified glob (...hostpath[/usr/*] would match either /usr/local or /usr/bin)", IDX_REQUIRED, IDX_KEY}, + {"ka.resp.name", "The response object name"}, + {"ka.response.code", "The response code"}, + {"ka.response.reason", "The response reason (usually present only for failures)"}}}; { m_aliases = { @@ -693,21 +697,19 @@ k8s_audit_filter_check::k8s_audit_filter_check() {"ka.req.volume.hostpath", {"/requestObject/spec/volumes"_json_pointer, check_hostpath_vols}}, {"ka.resp.name", {"/responseObject/metadata/name"_json_pointer}}, {"ka.response.code", {"/responseStatus/code"_json_pointer}}, - {"ka.response.reason", {"/responseStatus/reason"_json_pointer}} - }; + {"ka.response.reason", {"/responseStatus/reason"_json_pointer}}}; } } k8s_audit_filter_check::~k8s_audit_filter_check() { - } json_event_filter_check *k8s_audit_filter_check::allocate_new() { k8s_audit_filter_check *chk = new k8s_audit_filter_check(); - return (json_event_filter_check *) chk; + return (json_event_filter_check *)chk; } json_event_filter::json_event_filter() @@ -762,9 +764,9 @@ std::list &json_event_filter_factory::get_f return m_info; } -json_event_formatter::json_event_formatter(json_event_filter_factory &json_factory, std::string &format) - : m_format(format), - m_json_factory(json_factory) +json_event_formatter::json_event_formatter(json_event_filter_factory &json_factory, std::string &format): + m_format(format), + m_json_factory(json_factory) { parse_format(); } @@ -777,7 +779,7 @@ std::string json_event_formatter::tostring(json_event *ev) { std::string ret; - std::list> resolved; + std::list> resolved; resolve_tokens(ev, resolved); @@ -793,7 +795,7 @@ std::string json_event_formatter::tojson(json_event *ev) { nlohmann::json ret; - std::list> resolved; + std::list> resolved; resolve_tokens(ev, resolved); @@ -828,11 +830,11 @@ void json_event_formatter::parse_format() { // Skip the % tformat.erase(0, 1); - json_event_filter_check *chk = (json_event_filter_check *) m_json_factory.new_filtercheck(tformat.c_str()); + json_event_filter_check *chk = (json_event_filter_check *)m_json_factory.new_filtercheck(tformat.c_str()); if(!chk) { - throw falco_exception(string ("Could not parse format string \"") + m_format + "\": unknown filtercheck field " + tformat); + throw falco_exception(string("Could not parse format string \"") + m_format + "\": unknown filtercheck field " + tformat); } size = chk->parsed_size(); @@ -852,7 +854,7 @@ void json_event_formatter::parse_format() // Empty fields are only allowed at the beginning of the string if(m_tokens.size() > 0) { - throw falco_exception(string ("Could not parse format string \"" + m_format + "\": empty filtercheck field")); + throw falco_exception(string("Could not parse format string \"" + m_format + "\": empty filtercheck field")); } continue; } @@ -864,7 +866,7 @@ void json_event_formatter::parse_format() } } -void json_event_formatter::resolve_tokens(json_event *ev, std::list> &resolved) +void json_event_formatter::resolve_tokens(json_event *ev, std::list> &resolved) { for(auto tok : m_tokens) { From 8155d467abc6d1891baecf07702f7206a4d300ad Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Mon, 8 Jul 2019 12:52:57 +0000 Subject: [PATCH 51/64] update: ka.useragent in k8s audit fields Signed-off-by: Lorenzo Fontana Co-authored-by: Leonardo Di Donato --- userspace/engine/json_evt.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/userspace/engine/json_evt.cpp b/userspace/engine/json_evt.cpp index a40ab0ba649..1aabfaa1cd4 100644 --- a/userspace/engine/json_evt.cpp +++ b/userspace/engine/json_evt.cpp @@ -660,7 +660,8 @@ k8s_audit_filter_check::k8s_audit_filter_check() {"ka.req.volume.hostpath", "If the request object contains volume definitions, whether or not a hostPath volume exists that mounts the specified path from the host (...hostpath[/etc]=true if a volume mounts /etc from the host). The index can be a glob, in which case all volumes are considered to find any path matching the specified glob (...hostpath[/usr/*] would match either /usr/local or /usr/bin)", IDX_REQUIRED, IDX_KEY}, {"ka.resp.name", "The response object name"}, {"ka.response.code", "The response code"}, - {"ka.response.reason", "The response reason (usually present only for failures)"}}}; + {"ka.response.reason", "The response reason (usually present only for failures)"}, + {"ka.useragent", "The useragent of the client who made the request to the apiserver"}}}; { m_aliases = { @@ -697,7 +698,8 @@ k8s_audit_filter_check::k8s_audit_filter_check() {"ka.req.volume.hostpath", {"/requestObject/spec/volumes"_json_pointer, check_hostpath_vols}}, {"ka.resp.name", {"/responseObject/metadata/name"_json_pointer}}, {"ka.response.code", {"/responseStatus/code"_json_pointer}}, - {"ka.response.reason", {"/responseStatus/reason"_json_pointer}}}; + {"ka.response.reason", {"/responseStatus/reason"_json_pointer}}, + {"ka.useragent", {"/userAgent"_json_pointer}}}; } } From affb1086a3652fe4a465a0082d41d47813cec96a Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Mon, 8 Jul 2019 13:05:52 +0000 Subject: [PATCH 52/64] update: fields checksum while adding ka.useragent Signed-off-by: Lorenzo Fontana Co-authored-by: Leonardo Di Donato --- userspace/engine/falco_engine_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/userspace/engine/falco_engine_version.h b/userspace/engine/falco_engine_version.h index d9b14b15f13..7b8e0a613f5 100644 --- a/userspace/engine/falco_engine_version.h +++ b/userspace/engine/falco_engine_version.h @@ -24,4 +24,4 @@ limitations under the License. // This is the result of running "falco --list -N | sha256sum" and // represents the fields supported by this version of falco. It's used // at build time to detect a changed set of fields. -#define FALCO_FIELDS_CHECKSUM "9b5557ec8f16f5606a1544573b152d211d5212f653ee039146836a17266ff449" +#define FALCO_FIELDS_CHECKSUM "ceb069d9f9b2d4ebcc5de39bddc53b7af2e6b8f072edc293668fd6ac4e532413" From f20a5a04bf48e3b7c04683dc511f84ac63899b02 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Wed, 3 Jul 2019 13:34:01 +0000 Subject: [PATCH 53/64] new: cmake format file Co-Authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- .cmake-format | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 .cmake-format diff --git a/.cmake-format b/.cmake-format new file mode 100644 index 00000000000..e6484a15e30 --- /dev/null +++ b/.cmake-format @@ -0,0 +1,119 @@ +# -------------------------- +# General Formatting Options +# -------------------------- +# How wide to allow formatted cmake files +line_width = 80 + +# How many spaces to tab for indent +tab_size = 2 + +# If arglists are longer than this, break them always +max_subargs_per_line = 3 + +# If true, separate flow control names from their parentheses with a space +separate_ctrl_name_with_space = False + +# If true, separate function names from parentheses with a space +separate_fn_name_with_space = False + +# If a statement is wrapped to more than one line, than dangle the closing +# parenthesis on it's own line +dangle_parens = False + +# If the statement spelling length (including space and parenthesis is larger +# than the tab width by more than this amoung, then force reject un-nested +# layouts. +max_prefix_chars = 2 + +# If a candidate layout is wrapped horizontally but it exceeds this many lines, +# then reject the layout. +max_lines_hwrap = 2 + +# What style line endings to use in the output. +line_ending = 'unix' + +# Format command names consistently as 'lower' or 'upper' case +command_case = 'canonical' + +# Format keywords consistently as 'lower' or 'upper' case +keyword_case = 'unchanged' + +# Specify structure for custom cmake functions +additional_commands = { + "pkg_find": { + "kwargs": { + "PKG": "*" + } + } +} + +# A list of command names which should always be wrapped +always_wrap = [] + +# Specify the order of wrapping algorithms during successive reflow attempts +algorithm_order = [0, 1, 2, 3, 4] + +# If true, the argument lists which are known to be sortable will be sorted +# lexicographicall +enable_sort = True + +# If true, the parsers may infer whether or not an argument list is sortable +# (without annotation). +autosort = False + +# If a comment line starts with at least this many consecutive hash characters, +# then don't lstrip() them off. This allows for lazy hash rulers where the first +# hash char is not separated by space +hashruler_min_length = 10 + +# A dictionary containing any per-command configuration overrides. Currently +# only `command_case` is supported. +per_command = {} + + +# -------------------------- +# Comment Formatting Options +# -------------------------- +# What character to use for bulleted lists +bullet_char = '*' + +# What character to use as punctuation after numerals in an enumerated list +enum_char = '.' + +# enable comment markup parsing and reflow +enable_markup = True + +# If comment markup is enabled, don't reflow the first comment block in each +# listfile. Use this to preserve formatting of your copyright/license +# statements. +first_comment_is_literal = False + +# If comment markup is enabled, don't reflow any comment block which matches +# this (regex) pattern. Default is `None` (disabled). +literal_comment_pattern = None + +# Regular expression to match preformat fences in comments +# default=r'^\s*([`~]{3}[`~]*)(.*)$' +fence_pattern = '^\\s*([`~]{3}[`~]*)(.*)$' + +# Regular expression to match rulers in comments +# default=r'^\s*[^\w\s]{3}.*[^\w\s]{3}$' +ruler_pattern = '^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$' + +# If true, then insert a space between the first hash char and remaining hash +# chars in a hash ruler, and normalize it's length to fill the column +canonicalize_hashrulers = True + + +# --------------------------------- +# Miscellaneous Options +# --------------------------------- +# If true, emit the unicode byte-order mark (BOM) at the start of the file +emit_byteorder_mark = False + +# Specify the encoding of the input file. Defaults to utf-8. +input_encoding = 'utf-8' + +# Specify the encoding of the output file. Defaults to utf-8. Note that cmake +# only claims to support utf-8 so be careful when using anything else +output_encoding = 'utf-8' \ No newline at end of file From fdbd520cce0db087fd89b3c11b2650dcb371ad0f Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Mon, 8 Jul 2019 16:57:10 +0000 Subject: [PATCH 54/64] fix: bump falco engine version Co-Authored-By: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- userspace/engine/falco_engine_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/userspace/engine/falco_engine_version.h b/userspace/engine/falco_engine_version.h index 7b8e0a613f5..e77bd1a2adb 100644 --- a/userspace/engine/falco_engine_version.h +++ b/userspace/engine/falco_engine_version.h @@ -19,7 +19,7 @@ limitations under the License. // The version of rules/filter fields/etc supported by this falco // engine. -#define FALCO_ENGINE_VERSION (3) +#define FALCO_ENGINE_VERSION (4) // This is the result of running "falco --list -N | sha256sum" and // represents the fields supported by this version of falco. It's used From a32870ae1d26f48660a1e44f447cd1b916b8e957 Mon Sep 17 00:00:00 2001 From: Mattia Pagnozzi Date: Tue, 9 Jul 2019 10:59:59 +0200 Subject: [PATCH 55/64] Add runc to the list of possible container entrypoint parents Docker versions >= 18.09 removed the "docker-" prefix, so include runc in the list. Signed-off-by: Mattia Pagnozzi --- rules/falco_rules.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index b4a86528421..79ba406c445 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1832,7 +1832,7 @@ # when we lose events and lose track of state. - macro: container_entrypoint - condition: (not proc.pname exists or proc.pname in (runc:[0:PARENT], runc:[1:CHILD], docker-runc, exe)) + condition: (not proc.pname exists or proc.pname in (runc:[0:PARENT], runc:[1:CHILD], runc, docker-runc, exe)) - rule: Launch Sensitive Mount Container desc: > From 4c68da0dcc61d827dbfcd9106767bfa28ede29fe Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Tue, 9 Jul 2019 13:25:29 +0000 Subject: [PATCH 56/64] new: YAML lint configuration Signed-off-by: Leonardo Di Donato --- .yamllint.conf | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .yamllint.conf diff --git a/.yamllint.conf b/.yamllint.conf new file mode 100644 index 00000000000..9554ad51cb7 --- /dev/null +++ b/.yamllint.conf @@ -0,0 +1,8 @@ +extends: default + +rules: + indentation: disable + document-start: disable + comments: disable + line-length: disable + new-line-at-end-of-file: disable From cb5a3a14e6da8d73a79584c2c08f082ee392f791 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Wed, 10 Jul 2019 13:40:47 +0000 Subject: [PATCH 57/64] new: k8s.gcr.io/kube-proxy addition to falco trusted images Signed-off-by: Leonardo Di Donato --- rules/falco_rules.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 79ba406c445..df8c12ae900 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1740,7 +1740,7 @@ docker.io/sysdig/agent, docker.io/sysdig/falco, docker.io/sysdig/sysdig, gcr.io/google_containers/kube-proxy, docker.io/calico/node, docker.io/rook/toolbox, docker.io/cloudnativelabs/kube-router, docker.io/mesosphere/mesos-slave, - docker.io/docker/ucp-agent, sematext_images + docker.io/docker/ucp-agent, sematext_images, k8s.gcr.io/kube-proxy ] - macro: falco_privileged_containers @@ -2253,7 +2253,7 @@ condition: > spawned_process and container and ((proc.name = "nc" and (proc.args contains "-e" or proc.args contains "-c")) or - (proc.name = "ncat" and (proc.args contains "--sh-exec" or proc.args contains "--exec" or proc.args contains "-e " + (proc.name = "ncat" and (proc.args contains "--sh-exec" or proc.args contains "--exec" or proc.args contains "-e " or proc.args contains "-c " or proc.args contains "--lua-exec")) ) output: > From 231f881c5a562633ef7a0f0635c8638ab9717c77 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Wed, 10 Jul 2019 14:08:26 +0000 Subject: [PATCH 58/64] update: ignore luacheck cache Signed-off-by: Leonardo Di Donato --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f2178ccce77..aead8da8470 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,7 @@ docker/event-generator/mysqld docker/event-generator/httpd docker/event-generator/sha1sum docker/event-generator/vipw -.vscode/* \ No newline at end of file + +.vscode/* + +.luacheckcache \ No newline at end of file From e80ff6296a19f358d9d71963bf15d160391b9163 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Wed, 10 Jul 2019 14:08:39 +0000 Subject: [PATCH 59/64] new: luacheck basic config Signed-off-by: Leonardo Di Donato --- .luacheckrc | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .luacheckrc diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 00000000000..9087792dd2f --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,9 @@ +std = "min" +cache = true +include_files = { + "userspace/falco/lua/*.lua", + "userspace/engine/lua/*.lua", + "userspace/engine/lua/lyaml/*.lua", + "*.luacheckrc" +} +exclude_files = {"build"} From dc7bff127f6e0f2cc503b9b1fc829c5eae905ec3 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 5 Jul 2019 15:33:56 -0700 Subject: [PATCH 60/64] New flags to compare stdout/stderr, validate rules New test options stdout_is/stderr_is do a direct comparison between stdout/stderr and the provided value. Test option validate_rules_file maps to -V arguments, which validate rules and exits. Signed-off-by: Mark Stemm --- test/falco_test.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/falco_test.py b/test/falco_test.py index 9908297973a..782e8aebf85 100644 --- a/test/falco_test.py +++ b/test/falco_test.py @@ -41,6 +41,9 @@ def setUp(self): build_dir = os.path.join('/build', build_type) self.falcodir = self.params.get('falcodir', '/', default=os.path.join(self.basedir, build_dir)) + self.stdout_is = self.params.get('stdout_is', '*', default='') + self.stderr_is = self.params.get('stderr_is', '*', default='') + self.stdout_contains = self.params.get('stdout_contains', '*', default='') if not isinstance(self.stdout_contains, list): @@ -83,8 +86,21 @@ def setUp(self): if not isinstance(self.rules_file, list): self.rules_file = [self.rules_file] + self.validate_rules_file = self.params.get('validate_rules_file', '*', default=False) + + if self.validate_rules_file == False: + self.validate_rules_file = [] + else: + if not isinstance(self.validate_rules_file, list): + self.validate_rules_file = [self.validate_rules_file] + self.rules_args = "" + for file in self.validate_rules_file: + if not os.path.isabs(file): + file = os.path.join(self.basedir, file) + self.rules_args = self.rules_args + "-V " + file + " " + for file in self.rules_file: if not os.path.isabs(file): file = os.path.join(self.basedir, file) @@ -433,6 +449,15 @@ def test(self): res = self.falco_proc.run(timeout=180, sig=9) + if self.stdout_is != '': + print(self.stdout_is) + if self.stdout_is != res.stdout: + self.fail("Stdout was not exactly {}".format(self.stdout_is)) + + if self.stderr_is != '': + if self.stderr_is != res.stdout: + self.fail("Stdout was not exactly {}".format(self.stderr_is)) + for pattern in self.stderr_contains: match = re.search(pattern, res.stderr) if match is None: From 839d76a7602eb75933a9e6ebec1581e2b3c03d55 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 5 Jul 2019 15:37:22 -0700 Subject: [PATCH 61/64] Send validate output to stdout When parsing rules files with -V (validate), print info on the result of loading the rules file to stdout. That way a caller can capture stdout to pass along any rules parsing error. Signed-off-by: Mark Stemm --- userspace/falco/falco.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/userspace/falco/falco.cpp b/userspace/falco/falco.cpp index 6f2312efc55..715a9aba492 100644 --- a/userspace/falco/falco.cpp +++ b/userspace/falco/falco.cpp @@ -716,7 +716,17 @@ int falco_init(int argc, char **argv) } for(auto file : validate_rules_filenames) { - engine->load_rules_file(file, verbose, all_events); + // Only include the prefix if there is more than one file + std::string prefix = (validate_rules_filenames.size() > 1 ? file + ": " : ""); + try { + engine->load_rules_file(file, verbose, all_events); + } + catch(falco_exception &e) + { + printf("%s%s\n", prefix.c_str(), e.what()); + throw; + } + printf("%sOk\n", prefix.c_str()); } falco_logger::log(LOG_INFO, "Ok\n"); goto exit; From 1711ed0a2e8dafd42a841b72ae5e240c82d1e49f Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 5 Jul 2019 15:42:03 -0700 Subject: [PATCH 62/64] Pass back explicit errors in load_rules() Instead of relying on lua errors to pass back parse errors, pass back an explicit true + required engine version or false + error message. Also clean up the error message to display info + context on the error. When the error related to yaml parsing, use the row number passed back in lyaml's error string to print the specific line with the error. When parsing rules/macros/lists, print the object being parsed alongside the error. Signed-off-by: Mark Stemm --- userspace/engine/lua/compiler.lua | 47 +++++--- userspace/engine/lua/rule_loader.lua | 162 +++++++++++++++++++++++---- userspace/engine/rules.cpp | 21 +++- 3 files changed, 186 insertions(+), 44 deletions(-) diff --git a/userspace/engine/lua/compiler.lua b/userspace/engine/lua/compiler.lua index 9a39cf7d925..595eec9712c 100644 --- a/userspace/engine/lua/compiler.lua +++ b/userspace/engine/lua/compiler.lua @@ -62,12 +62,12 @@ function expand_macros(ast, defs, changed) elseif ast.type == "Filter" then if (ast.value.type == "Macro") then if (defs[ast.value.value] == nil) then - error("Undefined macro '".. ast.value.value .. "' used in filter.") + return false, "Undefined macro '".. ast.value.value .. "' used in filter." end defs[ast.value.value].used = true ast.value = copy_ast_obj(defs[ast.value.value].ast) changed = true - return changed + return true, changed end return expand_macros(ast.value, defs, changed) @@ -75,7 +75,7 @@ function expand_macros(ast, defs, changed) if (ast.left.type == "Macro") then if (defs[ast.left.value] == nil) then - error("Undefined macro '".. ast.left.value .. "' used in filter.") + return false, "Undefined macro '".. ast.left.value .. "' used in filter." end defs[ast.left.value].used = true ast.left = copy_ast_obj(defs[ast.left.value].ast) @@ -84,21 +84,27 @@ function expand_macros(ast, defs, changed) if (ast.right.type == "Macro") then if (defs[ast.right.value] == nil) then - error("Undefined macro ".. ast.right.value .. " used in filter.") + return false, "Undefined macro ".. ast.right.value .. " used in filter." end defs[ast.right.value].used = true ast.right = copy_ast_obj(defs[ast.right.value].ast) changed = true end - local changed_left = expand_macros(ast.left, defs, false) - local changed_right = expand_macros(ast.right, defs, false) - return changed or changed_left or changed_right + local status, changed_left = expand_macros(ast.left, defs, false) + if status == false then + return false, changed_left + end + local status, changed_right = expand_macros(ast.right, defs, false) + if status == false then + return false, changed_right + end + return true, changed or changed_left or changed_right elseif ast.type == "UnaryBoolOp" then if (ast.argument.type == "Macro") then if (defs[ast.argument.value] == nil) then - error("Undefined macro ".. ast.argument.value .. " used in filter.") + return false, "Undefined macro ".. ast.argument.value .. " used in filter." end defs[ast.argument.value].used = true ast.argument = copy_ast_obj(defs[ast.argument.value].ast) @@ -106,7 +112,7 @@ function expand_macros(ast, defs, changed) end return expand_macros(ast.argument, defs, changed) end - return changed + return true, changed end function get_macros(ast, set) @@ -195,7 +201,7 @@ function compiler.compile_macro(line, macro_defs, list_defs) if (error_msg) then msg = "Compilation error when compiling \""..line.."\": ".. error_msg - error(msg) + return false, msg end -- Simply as a validation step, try to expand all macros in this @@ -206,14 +212,18 @@ function compiler.compile_macro(line, macro_defs, list_defs) if (ast.type == "Rule") then -- Line is a filter, so expand macro references repeat - expanded = expand_macros(ast_copy, macro_defs, false) + status, expanded = expand_macros(ast_copy, macro_defs, false) + if status == false then + msg = "Compilation error when compiling \""..line.."\": ".. expanded + return false, msg + end until expanded == false else - error("Unexpected top-level AST type: "..ast.type) + return false, "Unexpected top-level AST type: "..ast.type end - return ast + return true, ast end --[[ @@ -227,22 +237,25 @@ function compiler.compile_filter(name, source, macro_defs, list_defs) if (error_msg) then msg = "Compilation error when compiling \""..source.."\": "..error_msg - error(msg) + return false, msg end if (ast.type == "Rule") then -- Line is a filter, so expand macro references repeat - expanded = expand_macros(ast, macro_defs, false) + status, expanded = expand_macros(ast, macro_defs, false) + if status == false then + return false, expanded + end until expanded == false else - error("Unexpected top-level AST type: "..ast.type) + return false, "Unexpected top-level AST type: "..ast.type end filters = get_filters(ast) - return ast, filters + return true, ast, filters end diff --git a/userspace/engine/lua/rule_loader.lua b/userspace/engine/lua/rule_loader.lua index a98b27bc624..6e1698f40f6 100644 --- a/userspace/engine/lua/rule_loader.lua +++ b/userspace/engine/lua/rule_loader.lua @@ -179,6 +179,71 @@ function table.tostring( tbl ) return "{" .. table.concat( result, "," ) .. "}" end +-- Split rules_content by lines and also remember the line numbers for +-- each top -level object. Returns a table of lines and a table of +-- line numbers for objects. + +function split_lines(rules_content) + lines = {} + indices = {} + + idx = 1 + last_pos = 1 + pos = string.find(rules_content, "\n", 1, true) + + while pos ~= nil do + line = string.sub(rules_content, last_pos, pos-1) + if line ~= "" then + lines[#lines+1] = line + if string.sub(line, 1, 1) == '-' then + indices[#indices+1] = idx + end + + idx = idx + 1 + end + + last_pos = pos+1 + pos = string.find(rules_content, "\n", pos+1, true) + end + + if last_pos < string.len(rules_content) then + line = string.sub(rules_content, last_pos) + lines[#lines+1] = line + if string.sub(line, 1, 1) == '-' then + indices[#indices+1] = idx + end + + idx = idx + 1 + end + + -- Add a final index for last line in document + indices[#indices+1] = idx + + return lines, indices +end + +function get_context(rules_lines, row, num_lines) + + local ret = "---\n" + + idx = row + while (idx < (row + num_lines) and idx <= #rules_lines) do + ret = ret..rules_lines[idx].."\n" + idx = idx + 1 + end + + ret = ret.."---" + + return ret + +end + +function build_error(rules_lines, row, num_lines, err) + + local ret = err.."\n"..get_context(rules_lines, row, num_lines) + + return ret +end function load_rules(sinsp_lua_parser, json_lua_parser, @@ -190,16 +255,45 @@ function load_rules(sinsp_lua_parser, replace_container_info, min_priority) - local rules = yaml.load(rules_content) local required_engine_version = 0 + local lines, indices = split_lines(rules_content) + + local status, rules = pcall(yaml.load, rules_content) + + if status == false then + local pat = "^([%d]+):([%d]+): " + -- rules is actually an error string + + local row = 0 + local col = 0 + + row, col = string.match(rules, pat) + if row ~= nil and col ~= nil then + rules = string.gsub(rules, pat, "") + end + + row = tonumber(row) + col = tonumber(col) + + return false, build_error(lines, row, 3, rules) + end + if rules == nil then -- An empty rules file is acceptable - return required_engine_version + return true, required_engine_version end if type(rules) ~= "table" then - error("Rules content \""..rules_content.."\" is not yaml") + return false, build_error(lines, 1, 1, "Rules content is not yaml") + end + + -- Look for non-numeric indices--implies that document is not array + -- of objects. + for key, val in pairs(rules) do + if type(key) ~= "number" then + return false, build_error(lines, 1, 1, "Rules content is not yaml array of objects") + end end -- Iterate over yaml list. In this pass, all we're doing is @@ -209,17 +303,25 @@ function load_rules(sinsp_lua_parser, for i,v in ipairs(rules) do if (not (type(v) == "table")) then - error ("Unexpected element of type " ..type(v)..". Each element should be a yaml associative array.") + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Unexpected element of type " ..type(v)..". Each element should be a yaml associative array.") end if (v['required_engine_version']) then required_engine_version = v['required_engine_version'] + if type(required_engine_version) ~= "number" then + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Value of required_engine_version must be a number") + end + if falco_rules.engine_version(rules_mgr) < v['required_engine_version'] then - error("Rules require engine version "..v['required_engine_version']..", but engine version is "..falco_rules.engine_version(rules_mgr)) + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Rules require engine version "..v['required_engine_version']..", but engine version is "..falco_rules.engine_version(rules_mgr)) end elseif (v['macro']) then + if (v['macro'] == nil or type(v['macro']) == "table") then + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Macro name is empty") + end + if v['source'] == nil then v['source'] = "syscall" end @@ -228,9 +330,9 @@ function load_rules(sinsp_lua_parser, state.ordered_macro_names[#state.ordered_macro_names+1] = v['macro'] end - for i, field in ipairs({'condition'}) do + for j, field in ipairs({'condition'}) do if (v[field] == nil) then - error ("Missing "..field.." in macro with name "..v['macro']) + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Macro must have property "..field) end end @@ -243,7 +345,7 @@ function load_rules(sinsp_lua_parser, if append then if state.macros_by_name[v['macro']] == nil then - error ("Macro " ..v['macro'].. " has 'append' key but no macro by that name already exists") + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Macro " ..v['macro'].. " has 'append' key but no macro by that name already exists") end state.macros_by_name[v['macro']]['condition'] = state.macros_by_name[v['macro']]['condition'] .. " " .. v['condition'] @@ -254,13 +356,17 @@ function load_rules(sinsp_lua_parser, elseif (v['list']) then + if (v['list'] == nil or type(v['list']) == "table") then + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "List name is empty") + end + if state.lists_by_name[v['list']] == nil then state.ordered_list_names[#state.ordered_list_names+1] = v['list'] end - for i, field in ipairs({'items'}) do + for j, field in ipairs({'items'}) do if (v[field] == nil) then - error ("Missing "..field.." in list with name "..v['list']) + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "List must have property "..field) end end @@ -273,10 +379,10 @@ function load_rules(sinsp_lua_parser, if append then if state.lists_by_name[v['list']] == nil then - error ("List " ..v['list'].. " has 'append' key but no list by that name already exists") + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "List " ..v['list'].. " has 'append' key but no list by that name already exists") end - for i, elem in ipairs(v['items']) do + for j, elem in ipairs(v['items']) do table.insert(state.lists_by_name[v['list']]['items'], elem) end else @@ -286,7 +392,7 @@ function load_rules(sinsp_lua_parser, elseif (v['rule']) then if (v['rule'] == nil or type(v['rule']) == "table") then - error ("Missing name in rule") + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Rule name is empty") end -- By default, if a rule's condition refers to an unknown @@ -309,15 +415,15 @@ function load_rules(sinsp_lua_parser, if append then -- For append rules, all you need is the condition - for i, field in ipairs({'condition'}) do + for j, field in ipairs({'condition'}) do if (v[field] == nil) then - error ("Missing "..field.." in rule with name "..v['rule']) + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Rule must have property "..field) end end if state.rules_by_name[v['rule']] == nil then if state.skipped_rules_by_name[v['rule']] == nil then - error ("Rule " ..v['rule'].. " has 'append' key but no rule by that name already exists") + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Rule " ..v['rule'].. " has 'append' key but no rule by that name already exists") end else state.rules_by_name[v['rule']]['condition'] = state.rules_by_name[v['rule']]['condition'] .. " " .. v['condition'] @@ -325,9 +431,9 @@ function load_rules(sinsp_lua_parser, else - for i, field in ipairs({'condition', 'output', 'desc', 'priority'}) do + for j, field in ipairs({'condition', 'output', 'desc', 'priority'}) do if (v[field] == nil) then - error ("Missing "..field.." in rule with name "..v['rule']) + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Rule must have property "..field) end end @@ -356,7 +462,7 @@ function load_rules(sinsp_lua_parser, end end else - error ("Unknown rule object: "..table.tostring(v)) + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Unknown rule object: "..table.tostring(v)) end end @@ -393,7 +499,11 @@ function load_rules(sinsp_lua_parser, local v = state.macros_by_name[name] - local ast = compiler.compile_macro(v['condition'], state.macros, state.lists) + local status, ast = compiler.compile_macro(v['condition'], state.macros, state.lists) + + if status == false then + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), ast) + end if v['source'] == "syscall" then if not all_events then @@ -413,8 +523,12 @@ function load_rules(sinsp_lua_parser, warn_evttypes = v['warn_evttypes'] end - local filter_ast, filters = compiler.compile_filter(v['rule'], v['condition'], - state.macros, state.lists) + local status, filter_ast, filters = compiler.compile_filter(v['rule'], v['condition'], + state.macros, state.lists) + + if status == false then + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), filter_ast) + end local evtttypes = {} local syscallnums = {} @@ -551,7 +665,7 @@ function load_rules(sinsp_lua_parser, formatter = formats.formatter(v['source'], v['output']) formats.free_formatter(v['source'], formatter) else - error ("Unexpected type in load_rule: "..filter_ast.type) + return false, build_error(lines, indices[i], (indices[i+1]-indices[i]), "Unexpected type in load_rule: "..filter_ast.type) end ::next_rule:: @@ -574,7 +688,7 @@ function load_rules(sinsp_lua_parser, io.flush() - return required_engine_version + return true, required_engine_version end local rule_fmt = "%-50s %s" diff --git a/userspace/engine/rules.cpp b/userspace/engine/rules.cpp index 140fc8803fa..e0691269715 100644 --- a/userspace/engine/rules.cpp +++ b/userspace/engine/rules.cpp @@ -425,15 +425,30 @@ void falco_rules::load_rules(const string &rules_content, lua_pushstring(m_ls, extra.c_str()); lua_pushboolean(m_ls, (replace_container_info ? 1 : 0)); lua_pushnumber(m_ls, min_priority); - if(lua_pcall(m_ls, 9, 1, 0) != 0) + if(lua_pcall(m_ls, 9, 2, 0) != 0) { const char* lerr = lua_tostring(m_ls, -1); + string err = "Error loading rules: " + string(lerr); + + throw falco_exception(err); + } + + // Either returns (true, required_engine_version), or (false, error string) + bool successful = lua_toboolean(m_ls, -2); + + if(successful) + { + required_engine_version = lua_tonumber(m_ls, -1); + } + else + { + std::string err = lua_tostring(m_ls, -1); throw falco_exception(err); } - required_engine_version = lua_tonumber(m_ls, -1); - lua_pop(m_ls, 1); + lua_pop(m_ls, 4); + } else { throw falco_exception("No function " + m_lua_load_rules + " found in lua rule module"); } From 01f65e3baeaa1e2b75d0bdd73d9c8f2e686f6092 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 5 Jul 2019 15:42:52 -0700 Subject: [PATCH 63/64] Add new tests for validating rules files Add a bunch of additional test cases for validating rules files. Each has a specific kind of parse failure and checks for the appropriate error info on stdout. Signed-off-by: Mark Stemm --- test/falco_tests.yaml | 199 +++++++++++++++++- test/rules/invalid_append_macro_dangling.yaml | 3 + ...invalid_append_rule_without_condition.yaml | 2 + test/rules/invalid_array_item_not_object.yaml | 1 + test/rules/invalid_condition_not_rule.yaml | 5 + .../invalid_engine_version_not_number.yaml | 34 +++ test/rules/invalid_list_without_items.yaml | 5 + test/rules/invalid_macro_comple_error.yaml | 2 + .../invalid_macro_without_condition.yaml | 6 + test/rules/invalid_missing_list_name.yaml | 2 + test/rules/invalid_missing_macro_name.yaml | 2 + test/rules/invalid_missing_rule_name.yaml | 4 + test/rules/invalid_not_array.yaml | 1 + test/rules/invalid_not_yaml.yaml | 1 + test/rules/invalid_rule_without_output.yaml | 4 + test/rules/invalid_unexpected_object.yaml | 1 + test/rules/invalid_yaml_parse_error.yaml | 1 + 17 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 test/rules/invalid_append_macro_dangling.yaml create mode 100644 test/rules/invalid_append_rule_without_condition.yaml create mode 100644 test/rules/invalid_array_item_not_object.yaml create mode 100644 test/rules/invalid_condition_not_rule.yaml create mode 100644 test/rules/invalid_engine_version_not_number.yaml create mode 100644 test/rules/invalid_list_without_items.yaml create mode 100644 test/rules/invalid_macro_comple_error.yaml create mode 100644 test/rules/invalid_macro_without_condition.yaml create mode 100644 test/rules/invalid_missing_list_name.yaml create mode 100644 test/rules/invalid_missing_macro_name.yaml create mode 100644 test/rules/invalid_missing_rule_name.yaml create mode 100644 test/rules/invalid_not_array.yaml create mode 100644 test/rules/invalid_not_yaml.yaml create mode 100644 test/rules/invalid_rule_without_output.yaml create mode 100644 test/rules/invalid_unexpected_object.yaml create mode 100644 test/rules/invalid_yaml_parse_error.yaml diff --git a/test/falco_tests.yaml b/test/falco_tests.yaml index 5a7c05981ff..aecc1a9af09 100644 --- a/test/falco_tests.yaml +++ b/test/falco_tests.yaml @@ -238,6 +238,199 @@ trace_files: !mux - rules/endswith.yaml trace_file: trace_files/cat_write.scap + invalid_not_yaml: + exit_status: 1 + stdout_is: |+ + Rules content is not yaml + --- + This is not yaml + --- + validate_rules_file: + - rules/invalid_not_yaml.yaml + trace_file: trace_files/cat_write.scap + + invalid_not_array: + exit_status: 1 + stdout_is: |+ + Rules content is not yaml array of objects + --- + foo: bar + --- + validate_rules_file: + - rules/invalid_not_array.yaml + trace_file: trace_files/cat_write.scap + + invalid_array_item_not_object: + exit_status: 1 + stdout_is: |+ + Unexpected element of type string. Each element should be a yaml associative array. + --- + - foo + --- + validate_rules_file: + - rules/invalid_array_item_not_object.yaml + trace_file: trace_files/cat_write.scap + + invalid_unexpected object: + exit_status: 1 + stdout_is: |+ + Unknown rule object: {foo="bar"} + --- + - foo: bar + --- + validate_rules_file: + - rules/invalid_unexpected_object.yaml + trace_file: trace_files/cat_write.scap + + invalid_engine_version_not_number: + exit_status: 1 + stdout_is: |+ + Value of required_engine_version must be a number + --- + - required_engine_version: not-a-number + --- + validate_rules_file: + - rules/invalid_engine_version_not_number.yaml + trace_file: trace_files/cat_write.scap + + invalid_yaml_parse_error: + exit_status: 1 + stdout_is: |+ + mapping values are not allowed in this context + --- + this : is : not : yaml + --- + validate_rules_file: + - rules/invalid_yaml_parse_error.yaml + trace_file: trace_files/cat_write.scap + + invalid_list_without_items: + exit_status: 1 + stdout_is: |+ + List must have property items + --- + - list: bad_list + no_items: foo + --- + validate_rules_file: + - rules/invalid_list_without_items.yaml + trace_file: trace_files/cat_write.scap + + invalid_macro_without_condition: + exit_status: 1 + stdout_is: |+ + Macro must have property condition + --- + - macro: bad_macro + nope: 1 + --- + validate_rules_file: + - rules/invalid_macro_without_condition.yaml + trace_file: trace_files/cat_write.scap + + invalid_rule_without_output: + exit_status: 1 + stdout_is: |+ + Rule must have property output + --- + - rule: no output rule + desc: some desc + condition: evt.type=fork + priority: INFO + --- + validate_rules_file: + - rules/invalid_rule_without_output.yaml + trace_file: trace_files/cat_write.scap + + invalid_append_rule_without_condition: + exit_status: 1 + stdout_is: |+ + Rule must have property condition + --- + - rule: no condition rule + append: true + --- + validate_rules_file: + - rules/invalid_append_rule_without_condition.yaml + trace_file: trace_files/cat_write.scap + + invalid_append_macro_dangling: + exit_status: 1 + stdout_is: |+ + Macro dangling append has 'append' key but no macro by that name already exists + --- + - macro: dangling append + condition: and evt.type=execve + append: true + --- + validate_rules_file: + - rules/invalid_append_macro_dangling.yaml + trace_file: trace_files/cat_write.scap + + invalid_list_append_dangling: + exit_status: 1 + stdout_is: |+ + List my_list has 'append' key but no list by that name already exists + --- + - list: my_list + items: [not-cat] + append: true + --- + validate_rules_file: + - rules/list_append_failure.yaml + trace_file: trace_files/cat_write.scap + + invalid_rule_append_dangling: + exit_status: 1 + stdout_is: |+ + Rule my_rule has 'append' key but no rule by that name already exists + --- + - rule: my_rule + condition: evt.type=open + append: true + --- + validate_rules_file: + - rules/rule_append_failure.yaml + trace_file: trace_files/cat_write.scap + + invalid_missing_rule_name: + exit_status: 1 + stdout_is: |+ + Rule name is empty + --- + - rule: + desc: some desc + condition: evt.type=execve + output: some output + --- + validate_rules_file: + - rules/invalid_missing_rule_name.yaml + trace_file: trace_files/cat_write.scap + + invalid_missing_list_name: + exit_status: 1 + stdout_is: |+ + List name is empty + --- + - list: + items: [foo] + --- + validate_rules_file: + - rules/invalid_missing_list_name.yaml + trace_file: trace_files/cat_write.scap + + invalid_missing_macro_name: + exit_status: 1 + stdout_is: |+ + Macro name is empty + --- + - macro: + condition: evt.type=execve + --- + validate_rules_file: + - rules/invalid_missing_macro_name.yaml + trace_file: trace_files/cat_write.scap + invalid_rule_output: exit_status: 1 stderr_contains: "Runtime error: Error loading rules:.* Invalid output format 'An open was seen %not_a_real_field': 'invalid formatting token not_a_real_field'. Exiting." @@ -601,7 +794,7 @@ trace_files: !mux list_append_failure: exit_status: 1 - stderr_contains: "List my_list has 'append' key but no list by that name already exists. Exiting" + stderr_contains: "List my_list has 'append' key but no list by that name already exists" rules_file: - rules/list_append_failure.yaml trace_file: trace_files/cat_write.scap @@ -621,7 +814,7 @@ trace_files: !mux macro_append_failure: exit_status: 1 - stderr_contains: "Macro my_macro has 'append' key but no macro by that name already exists. Exiting" + stderr_contains: "Macro my_macro has 'append' key but no macro by that name already exists" rules_file: - rules/macro_append_failure.yaml trace_file: trace_files/cat_write.scap @@ -641,7 +834,7 @@ trace_files: !mux rule_append_failure: exit_status: 1 - stderr_contains: "Rule my_rule has 'append' key but no rule by that name already exists. Exiting" + stderr_contains: "Rule my_rule has 'append' key but no rule by that name already exists" rules_file: - rules/rule_append_failure.yaml trace_file: trace_files/cat_write.scap diff --git a/test/rules/invalid_append_macro_dangling.yaml b/test/rules/invalid_append_macro_dangling.yaml new file mode 100644 index 00000000000..3348a7f13b0 --- /dev/null +++ b/test/rules/invalid_append_macro_dangling.yaml @@ -0,0 +1,3 @@ +- macro: dangling append + condition: and evt.type=execve + append: true \ No newline at end of file diff --git a/test/rules/invalid_append_rule_without_condition.yaml b/test/rules/invalid_append_rule_without_condition.yaml new file mode 100644 index 00000000000..b9a4011fac9 --- /dev/null +++ b/test/rules/invalid_append_rule_without_condition.yaml @@ -0,0 +1,2 @@ +- rule: no condition rule + append: true \ No newline at end of file diff --git a/test/rules/invalid_array_item_not_object.yaml b/test/rules/invalid_array_item_not_object.yaml new file mode 100644 index 00000000000..a4b65cdd2e9 --- /dev/null +++ b/test/rules/invalid_array_item_not_object.yaml @@ -0,0 +1 @@ +- foo diff --git a/test/rules/invalid_condition_not_rule.yaml b/test/rules/invalid_condition_not_rule.yaml new file mode 100644 index 00000000000..158eff61df0 --- /dev/null +++ b/test/rules/invalid_condition_not_rule.yaml @@ -0,0 +1,5 @@ +- rule: condition not rule + condition: + desc: some desc + output: some output + priority: INFO diff --git a/test/rules/invalid_engine_version_not_number.yaml b/test/rules/invalid_engine_version_not_number.yaml new file mode 100644 index 00000000000..fa77b4a5456 --- /dev/null +++ b/test/rules/invalid_engine_version_not_number.yaml @@ -0,0 +1,34 @@ +# +# Copyright (C) 2016-2018 Draios Inc dba Sysdig. +# +# This file is part of falco. +# +# 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. +# + +- required_engine_version: not-a-number + +- list: cat_binaries + items: [cat] + +- list: cat_capable_binaries + items: [cat_binaries] + +- macro: is_cat + condition: proc.name in (cat_capable_binaries) + +- rule: open_from_cat + desc: A process named cat does an open + condition: evt.type=open and is_cat + output: "An open was seen (command=%proc.cmdline)" + priority: WARNING \ No newline at end of file diff --git a/test/rules/invalid_list_without_items.yaml b/test/rules/invalid_list_without_items.yaml new file mode 100644 index 00000000000..e3d21438d56 --- /dev/null +++ b/test/rules/invalid_list_without_items.yaml @@ -0,0 +1,5 @@ +- list: good_list + items: [foo] + +- list: bad_list + no_items: foo \ No newline at end of file diff --git a/test/rules/invalid_macro_comple_error.yaml b/test/rules/invalid_macro_comple_error.yaml new file mode 100644 index 00000000000..57bf69adf9c --- /dev/null +++ b/test/rules/invalid_macro_comple_error.yaml @@ -0,0 +1,2 @@ +- macro: macro with comp error + condition: gak diff --git a/test/rules/invalid_macro_without_condition.yaml b/test/rules/invalid_macro_without_condition.yaml new file mode 100644 index 00000000000..5b528dc391a --- /dev/null +++ b/test/rules/invalid_macro_without_condition.yaml @@ -0,0 +1,6 @@ +- macro: bad_macro + nope: 1 + +- macro: good_macro + condition: evt.type=execve + diff --git a/test/rules/invalid_missing_list_name.yaml b/test/rules/invalid_missing_list_name.yaml new file mode 100644 index 00000000000..90ed15f0e86 --- /dev/null +++ b/test/rules/invalid_missing_list_name.yaml @@ -0,0 +1,2 @@ +- list: + items: [foo] \ No newline at end of file diff --git a/test/rules/invalid_missing_macro_name.yaml b/test/rules/invalid_missing_macro_name.yaml new file mode 100644 index 00000000000..77f102ab0aa --- /dev/null +++ b/test/rules/invalid_missing_macro_name.yaml @@ -0,0 +1,2 @@ +- macro: + condition: evt.type=execve diff --git a/test/rules/invalid_missing_rule_name.yaml b/test/rules/invalid_missing_rule_name.yaml new file mode 100644 index 00000000000..238f563f432 --- /dev/null +++ b/test/rules/invalid_missing_rule_name.yaml @@ -0,0 +1,4 @@ +- rule: + desc: some desc + condition: evt.type=execve + output: some output diff --git a/test/rules/invalid_not_array.yaml b/test/rules/invalid_not_array.yaml new file mode 100644 index 00000000000..7daacd5db8d --- /dev/null +++ b/test/rules/invalid_not_array.yaml @@ -0,0 +1 @@ +foo: bar \ No newline at end of file diff --git a/test/rules/invalid_not_yaml.yaml b/test/rules/invalid_not_yaml.yaml new file mode 100644 index 00000000000..2626d0a1ff1 --- /dev/null +++ b/test/rules/invalid_not_yaml.yaml @@ -0,0 +1 @@ +This is not yaml \ No newline at end of file diff --git a/test/rules/invalid_rule_without_output.yaml b/test/rules/invalid_rule_without_output.yaml new file mode 100644 index 00000000000..f337b1ad3de --- /dev/null +++ b/test/rules/invalid_rule_without_output.yaml @@ -0,0 +1,4 @@ +- rule: no output rule + desc: some desc + condition: evt.type=fork + priority: INFO diff --git a/test/rules/invalid_unexpected_object.yaml b/test/rules/invalid_unexpected_object.yaml new file mode 100644 index 00000000000..3867010ce7f --- /dev/null +++ b/test/rules/invalid_unexpected_object.yaml @@ -0,0 +1 @@ +- foo: bar diff --git a/test/rules/invalid_yaml_parse_error.yaml b/test/rules/invalid_yaml_parse_error.yaml new file mode 100644 index 00000000000..210c555542d --- /dev/null +++ b/test/rules/invalid_yaml_parse_error.yaml @@ -0,0 +1 @@ +this : is : not : yaml \ No newline at end of file From a084f8c4ed5ff5837a2832a7e5769868dcbe318f Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 12 Jul 2019 10:41:37 -0700 Subject: [PATCH 64/64] CHANGELOG/README changes for 0.16.0 Bumping version, noting changes since last release. Signed-off-by: Mark Stemm --- CHANGELOG.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 +- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe78eab0c50..a362eb65768 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,74 @@ This file documents all notable changes to Falco. The release numbering uses [semantic versioning](http://semver.org). +## v0.16.0 + +Released 2019-07-12 + +## Major Changes + +* Clean up error reporting to provide more meaningful error messages along with context when loading rules files. When run with -V, the results of the validation ("OK" or error message) are sent to standard output. [[#708](https://github.com/falcosecurity/falco/pull/708)] + +* Improve rule loading performance by optimizing lua parsing paths to avoid expensive pattern matches. [[#694](https://github.com/falcosecurity/falco/pull/694)] + +* Bump falco engine version to 4 to reflect new fields `ka.useragent`, others. [[#710](https://github.com/falcosecurity/falco/pull/710)] [[#681](https://github.com/falcosecurity/falco/pull/681)] + +* Add Catch2 as a unit testing framework. This will add additional coverage on top of the regression tests using Avocado. [[#687](https://github.com/falcosecurity/falco/pull/687)] + +## Minor Changes + +* Add SYSDIG_DIR Cmake option to specify location for sysdig source code when building falco. [[#677](https://github.com/falcosecurity/falco/pull/677)] [[#679](https://github.com/falcosecurity/falco/pull/679)] [[#702](https://github.com/falcosecurity/falco/pull/702)] + +* New field `ka.useragent` reports the useragent from k8s audit events. [[#709](https://github.com/falcosecurity/falco/pull/709)] + +* Add clang formatter for C++ syntax formatting. [[#701](https://github.com/falcosecurity/falco/pull/701)] [[#689](https://github.com/falcosecurity/falco/pull/689)] + +* Partial changes towards lua syntax formatting. No particular formatting enforced yet, though. [[#718](https://github.com/falcosecurity/falco/pull/718)] + +* Partial changes towards yaml syntax formatting. No particular formatting enforced yet, though. [[#714](https://github.com/falcosecurity/falco/pull/714)] + +* Add cmake syntax formatting. [[#703](https://github.com/falcosecurity/falco/pull/703)] + +* Token bucket unit tests and redesign. [[#692](https://github.com/falcosecurity/falco/pull/692)] + +* Update github PR template. [[#699](https://github.com/falcosecurity/falco/pull/699)] + +* Fix PR template for kind/rule-*. [[#697](https://github.com/falcosecurity/falco/pull/697)] + +## Bug Fixes + +* Remove an unused cmake file. [[#700](https://github.com/falcosecurity/falco/pull/700)] + +* Misc Cmake cleanups. [[#673](https://github.com/falcosecurity/falco/pull/673)] + +* Misc k8s install docs improvements. [[#671](https://github.com/falcosecurity/falco/pull/671)] + +## Rule Changes + +* Allow k8s.gcr.io/kube-proxy image to run privileged. [[#717](https://github.com/falcosecurity/falco/pull/717)] + +* Add runc to the list of possible container entrypoint parents. [[#712](https://github.com/falcosecurity/falco/pull/712)] + +* Skip Source RFC 1918 addresses when considering outbound connections. [[#685](https://github.com/falcosecurity/falco/pull/685)] + +* Add additional `user_XXX` placeholder macros to allow for easy customization of rule exceptions. [[#685](https://github.com/falcosecurity/falco/pull/685)] + +* Let weaveworks programs change namespaces. [[#685](https://github.com/falcosecurity/falco/pull/685)] + +* Add additional openshift images. [[#685](https://github.com/falcosecurity/falco/pull/685)] + +* Add openshift as a k8s binary. [[#678](https://github.com/falcosecurity/falco/pull/678)] + +* Add dzdo as a binary that can change users. [[#678](https://github.com/falcosecurity/falco/pull/678)] + +* Allow azure/calico binaries to change namespaces. [[#678](https://github.com/falcosecurity/falco/pull/678)] + +* Add back trusted_containers list for backport compatibility [[#675](https://github.com/falcosecurity/falco/pull/675)] + +* Add mkdirat as a syscall for mkdir operations. [[#667](https://github.com/falcosecurity/falco/pull/667)] + +* Add container id/repository to rules that can work with containers. [[#667](https://github.com/falcosecurity/falco/pull/667)] + ## v0.15.3 Released 2019-06-12 diff --git a/README.md b/README.md index df9e22ea29f..cd719c2f18b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ #### Latest release -**v0.15.3** +**v0.16.0** Read the [change log](https://github.com/falcosecurity/falco/blob/dev/CHANGELOG.md) Dev Branch: [![Build Status](https://travis-ci.com/falcosecurity/falco.svg?branch=dev)](https://travis-ci.com/falcosecurity/falco)