- A comunidade do kernel Linux há muito tempo vê com maus olhos os módulos proprietários do kernel, e o patch de Christoph Hellwig é uma medida para estreitar novamente essas brechas
- Em vez de proibir o carregamento de módulos proprietários, o kernel usa GPL-only exports para permitir o acesso a alguns símbolos do kernel apenas a módulos compatíveis com GPL
- Em 2020, veio à tona um método de GPL condom em que um módulo GPL fazia a ponte entre um módulo proprietário e o kernel; depois disso, módulos que usam símbolos proprietários também passaram a ser tratados como proprietários
- A nova brecha usa
symbol_get()para obter o endereço de símbolos internos de módulos proprietários sem passar pelo processo normal de importação, e Hellwig entende que a NVIDIA alterou seu código para usar esse método - O patch proposto faz
symbol_get()falhar ao buscar símbolos que não sejam GPL-only, bloqueando a brecha, mas é difícil tornar esse controle de acesso totalmente seguro enquanto os módulos executam no espaço de endereçamento do kernel
A velha tensão em torno dos módulos proprietários do kernel
- A comunidade do kernel Linux nunca teve uma relação tranquila com fornecedores de módulos proprietários do kernel
- Esses módulos são difíceis de depurar ou corrigir por qualquer pessoa que não seja quem os criou
- Muitos desenvolvedores veem isso como violação da licença do kernel e dos direitos autorais do código
- Ainda assim, módulos proprietários foram permitidos dentro de certos limites
- O patch recente de Christoph Hellwig é um movimento para estreitar um pouco mais esse limite
A tentativa de proibição em 2006 e os GPL-only exports
- Em 2006, houve uma breve tentativa de proibir completamente o carregamento de módulos proprietários do kernel
- Linus Torvalds impediu essa tentativa por vários motivos
- O simples ato de carregar um módulo proprietário no kernel Linux não constitui, por si só, violação de direitos autorais
- Usuários de Linux podem fazer isso
- Torvalds avaliou que essa proibição poderia sinalizar mais interesse em disputas de licença do que em melhorias técnicas
- A distribuição de módulos proprietários pode configurar violação de direitos autorais se esses módulos forem obras derivadas do código do kernel
- Mas determinar se algo é uma obra derivada é ambíguo, e o próprio kernel dificilmente consegue fazer esse julgamento na prática
- O kernel tem há muito tempo um mecanismo para bloquear módulos potencialmente infratores: os GPL-only exports
- Para fazer algo útil, módulos do kernel precisam acessar funções e símbolos de estruturas de dados exportados pelo kernel
- Muitos símbolos só são permitidos para módulos que declaram uma licença compatível com GPL
- Isso mantém módulos proprietários afastados de uma parte considerável das funcionalidades do kernel
A intenção e a realidade da marcação GPL-only
- Em teoria, a marcação GPL-only significa que um símbolo está profundamente acoplado ao interior do kernel e, portanto, qualquer código que o use inevitavelmente é uma obra derivada do kernel
- Na prática, desenvolvedores não fazem esse tipo de análise jurídica
- Em geral, nem têm qualificação para isso
- Na realidade, marcar símbolos como GPL-only costuma ser usado como forma de dificultar de modo geral a vida dos módulos proprietários
O método de contorno com intermediário revelado em 2020
- Fabricantes de módulos proprietários há muito tempo procuram formas de contornar as restrições dos GPL-only exports
- Há a opção de declarar falsamente uma licença compatível com GPL, mas isso parece uma admissão explícita de irregularidade, então empresas tendem a evitar esse caminho instintivamente
- Um método mais sutil apareceu durante a discussão de um conjunto de patches sobre DMA peer-to-peer em 2020
- Nessa estrutura, um módulo que declara licença compatível com GPL atua como intermediário
- Esse módulo pode acessar todos os símbolos exportados pelo kernel
- Ao importar então os símbolos de um módulo proprietário, o código proprietário consegue acessar as funções do kernel de que precisa
- Isso é uma variação do chamado método GPL condom
O patch de resposta em 2020
- Na época, Hellwig integrou um patch para tornar essa abordagem mais difícil
- No kernel atual, módulos que usam símbolos de módulos proprietários também passam a ser tratados como proprietários
- Eles perdem imediatamente a capacidade de acessar símbolos GPL-only
- Se já estiverem usando símbolos GPL-only e tentarem importar símbolos de um módulo proprietário, a operação falha
- Essa verificação bloqueia o caminho em que um módulo GPL atua como intermediário entre um módulo proprietário e o kernel
A nova brecha por meio de symbol_get()
- O kernel fornece a macro
symbol_get(), enquanto o trabalho real é feito por__symbol_get() - Essa funcionalidade localiza o endereço associado a um símbolo do kernel
symbol_get()existe no kernel desde a release 2.5.48, em 2002, quando foi adicionada durante uma grande reformulação do carregador de módulos- Também há limitações importantes
- Ela só consulta símbolos fornecidos por módulos carregáveis
- Seu uso é voltado para módulos fortemente conectados entre si, para lidar com a possibilidade de um deles ainda não estar carregado, sem criar loops de referência
- À primeira vista, isso não parece muito útil para fornecedores de módulos proprietários que queiram contornar as regras, já que não serve para localizar símbolos GPL-only do kernel
Como symbol_get() contorna a defesa de 2020
symbol_get()pode ser usado para obter o endereço de módulos proprietários sem passar pelo mecanismo normal de importação e por suas restrições- Por isso, a correção de 2020 pode voltar a ser contornada
- Um módulo nominalmente licenciado sob GPL pode chamar um módulo proprietário
- Esse módulo proprietário, por sua vez, pode acessar as funções do kernel de que precisa
- Hellwig avalia que a NVIDIA alterou seu código para usar esse método de contorno
Mudança de comportamento no novo conjunto de patches
- Hellwig enviou um conjunto de patches para fechar novamente essa brecha, e depois também apresentou uma versão revisada
- A mudança central é alterar o comportamento de
symbol_get()- Se o símbolo consultado não estiver marcado como GPL-only, a operação falha
- É uma verificação no sentido oposto ao mecanismo que normalmente recusa acesso a símbolos GPL-only
- O motivo é que
symbol_get()foi originalmente pensado como um recurso para cooperação de baixo nível em áreas profundas do kernel, onde se espera que tudo seja GPL-only - Alguns usos existentes dentro do kernel apontavam para símbolos que não estavam marcados como GPL-only
- O conjunto de patches também inclui mudanças para converter esses casos em símbolos GPL-only
Impacto esperado e limitações
- Essa mudança em
symbol_get()impede que módulos do kernel sob licença GPL resolvam símbolos internos de módulos proprietários viasymbol_get() - Se essa mudança entrar em uma release mainline e chegar às distribuições, desenvolvedores de módulos proprietários terão de procurar outros meios de obter o acesso interno ao kernel de que precisam
- Como o mantenedor de módulos Luis Chamberlain aplicou essa alteração, a chance de ela acabar entrando na mainline parece bastante boa
- Esse conflito já dura muito tempo, e não é pequena a chance de autores de módulos proprietários encontrarem outros meios de contornar a intenção da comunidade do kernel
- Independentemente de serem proprietários ou não, módulos executam no espaço de endereçamento do kernel
- A superfície de ataque disponível para módulos que tentem contornar a política de acesso a símbolos do kernel é grande
- É difícil proteger completamente essa área
- Na prática, o melhor que se pode fazer é continuar tornando a vida desconfortável para distribuidores de módulos binários proprietários, para incentivá-los a criar soluções sob licenças livres
- Esse método não é perfeito, mas ao longo dos anos muitas vezes funcionou
1 comentários
Opiniões no Hacker News
O código do linker do kernel Linux foi projetado para impor a interpretação de Linus Torvalds sobre como a GPL e a exceção para chamadas de sistema devem funcionar, então parece haver espaço jurídico para a Nvidia alegar que houve burla de proteção de direitos autorais (DMCA 1201).
Linus provavelmente não faria isso de fato, e seria bem terrível para todo o ecossistema FOSS se fizesse, mas, considerando o que a Nvidia tem feito ao longo dos anos, dá até vontade de ver isso uma vez.
Se nem o Linux, o gorila de 800 libras na sala, está disposto a ir ao tribunal, as perspectivas para os outros projetos também não parecem animadoras.
Se o Linux vai usar apenas uma pressão técnica “suave” contra violações escancaradas de licença e copyright por grandes empresas, dá até a impressão de que seria melhor considerar a GPL encerrada e migrar para algo como BSD3 ou MIT+Apache.
O LLVM não usa copyleft forte e, com meios puramente técnicos como mudanças de API e um ritmo de desenvolvimento muito rápido, incentiva a cooperação upstream; funciona bem sem diluir a licença escolhida.
Uma contra-ação capaz de causar dano real às oportunidades de negócio da Nvidia pode funcionar bem como dissuasão contra problemas futuros.
É algo como: “como symbol_get originalmente era destinado apenas a módulos que cooperam estreitamente e usam símbolos muito internos, faz sentido restringi-lo ao uso apenas com EXPORY_SYMBOL_GPL e poupar a Nvidia de um caro processo por burlar controles de acesso sob a DMCA”; é uma ótima forma irônica de apontar que a Nvidia ignora descaradamente a intenção e a consideração e faz o que quer.
Sonhar é de graça :)
[1]: https://www.youtube.com/watch?v=tQIdxbWhHSM
Linus não tem uma autoridade especial nesse ponto.
O comentário deixado pelo autor desse patch é realmente peculiar.
https://lore.kernel.org/lkml/20230731083806.453036-6-hch@lst...
Ele diz: “como symbol_get originalmente era destinado apenas a módulos que cooperam estreitamente e usam símbolos muito internos, faz sentido restringi-lo ao uso apenas com EXPORY_SYMBOL_GPL e poupar a nvidia de um caro processo por burlar controles de acesso sob a DMCA”.
Isso é literalmente uma tentativa de reivindicar, para o kernel Linux, que é um projeto open source, a proteção das cláusulas anticircunvenção da DMCA, que tornam ilegal burlar DRM.
Ao mesmo tempo, também é uma admissão implícita de que EXPORT_SYMBOL_GPL é claramente um esquema de DRM.
Pessoalmente, não gosto da NVIDIA e não tenho nenhuma intenção especial de defender o comportamento dela, mas é surpreendente ver o projeto Linux alegar que leis anticircunvenção de DRM se aplicam também a projetos open source.
É uma das leis às quais a comunidade open source se opõe quase universalmente, e qualquer esquema de DRM parece bastante desalinhado com os valores do FOSS.
O objetivo central da GPL sempre foi usar a lei de direitos autorais contra a própria lei de direitos autorais, ou seja, o copyleft.
Quanto mais forte a lei de direitos autorais, mais fortes são as proteções da GPL; portanto, usar legislação adicional de copyright para proteger software open source me parece bem alinhado com o espírito da GPL.
A GPL não é uma licença permissiva, mas uma licença de copyleft forte, e tem força real de aplicação.
O mecanismo de contaminação não é hipocrisia; ele é open source, e se o código é GPL, você pode fazer o que quiser com ele.
É literalmente um dispositivo que impõe a cláusula de linking da licença GPL.
Quando necessário, é preciso usá-la, então isso não me parece nada estranho.
Se alguém fez algo suspeito e ainda assim recebe uma saída tão suave para salvar as aparências, está com sorte.
DRM para impedir a apropriação indevida da GPL parece o próximo passo lógico.
Não entendo por que drivers proprietários não deveriam interagir com um kernel livre
O Linux está literalmente implementando DRM em nível de kernel, exatamente aquilo que o software livre jurou destruir
Pelo menos, a exigência de impedir que drivers proprietários interajam com código exclusivo da GPL parece, do meu ponto de vista, mais próxima de um EULA
Se fosse apenas a GPLv2, módulos proprietários provavelmente seriam uma infração
Mas, como Linus deixou explícito que chamadas de sistema não acionam o copyleft da GPL, os símbolos do kernel que correspondem a chamadas de sistema também não acionam o copyleft da GPL
Então, para evitar uma violação de licença de acordo com a interpretação de Linus sobre a exceção da GPL, é necessário um loader que verifique os dados de licença para saber quais símbolos podem ou não ser linkados
Isso é, sim, DRM em nível de kernel[0], e talvez Linus tenha margem para apresentar um argumento jurídico contra a Nvidia por burlar a proteção contra cópia
A GPLv3 nega explicitamente qualquer proteção contra cópia no código coberto por ela, então, em teoria, poderia impedir esse tipo de processo, mas essa cláusula não foi testada nos tribunais, e Linus detesta especialmente a GPLv3 por ela ter acrescentado a cláusula TiVo[1]
Esse recurso foi implementado décadas atrás, e o objetivo original era evitar receber relatórios de bug dizendo que o kernel Linux travou por causa de módulos proprietários impossíveis de corrigir
A aplicação da GPL foi um efeito colateral
[0] Não confundir com outro DRM dentro do kernel, o Direct Rendering Manager
[1] Não é tanto por detestar a cláusula TiVo em si, mas por detestar que ela acrescente condições retroativamente a software v2 e mude os termos do acordo. Porque isso parece como se o Linux estivesse sendo tomado pela FSF
Só que precisam usar apenas recursos de sistema operacional bastante genéricos, encontrados em vários kernels parecidos
Um driver desse tipo, que não dependa de funcionalidades específicas do Linux, não pode ser considerado uma “obra derivada” do kernel Linux, portanto pode escolher a licença que quiser
Por outro lado, um driver que usa interfaces específicas do kernel Linux, inexistentes em outros sistemas operacionais, até mesmo em outros kernels da família Unix, é por definição mais próximo de uma “obra baseada no Programa” do kernel e, portanto, deve ser licenciado de maneira semelhante
Basta ver o texto da GPL-2 que rege o kernel
https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
A LGPL existe separadamente para permitir a linkagem separada entre software livre e software proprietário, algo proibido na GPL
Mas o Linux é GPL-2, então essa permissão adicional não se aplica
Se o driver da Nvidia usasse apenas APIs genéricas de kernel, estaria tudo bem, mas na prática não é isso que acontece
Como ele tenta usar, sem estar sob a GPL, APIs específicas do Linux marcadas para uso por drivers com licenças compatíveis com a GPL, isso é uma violação clara da licença de software livre sob a qual o Linux é fornecido
Por que software proprietário deveria poder desfrutar de todos os benefícios do software livre sem seguir regra nenhuma, enquanto o software livre simplesmente teria de aceitar isso?
Sociedades democráticas também têm mecanismos que restringem a expressão em certa medida para se proteger
Sistemas operacionais proprietários já existem em grande quantidade, e eles não se importam nem um pouco com isso
Não pode haver também um sistema operacional que se importe com esses princípios? Tudo precisa ser apenas uma ferramenta fria e favorável à indústria, sem consideração humana?
A intenção da licença é que tudo que seja linkado e carregado no kernel seja distribuído sob uma licença copyleft compatível
A exigência de que código proprietário não “inclua” código GPL é a própria GPL, e é o objetivo central da GPL
Ainda assim, há espaço para discussão sobre até que ponto simplesmente linkar a uma API constitui infração
Parece possível uma decisão para qualquer um dos lados, e esse tipo de julgamento teria grande impacto sobre a GPL
Como o código da Nvidia roda em ring0, pela experiência há muitos truques mais interessantes que a Nvidia poderia usar, mas provavelmente está se segurando por enquanto
O mesmo vale para os desenvolvedores do Linux
Essa briga idiota de DRM não ajuda ninguém e só incentiva ainda mais um jogo de gato e rato que desperdiça o tempo de todo mundo
“Pessoal, convivam em paz”
Não entendo por que a Nvidia se esforça tanto para manter seus drivers como um bloco binário proprietário
Software nem é o núcleo de sua defensibilidade; a Nvidia é uma empresa de hardware
Abrir o módulo do kernel não só não afetaria as vendas de hardware, como também melhoraria a estabilidade e ainda conquistaria a simpatia de desenvolvedores que hoje fazem questão de comprar uma GPU da AMD
Porque comoditização é o oposto de margens de lucro gordas
Com cerca de 80% do mercado de GPUs, para aumentar ainda mais as margens fica mais fácil cobrar preços mais altos ou controlar camadas mais altas de toda a stack
Por exemplo, é vantajoso se a principal linguagem de GPU de propósito geral for construída em torno da arquitetura de GPUs da própria empresa
Ou então ela precisa se expandir para áreas completamente diferentes, e a Nvidia está entrando forte em IA justamente porque pode aproveitar seu domínio em GPUs para conquistar uma vantagem inicial nessa área
Mas não tenho base para isso
“Ilegal” é apenas uma teoria até que seja provado em juízo
O que se está falando aqui é, essencialmente, DRM dentro do código do kernel, tentando impedir que módulos de kernel carregáveis adivinhem onde, na memória, ficam as estruturas de dados do kernel
Como sabem que as pessoas provavelmente vão forçar os limites, querem tornar isso o mais difícil possível como forma de dissuasão
Mas também se poderia argumentar que todos os módulos de kernel carregáveis de código fechado violam a GPL da mesma forma, com ou sem “shim”, e de fato esse argumento já foi feito; só que a maioria esqueceu disso e usa essa ficção de DRM como se fosse um substituto para a ficção jurídica
Ou, se as funções marcadas como GPL dentro do kernel forem APIs no sentido definido no caso Google contra Oracle, talvez toda essa discussão nem tenha muito sentido
A maioria dos módulos de kernel carregáveis está na árvore de código-fonte do kernel e é fornecida sob a GPL
O próximo passo seria criar um módulo carregável open source que inclua uma pequena máquina virtual que carregue blobs binários em modo de usuário
Ela executaria apenas blobs binários assinados com uma chave privada da NVIDIA, enquanto a chave pública ficaria incluída no módulo open source
Ou então criar um hipervisor que virtualize o Linux e contorne a maior parte do kernel…
Sempre há um jeito
Isso só torna tudo mais irritante e aumenta o custo de obter drivers decentes para Linux, então o esforço investido nisso vai diminuir
Não está claro se isso é uma grande perda
Espero que essa briga não acabe fazendo com que os drivers da Nvidia para Linux desapareçam ou piorem
Sem eles, meu sistema operacional favorito fica de repente menos útil por causa de games e IA
Dez anos antes era diferente
Naquela época, quem se importava eram principalmente alguns poucos geeks de Linux que queriam jogar no Linux, e eles representavam uma fatia pequena da receita
Hoje, praticamente todo o valor de mercado da NVIDIA está construído sobre IA, e quase todos os principais players que compram esse hardware em grande volume o usam no Linux
Cortar o Linux não é uma opção para a NVIDIA
É provável que ela faça o que for necessário para impedir que isso aconteça
Remover todo o suporte até que a nVidia se abra
Mas hoje em dia não somos nós, e sim empresas comerciais, que têm mais poder de decisão sobre como o hardware é usado e suportado no Linux
A Nvidia abriu o código do driver, ou de partes dele, e agora também fornece binários de firmware redistribuíveis
Além disso, em algumas placas mais antigas, a autenticação do firmware também foi quebrada
Então espero que, com o tempo, a importância do driver proprietário diminua
No nível do kernel, virou uma questão de “qual é a cor dos seus bits”[1]… legal?
[1] https://ansuz.sooke.bc.ca/entry/23