SlideShare une entreprise Scribd logo
1  sur  14
Télécharger pour lire hors ligne
PVS-Studio in the Clouds: Travis CI
Author: Oleg Andreev
Date: 28.06.2019
Tags: Cpp, DevOps
At the moment, cloud CI systems are a highly-demanded service. In this article, we'll tell you how to
integrate analysis of source code into a CI cloud platform with the tools that are already available in
PVS-Studio. As an example we'll use the Travis CI service.
Why do we consider third-party clouds and don't make our own? There is a number of reasons, the
main one is that the SaaS implementation is quite an expensive and difficult procedure. In fact, it is a
simple and trivial task to directly integrate PVS-Studio analysis into a third-party cloud platform -
whether it's open platforms like CircleCI, Travis CI, GitLab, or a specific enterprise solution used only
in a certain company. Therefore we can say that PVS-Studio is already available "in the clouds".
Another issue is implementing and ensuring access to the infrastructure 24/7. This is a more
complicated task. PVS-Studio is not going to provide its own cloud platform directly for running
analysis on it.
Some Information about the Used Software
Travis CI is a service for building and testing software that uses GitHub as a storage. Travis CI doesn't
require changing of programming code for using the service. All settings are made in the file
.travis.yml located in the root of the repository.
We'll take LXC (Linux Containers) as a test project for PVS-Studio. It is a virtualization system at the
operation system level for launching several instances of the Linux OS at one node.
The project is small, but more than enough for demonstration. Output of the cloc command:
Language files blank comment code
C 124 11937 6758 50836
C/C++ Header 65 1117 3676 3774
Note: LXC developers already use Travis CI, so we'll take their configuration file as the basis and edit
it for our purposes.
Configuration
To start working with Travis CI we follow the link and login using a GitHub-account.
In the open window we need to login Travis CI.
After authorization, it redirects to the welcome page "First time here? Lets get you started!", where
we find a brief description what has to be done afterwards to get started:
• enable the repositories;
• add the .travis.yml file in the repository;
• start the first build.
Let's start doing these actions.
To add our repository in Travis CI we go to the profile settings by the link and press "Activate".
Once clicked, a window will open to select repositories that the Travis CI app will be given access to.
Note: to provide access to the repository, your account must have administrator's rights to do so.
After that we choose the right repository, confirm the choice with the "Approve & Install" button,
and we'll be redirected back to the profile settings page.
Let's add some variables that we'll use to create the analyzer's license file and send its reports. To do
this, we'll go to the settings page - the "Settings" button to the right of the needed repository.
The settings window will open.
Brief description of settings;
● "General" section - configuring auto-start task triggers;
● "Auto Cancelation" section allows to configure build auto-cancellation;
● "Environment Variables" section allows to define environment variables that contain both
open and confidential information, such as login information, ssh-keys;
● "Cron Jobs" section is a configuration of task running schedule.
In the section "Environment Variables" we'll create variables PVS_USERNAME and PVS_KEY
containing a username and a license key for the static analyzer respectively. If you don't have a
permanent PVS-Studio license, you can request a trial license.
Right here we'll create variables MAIL_USER and MAIL_PASSWORD, containing a username and an
email password, which we'll use for sending reports.
When running tasks, Travis CI takes instructions from the .travis.yml file, located in the root of the
repository.
By using Travis CI, we can run static analysis both directly on the virtual machine and use a
preconfigured container to do so. The results of these approaches are no different from each other.
However, usage of a pre-configured container can be useful. For example, if we already have a
container with some specific environment, inside of which a software product is built and tested and
we don't want to restore this environment in Travis CI.
Let's create a configuration to run the analyzer on a virtual machine.
For building and testing we'll use a virtual machine on Ubuntu Trusty, its description is available by
the link.
First of all, we specify that the project is written in C and list compilers that we will use for the build:
language: c
compiler:
- gcc
- clang
Note: if you specify more than one compiler, the tasks will run simultaneously for each of them.
Read more here.
Before the build we need to add the analyzer repository, set dependencies and additional packages:
before_install:
- sudo add-apt-repository ppa:ubuntu-lxc/daily -y
- wget -q -O - https://files.viva64.com/etc/pubkey.txt |sudo apt-key add -
- sudo wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
- sudo apt-get update -qq
- sudo apt-get install -qq coccinelle parallel
libapparmor-dev libcap-dev libseccomp-dev
python3-dev python3-setuptools docbook2x
libgnutls-dev libselinux1-dev linux-libc-dev pvs-studio
libio-socket-ssl-perl libnet-ssleay-perl sendemail
ca-certificates
Before we build a project, we need to prepare your environment:
script:
- ./coccinelle/run-coccinelle.sh -i
- git diff --exit-code
- export CFLAGS="-Wall -Werror"
- export LDFLAGS="-pthread -lpthread"
- ./autogen.sh
- rm -Rf build
- mkdir build
- cd build
- ../configure --enable-tests --with-distro=unknown
Next, we need to create a license file and start analyzing the project.
Then we create a license file for the analyzer by the first command. Data for the $PVS_USERNAME
and $PVS_KEY variables is taken from the project settings.
- pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic
By the next command, we start tracing the project build.
- pvs-studio-analyzer trace -- make -j4
After that we run static analysis.
Note: when using a trial license, you need to specify the parameter --disableLicenseExpirationCheck.
- pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic
-o PVS-Studio-${CC}.log
--disableLicenseExpirationCheck
The file with the analysis results is converted into the html-report by the last command.
- plog-converter -t html PVS-Studio-${CC}.log
-o PVS-Studio-${CC}.html
Since TravisCI doesn't let you change the format of email notifications, in the last step we'll use the
sendemail package for sending reports:
- sendemail -t mail@domain.com
-u "PVS-Studio $CC report, commit:$TRAVIS_COMMIT"
-m "PVS-Studio $CC report, commit:$TRAVIS_COMMIT"
-s smtp.gmail.com:587
-xu $MAIL_USER
-xp $MAIL_PASSWORD
-o tls=yes
-f $MAIL_USER
-a PVS-Studio-${CC}.log PVS-Studio-${CC}.html
Here is the full text of the configuration file for running the analyzer on the virtual machine:
language: c
compiler:
- gcc
- clang
before_install:
- sudo add-apt-repository ppa:ubuntu-lxc/daily -y
- wget -q -O - https://files.viva64.com/etc/pubkey.txt |sudo apt-key add -
- sudo wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
- sudo apt-get update -qq
- sudo apt-get install -qq coccinelle parallel
libapparmor-dev libcap-dev libseccomp-dev
python3-dev python3-setuptools docbook2x
libgnutls-dev libselinux1-dev linux-libc-dev pvs-studio
libio-socket-ssl-perl libnet-ssleay-perl sendemail
ca-certificates
script:
- ./coccinelle/run-coccinelle.sh -i
- git diff --exit-code
- export CFLAGS="-Wall -Werror"
- export LDFLAGS="-pthread -lpthread"
- ./autogen.sh
- rm -Rf build
- mkdir build
- cd build
- ../configure --enable-tests --with-distro=unknown
- pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic
- pvs-studio-analyzer trace -- make -j4
- pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic
-o PVS-Studio-${CC}.log
--disableLicenseExpirationCheck
- plog-converter -t html PVS-Studio-${CC}.log -o PVS-Studio-${CC}.html
- sendemail -t mail@domain.com
-u "PVS-Studio $CC report, commit:$TRAVIS_COMMIT"
-m "PVS-Studio $CC report, commit:$TRAVIS_COMMIT"
-s smtp.gmail.com:587
-xu $MAIL_USER
-xp $MAIL_PASSWORD
-o tls=yes
-f $MAIL_USER
-a PVS-Studio-${CC}.log PVS-Studio-${CC}.html
To run PVS-Studio in a container, let's pre-create it using the following Dockerfile:
FROM docker.io/ubuntu:trusty
ENV CFLAGS="-Wall -Werror"
ENV LDFLAGS="-pthread -lpthread"
RUN apt-get update && apt-get install -y software-properties-common wget 
&& wget -q -O - https://files.viva64.com/etc/pubkey.txt |
sudo apt-key add - 
&& wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
&& apt-get update 
&& apt-get install -yqq coccinelle parallel
libapparmor-dev libcap-dev libseccomp-dev
python3-dev python3-setuptools docbook2x
libgnutls-dev libselinux1-dev linux-libc-dev
pvs-studio git libtool autotools-dev automake
pkg-config clang make libio-socket-ssl-perl
libnet-ssleay-perl sendemail ca-certificates 
&& rm -rf /var/lib/apt/lists/*
In this case, the configuration file may look like this:
before_install:
- docker pull docker.io/oandreev/lxc
env:
- CC=gcc
- CC=clang
script:
- docker run
--rm
--cap-add SYS_PTRACE
-v $(pwd):/pvs
-w /pvs
docker.io/oandreev/lxc
/bin/bash -c " ./coccinelle/run-coccinelle.sh -i
&& git diff --exit-code
&& ./autogen.sh
&& mkdir build && cd build
&& ../configure CC=$CC
&& pvs-studio-analyzer credentials
$PVS_USERNAME $PVS_KEY -o PVS-Studio.lic
&& pvs-studio-analyzer trace -- make -j4
&& pvs-studio-analyzer analyze -j2
-l PVS-Studio.lic
-o PVS-Studio-$CC.log
--disableLicenseExpirationCheck
&& plog-converter -t html
-o PVS-Studio-$CC.html
PVS-Studio-$CC.log
&& sendemail -t mail@domain.com
-u 'PVS-Studio $CC report, commit:$TRAVIS_COMMIT'
-m 'PVS-Studio $CC report, commit:$TRAVIS_COMMIT'
-s smtp.gmail.com:587
-xu $MAIL_USER -xp $MAIL_PASSWORD
-o tls=yes -f $MAIL_USER
-a PVS-Studio-${CC}.log PVS-Studio-${CC}.html"
As you can see, in this case we do nothing inside the virtual machine, and all the actions on building
and testing the project take place inside the container.
Note: when you start the container, you need to specify the parameter --cap-add SYS_PTRACE or --
security-opt seccomp:unconfined, as a ptrace system call is used for compiler tracing.
Next, we load the configuration file in the root of the repository and see that Travis CI has been
notified of changes in the project and has automatically started the build.
Details of the build progress and analyzer check can be seen in the console.
After the tests are over, we will receive two emails: the first - with static analysis results for building
a project using gcc, and the second - for clang, respectively.
Briefly About the Check Results
In general, the project is quite clean, the analyzer issued only 24 high-certainty and 46 medium-
certainty warnings. Let's look at a couple of interesting notifications:
Redundant conditions in if
V590 Consider inspecting the 'ret != (- 1) && ret == 1' expression. The expression is excessive or
contains a misprint. attach.c 107
#define EOF -1
static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
{
....
while (getline(&line, &line_bufsz, proc_file) != -1)
{
ret = sscanf(line, "CapBnd: %llx", &info->capability_mask);
if (ret != EOF && ret == 1) // <=
{
found = true;
break;
}
}
....
}
If ret == 1, it is definitely not equal to -1 (EOF). Redundant check, ret != EOF can be removed.
Two similar warnings have been issued:
• V590 Consider inspecting the 'ret != (- 1) && ret == 1' expression. The expression is excessive
or contains a misprint. attach.c 579
• V590 Consider inspecting the 'ret != (- 1) && ret == 1' expression. The expression is excessive
or contains a misprint. attach.c 583
Loss of High Bits
V784 The size of the bit mask is less than the size of the first operand. This will cause the loss of
higher bits. conf.c 1879
struct mount_opt
{
char *name;
int clear;
int flag;
};
static void parse_mntopt(char *opt, unsigned long *flags,
char **data, size_t size)
{
struct mount_opt *mo;
/* If opt is found in mount_opt, set or clear flags.
* Otherwise append it to data. */
for (mo = &mount_opt[0]; mo->name != NULL; mo++)
{
if (strncmp(opt, mo->name, strlen(mo->name)) == 0)
{
if (mo->clear)
{
*flags &= ~mo->flag; // <=
}
else
{
*flags |= mo->flag;
}
return;
}
}
....
}
Under Linux, long is a 64-bit integer variable, mo->flag is a 32-bit integer variable. Usage of mo->flag
as a bit mask will lead to the loss of 32 high bits. A bit mask is implicitly cast to a 64-bit integer
variable after bitwise inversion. High bits of this mask may be lost.
I'll show it using an example:
unsigned long long x;
unsigned y;
....
x &= ~y;
Here is the correct version of code:
*flags &= ~(unsigned long)(mo->flag);
The analyzer issued another similar warning:
• V784 The size of the bit mask is less than the size of the first operand. This will cause the loss
of higher bits. conf.c 1933
Suspicious Loop
V612 An unconditional 'return' within a loop. conf.c 3477
#define lxc_list_for_each(__iterator, __list) 
for (__iterator = (__list)->next; __iterator != __list; 
__iterator = __iterator->next)
static bool verify_start_hooks(struct lxc_conf *conf)
{
char path[PATH_MAX];
struct lxc_list *it;
lxc_list_for_each (it, &conf->hooks[LXCHOOK_START]) {
int ret;
char *hookname = it->elem;
ret = snprintf(path, PATH_MAX, "%s%s",
conf->rootfs.path ? conf->rootfs.mount : "",
hookname);
if (ret < 0 || ret >= PATH_MAX)
return false;
ret = access(path, X_OK);
if (ret < 0) {
SYSERROR("Start hook "%s" not found in container",
hookname);
return false;
}
return true; // <=
}
return true;
}
The loop is started and interrupted on the first iteration. This might have been made intentionally,
but in this case the loop could have been omitted.
Array Index out of Bounds
V557 Array underrun is possible. The value of 'bytes - 1' index could reach -1. network.c 2570
static int lxc_create_network_unpriv_exec(const char *lxcpath,
const char *lxcname,
struct lxc_netdev *netdev,
pid_t pid,
unsigned int hooks_version)
{
int bytes;
char buffer[PATH_MAX] = {0};
....
bytes = lxc_read_nointr(pipefd[0], &buffer, PATH_MAX);
if (bytes < 0)
{
SYSERROR("Failed to read from pipe file descriptor");
close(pipefd[0]);
}
else
{
buffer[bytes - 1] = '0';
}
....
}
Bytes are read in the buffer from the pipe. In case of an error, the lxc_read_nointr function will
return a negative value. If all goes successfully, a terminal null is written by the last element.
However, if 0 bytes are read, the index will be out of buffer bounds, leading to undefined behavior.
The analyzer issued another similar warning:
• V557 Array underrun is possible. The value of 'bytes - 1' index could reach -1. network.c
2725
Buffer Overflow
V576 Incorrect format. Consider checking the third actual argument of the 'sscanf' function. It's
dangerous to use string specifier without width specification. Buffer overflow is possible.
lxc_unshare.c 205
static bool lookup_user(const char *oparg, uid_t *uid)
{
char name[PATH_MAX];
....
if (sscanf(oparg, "%u", uid) < 1)
{
/* not a uid -- perhaps a username */
if (sscanf(oparg, "%s", name) < 1) // <=
{
free(buf);
return false;
}
....
}
....
}
In this case, usage of sscanf can be dangerous, because if the oparq buffer is larger than the name
buffer, the index will be out of bounds when forming the name buffer.
Conclusion
As we see, it's a quite simple task to configure a static code analyzer check in a cloud. For this, we
just need to add one file in a repository and spend little time setting up the CI system. As a result,
we'll get a tool to detect problem at the stage of writing code. The tool lets us prevent bugs from
getting to the next stages of testing, where their fixing will require much time and efforts.
Of course, PVS-Studio usage with cloud platforms is not only limited to Travis CI. Similar to the
method described in the article, with small differences, PVS-Studio analysis can be integrated into
other popular cloud CI solutions, such as CircleCI, GitLab, etc.
Useful links
• For additional information on running PVS-Studio on Linux and MacOS, follow the link.
• You can also read about creating, setting and using containers with installed PVS-Studio
static code analyzer by the link.
• TravisCI documentation.

Contenu connexe

Tendances

Learn RabbitMQ with Python in 90mins
Learn RabbitMQ with Python in 90minsLearn RabbitMQ with Python in 90mins
Learn RabbitMQ with Python in 90mins
Larry Cai
 
Binary Packaging for HPC with Spack
Binary Packaging for HPC with SpackBinary Packaging for HPC with Spack
Binary Packaging for HPC with Spack
inside-BigData.com
 
Installaling Puppet Master and Agent
Installaling Puppet Master and AgentInstallaling Puppet Master and Agent
Installaling Puppet Master and Agent
Ranjit Avasarala
 

Tendances (20)

Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014
 
A Survey of Container Security in 2016: A Security Update on Container Platforms
A Survey of Container Security in 2016: A Security Update on Container PlatformsA Survey of Container Security in 2016: A Security Update on Container Platforms
A Survey of Container Security in 2016: A Security Update on Container Platforms
 
Jenkins & IaC
Jenkins & IaCJenkins & IaC
Jenkins & IaC
 
PHP development with Docker
PHP development with DockerPHP development with Docker
PHP development with Docker
 
Puppet evolutions
Puppet evolutionsPuppet evolutions
Puppet evolutions
 
devops@cineca
devops@cinecadevops@cineca
devops@cineca
 
Programowanie AWSa z CLI, boto, Ansiblem i libcloudem
Programowanie AWSa z CLI, boto, Ansiblem i libcloudemProgramowanie AWSa z CLI, boto, Ansiblem i libcloudem
Programowanie AWSa z CLI, boto, Ansiblem i libcloudem
 
There is No Server: Immutable Infrastructure and Serverless Architecture
There is No Server: Immutable Infrastructure and Serverless ArchitectureThere is No Server: Immutable Infrastructure and Serverless Architecture
There is No Server: Immutable Infrastructure and Serverless Architecture
 
PHP on Heroku: Deploying and Scaling Apps in the Cloud
PHP on Heroku: Deploying and Scaling Apps in the CloudPHP on Heroku: Deploying and Scaling Apps in the Cloud
PHP on Heroku: Deploying and Scaling Apps in the Cloud
 
Learn RabbitMQ with Python in 90mins
Learn RabbitMQ with Python in 90minsLearn RabbitMQ with Python in 90mins
Learn RabbitMQ with Python in 90mins
 
Binary Packaging for HPC with Spack
Binary Packaging for HPC with SpackBinary Packaging for HPC with Spack
Binary Packaging for HPC with Spack
 
Amending and Testing changes lab guide
Amending and Testing changes lab guideAmending and Testing changes lab guide
Amending and Testing changes lab guide
 
Docker for Developers - Sunshine PHP
Docker for Developers - Sunshine PHPDocker for Developers - Sunshine PHP
Docker for Developers - Sunshine PHP
 
Build service with_docker_in_90mins
Build service with_docker_in_90minsBuild service with_docker_in_90mins
Build service with_docker_in_90mins
 
Docker Meetup Paris: enterprise Docker
Docker Meetup Paris: enterprise DockerDocker Meetup Paris: enterprise Docker
Docker Meetup Paris: enterprise Docker
 
Linux containers & Devops
Linux containers & DevopsLinux containers & Devops
Linux containers & Devops
 
Zero Downtime Deployment with Ansible
Zero Downtime Deployment with AnsibleZero Downtime Deployment with Ansible
Zero Downtime Deployment with Ansible
 
How to deploy PHP projects with docker
How to deploy PHP projects with dockerHow to deploy PHP projects with docker
How to deploy PHP projects with docker
 
Simplify and run your development environments with Vagrant on OpenStack
Simplify and run your development environments with Vagrant on OpenStackSimplify and run your development environments with Vagrant on OpenStack
Simplify and run your development environments with Vagrant on OpenStack
 
Installaling Puppet Master and Agent
Installaling Puppet Master and AgentInstallaling Puppet Master and Agent
Installaling Puppet Master and Agent
 

Similaire à PVS-Studio in the Clouds: Travis CI

Similaire à PVS-Studio in the Clouds: Travis CI (20)

PVS-Studio in the Clouds: CircleCI
PVS-Studio in the Clouds: CircleCIPVS-Studio in the Clouds: CircleCI
PVS-Studio in the Clouds: CircleCI
 
Analysis of merge requests in GitLab using PVS-Studio for C#
Analysis of merge requests in GitLab using PVS-Studio for C#Analysis of merge requests in GitLab using PVS-Studio for C#
Analysis of merge requests in GitLab using PVS-Studio for C#
 
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOpsPVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
 
CICD With GitHub, Travis, SonarCloud and Docker Hub
CICD With GitHub, Travis, SonarCloud and Docker HubCICD With GitHub, Travis, SonarCloud and Docker Hub
CICD With GitHub, Travis, SonarCloud and Docker Hub
 
Continuous Testing and New Tools for Automation - Presentation from StarWest ...
Continuous Testing and New Tools for Automation - Presentation from StarWest ...Continuous Testing and New Tools for Automation - Presentation from StarWest ...
Continuous Testing and New Tools for Automation - Presentation from StarWest ...
 
PVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agents
PVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agentsPVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agents
PVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agents
 
Trusting the Unknown
Trusting the UnknownTrusting the Unknown
Trusting the Unknown
 
Trusting the Unknown
Trusting the UnknownTrusting the Unknown
Trusting the Unknown
 
DevOps on AWS: Accelerating Software Delivery with the AWS Developer Tools
DevOps on AWS: Accelerating Software Delivery with the AWS Developer ToolsDevOps on AWS: Accelerating Software Delivery with the AWS Developer Tools
DevOps on AWS: Accelerating Software Delivery with the AWS Developer Tools
 
The DevOps paradigm - the evolution of IT professionals and opensource toolkit
The DevOps paradigm - the evolution of IT professionals and opensource toolkitThe DevOps paradigm - the evolution of IT professionals and opensource toolkit
The DevOps paradigm - the evolution of IT professionals and opensource toolkit
 
The DevOps Paradigm
The DevOps ParadigmThe DevOps Paradigm
The DevOps Paradigm
 
Jump into Squeak - Integrate Squeak projects with Docker & Github
Jump into Squeak - Integrate Squeak projects with Docker & GithubJump into Squeak - Integrate Squeak projects with Docker & Github
Jump into Squeak - Integrate Squeak projects with Docker & Github
 
AWS EC2 Ubuntu Instance - Step-by-Step Deployment Guide
AWS EC2 Ubuntu Instance - Step-by-Step Deployment GuideAWS EC2 Ubuntu Instance - Step-by-Step Deployment Guide
AWS EC2 Ubuntu Instance - Step-by-Step Deployment Guide
 
Containerizing your Security Operations Center
Containerizing your Security Operations CenterContainerizing your Security Operations Center
Containerizing your Security Operations Center
 
Automate Your Automation | DrupalCon Vienna
Automate Your Automation | DrupalCon ViennaAutomate Your Automation | DrupalCon Vienna
Automate Your Automation | DrupalCon Vienna
 
Function as a Service
Function as a ServiceFunction as a Service
Function as a Service
 
Azure DevOps Deployment Group
Azure DevOps Deployment GroupAzure DevOps Deployment Group
Azure DevOps Deployment Group
 
Why so continuous
Why so continuousWhy so continuous
Why so continuous
 
Care and feeding notes
Care and feeding notesCare and feeding notes
Care and feeding notes
 
AWS re:Invent 2016: DevOps on AWS: Accelerating Software Delivery with the AW...
AWS re:Invent 2016: DevOps on AWS: Accelerating Software Delivery with the AW...AWS re:Invent 2016: DevOps on AWS: Accelerating Software Delivery with the AW...
AWS re:Invent 2016: DevOps on AWS: Accelerating Software Delivery with the AW...
 

Plus de Andrey Karpov

Plus de Andrey Karpov (20)

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developer
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature Overview
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
PVS-Studio в 2021
PVS-Studio в 2021PVS-Studio в 2021
PVS-Studio в 2021
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and Java
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal Engine
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for you
 

Dernier

%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
chiefasafspells
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 

Dernier (20)

%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 

PVS-Studio in the Clouds: Travis CI

  • 1. PVS-Studio in the Clouds: Travis CI Author: Oleg Andreev Date: 28.06.2019 Tags: Cpp, DevOps At the moment, cloud CI systems are a highly-demanded service. In this article, we'll tell you how to integrate analysis of source code into a CI cloud platform with the tools that are already available in PVS-Studio. As an example we'll use the Travis CI service. Why do we consider third-party clouds and don't make our own? There is a number of reasons, the main one is that the SaaS implementation is quite an expensive and difficult procedure. In fact, it is a simple and trivial task to directly integrate PVS-Studio analysis into a third-party cloud platform - whether it's open platforms like CircleCI, Travis CI, GitLab, or a specific enterprise solution used only in a certain company. Therefore we can say that PVS-Studio is already available "in the clouds". Another issue is implementing and ensuring access to the infrastructure 24/7. This is a more complicated task. PVS-Studio is not going to provide its own cloud platform directly for running analysis on it. Some Information about the Used Software Travis CI is a service for building and testing software that uses GitHub as a storage. Travis CI doesn't require changing of programming code for using the service. All settings are made in the file .travis.yml located in the root of the repository. We'll take LXC (Linux Containers) as a test project for PVS-Studio. It is a virtualization system at the operation system level for launching several instances of the Linux OS at one node. The project is small, but more than enough for demonstration. Output of the cloc command: Language files blank comment code C 124 11937 6758 50836
  • 2. C/C++ Header 65 1117 3676 3774 Note: LXC developers already use Travis CI, so we'll take their configuration file as the basis and edit it for our purposes. Configuration To start working with Travis CI we follow the link and login using a GitHub-account. In the open window we need to login Travis CI.
  • 3. After authorization, it redirects to the welcome page "First time here? Lets get you started!", where we find a brief description what has to be done afterwards to get started: • enable the repositories; • add the .travis.yml file in the repository; • start the first build. Let's start doing these actions. To add our repository in Travis CI we go to the profile settings by the link and press "Activate".
  • 4. Once clicked, a window will open to select repositories that the Travis CI app will be given access to. Note: to provide access to the repository, your account must have administrator's rights to do so. After that we choose the right repository, confirm the choice with the "Approve & Install" button, and we'll be redirected back to the profile settings page. Let's add some variables that we'll use to create the analyzer's license file and send its reports. To do this, we'll go to the settings page - the "Settings" button to the right of the needed repository.
  • 5. The settings window will open.
  • 6. Brief description of settings; ● "General" section - configuring auto-start task triggers; ● "Auto Cancelation" section allows to configure build auto-cancellation; ● "Environment Variables" section allows to define environment variables that contain both open and confidential information, such as login information, ssh-keys; ● "Cron Jobs" section is a configuration of task running schedule. In the section "Environment Variables" we'll create variables PVS_USERNAME and PVS_KEY containing a username and a license key for the static analyzer respectively. If you don't have a permanent PVS-Studio license, you can request a trial license. Right here we'll create variables MAIL_USER and MAIL_PASSWORD, containing a username and an email password, which we'll use for sending reports. When running tasks, Travis CI takes instructions from the .travis.yml file, located in the root of the repository. By using Travis CI, we can run static analysis both directly on the virtual machine and use a preconfigured container to do so. The results of these approaches are no different from each other. However, usage of a pre-configured container can be useful. For example, if we already have a container with some specific environment, inside of which a software product is built and tested and we don't want to restore this environment in Travis CI. Let's create a configuration to run the analyzer on a virtual machine. For building and testing we'll use a virtual machine on Ubuntu Trusty, its description is available by the link. First of all, we specify that the project is written in C and list compilers that we will use for the build: language: c compiler: - gcc - clang Note: if you specify more than one compiler, the tasks will run simultaneously for each of them. Read more here. Before the build we need to add the analyzer repository, set dependencies and additional packages:
  • 7. before_install: - sudo add-apt-repository ppa:ubuntu-lxc/daily -y - wget -q -O - https://files.viva64.com/etc/pubkey.txt |sudo apt-key add - - sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.viva64.com/etc/viva64.list - sudo apt-get update -qq - sudo apt-get install -qq coccinelle parallel libapparmor-dev libcap-dev libseccomp-dev python3-dev python3-setuptools docbook2x libgnutls-dev libselinux1-dev linux-libc-dev pvs-studio libio-socket-ssl-perl libnet-ssleay-perl sendemail ca-certificates Before we build a project, we need to prepare your environment: script: - ./coccinelle/run-coccinelle.sh -i - git diff --exit-code - export CFLAGS="-Wall -Werror" - export LDFLAGS="-pthread -lpthread" - ./autogen.sh - rm -Rf build - mkdir build - cd build - ../configure --enable-tests --with-distro=unknown Next, we need to create a license file and start analyzing the project. Then we create a license file for the analyzer by the first command. Data for the $PVS_USERNAME and $PVS_KEY variables is taken from the project settings. - pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic By the next command, we start tracing the project build. - pvs-studio-analyzer trace -- make -j4 After that we run static analysis. Note: when using a trial license, you need to specify the parameter --disableLicenseExpirationCheck. - pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic -o PVS-Studio-${CC}.log --disableLicenseExpirationCheck The file with the analysis results is converted into the html-report by the last command. - plog-converter -t html PVS-Studio-${CC}.log -o PVS-Studio-${CC}.html Since TravisCI doesn't let you change the format of email notifications, in the last step we'll use the sendemail package for sending reports: - sendemail -t mail@domain.com -u "PVS-Studio $CC report, commit:$TRAVIS_COMMIT" -m "PVS-Studio $CC report, commit:$TRAVIS_COMMIT" -s smtp.gmail.com:587 -xu $MAIL_USER -xp $MAIL_PASSWORD
  • 8. -o tls=yes -f $MAIL_USER -a PVS-Studio-${CC}.log PVS-Studio-${CC}.html Here is the full text of the configuration file for running the analyzer on the virtual machine: language: c compiler: - gcc - clang before_install: - sudo add-apt-repository ppa:ubuntu-lxc/daily -y - wget -q -O - https://files.viva64.com/etc/pubkey.txt |sudo apt-key add - - sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.viva64.com/etc/viva64.list - sudo apt-get update -qq - sudo apt-get install -qq coccinelle parallel libapparmor-dev libcap-dev libseccomp-dev python3-dev python3-setuptools docbook2x libgnutls-dev libselinux1-dev linux-libc-dev pvs-studio libio-socket-ssl-perl libnet-ssleay-perl sendemail ca-certificates script: - ./coccinelle/run-coccinelle.sh -i - git diff --exit-code - export CFLAGS="-Wall -Werror" - export LDFLAGS="-pthread -lpthread" - ./autogen.sh - rm -Rf build - mkdir build - cd build - ../configure --enable-tests --with-distro=unknown - pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic - pvs-studio-analyzer trace -- make -j4 - pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic -o PVS-Studio-${CC}.log --disableLicenseExpirationCheck - plog-converter -t html PVS-Studio-${CC}.log -o PVS-Studio-${CC}.html - sendemail -t mail@domain.com -u "PVS-Studio $CC report, commit:$TRAVIS_COMMIT" -m "PVS-Studio $CC report, commit:$TRAVIS_COMMIT" -s smtp.gmail.com:587 -xu $MAIL_USER -xp $MAIL_PASSWORD -o tls=yes -f $MAIL_USER -a PVS-Studio-${CC}.log PVS-Studio-${CC}.html To run PVS-Studio in a container, let's pre-create it using the following Dockerfile: FROM docker.io/ubuntu:trusty ENV CFLAGS="-Wall -Werror" ENV LDFLAGS="-pthread -lpthread" RUN apt-get update && apt-get install -y software-properties-common wget && wget -q -O - https://files.viva64.com/etc/pubkey.txt | sudo apt-key add - && wget -O /etc/apt/sources.list.d/viva64.list https://files.viva64.com/etc/viva64.list
  • 9. && apt-get update && apt-get install -yqq coccinelle parallel libapparmor-dev libcap-dev libseccomp-dev python3-dev python3-setuptools docbook2x libgnutls-dev libselinux1-dev linux-libc-dev pvs-studio git libtool autotools-dev automake pkg-config clang make libio-socket-ssl-perl libnet-ssleay-perl sendemail ca-certificates && rm -rf /var/lib/apt/lists/* In this case, the configuration file may look like this: before_install: - docker pull docker.io/oandreev/lxc env: - CC=gcc - CC=clang script: - docker run --rm --cap-add SYS_PTRACE -v $(pwd):/pvs -w /pvs docker.io/oandreev/lxc /bin/bash -c " ./coccinelle/run-coccinelle.sh -i && git diff --exit-code && ./autogen.sh && mkdir build && cd build && ../configure CC=$CC && pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic && pvs-studio-analyzer trace -- make -j4 && pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic -o PVS-Studio-$CC.log --disableLicenseExpirationCheck && plog-converter -t html -o PVS-Studio-$CC.html PVS-Studio-$CC.log && sendemail -t mail@domain.com -u 'PVS-Studio $CC report, commit:$TRAVIS_COMMIT' -m 'PVS-Studio $CC report, commit:$TRAVIS_COMMIT' -s smtp.gmail.com:587 -xu $MAIL_USER -xp $MAIL_PASSWORD -o tls=yes -f $MAIL_USER -a PVS-Studio-${CC}.log PVS-Studio-${CC}.html" As you can see, in this case we do nothing inside the virtual machine, and all the actions on building and testing the project take place inside the container. Note: when you start the container, you need to specify the parameter --cap-add SYS_PTRACE or -- security-opt seccomp:unconfined, as a ptrace system call is used for compiler tracing. Next, we load the configuration file in the root of the repository and see that Travis CI has been notified of changes in the project and has automatically started the build.
  • 10. Details of the build progress and analyzer check can be seen in the console. After the tests are over, we will receive two emails: the first - with static analysis results for building a project using gcc, and the second - for clang, respectively. Briefly About the Check Results In general, the project is quite clean, the analyzer issued only 24 high-certainty and 46 medium- certainty warnings. Let's look at a couple of interesting notifications: Redundant conditions in if V590 Consider inspecting the 'ret != (- 1) && ret == 1' expression. The expression is excessive or contains a misprint. attach.c 107 #define EOF -1 static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid) { .... while (getline(&line, &line_bufsz, proc_file) != -1) { ret = sscanf(line, "CapBnd: %llx", &info->capability_mask);
  • 11. if (ret != EOF && ret == 1) // <= { found = true; break; } } .... } If ret == 1, it is definitely not equal to -1 (EOF). Redundant check, ret != EOF can be removed. Two similar warnings have been issued: • V590 Consider inspecting the 'ret != (- 1) && ret == 1' expression. The expression is excessive or contains a misprint. attach.c 579 • V590 Consider inspecting the 'ret != (- 1) && ret == 1' expression. The expression is excessive or contains a misprint. attach.c 583 Loss of High Bits V784 The size of the bit mask is less than the size of the first operand. This will cause the loss of higher bits. conf.c 1879 struct mount_opt { char *name; int clear; int flag; }; static void parse_mntopt(char *opt, unsigned long *flags, char **data, size_t size) { struct mount_opt *mo; /* If opt is found in mount_opt, set or clear flags. * Otherwise append it to data. */ for (mo = &mount_opt[0]; mo->name != NULL; mo++) { if (strncmp(opt, mo->name, strlen(mo->name)) == 0) { if (mo->clear) { *flags &= ~mo->flag; // <= } else { *flags |= mo->flag; } return; } } .... } Under Linux, long is a 64-bit integer variable, mo->flag is a 32-bit integer variable. Usage of mo->flag as a bit mask will lead to the loss of 32 high bits. A bit mask is implicitly cast to a 64-bit integer variable after bitwise inversion. High bits of this mask may be lost.
  • 12. I'll show it using an example: unsigned long long x; unsigned y; .... x &= ~y; Here is the correct version of code: *flags &= ~(unsigned long)(mo->flag); The analyzer issued another similar warning: • V784 The size of the bit mask is less than the size of the first operand. This will cause the loss of higher bits. conf.c 1933 Suspicious Loop V612 An unconditional 'return' within a loop. conf.c 3477 #define lxc_list_for_each(__iterator, __list) for (__iterator = (__list)->next; __iterator != __list; __iterator = __iterator->next) static bool verify_start_hooks(struct lxc_conf *conf) { char path[PATH_MAX]; struct lxc_list *it; lxc_list_for_each (it, &conf->hooks[LXCHOOK_START]) { int ret; char *hookname = it->elem; ret = snprintf(path, PATH_MAX, "%s%s", conf->rootfs.path ? conf->rootfs.mount : "", hookname); if (ret < 0 || ret >= PATH_MAX) return false; ret = access(path, X_OK); if (ret < 0) { SYSERROR("Start hook "%s" not found in container", hookname); return false; } return true; // <= } return true; }
  • 13. The loop is started and interrupted on the first iteration. This might have been made intentionally, but in this case the loop could have been omitted. Array Index out of Bounds V557 Array underrun is possible. The value of 'bytes - 1' index could reach -1. network.c 2570 static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcname, struct lxc_netdev *netdev, pid_t pid, unsigned int hooks_version) { int bytes; char buffer[PATH_MAX] = {0}; .... bytes = lxc_read_nointr(pipefd[0], &buffer, PATH_MAX); if (bytes < 0) { SYSERROR("Failed to read from pipe file descriptor"); close(pipefd[0]); } else { buffer[bytes - 1] = '0'; } .... } Bytes are read in the buffer from the pipe. In case of an error, the lxc_read_nointr function will return a negative value. If all goes successfully, a terminal null is written by the last element. However, if 0 bytes are read, the index will be out of buffer bounds, leading to undefined behavior. The analyzer issued another similar warning: • V557 Array underrun is possible. The value of 'bytes - 1' index could reach -1. network.c 2725 Buffer Overflow V576 Incorrect format. Consider checking the third actual argument of the 'sscanf' function. It's dangerous to use string specifier without width specification. Buffer overflow is possible. lxc_unshare.c 205 static bool lookup_user(const char *oparg, uid_t *uid) { char name[PATH_MAX]; .... if (sscanf(oparg, "%u", uid) < 1) { /* not a uid -- perhaps a username */ if (sscanf(oparg, "%s", name) < 1) // <= { free(buf); return false; } .... } .... }
  • 14. In this case, usage of sscanf can be dangerous, because if the oparq buffer is larger than the name buffer, the index will be out of bounds when forming the name buffer. Conclusion As we see, it's a quite simple task to configure a static code analyzer check in a cloud. For this, we just need to add one file in a repository and spend little time setting up the CI system. As a result, we'll get a tool to detect problem at the stage of writing code. The tool lets us prevent bugs from getting to the next stages of testing, where their fixing will require much time and efforts. Of course, PVS-Studio usage with cloud platforms is not only limited to Travis CI. Similar to the method described in the article, with small differences, PVS-Studio analysis can be integrated into other popular cloud CI solutions, such as CircleCI, GitLab, etc. Useful links • For additional information on running PVS-Studio on Linux and MacOS, follow the link. • You can also read about creating, setting and using containers with installed PVS-Studio static code analyzer by the link. • TravisCI documentation.