DEV Community

Cover image for Rust e a segurança de memória
Guilherme Thomas
Guilherme Thomas

Posted on • Updated on

Rust e a segurança de memória

Problemas de segurança

Durante o desenvolvimento de um software, o controle de memória é, ou deveria ser, um dos fatores mais relevantes para garantir tanto performance quanto segurança.

Diferentes linguagens de programação lidam de maneiras diferentes com o controle da memória. Linguagens como C e C++ dão o controle da memória na mão de quem escreve o código, linguagens como Java e .NET possuem o "Coletor de Lixo" (Garbage Collector, GC) que realiza o gerenciamento da memória, liberando-a e preparando-a para novas alocações.

O custo de ter um GC administrando a memória é, em geral, velocidade e custo energético. Com a Linguagem C é possível definir quando alocar a memória, quando liberar, quanto alocar, em C alguns comportamentos não são definidos. Acessar o elemento 12 de uma array com 10 elementos gera erros em diversas linguagens, já em C ele irá acessar o que estiver disponível na array, caso contrário, onde conseguir na memória. Basicamente, se não for explicitamente dito o que C deve fazer, ele irá fazer o mais simples.

Essa velocidade na operação vem com o custo de segurança da memória.

Um dos engenheiros da Microsoft, Matt Miller, disse em 2019 que da última década, 70% dos erros corrigidos em patchs do Windows eram relacionados a erros de memória. No iOS e macOS, idem, de 60 a 70% dos erros eram relacionados a memória. Android? 90% dos erros eram relacionados a memória.

Image description

Isso não significa em momento algum que C ou C++ sejam ruins. Porém, software (ainda) é escrito por humanos, e humanos erram. O tempo todo, por diversos motivos, de diversas formas.

Quanto mais complexo é um software, mais suscetível a erros também.

No livro Code Complete, Steve McConnell realizou algumas pesquisas e cogita que para cada 1000 linhas de código, existam entre 1-25 erros. Software extremamente complexo como um Sistema Operacional pode ir muito além da casa dos milhões de linhas. Um OS com 1 milhão de linhas poderia ter até 25 mil erros escritos seguindo a pesquisa de McConnell.

Benefícios e limitações

Obviamente durante os anos, C e C++ evoluíram. Smart pointers, C++ moderno, Fuzzers, Sanitizers ajudam imensamente a escrever código com mais segurança de memória. Mas mesmo assim eles continuam ocorrendo.

Rust surge como um projeto pessoal de um funcionário da Mozilla, e em 2009-10 ganha tração com apoio da empresa. Rust 1.0 foi lançado em 2015.

Sua base é:

  • Segurança de memória sem uso de coletor de lixo;
  • Concorrência sem disputa dos dados;
  • Abstração sem processamento ou armazenamento em excesso;
  • Estabilidade sem estagnação.

Como dito antes, muitas linguagens que garantem segurança à memória possuem um GC. Rust gerencia a memória de maneira diferente, utilizando um conceito chamado de ownership (propriedade).

A ideia de ownership vem de Sistema do tipo subestrutural. Mas que caralho é isso, né?
Sistema do tipo subestrutural é um conceito para que seja mantido um histórico das mudanças de estado na memória, arquivos e recursos do sistema para garantir que não hajam estados inválidos.

A maneira que ownership atua na linguagem Rust é garantida pelo seu compilador, rustc. Existem três regras que rustc exige:

  1. Cada valor em Rust, tem uma variável que é seu proprietário;
  2. Somente pode existir um proprietário por vez;
  3. O valor é descartado quando o proprietário sai de escopo.

Pra quem está aprendendo sobre Rust como eu, esse conceito pode ser um dos degraus mais elevados da Linguagem. Compartilhar dados entre o código pode se tornar um "problema".

Um exemplo da atuação do compilador para garantir que as regras sejam seguidas é a seguinte:

Image description

Declaramos a marca de chocolate dentro de main, e encerramos o escopo, ao tentar acessar a marca do chocolate, rustc não compilará pois não consegue acessar o valor da marca de chocolate.

Image description

Escrevendo assim, tudo parece mil maravilhas. Se mais de 70% dos erros são problemas na memória, e Rust surge como uma linguagem de mesma velocidade que C e C++ e que ainda gerencia lindamente a memória, é só reescrever todos os sistema em Rust, certo?

Não. Nossa, nem fudendo.

Inclusive tenho certeza que o objetivo de Rust não seja reescrever nada, e sim criar. E isso já está acontecendo: Rust foi incluída como linguagem oficial do Linux, onde drivers vão começar a serem escritos na nova Linguagem.

Atualmente temos um deficit de pessoas desenvolvedoras gigantesco, e que segundo previsões só tende a aumentar. Negócios hoje dependem de software para quase tudo: Análise, gerenciamento, vendas, comunicação.

Soma-se isso a curva de aprendizado relativamente mais difícil de Rust e seu tempo curto de presença no mercado, ou seja, temos poucas pessoas desenvolvedoras, e menos ainda em Rust.

Outro fator com muita influência é em relação à investimento, tanto de tempo quanto dinheiro. Para implementar um novo sistema em qualquer linguagem nova dentro de uma empresa, é necessário um investimento tanto em tempo para criação desse sistema ou ferramenta por parte da equipe de devs, e esse tempo vai ter variáveis como nível de maturidade da equipe, complexidade da tarefa, que são variáveis que impactam nos resultados do projeto, bem como dinheiro em forma de contratação de pessoas para atuar com uma nova linguagem.

De qualquer maneira, o futuro de Rust parece ser inegavelmente consolidado.
Desde 2016 a Linguagem é eleita como a mais amada em diversas pesquisas.

Image description

Mas não só de amor vive uma Linguagem, muitas empresas tem interesse genuíno em Rust:

Why AWS loves Rust, and how we’d like to help

Google joins the Rust Foundation

Microsoft joins the Rust Foundation

A brief history of Rust at Facebook

Rust in Production at Figma

Why Discord is switching from Go to Rust

The rise of WebAssembly

Definitivamente é uma Linguagem que deve estar no seu radar.

Discussion (0)