Coverity Scan is a free, cloud-based static analysis service provided by Synopsys for the Open Source community. It is a powerful tool for finding defects and security vulnerabilities in code before they hit production.
The core of using Coverity is the build capture process, where the
Coverity tool intercepts your standard compiler calls (like
gcc, clang, cl or
javac) to create an intermediate cov-int
directory containing a detailed model of your codebase.
Here is a step-by-step guide on how to perform a Coverity Scan build, focusing on the standard command-line workflow. Important note here is we're going to use Ubuntu Linux container to run Coverity Scan software since it's unavailable for FreeBSD.
Before you begin, your project must be registered with the Coverity Scan service (for Open Source projects).
cov-analysis-linux64-2024.12.1.tar.gz./bin directory of the Coverity
installation to your system's PATH. This
allows you to run commands like cov-build
directly.sysutils/podman-suite. Enabled corresponding
service in /etc/rc.conf and start them:
podman_enable="YES"
podman_service_enable="YES"
podman_service_flags="--log-level=debug --time=0"
linux container,
another important component is the
emulators/linux_base-rl9 package. Do
not forget to enable linux service via:
service linux enable
service linux start
ubuntu:24.04
image from the Docker registry:
% doas podman pull --os=linux --arch=amd64 docker.io/library/ubuntu:24.04
Trying to pull docker.io/library/ubuntu:24.04...
Getting image source signatures
Copying blob 4b3ffd8ccb52 skipped: already exists
Copying config 97bed23a34 done |
Writing manifest to image destination
97bed23a34971024aa8d254abbe67b7168772340d1f494034773bc464e8dd5b6
ubuntu:24.04
container:
% doas podman run --rm -it --os=linux --arch=amd64 docker.io/library/ubuntu:24.04
root@8313a0296da2:/
So, the container is running interactively now, we can move
forward to the next phase.
It's necessary to install build tools, such as gcc
compiler and libraries in a running container:
root@8313a0296da2:/ echo 'APT::Cache-Limit "1000000000";' > /etc/apt/apt.conf.d/70debconf
root@8313a0296da2:/ echo 'APT::Cache-Start "500000000";' >> /etc/apt/apt.conf.d/70debconf
root@8313a0296da2:/ apt update
root@8313a0296da2:/ apt install build-essential file libpcre2-dev libssl-dev wget zlib1g-dev
The Coverity Scan distibution was copied to the running container and then it's been unpacked.
% doas podman ps --format "{{.ID}}\t{{.Image}}"
8313a0296da2 docker.io/library/ubuntu:24.04
% doas podman cp cov-analysis-linux64-2024.12.1.tar.gz 8313a0296da2:/home/ubuntu
ubuntu container:
root@8313a0296da2:/ cd /home/ubuntu && \
mkdir cov && \
cat cov-analysis-linux64-2024.12.1.tar.gz | \
tar xfvz - -C cov --strip-components=1
PATH variable to run
Coverity Scan binaries:
root@8313a0296da2:/home/ubuntu# export PATH=/home/ubuntu/cov/bin:$PATH
freenginx
and run Coverity Scan.
root@8313a0296da2:/home/ubuntu# wget -qO- https://freenginx.org/download/freenginx-1.29.3.tar.gz | \
tar xvzf - -C . && \
cd freenginx-1.29.3 && \
./configure && \
cov-build --dir cov-int make && \
tar czvf freenginx.tgz cov-int
After a successful Coverity Scan build, a tarball was
created, now it's time to submit it to the
portal.
Now we know all Coverity Scan build parts, and it's time to combain
all our knowledge in a Containerfile, a configuration file
that automates the steps of creating a container image. The
Containerfile(5) says that the file is similar to a
Makefile, but from my perspective, that file is similar
to a Dockerfile.
FROM ubuntu:24.04
MAINTAINER info@tipi.work
USER root
ARG PROJECT
ARG VERSION
ARG TOKEN
ENV PATH="/home/ubuntu/cov/bin:$PATH"
RUN echo 'APT::Cache-Limit "1000000000";\nAPT::Cache-Start "500000000";' \
>/etc/apt/apt.conf.d/70debconf \
&& echo 'APT::Install-Recommends "false";\nAPT::Install-Suggests "false";' \
>>/etc/apt/apt.conf.d/70debconf \
&& apt-get -y update \
&& apt-get -y install build-essential ca-certificates \
file libpcre2-dev libssl-dev wget zlib1g-dev \
&& cd /home/ubuntu \
&& wget -qO- https://${PROJECT}.org/download/${PROJECT}-${VERSION}.tar.gz \
| tar xvzf - -C . \
&& mkdir cov \
&& wget https://scan.coverity.com/download/linux64 \
--post-data "token=${TOKEN}&project=${PROJECT}" -qO- \
| tar xfvz - -C cov --strip-components=1 \
--exclude=bazel --exclude=bin/nupkgs --exclude=closure-compiler \
--exclude=dotnet --exclude=go --exclude=jars --exclude=jdk21 \
--exclude=jdk23 --exclude=jre --exclude=node --exclude=template-da \
--exclude=support-angularjs \
&& cd ${PROJECT}-${VERSION} \
&& ./configure \
&& cov-build --dir cov-int make -j 4 \
&& tar cfvz ${PROJECT}.tgz cov-int
Important note: in case you're using ipfw(8) on your
FreeBSD system, you may need to update the Containerfile
with the following patch:
--- Containerfile.orig 2025-11-13 22:29:43.213699000 -0500
+++ Containerfile 2025-11-13 22:45:31.218896000 -0500
@@ -8,7 +8,10 @@
ENV PATH="/home/ubuntu/cov/bin:$PATH"
-RUN echo 'APT::Cache-Limit "1000000000";\nAPT::Cache-Start "500000000";' \
+COPY sysctl /tmp
+
+RUN /tmp/sysctl net.inet.ip.fw.enable=0 \
+ && echo 'APT::Cache-Limit "1000000000";\nAPT::Cache-Start "500000000";' \
>/etc/apt/apt.conf.d/70debconf \
&& echo 'APT::Install-Recommends "false";\nAPT::Install-Suggests "false";' \
>>/etc/apt/apt.conf.d/70debconf \
It's a small trick, but it's necessary because a jail
inherits net.inet.ip.fw.enable state from a host system,
please visit ipfw(8) manual page to get details.
It's possible to avoid such behaviour by switching from the
ipfw(8) to the pf(4).
We successfully ran a linux version of the Coverity Scan build software in an Ubuntu container under FreeBSD.