1 pontos por GN⁺ 2024-03-12 | 1 comentários | Compartilhar no WhatsApp
  • O suporte a marcação de memória por hardware do Pixel 8 e Pixel 8 Pro revelou um bug de corrupção de memória introduzido recentemente no Bluetooth LE no Android 14 QPR2
  • A causa foi confirmada como um bug upstream de use-after-free no Bluetooth LE, e o GrapheneOS criou um patch de correção que pretende incluir em uma nova versão
  • Um usuário que reproduziu o problema no modo Bluetooth LE do Samsung Galaxy Buds2 Pro confirmou que a correção funciona, e o stock Pixel OS também é afetado
  • Como o Bluetooth é uma grande superfície de ataque, o GrapheneOS considera inadequada, mesmo no curto prazo, a solução de contorno de desativar a marcação de memória nesse processo
  • Parte do código de Bluetooth do Android foi portada para Rust, mas ainda são necessários mais port do código restante e testes em dispositivos reais de builds com HWASan e MTE

Bug e correção no Bluetooth LE do Android 14 QPR2

  • O GrapheneOS descobriu um bug de corrupção de memória no Bluetooth LE do Android 14 QPR2 graças ao suporte a marcação de memória por hardware do Pixel 8 e Pixel 8 Pro
    • O problema não ocorre com todos os dispositivos Bluetooth; ele só é reproduzido em determinados dispositivos Bluetooth LE
    • O GrapheneOS está investigando formas de corrigir o recurso recém-introduzido ou desativá-lo temporariamente
  • A causa foi confirmada como um bug upstream de use-after-free no Bluetooth LE, e o GrapheneOS desenvolveu um patch
    • A prioridade é distribuir rapidamente uma versão do GrapheneOS com essa correção
    • O problema será reportado como bug de segurança do Android
    • Essa correção também parece resolver uma regressão de áudio BLE
  • Um usuário que reproduzia o problema usando o Samsung Galaxy Buds2 Pro em modo Bluetooth LE confirmou que a correção funciona
  • O mesmo problema também afeta o stock Pixel OS
  • O GrapheneOS detectou isso graças ao suporte a marcação de memória do hardened_malloc e adicionou uma notificação de crash de MTE com um relatório copiável

Como o MTE é aplicado e os desafios do código Bluetooth do Android

  • O GrapheneOS considera que desativar a marcação de memória nesse processo como solução de contorno não é apropriado nem mesmo no curto prazo
    • O Bluetooth é uma grande superfície de ataque, independentemente da possibilidade real de exploração desse bug
  • O Android portou uma parte significativa do código Bluetooth para Rust, mas ainda são necessários mais recursos para portar o código restante
  • Em ambientes reais, são necessários mais testes de builds com HWASan e MTE usando diversos dispositivos Bluetooth
  • Os dispositivos Pixel incluem MTE, um importante recurso de segurança de hardware, mas o sistema operacional padrão não o ativa para economizar 3,125% de uso de memória e cache
    • O cálculo se baseia em uma tag de 4 bits para cada 16 bytes de memória marcada
    • O heap MTE tem overhead de desempenho próximo de 0% no modo assíncrono (async mode) e, no modo assimétrico (asymmetric mode), tem custo menor do que mitigações existentes como SSP
  • O GrapheneOS ativa MTE por padrão para apps instalados pelo usuário cuja compatibilidade com o sistema operacional padrão é conhecida
    • É possível ativá-lo como opt-in para todos os apps instalados pelo usuário em Settings > Security
    • Ele oferece uma notificação que permite copiar relatórios de crash e um toggle por app
  • A implementação de MTE do hardened_malloc no GrapheneOS usa tags aleatórias padrão e uma tag dedicada para memória liberada, excluindo dinamicamente a tag anterior e as tags adjacentes atual ou anterior
  • A integração com o Chromium foi corrigida, e o PartitionAlloc também será aprimorado

1 comentários

 
GN⁺ 2024-03-12
Opiniões no Hacker News
  • É estranho que os Pixels tragam um grande recurso de segurança de hardware chamado MTE, mas o OS não o ative para economizar 3,125% de uso de memória/cache
    Eu realmente gostaria de ver como a equipe do Pixel justifica essa decisão, e fico curioso sobre o raciocínio por trás de desativar um recurso de segurança tão importante por um ganho de desempenho mínimo

    • Sou engenheiro do AOSP, mas não trabalho na parte de Bluetooth, então não conheço os detalhes profundos deste caso
      Dito isso, o GrapheneOS é um projeto excelente, mas dá suporte a apenas cerca de 11 dispositivos, enquanto mudanças no AOSP precisam considerar um ecossistema de OEMs muito maior
      Estamos sempre procurando formas de tornar o Android melhor, mas criticar o lançamento de um recurso específico ignorando o ecossistema mais amplo de OEMs parece uma visão estreita
      É muito improvável que esse recurso não tenha sido ativado por causa de 3% de memória/cache; provavelmente houve outras considerações
    • O trade-off não envolve apenas uso de memória ou desempenho, mas também crashes visíveis ao usuário que antes não existiam
      Ao decidir ativar ou não o recurso, é provável que esse tenha sido um fator ainda maior
    • A acusação de que a decisão foi tomada para economizar 3% de uso de memória parece categórica demais
      Como outros OSs também não são lançados atualmente com o MTE ativado, a decisão de ativá-lo ou não provavelmente é bem mais sutil
    • Em resumo, eu não presumiria que esse recurso não esteja sendo usado, nem que seja por causa dos 3,125% de uso de memória/cache
      Pessoas do Google foram justamente quem impulsionou o MTE de hardware no início, e isso começou em uma equipe envolvida com ASAN, syzkaller etc.
      Eu não era da equipe do Android, mas houve ajuda e apoio do lado do Android, e naturalmente também colaboração com a ARM e outros
      Como eu liderava essas equipes na época, conheço bem os trade-offs, e não se trata apenas de memória ou cache
      É verdade que o MTE pode ser ativado e desativado dinamicamente e foi projetado para ter custo de desempenho quase zero, mas o principal uso naquela época era encontrar bugs por amostragem
      Se ele for ativado em apenas 1% do tempo em toda a frota de dispositivos, isso já é escala suficiente para encontrar bugs muito rapidamente, e também pode ser usado em testes internos
      Ou seja, o objetivo era permitir ativar e desativar, quando se quisesse, um recurso comparável ao ASAN
      Usá-lo como mitigação de segurança sempre ativada era uma possibilidade secundária, e há problemas além do overhead de memória
      Por exemplo, de repente surgem muitos crashes visíveis ao usuário; em telefones com MTE ocorre crash, e em telefones sem MTE talvez não ocorra, o que também gera inconsistência
      Do ponto de vista dos desenvolvedores, também não seria agradável ter que obrigar todo mundo a testar naquele telefone, em um cenário em que praticamente só há um modelo com MTE ativado
      Ele pode impedir exploits de segurança e fazer com que ocorra um crash em vez de exploração
      Também pode encontrar bugs inofensivos
      Mas, como eu disse, eu não presumiria que ele não esteja sendo usado; parece mais correto dizer que ele não fica sempre ativado em produção
      Quem já teve experiência introduzindo esse tipo de recurso de hardware diria que o simples fato de o sistema inicializar, executar e só apresentar crash sob MTE em um comportamento específico é, na verdade, um bom sinal de que ele já está sendo usado
      Se não estivesse sendo usado, provavelmente já teria travado um milhão de vezes
      Além disso, também não está claro se ele é a melhor opção como mitigação em tempo de execução
  • O Pixel padrão pode não vir com isso ativado por padrão para o usuário final, mas qualquer pessoa pode ativar Memory Tagging Extensions nas opções de desenvolvedor se quiser
    É possível mantê-lo ativado até desativar, ou ativá-lo por apenas uma sessão para testar um app específico

    • Isso não é igual ao que o GrapheneOS usa, e uma parte considerável do Bluetooth também fica excluída
      No Pixel OS padrão, ativar o suporte a marcação de memória nas opções de desenvolvedor apenas o torna disponível, mas não o usa de fato
      Também é preciso ativar a marcação de memória do heap com setprop no shell do Android Debug Bridge (ADB)
      Se as alocações não recebem tags, simplesmente estar ativado não tem nenhum valor
      É possível ativar completamente o MTE de heap em espaço de usuário no OS padrão por meio do Scudo, a implementação padrão do alocador, mas atualmente ela não é uma implementação especialmente reforçada
      O KASan que usa o backend MTE também pode ser usado com setprop, mas no momento não foi projetado para fins de reforço, e não está claro se será no futuro
      O kernel provavelmente precisa de uma implementação separada de MTE que não seja parte do KASan, e o GrapheneOS ainda não fez isso, portanto o reforço atual com MTE é um recurso de espaço de usuário
      O GrapheneOS usa sua própria implementação de marcação de memória por hardware para o hardened_malloc, com propriedades de segurança mais fortes
      Para ativá-la por padrão no OS padrão, foi preciso corrigir ou contornar vários problemas, incluindo este
      Em vez de usar MTE assíncrono nos núcleos principais, ele usa o modo assimétrico em todos os núcleos
      O modo assimétrico é assíncrono para gravações e síncrono para leituras, de modo que bloqueia corretamente sem deixar uma janela de oportunidade para o exploit ter sucesso
      Ele é verificado em chamadas de sistema, e o io_uring, que poderia ser outra via de bypass, é limitado no Android por restrições do SELinux a apenas 2 processos centrais do sistema
      O fastbootd é usado somente durante a instalação, e o snapuserd é usado no OS principal após a aplicação de uma atualização
      O GrapheneOS sempre usa MTE de heap em apps cuja compatibilidade com o OS padrão foi confirmada
      Para apps instalados pelo usuário que não estejam no banco de dados de compatibilidade e que não se declarem compatíveis, ele oferece um toggle de MTE por app
      O usuário também pode ativar a imposição de MTE por padrão para apps instalados pelo usuário e excluir apenas os apps incompatíveis
      Para tornar isso realmente utilizável, foi necessário um sistema de relatório de crashes visível ao usuário, e ele foi implementado de modo que seja fácil copiar e enviar aos desenvolvedores relatórios de crash úteis
    • Procurei três vezes o menu de opções de desenvolvedor em um Pixel 7a e não consegui encontrar
      Ao pesquisar por Memory Tagging Extensions nas configurações, aparece como existente, mas quando pensei que talvez estivesse escondido em algum lugar, descobri que era exclusivo dos telefones Pixel 8: https://news.ycombinator.com/item?id=38125379
  • O GrapheneOS está tão à frente dos outros em termos de segurança que fica difícil entender por que escolher algo que não seja hardware Pixel
    Mas eu realmente queria uma bateria substituível
    Não sei por que tudo anda tão ruim hoje em dia

    • Atualmente, só o Pixel atende aos nossos requisitos de segurança
      Outros aparelhos Android nem chegam perto
      O suporte a marcação de memória por hardware é uma das várias grandes vantagens de segurança do Pixel
      A lista oficial de requisitos de hardware está aqui: https://grapheneos.org/faq#future-devices
      Esse requisito é totalmente atendido na 8ª geração do Pixel
      Nos Pixels de 6ª/7ª geração faltam apenas MTE, BTI e PAC, sendo que o MTE é o recurso mais valioso na lista de requisitos de hardware
      Patches de segurança adequados são mais importantes e, fora do Pixel, não são fornecidos da mesma forma
      O Android tem lançamentos mensais, trimestrais e anuais
      Outros OEMs de Android fornecem, nos backports mensais de segurança, apenas todas as correções de gravidade Critical/High, e em geral não fornecem as correções de gravidade Moderate/Low, incluindo a maioria das correções de privacidade
      Usar um sistema operacional alternativo para fornecer esses patches mitiga parte disso, mas sistemas alternativos para esses aparelhos muitas vezes revertem a segurança de várias formas
      O firmware e boa parte do código de suporte aos dispositivos vêm, na prática, do OEM
      É possível executar o Android 14 QPR2 sobre o kernel/drivers do Android 12, mas isso deixa de fora melhorias de segurança de grandes partes do sistema operacional
      As baterias do Pixel não são simples de trocar sem danificar o aparelho, mas a troca tem suporte oficial e há peças oficiais: https://www.ifixit.com/Device/Google_Pixel
      Não podemos dar suporte a aparelhos inseguros que nem atendem ao básico
      Nossa lista de requisitos de hardware inclui tanto coisas muito básicas que a maioria dos OEMs de Android não fornece quanto recursos avançados como MTE, que agora vemos como um requisito básico para uma segurança adequada
      Gostaríamos de oferecer suporte a outros aparelhos, mas eles precisam atender a esses requisitos
      A marcação de memória é um recurso básico suportado por núcleos Cortex ARMv9 padrão
      É lamentável que a Qualcomm não implemente isso e que os OEMs que usam SoCs compatíveis não o configurem
      É triste quando o recurso existe na arquitetura da CPU, mas não pode ser usado por causa do SoC ou do OEM
    • Não é o GrapheneOS, mas o CalyxOS, que chega bem perto, começou a oferecer suporte ao Fairphone 5 e, pelo que sei, ele tem bateria substituível: https://calyxos.org/news/2024/03/05/fp5/
    • Concordo, mas eles tendem a encerrar o suporte a aparelhos Pixel antigos muito rapidamente, o que é bem irritante
      Ainda assim, é bom que o Pixel 8 tenha previsão de 7 anos de suporte
    • Se você carrega segredos muito caros no telefone, no fim acaba cedendo ao Google
      É difícil confiar na Apple ou na Samsung, e o Google acabou virando a melhor opção
    • O Pixel parece ter um problema antigo relacionado a serviços de emergência: https://www.reddit.com/r/GooglePixel/search/?q=emergency
  • Seria bom se alguém que usa GrapheneOS pudesse responder

    1. A instalação é muito difícil? Precisa de um cabo especial e de muito conhecimento sobre jailbreak/root de dispositivos Android, ou basta seguir as instruções?
    2. É muito incômodo para uso diário? Com que frequência o celular trava e exige dias de depuração? Apps de banco funcionam?
    • A instalação é fácil e, em 99% dos casos de uso, é tão conveniente quanto qualquer outro celular Android
      Porém, quando fui recentemente com minha esposa a Orlando, Flórida, para o Disney World e o Universal Studios, embora os apps em geral funcionassem com o Google Play Services em sandbox, houve alguns problemas irritantes
      O app My Disney Experience apresentou vários erros relacionados à localização e, de vez em quando, dizia que era preciso estar nos EUA ou no Canadá para realizar alguma ação importante, então tivemos de usar o celular da minha esposa como alternativa
      No app da Universal, eu não conseguia fazer login na conta; no Samsung Galaxy padrão da minha esposa funcionava bem, então parecia ser um problema do GrapheneOS
      Além disso, se você paga com cartão de crédito pelo Google Wallet, isso não é compatível porque o Google não certifica o GrapheneOS
      Outros recursos do Wallet funcionam
      O Uber funciona sem problemas
      Fora isso, não uso apps proprietários
      Se sua ideia é usar principalmente apps livres/de código aberto, você provavelmente não terá problemas
      A maioria dos apps proprietários funciona com o Google Play Services em sandbox, mas, se algum deles for muito importante para o seu trabalho, você pode encontrar problemas irritantes como os que tive com o Universal Studios e o My Disney Experience
      1. Não, foi muito fácil
        Usei um cabo USB comum e o adb pela linha de comando no Linux, mas o método recomendado usa o WebUSB do Chromium e deve ser mais fácil para pessoas não técnicas
        Só que, no meu caso, isso não funcionou bem
      2. Não, é muito conveniente
        Como há Google Play Services em sandbox, você pode instalar todo tipo de app proprietário que torna a vida moderna suportável, ao mesmo tempo em que o Google Play não tem acesso irrestrito ao celular inteiro — é um bom equilíbrio entre os dois lados
        Se quiser mais isolamento, você pode criar um usuário separado e executar os itens relacionados ao Google Play nessa conta
        Testei por um tempo, mas, pessoalmente, achei chato ficar trocando de usuário toda vez
        O celular nunca travou, e os apps de banco funcionam
        O aparelho é um Pixel 6a
    • Instalando pelo instalador web, é muito fácil: https://grapheneos.org/install/web
      Também é possível comprar um aparelho já instalado, mas praticamente qualquer pessoa consegue usar o instalador web
      Em Android, ChromeOS e macOS é especialmente fácil; no Windows é um pouco mais trabalhoso porque exige instalar drivers
      No Linux desktop, é preciso instalar regras udev, e algumas distribuições com versões de software congeladas têm serviços com bugs que atrapalham
      Uma pessoa sem conhecimentos técnicos consegue fazer, bastando um navegador com suporte a WebUSB
      Não é necessário nenhum software especial
      Para uso diário, com o Google Play em sandbox, é quase igual ao Pixel OS padrão e a compatibilidade de apps também é quase a mesma
      É bem provável que você não tenha significativamente mais travamentos
      Há relatórios de travamento voltados ao usuário que não existem no OS padrão, então você pode acabar percebendo travamentos que antes passariam despercebidos
      Apps bugados com corrupção de memória podem travar até que você ative o modo de compatibilidade por app, especialmente se optar por forçar MTE em todos os apps instalados pelo usuário
      Apps de banco funcionam se o banco permitir um OS que não seja certificado pelo Google, e por enquanto a maioria ainda permite
      Porém, os bancos vêm bloqueando cada vez mais OSs sem certificação do Google, então isso precisa ser tratado essencialmente como uma questão regulatória anticompetitiva
      Enquanto isso, estamos tentando convencer os bancos a usar https://grapheneos.org/articles/attestation-compatibility-guide
    • Não chega a ser inutilizável no dia a dia, mas também não é a opção mais confortável
      Os recursos extras de segurança, as configurações de sandboxing e o hardened memory allocator tornam tudo um pouco mais lento e trabalhoso do que usar Android puro e apertar OK em todas as solicitações de acesso a dados
      Também leva algum tempo na configuração inicial para entender o que é diferente no GrapheneOS e como usar os recursos de segurança
      Em 4 anos de uso, não tive travamentos
      Pelo menos não houve travamentos do sistema inteiro, e, na minha experiência, travamentos que exigem dias de depuração não acontecem porque o hardware e o software do Pixel são bem ajustados entre si
      Apps de banco dependem do app
      Alguns funcionam até sem Play Services, a maioria funciona com Play Services em sandbox, e apenas uma pequena minoria não funciona de jeito nenhum
      Se você disser qual banco usa, outros usuários podem verificar se funciona
    • A instalação é extremamente fácil
      Até o método difícil se resume a conectar o celular por USB, apertar um pouco os botões de energia/volume e copiar e colar dois ou três comandos no terminal
      O método fácil é apenas conectar o celular ao computador e clicar no botão de instalação de um clique que roda no navegador Chrome
      Venho usando como OS diário praticamente sem parar desde logo após o lançamento do Google Pixel 6, e ele nunca travou uma única vez
      Também nunca tive bugs nem precisei depurar, corrigir ou fazer manutenção
      Todos os apps que testei simplesmente funcionaram como no Android de fábrica e, sinceramente, quase não percebo diferença
      Às vezes até esqueço que esse não é o OS que veio originalmente instalado no celular
      Pessoalmente, o app do banco Discover funciona, mas não sei ao certo sobre outros apps
      Ainda assim, como há Google Play services e o bootloader fica bloqueado após a instalação, acho provável que a maioria funcione
  • Em 2024, precisamos de sistemas operacionais, aplicações e ferramentas com verificação formal em um nível mais rigoroso, seguindo o espírito do seL4
    Nos dias de hoje, juntar bases de código superprojetadas e testadas superficialmente com linguagens frágeis e perigosas é algo que pode permitir que agentes estrangeiros invadam sistemas e usuários morram, além de criar muitos bugs irritantes e uma superfície de ataque para malware e invasões
    Além disso, é preciso oferecer uma experiência de usuário limpa e integrada e recursos úteis; caso contrário, toda a engenharia terá sido em vão

    • Pela minha experiência, compartimentalização é um mecanismo de segurança muito mais forte
      Basta olhar para o Qubes OS
  • Existe algum computador de placa única decente que implemente Arm MTE? Algo como o Raspberry Pi mais recente

    • Provavelmente não
      O RasPi 5 é um quad A76 e usa extensões v8.2, enquanto MTE é v8.5
  • Como o MTE se compara ao CHERI?

    • O CHERI oferece proteção real imposta por hardware
      O MTE serve para encontrar possíveis bugs de segurança, não é proteção de verdade
      Como a tag tem só 4 bits e a aplicação pode falsificá-la, se o atacante precisar acertar a tag correta, escolhendo aleatoriamente ele tem 1/16 de chance de acertar
      A ideia ao aplicar MTE é que acessos incorretos às vezes acontecem mesmo sem um atacante e ele consegue capturar casos que na prática não gerariam um resultado ruim
      Pense em um overflow de buffer típico: as palavras logo depois do fim do buffer podem não estar sendo usadas para outra coisa, então na prática ainda poderia funcionar
      O MTE detecta esses acessos e permite investigar e corrigir antes que virem um exploit weaponizado
    • MTE e CHERI usam abordagens parecidas, mas no caso geral o MTE não tem tags grandes o suficiente para oferecer segurança forte
      Ainda assim, por meio de tags reservadas, ele pode oferecer propriedades de segurança determinísticas fortes
      O que não tem tag usa a tag 0, e o que tem tag, por causa da exclusão padrão, normalmente tem uma tag diferente de 0
      Outras tags também podem ser excluídas estática e dinamicamente por instruções, mas é possível aproveitar o fato de que, se a tag 0 for usada para fins internos como memória liberada, nenhum ponteiro com tag consegue acessá-la
      No hardened_malloc, para slots de alocação, as tags adjacentes e as usadas anteriormente são excluídas dinamicamente
      Isso fornece proteção determinística contra overflows lineares e pequenos overflows
      No caso de use-after-free, um ponteiro para uma alocação liberada não consegue acessá-la enquanto ela estiver liberada nem logo após ser realocada; ele precisa esperar até a próxima atribuição, quando a chance de estar com a tag correta é de 1/15
      Isso combina bem com outras propriedades de segurança do hardened_malloc
      Há zonas de quarentena FIFO/aleatórias para alocação em slab e memória virtual, o que atrasa ainda mais a reutilização e a torna não determinística
      Até passar de 128k, posições de memória nunca são reutilizadas entre classes de tamanho de alocação diferentes; cada classe fica em uma região distinta, e todos os metadados ficam em outra região reservada
      No caso geral, o MTE atualmente tem só 4 bits, então a probabilidade de bypass é de cerca de 1/15
      Ele poderia ser facilmente ampliado para dar suporte ao uso de 8 bits, e, se PAC não for usado, há outros bits livres
      Em teoria, em um espaço de endereçamento comum de 39 bits, seria possível dar suporte a até 16 bits de MTE para espaços de endereçamento de 48 bits ou mais
      Hoje ele é fixo em 4 bits; ouvi dizer que isso foi escolhido em vez de 8 bits para permitir armazenar bits adicionais em memória de paridade ECC
    • O MTE tem overhead muito menor, já está presente em produtos reais hoje e consegue detectar algumas formas de corrupção de heap
      Mas não detecta com a mesma confiabilidade que o CHERI
      Não há proteção para as tags e o espaço de tags também é pequeno (2^4)
  • Estou esperando o dia em que o hardware mainstream alcance as arquiteturas de tags de memória do Solaris SPARC de 2015, ou anteriores, e finalmente consiga domar o problema de corrupção de memória
    Claro que esses problemas costumam ser descartados como algo que só desenvolvedores incompetentes criam

    • Isto pode receber muitos downvotes, mas, se for o caso, essas pessoas são justamente as que escrevem bugs
      Isto não é um problema de “desenvolvedores incompetentes”, é um problema de todos
      Corrupção de memória é praticamente um recurso de linguagem em C/C++
      É melhor não espalhar a crença de que isso acontece por causa de gente burra
      Quase ninguém se considera burro, e eu já vi programadores realmente brilhantes criarem bugs de memória ridículos
      É simplesmente algo que faz parte do domínio dessas linguagens; não é uma questão de “se”, mas de “quando”
  • Gosto de como foi inserida discretamente a frase mostrando que o Android moveu grande parte do código de Bluetooth para Rust e por que deveria investir mais recursos para mover o restante do código para Rust
    Usei C e C++ por muitos anos, mas não tenho experiência com Rust, então fico curioso sobre quanta refatoração é necessária ao portar de C para Rust
    Dividindo a pergunta: 1. Quão diretamente C se traduz para Rust? Rust exige reorganização estrutural ou refatoração?
    2. Como o Google está abordando isso? Estou curioso se eles estão tentando “traduzir” da forma mais próxima possível ou se veem isso como uma oportunidade para uma grande reescrita/refatoração
    Também fico curioso se algum dia a stack Bluetooth do Android poderá ser usada em sistemas desktop de distribuições Linux padrão

    • Em um experimento recente e inacabado, tentei portar um simulador de microcontrolador PIC de C++ para Rust
      Havia muitas referências cíclicas, e a estrutura era de módulos se comunicando por meio de um “barramento de sinais” com callbacks; senti que o Rust mais atrapalhava do que ajudava
      Mesmo em lugares onde, em C++, era possível armazenar dados inline, acabei precisando de muitos Box, ponteiros de heap
      No fim, se for uma ferramenta simples de linha de comando ou uma estrutura de requisição-resposta, portar para Rust provavelmente é fácil
      De forma mais geral, se a estrutura do código se encaixa bem com alocação em arena, migrar usando tags de tempo de vida nas referências não é um grande problema
      Mas se você escreveu, no estilo de programador C, um código com referências cíclicas — admitidamente feio —, Rust parece uma subida difícil e não é um bom lugar para começar
      Primeiro seria preciso mudar a estrutura do código C++ para mover a posse para um pai comum
      Acho que assim ficaria melhor
      Pretendo continuar aprendendo Rust de forma iterativa, mas seguir trabalhando em C++ até que o código se alinhe melhor com Rust
    • Provavelmente estará bem longe de um port 1:1
      Será preciso rearquitetar uma parte considerável do que está sendo escrito
      Isso é inevitável por causa da forma como Rust garante segurança de memória