Boas Práticas de Programação de Sistemas
Regras para código de sistemas e FFI seguro, portável e bem testado em Rust.
Como Usar Esta Lista
- Revise antes de mesclar PRs de FFI ou específicos de plataforma
- Trate
unsafenão verificado como uma alteração sensível à segurança - Execute Miri e CI multiplataforma em código de sistemas
A - Limites de Segurança
- Minimize o escopo de
unsafe. Mantenha FFI em módulos dedicados com revisões. - RAII para cada recurso. Arquivos, sockets, mapeamentos e handles recebem
Drop. - Documente pré-condições
# Safety. Cadaunsafe fnlista as obrigações do chamador. - Sem pânicos através de FFI. Capture na fronteira; retorne códigos de erro para C.
B - ABI e Memória
-
repr(C)para structs exportadas. Nunca assuma que o layout padrão do Rust cruza FFI. - Regras explícitas de propriedade. Emparelhe alocadores com funções de liberação; documente tempos de vida.
- Valide comprimentos antes de conversões. Verifique o tamanho do buffer e o alinhamento antes de conversões de ponteiro.
- Testes de layout em CI. Compare
size_of/align_ofcom cabeçalhos C.
C - Portabilidade
- CI em Linux, macOS, Windows. Detecte desvios de
cfgprecocemente. - Use
Path, não strings. Evite separadores/codificados. - Abstraia APIs de plataforma. Isole módulos
cfg(unix)/cfg(windows). - Teste musl e glibc. O comportamento do Alpine vs Debian difere.
D - Processos e I/O
- Colete processos filhos. Sempre
waitapósspawn. - Desligamento gracioso. Manipule SIGINT/SIGTERM; drene o trabalho antes de sair.
- Bloqueio fora de executores assíncronos. Use
spawn_blockingpara trabalho intensivo de syscall. - Escritas atômicas de arquivos. Arquivo temporário + renomear para configuração e estado.
E - Testes e Ferramentas
- Miri em testes de FFI. Capture comportamento indefinido em CI.
- Valgrind/LSan periodicamente. Encontre vazamentos em caminhos de interoperação C.
- Fixe versões de bibliotecas nativas. Documente as versões mínimas das bibliotecas do sistema.
- Sanitize caminhos de usuário. Rejeite travessia de
..em ferramentas privilegiadas.
FAQs
Quanta `unsafe` é demais?
Se wrappers seguros não puderem escondê-la, divida em funções menores revisadas com invariantes claras.
Quando `bindgen` é necessário?
Quando a API C tem mais do que um punhado de funções ou muda frequentemente.
Devo usar `nix` ou `libc`?
Prefira std, depois nix, depois libc bruto conforme precisar de controle de nível inferior.
FFI em servidores async?
Nunca bloqueie o runtime. Descarregue para threads de bloqueio ou use I/O nativo assíncrono.
Como auditar bibliotecas C de terceiros?
Rastreie CVEs, ative ASan em testes e sand-box operações privilegiadas.
Promessas de ABI estável?
Comprometa-se com a estabilidade da ABI apenas com repr(C), semver e testes explícitos de compatibilidade.
Manipuladores de sinal?
Defina apenas flags atômicas. Adie o trabalho real para a thread principal ou runtime.
Permissões de arquivo no Unix?
Defina modos explícitos em arquivos criados. Não confie nos padrões umask para segredos.
Serviço Windows vs CLI?
Compartilhe a lógica central em uma biblioteca; binários finos para pontos de entrada de serviço e CLI.
Cadeia de suprimentos para código nativo?
Forneça hashes conhecidos para SDKs baixados. Verifique checksums em build.rs.
Relacionados
- Fundamentos de Sistemas - Fundamentos do std
- Construindo Bindings Sólidos - Wrappers seguros
- Código de Sistemas Multiplataforma - Padrões
cfg - Trabalhando com Memória Bruta - Regras de layout
Versões da Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.