Recurso

Privado por padrão

Apps instaláveis rodam trancados no próprio processo e pedem permissão antes de tocar na câmera, no microfone ou nos arquivos.

Eu sou quem fica na porta. Os apps que você instala ganham um quarto só deles, e quando querem sua câmera, seu microfone ou um arquivo, primeiro precisam pedir para mim, e eu pergunto para você.

Em poucas palavras#

Um app instalável do LordOS (um pacote .lpk) não recebe as chaves da sua casa. Ele roda num quarto só dele, com a porta trancada por fora. Quando precisa de algo, pede ao sistema por uma única portinhola, o broker. O sistema confere o que você decidiu e, se você ainda não decidiu, pergunta com um aviso desenhado pelo sistema, não pelo app.

Um app de teste isolado pede o microfone; o aviso é desenhado pelo sistema.
Um app de teste isolado pede o microfone; o aviso é desenhado pelo sistema.

Três ideias fazem a maior parte do trabalho:

  • Isolamento. Cada app .lpk é um processo próprio, trancado com recursos do kernel Linux antes que qualquer código dele rode.
  • Mediação. Tudo o que toca nas suas coisas (arquivos, câmera, microfone, área de transferência, senhas) passa pelo broker no lord-server, que confere a permissão a cada pedido.
  • Sua decisão, guardada onde o app não alcança. As decisões ficam em ~/.config/lordos/permisos.json, que os apps isolados não conseguem ver nem escrever.

Como um pedido de permissão viaja

  1. VocêApp isoladoPede pelo socket do broker
    depois pedido
  2. NossoBroker no lord-serverConsulta a decisão salva (perms.c)
    depois estado Perguntar
  3. NossoAviso do sistemaSó se ainda não foi decidido; desenhado pela sessão
    depois exibido
  4. VocêVocê decidePermitir ou Não permitir, salvo em permisos.json
    depois resposta
  5. KernelAplicadoO broker confere cada chamada; o sandbox e o kernel bloqueiam o resto
    depois depois
  6. PermitidoRevogávelAjustes → Privacidade; câmera e microfone param na hora

Legenda: VocêNossoKernelPermitido

O app nunca responde ao próprio aviso: a decisão fica onde ele não pode escrever e é conferida em C a cada pedido.

Quais apps são isolados, exatamente?#

Esta é a primeira pergunta que um leitor atento deve fazer, então aqui vai a resposta precisa:

Tipo de appProcesso próprioSandbox (Landlock + seccomp)cgroup por appBroker e permissõesFirewall por app
Apps .lpk instaladossimsimsim, com limites de memória e CPUsimsim
Senhas (hoje o único app incluído com processo próprio)simsimsimsimsim
Outros apps incluídos (Arquivos, Ajustes, E-mail, Terminal…)não, rodam dentro do lord-servernãonão (contam como "LordOS")o uso de câmera, microfone e tela é conferido em Csim, como "LordOS"
Apps Linux abertos pelo lançador de apps (apt, a Loja)sim, um processo comumnão por padrão; com "sem acesso aos seus arquivos", namespaces próprios e Landlocksim, app-lordos-<id>.scope, sem limitesnãosim, mais as restrições que você definir (câmera, microfone, USB, Bluetooth, arquivos, notificações)
Programas iniciados pelo Terminalsimnãodividem o lugar do Terminal na árvorenãocomo "LordOS"

Ou seja: os apps Linux não ficam em sandbox por padrão. Eles rodam como o seu usuário, exatamente como em qualquer sistema Debian, e podem ler sua pasta pessoal. O que o LordOS acrescenta para eles é a atribuição (o Monitor sabe qual app fez cada conexão), o firewall por app aplicado pelo kernel e as restrições que você escolher para um app: sem câmera, sem microfone, sem USB, sem sockets Bluetooth, sem notificações e "sem acesso aos seus arquivos", que a partir da próxima abertura inicia o app em namespaces próprios, com uma pasta pessoal vazia que só tem as pastas dele. O Flatpak não é usado nem integrado pelo LordOS, e não foi testado.

Os apps incluídos fazem parte do código do próprio sistema, revisado junto com ele; eles não recebem o isolamento por processo que os pacotes de terceiros recebem, com Senhas como exceção, porque guarda seus segredos.

Como o sandbox funciona#

O sandbox é código próprio do LordOS (server/src/sec/sandbox.c), não bubblewrap, Flatpak nem firejail. Ele usa recursos do kernel diretamente e é aplicado depois que o app se conecta ao compositor e ao broker, e antes de qualquer linha do código do app ser carregada.

As paredes em volta de um app instalado

  1. VocêO código do appCarregado só depois que as paredes estão de pé
  2. KernelLandlockArquivos: o pacote só leitura, a pasta de dados leitura e escrita, nada mais da sua pasta pessoal
  3. Kernelseccomp-bpfUma lista de chamadas de sistema permitidas; sem exec, ptrace, mount nem sockets novos
  4. KernelSem privilégiosno_new_privs, todas as capacidades removidas
  5. KernelEscopo de cgroup v2Do root; no máximo 512 MB e um núcleo; o firewall reconhece o app por ele

Legenda: VocêKernel

Tudo isso é código próprio do LordOS chamando o kernel diretamente; nenhuma ferramenta de contêiner é usada.
  • Landlock limita os arquivos que o processo pode tocar: acesso só de leitura ao próprio pacote, ao runtime compartilhado de apps, às fontes e às bibliotecas; leitura e escrita apenas em ~/.local/share/lordos/appdata/<id>. Nada mais da sua pasta pessoal, e nada de /dev.
  • seccomp-bpf é uma lista de chamadas de sistema permitidas, aplicada a todas as threads. Chamadas como ptrace, mount, bpf, execve, keyctl e carregamento de módulos simplesmente não estão nela. O app também não consegue abrir novos sockets Unix, então não alcança sozinho o barramento da sessão, o serviço de impressão nem o socket Wayland.
  • Sem privilégios. no_new_privs é ativado e todas as capacidades são removidas.
  • Um cgroup próprio, app-lordos-lpk-<id>.scope, com limite suave de memória de 192 MB, limite rígido de 512 MB e no máximo um núcleo de CPU. O escopo é criado pelo root (lord-sessiond) e pertence a ele, então o app não consegue se mudar para outro lugar.
  • Rede só com permissão. Sem a permissão network, o seccomp recusa criar sockets de internet e o Landlock recusa connect e bind TCP. Com ela (declarada no manifesto e permitida por você), eles são liberados, e o firewall por app continua valendo.

São usados namespaces? Não para os apps .lpk. O lord-server roda sem root, e criar um namespace de rede exige privilégios que ele não tem. O projeto usa Landlock, seccomp e cgroups no lugar disso, e deixa o app no namespace de rede da máquina, sob as regras acima. O único lugar em que o LordOS usa namespaces é um app Linux restrito com "sem acesso aos seus arquivos": ele inicia em namespaces próprios de usuário, montagem e PID, sem privilégios, montados por código próprio do LordOS no lançador, então não alcança os sockets da sessão.

O projeto mantém um app de teste propositalmente malicioso (tests/lpk-evil). Ele não declara nenhuma permissão e tenta de tudo ao abrir: ler ~/.ssh/id_rsa e settings.json, escrever fora da própria pasta, ler a área de transferência escondido, abrir /etc/shadow, abrir um socket, executar /bin/sh, ptrace, abrir a placa de vídeo. Todas as tentativas são bloqueadas. A suíte de testes do sandbox passa em 14 de 14 verificações para apps, 14 de 14 com rede e 17 de 17 para os ajudantes.

O app de teste propositalmente malicioso, no próprio processo: todas as tentativas bloqueadas.
O app de teste propositalmente malicioso, no próprio processo: todas as tentativas bloqueadas.

O que você vê e decide#

  • O aviso. Na primeira vez que um app pede algo, o sistema mostra: "App" quer usar o microfone — Permitir / Não permitir. A resposta fica salva para aquele app.
  • Ajustes → Privacidade lista cada permissão com os apps que a pediram e um controle Permitir / Perguntar / Negar.
  • Indicadores. Um ponto verde na barra de menus enquanto a câmera está em uso, e um laranja para o microfone. Ao tocar nele, aparece qual app está usando.

Permissões que um app pode declarar: arquivos, área de transferência, notificações, rede, câmera, microfone, tela, escuta de portas, USB, Bluetooth e apps. Um app não consegue uma permissão que não declarou.

Ajustes → Privacidade: cada permissão com seus apps e um controle Permitir / Perguntar / Negar.
Ajustes → Privacidade: cada permissão com seus apps e um controle Permitir / Perguntar / Negar.

As perguntas do leitor cético#

Dá para contornar o aviso? Não pelo app isolado. O aviso é desenhado pela sessão, fora da janela do app. A resposta chega diretamente ao lord-server, e o broker lê a decisão salva, em C, a cada pedido. O arquivo de decisões fica fora do que o Landlock deixa o app ver, e o lord.fs se recusa a escrevê-lo. Um app até poderia desenhar um diálogo falso dentro da própria janela, mas clicar nele não muda nada. A brecha, sendo honesto: um app Linux, que por padrão não tem sandbox e roda como você, poderia editar o permisos.json como qualquer outro arquivo da sua pasta pessoal, a menos que esteja restrito com "sem acesso aos seus arquivos".

Existe "Permitir uma vez" ou "Permitir sempre"? Hoje o aviso oferece Permitir e Não permitir, e a decisão fica lembrada até você mudá-la em Ajustes. Ainda não há "permitir uma vez" para as permissões dos apps.

O app recebe só o arquivo que eu escolho? Sim. Para abrir ou salvar, um app isolado chama o diálogo de arquivos do sistema. O lord-server o desenha (o "powerbox"), abre o arquivo que você escolheu com as suas permissões e passa ao app só aquele descritor de arquivo. O app nunca vê a pasta nem o resto do disco. Nenhuma permissão extra é necessária, porque escolher o arquivo já é o consentimento.

O diálogo de arquivos do sistema: o lord-server o desenha e o app recebe só o arquivo escolhido.
O diálogo de arquivos do sistema: o lord-server o desenha e o app recebe só o arquivo escolhido.

Como a câmera e o microfone são mediados? O app nunca abre o dispositivo.

  • Microfone: o lord-server abre o fluxo de captura do PipeWire e escreve o áudio num anel compartilhado; o app recebe uma cópia somente leitura dele.
  • Câmera: o lord-server abre /dev/videoN e o entrega só ao ajudante de mídia em sandbox, o lord-media, que decodifica os quadros num anel compartilhado e selado. O app recebe um mapeamento somente leitura e precisa confirmar cada quadro; o lord-server valida cada confirmação (geração, posição, ritmo). Fotos e vídeos vão para um arquivo que você escolhe no diálogo de salvar do sistema.

A câmera sem entregar a câmera

  1. Kernel/dev/videoNAberto pelo lord-server após o consentimento
    depois fd do dispositivo
  2. Nossolord-mediaDecodificador em sandbox; quadros num anel selado
    depois anel de quadros
  3. Nossolord-serverValida cada confirmação
    depois reabertura só leitura
  4. VocêApp isoladoVisão somente leitura dos quadros

Legenda: KernelNossoVocê

Revogar a permissão encerra o lord-media do app e a imagem para na hora.

Dá para revogar permissões com o app aberto? Sim, para a câmera e o microfone: colocar qualquer um deles em Perguntar ou Negar em Ajustes corta na hora. No caso da câmera, o lord-server encerra o processo lord-media do app (testado: some em até 0,5 s); no do microfone, fecha o fluxo do PipeWire. Verificações como a da área de transferência valem a partir do próximo pedido. A permissão network é decidida quando o app inicia, então uma mudança vale no próximo lançamento; para tirar da rede um app que já está rodando na hora, use o botão do firewall no Monitor.

Depois de Negar em Ajustes, a câmera parou e o ponto verde sumiu.
Depois de Negar em Ajustes, a câmera parou e o ponto verde sumiu.

Posso garantir que um app nunca receba a câmera, peça o que pedir? Sim: restrinja-o em Ajustes → Privacidade → Rede dos apps. Uma restrição do firewall vence as permissões: o app é recusado sem aviso mesmo que você o tenha permitido antes, e restringir um app em execução tira dele a câmera e o microfone na hora. Para os apps isolados, o broker aplica as oito restrições (câmera, microfone, tela, USB, arquivos, área de transferência, Bluetooth, notificações).

E os apps que precisam de mais privilégios? Não há como um app .lpk obter root ou capacidades extras. Tudo no LordOS que precisa de root passa por uma lista fechada de ações validadas (server/src/admin.c), e o JavaScript não consegue executar comandos arbitrários. Os apps Linux se comportam como em qualquer sistema Debian: se um programa precisa de sudo, você mesmo o executa no Terminal.

Os ajudantes que leem dados não confiáveis#

Arquivos vindos de fora são a porta de entrada clássica. O LordOS os abre em pequenos processos separados, trancados com ainda mais rigor que os apps: lord-doc (PDFs, arquivos compactados, fontes), lord-media (vídeo, música, fotos, câmera), lord-maild (e-mail, calendários, contatos) e lord-vault (senhas). Eles não têm rede, não conseguem criar sockets, não conseguem executar programas e só podem criar threads, não processos. Eles não abrem caminhos: o lord-server abre os arquivos e os passa como descritores. Se o seccomp não puder ser aplicado, o ajudante encerra em vez de rodar sem confinamento. Um PDF malicioso pode derrubar o lord-doc, mas não o desktop.

Janelas protegidas#

Uma janela pode ser marcada como protegida. A de Senhas é. Os pixels dela saem pretos nas capturas de tela do LordOS, nas gravações de tela, nas miniaturas e na área de trabalho remota, enquanto o monitor de verdade a mostra normalmente. Os apps Linux não conseguem capturar a tela pelo LordOS: o compositor não oferece a eles nenhum protocolo de captura de tela, não há servidor X, e um app restrito também tem o dispositivo de framebuffer negado.

Uma janela protegida sai preta numa captura do LordOS.
Uma janela protegida sai preta numa captura do LordOS.

Limites honestos#

  • Os apps Linux não têm sandbox por padrão. Para eles valem as regras de rede, a atribuição e as restrições que você definir; as restrições não cobrem a área de transferência, o Bluetooth através do BlueZ no barramento do sistema, o barramento do sistema em geral nem programas iniciados fora do lançador de apps.
  • O uso de câmera e microfone por apps Linux ainda não aparece nos indicadores. A lista de dispositivos do Monitor está planejada.
  • O broker ainda não cobre tudo. Permissões como Bluetooth ou abrir outros apps podem ser declaradas, mas não há chamada do broker para elas, então um app isolado simplesmente não consegue fazer essas coisas.
  • A falta de um recurso do kernel enfraquece o sandbox dos apps sem alarde. Se faltar o Landlock ou um controlador de cgroup, os apps iniciam mesmo assim, com um aviso no log. Já os ajudantes se recusam a rodar sem seccomp.

Leia o código

O código por trás deste recurso, no GitHub.

·