Skip to main content

Desenvolvimento em C e C++ sem vulnerabilidades na manufatura automotiva e em veículos definidos por software (SDV)

Escrito por

23 de outubro de 2024

0 minutos de leitura

O setor automotivo está em um ponto de inflexão único em sua história com o advento do veículo definido por software (SDV). Durante o Society of Automotive Engineers (SAE) World Congress, realizado em Detroit de 16/04/2024 a 18/04/2024, foi citada explicitamente a existência de um mercado de mais de US$ 500 bilhões, que receberá investimentos em P&D e avanços tecnológicos da indústria automotiva. A transição para o SDV possibilitará novas fontes de receita por meio de assinaturas de recursos e serviços, antes impossíveis com o modelo herdado de “compra única” inerente à indústria automobilística desde sua criação. 

Montadoras e seus fornecedores transformam-se em empresas de tecnologia impulsionadas pela arquitetura elétrica/eletrônica (E/E), com inovações centradas em semicondutores.  Além disso, os microsserviços, as arquiteturas conteinerizadas e a forte presença de computação na nuvem são facilitadores cruciais para o SDV. 

Esse setor depende quase exclusivamente do desenvolvimento de software em C e C++, por serem linguagens de programação confiáveis, eficientes e robustas. No entanto, essas linguagens apresentam riscos de segurança, como estouros de buffer e problemas de segurança de memória que remontam a décadas. O mercado de SDV está diretamente relacionado à missão da Snyk de proteger software. As montadoras se beneficiam dos produtos de infraestrutura como código (IaC) e de contêineres da Snyk, bem como da integração natural da Snyk com diversos provedores de nuvem.

Por exemplo, a Mercedes assumiu uma posição de liderança com seu MB Operating System.

Integramos rapidamente o melhor hardware disponível com o Qualcomm Gen4 8295, que havia sido disponibilizado aos consumidores apenas seis meses antes. Foi um projeto ambicioso, e tenho enorme orgulho da equipe por aceitar o desafio de criar 20 GB de código compilado e colocar este precursor do MB.OS na linha Classe E, pois os aprendizados foram cruciais para o lançamento do MB.OS 1.0 completo.

Conformidade com MISRA para C e C++

O principal foco das diretrizes da MISRA C:2023 é a segurança e a confiabilidade de sistemas críticos, incluindo aspectos relevantes para a segurança de aplicativos, principalmente onde vulnerabilidades podem levar a riscos de segurança. As diretrizes da MISRA C:2023 abrangem uma grande variedade de tópicos, mas algumas regras e diretivas são particularmente relevantes para aprimorar a segurança de aplicativos, promovendo práticas que evitam comportamento indefinido, corrupção de memória, acesso não autorizado e outras vulnerabilidades comuns.

De forma semelhante às diretrizes para C, a estrutura e o conteúdo da especificação MISRA C++:2023 definem várias regras e diretivas relacionadas à segurança de aplicativos, acompanhadas de exemplos de código em conformidade e fora de conformidade.

Algumas das diretrizes de conformidade da MISRA para desenvolvimento em C e C++ citam diretivas e regras de segurança de aplicativos e criação de software C e C++ seguro, como:

  • Diretiva MISRA 4.12 – Não se deve usar alocação dinâmica de memória: restringir a alocação dinâmica de memória pode evitar uma classe de vulnerabilidades relacionadas a erros de gerenciamento de memória.

  • Regra MISRA 1.3 – Não deve haver comportamento indefinido ou crítico não especificado: o comportamento indefinido pode levar a vulnerabilidades de segurança, tornando esta regra crucial.

  • Regra MISRA 18.1 – um ponteiro resultante de aritmética em um operando de ponteiro deve referenciar um elemento do mesmo vetor que esse operando de ponteiro: o objetivo dessa é evitar acessos fora dos limites, uma vulnerabilidade comum em programas C.

  • Regra MISRA 21.3 – as funções de alocação e desalocação de memória de <stdlib.h> não devem ser usadas: assim como a diretiva 4.12, evitar alocação dinâmica de memória reduz riscos relacionados a vulnerabilidades de gerenciamento de memória.

  • Regras MISRA 22.1 a 22.20 (Recursos) – o gerenciamento adequado de recursos, incluindo tratamento de erros e liberação de recursos, é fundamental para prevenir evitar vazamentos e exaustão, que podem ser explorados em ataques de negação de serviço ou levar a comportamento indefinido explorável por invasores.

Embora a especificação MISRA C não descreva explicitamente as diretrizes como medidas de segurança, o cumprimento de suas regras e diretivas abrangentes aprimora a postura de segurança do software, eliminando muitas fontes comuns de vulnerabilidades em código C e C++. As diretrizes ajudam a desenvolver sistemas seguros, confiáveis e íntegros com a promoção de comportamentos bem definidos e robustos.

Por que a Snyk está aqui para ajudar

A Snyk se dedica a ajudar desenvolvedores a proteger o código, incluindo os que trabalham com C e C++. Com a integração da segurança no ciclo de vida de desenvolvimento, como métodos de DevSecOps, a Snyk capacita desenvolvedores a identificar vulnerabilidades antes que se tornem problemas críticos. Além disso, a Snyk ajuda desenvolvedores a detectar padrões de código inseguro quando salvam código no IDE, sem a necessidade de esperar pela conclusão de pipelines de integração contínua (CI) e compilação, nem exigir uma etapa de compilação de código.

Com ferramentas como o Snyk Code, você pode verificar bases de código C e C++ em busca de vulnerabilidades e receber insights acionáveis para corrigi-las.

Por exemplo, considere uma vulnerabilidade comum em C++: o estouro de buffer. Este é um trecho simples de código que demonstra esse problema:

#include <iostream>
#include <cstring>

void vulnerableFunction(char* input) {
    char buffer[10];
    // ❌ Potential buffer overflow
    strcpy(buffer, input);
}

int main() {
    char input[20] = "This is a long string";
    vulnerableFunction(input);
    return 0;
}

Neste exemplo de programa C++, a função strcpy pode causar um estouro de buffer se a string de entrada exceder o tamanho do buffer. A Snyk pode ajudar a identificar essas vulnerabilidades e oferecer recomendações para alternativas mais seguras, como usar strncpy:

void secureFunction(char* input) {
    char buffer[10];
    strncpy(buffer, input, sizeof(buffer) - 1);
    buffer[sizeof(buffer) - 1] = '\0'; // Ensure null-termination
}

Com a instalação da Snyk no IDE, você ganha dois superpoderes:

  1. A Snyk detecta código vulnerável, como esse estouro de buffer, sem exigir uma etapa de compilação.

  2. A Snyk se oferece para corrigi-las usando o Snyk Agent Fix.

Você quer ver como essa mágica funciona? Assista aqui:

Ao adotar práticas de codificação segura e utilizar ferramentas como a Snyk, os desenvolvedores podem reduzir significativamente o risco de vulnerabilidades em bases de código C e C++. Registre-se na Snyk ainda hoje e comece a proteger seus projetos de software críticos.

Exemplos de código C e C++ seguro e em conformidade vs. inseguro e vulnerável

Para mostrar como as diretrizes e especificações da MISRA se conectam ao código e às vulnerabilidades reais, vamos explorar um programa em C, program2.c, que mostra um exemplo de comportamento indesejado (Regra MISRA 1.3) da lista acima.

Este é o código do programa em C:

#include <stdio.h>

void undefinedBehavior() {
    int x = 5 / 0;
    printf("Value of x: %d\n", x);
}

int main() {
    undefinedBehavior();
    return 0;
}

A divisão por zero é um comportamento indefinido em C que pode levar a resultados imprevisíveis. As diretrizes da MISRA, com toda razão, proíbem essas operações para garantir a segurança e a integridade do código em softwares críticos.

Compile e execute o programa:

$ gcc program2.c -o program2
$ ./program2

Você verá que o compilador GCC emitirá um aviso sobre divisão por zero:

program2.c:5:15: warning: division by zero is undefined [-Wdivision-by-zero]
    int x = 5 / 0;
              ^ ~
1 warning generated.

No entanto, este é um exemplo simples e pequeno de código de programa. Em cenários reais, esses problemas podem ser difíceis de encontrar em um código grande, com diversos avisos de compilador enviados para a saída padrão.

Encontre a vulnerabilidade com o Snyk Code

A exibição da mensagem de erro de comportamento indefinido de um aviso de compilador sobre _divisão por zero_ e outros problemas pode ser difícil de identificar e ocorrer nas últimas etapas do ciclo de desenvolvimento. O Snyk Code pode ajudar nessa identificação nas primeiras etapas do ciclo de desenvolvimento, verificando a base de código em busca de vulnerabilidades antes de compilar o código.

Isso ocorre porque a Snyk utiliza técnicas de machine learning no mecanismo de segurança estática de código de aplicativos para entender os fluxos de chamadas do programa e conectar fluxos de caminho de código de coletores a fontes, detectando código inseguro e possíveis vulnerabilidades na base de código sem compilar o código.

Vulnerable C program code showing undefined behavior

Ferramentas para conformidade de segurança e código seguro em C e C++

Estas são algumas opções de ferramentas de código aberto para verificar a conformidade com MISRA em código C e C++:

  • OpenMRC: um verificador de regras da MISRA-C de código aberto desenvolvido como um plugin do Eclipse CDT (C/C++ Development Tooling). Ele foi projetado para analisar o código de veículos definidos por software em relação às diretrizes da MISRA-C:2004 e gerar mensagens de violação, ajudando os desenvolvedores a atualizar o código-fonte para manter a conformidade com a segurança funcional.

  • Clang-misracpp2008: o objetivo desse projeto, já arquivado, era criar um verificador de código aberto para as regras da MISRA C++:2008 usando a infraestrutura LLVM/Clang. Embora já esteja arquivado e desativado, os desenvolvedores recomendam usar o clang-tidy-misra como alternativa. O clang-misracpp2008 foi implementado como um plugin de LLVM/Clang, demonstrando um esforço para cobrir as regras da MISRA para C++ usando lógica personalizada e sinalizadores fornecidos pelo compilador.

Além das ferramentas mencionadas (caso sejam mantidas de acordo com seus padrões e respeitem as diretrizes de qualidade e o limite abrangente para os testes de segurança), a Snyk é outra opção a explorar.

A plataforma de segurança da Snyk inclui o Snyk Code, um SAST em tempo real com foco no desenvolvedor que otimiza a segurança do código com uma experiência voltada a desenvolvedores. As descobertas da Snyk incluem recursos de aprendizado, exemplos de correções para orientação e, às vezes, até uma correção automática baseada no Snyk Agent Fix.

O Snyk é gratuito e pode ser utilizado de diferentes formas para verificar código C e C++, como instalando a extensão da Snyk no IDE, importando repositórios Git do Bitbucket ou GitHub e usando a Snyk CLI.

Para programas em C e C++, há outro vetor de vulnerabilidades de segurança nas bases de código que pode ir além do código criado pelo desenvolvedor: o código importado de bibliotecas de código aberto.

Por fim, recomendo fortemente assistir às aulas compactas e breves de vulnerabilidades em C do Snyk Learn para aproveitar experiências interativas de aprendizado de segurança. As aulas abordam diferentes vulnerabilidades em C e C++, como desreferência nula, dupla liberação e convenções de codificação inadequadas, entre outras.

Proteja seu código com inteligência de última geração

Em apenas 30 minutos, você pode aprender sobre toda a gama de funcionalidades para SAST do Snyk Code.

Quer experimentar?

Find out which types of vulnerabilities are most likely to appear in your projects based on Snyk scan results and security research.