Skip to main content

Desenvolvimento de C e C++ sem vulnerabilidades na fabricação automotiva e em veículos definidos por software (SDV)

Escrito por
blog feature snyk code party

23 de outubro de 2024

0 minutos de leitura

A indústria automotiva vive um momento decisivo e singular de sua história com o surgimento dos veículos definidos por software (SDV). Durante o Congresso Mundial da Society of Automotive Engineers (SAE), realizado em Detroit de 16 a 18 de abril de 2024, foi declarado explicitamente que há um mercado de mais de US$ 500 bilhões que receberá investimentos em P&D e avanços tecnológicos para o setor automotivo. A transição para os SDVs viabilizará novas fontes de receita por meio de assinaturas de recursos e serviços, algo impossível no modelo legado de “compra única”, característico da indústria automotiva desde sua criação.

As montadoras e seus fornecedores estão se transformando em empresas de tecnologia, impulsionadas pela arquitetura elétrica/eletrônica (E/E), com os semicondutores no centro dessas inovações. Além disso, microsserviços, arquitetura baseada em contêineres e ampla presença da computação em nuvem são elementos essenciais para viabilizar os SDVs.

Esse setor depende quase exclusivamente do desenvolvimento de software em C e C++, 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, conhecidos há décadas. O mercado de SDVs está diretamente alinhado à missão da Snyk de proteger software. As montadoras podem se beneficiar das soluções de Infraestrutura como Código (IaC) e contêineres da Snyk, além da integração nativa da Snyk com diversos provedores de nuvem.

Por exemplo, a Mercedes está um passo à frente com seu sistema operacional MB.

Integramos rapidamente o melhor hardware disponível com o Qualcomm Gen4 8295, que havia sido lançado para uso por consumidores apenas seis meses antes. Foi um projeto ambicioso, e tenho muito orgulho da equipe por ter aceitado o desafio, criado 20 GB de código compilado e levado esse precursor do MB.OS ao Classe E. Os aprendizados são fundamentais para o lançamento da versão completa do MB.OS 1.0.

Conformidade com MISRA para C e C++

As diretrizes MISRA C:2023 se concentram principalmente em segurança e confiabilidade em sistemas críticos, incluindo aspectos relevantes para a segurança de aplicações, sobretudo nos casos em que vulnerabilidades podem gerar riscos à segurança. Embora as diretrizes MISRA C:2023 abranjam uma ampla variedade de tópicos, algumas regras e diretivas são especialmente relevantes para reforçar a segurança de aplicações, promovendo práticas que evitam comportamento indefinido, corrupção de memória, acesso não autorizado e outras vulnerabilidades comuns.

Assim como as diretrizes para C, a estrutura e o conteúdo da especificação MISRA C++:2023 apresentam diversas regras e diretivas relacionadas à segurança de aplicações, acompanhadas de exemplos de código em conformidade e em não conformidade.

Algumas diretrizes de conformidade MISRA para desenvolvimento em C e C++ citam diretivas e regras como as seguintes, relacionadas à segurança de aplicações e à criação de software seguro em C e C++:

  • MISRA Dir 4.12 - A alocação dinâmica de memória não deve ser usada: restringir a alocação dinâmica de memória pode evitar uma categoria de vulnerabilidades relacionadas a erros de gerenciamento de memória.

  • MISRA Rule 1.3 - Não deve haver comportamento indefinido ou crítico não especificado: o comportamento indefinido pode levar a vulnerabilidades de segurança, o que torna essa regra essencial.

  • MISRA Rule 18.1 - Um ponteiro resultante de uma operação aritmética com um operando ponteiro deve apontar para um elemento do mesmo array que esse operando: essa regra busca evitar acesso fora dos limites, uma vulnerabilidade comum em programas C.

  • MISRA Rule 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 Dir 4.12, evitar a alocação dinâmica de memória reduz os riscos de vulnerabilidades relacionadas ao gerenciamento de memória.

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

Embora a especificação MISRA C não classifique explicitamente as diretrizes como medidas de “segurança”, seguir suas regras e diretivas abrangentes fortalece a postura de segurança do software ao eliminar muitas fontes comuns de vulnerabilidades em código C e C++. As diretrizes ajudam a desenvolver sistemas seguros e confiáveis, promovendo um comportamento robusto e bem definido.

Como a Snyk pode ajudar

A Snyk se dedica a ajudar desenvolvedores a proteger seu código, inclusive quem trabalha com C e C++. Ao integrar a segurança ao ciclo de vida do desenvolvimento, seguindo práticas como DevSecOps, a Snyk permite que os desenvolvedores detectem vulnerabilidades antes que se tornem problemas críticos. Além disso, a Snyk ajuda a identificar padrões de código inseguro quando você salva o código no IDE, sem precisar esperar que os pipelines de integração contínua (CI) e build sejam executados ou exigir uma etapa de compilação.

Com ferramentas como Snyk Code, você pode analisar suas bases de código C e C++ em busca de vulnerabilidades e receber recomendações práticas para corrigi-las.

Por exemplo, considere uma vulnerabilidade comum em C++: o estouro de buffer. Veja um trecho de código simples 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 for maior que o tamanho do buffer. A Snyk pode ajudar a identificar essas vulnerabilidades e recomendar alternativas mais seguras, como o uso de strncpy:

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

Com a Snyk instalada no seu 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 propõe uma correção com o Snyk Agent Fix.

Quer ver essa mágica em ação? Assista:

Snyk installed in your IDE

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

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

Para mostrar como as diretrizes e especificações MISRA se relacionam com o código e as vulnerabilidades do mundo real, vamos analisar um programa C, program2.c, que demonstra um exemplo de comportamento indesejado (MISRA Rule 1.3) da lista acima.

Veja o código do programa 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. Com razão, as diretrizes MISRA proíbem essas operações para garantir a segurança do código em softwares críticos.

Execute o programa compilando-o primeiro:

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

Você verá que o compilador GCC exibirá um aviso sobre a 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 programa simples e pequeno. Em situações reais, pode ser difícil encontrar problemas desse tipo em uma base de código extensa, entre muitos avisos do compilador enviados para a saída padrão.

Encontre a vulnerabilidade com Snyk Code

Pode ser difícil detectar erros de comportamento indefinido, como _divisão por zero_, e outros problemas indicados por avisos do compilador — e, quando encontrados, eles podem surgir tarde no ciclo de desenvolvimento. Snyk Code ajuda você a identificá-los logo no início, analisando sua base de código em busca de vulnerabilidades antes da compilação.

Isso é possível porque a Snyk usa técnicas de aprendizado de máquina em seu mecanismo de segurança de aplicações para análise estática de código. Assim, ela entende os fluxos de chamadas do programa e conecta os caminhos entre origem e destino, identificando código inseguro e possíveis vulnerabilidades na sua base de código sem compilá-la.

Código de programa em C vulnerável, exibindo comportamento indefinido

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

Algumas ferramentas de código aberto para verificar a conformidade com MISRA em código C e C++ incluem:

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

  • Clang-misracpp2008: embora atualmente arquivado, esse projeto buscava criar um verificador de código aberto para as regras MISRA C++:2008 usando a infraestrutura LLVM/Clang. Apesar de estar arquivado e inativo, os desenvolvedores recomendam usar clang-tidy-misra como alternativa. O clang-misracpp2008 foi implementado como um plugin de LLVM/Clang, demonstrando um esforço para abranger as regras MISRA C++ com lógica personalizada e sinalizadores fornecidos pelo compilador.

Além das opções acima, vale considerar a Snyk, independentemente de essas ferramentas serem mantidas de acordo com seus padrões e atenderem aos requisitos de qualidade e aos critérios abrangentes dos testes de segurança.

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

A Snyk é gratuita e pode ser usada de várias maneiras para analisar código C e C++, como instalar a extensão da Snyk para IDE, importar repositórios Git do Bitbucket ou GitHub e usar a CLI da Snyk.

Em programas C e C++, outra fonte de vulnerabilidades na base de código pode estar além do código escrito pelos desenvolvedores: o código importado por meio de bibliotecas de código aberto.

Por fim, recomendo muito as lições interativas, curtas e objetivas de Snyk Learn sobre vulnerabilidades em C. Elas abordam diversas vulnerabilidades em C e C++, como desreferência de ponteiro nulo, liberação dupla, más práticas de programação e outras.

Proteja seu código com inteligência de ponta

Conheça toda a gama de recursos de análise estática (SAST) do Snyk Code em apenas 30 minutos.