Acontece que o código Assembly escrito à mão que fornece uma função "strcmp" de comparação de string otimizada para a arquitetura do processador Motorola 68000 (m68k) "sempre foi quebrado" e só agora foi descoberto no final de 2022.
Enquanto entusiastas de código aberto e outros gosto de pensar que os bugs no código-fonte aberto são facilmente detectados, principalmente quando se trata da enorme base de código do kernel do Linux para código que toca hardware antigo/de nicho, o que nem sempre é o caso. Para os processadores Motorola 68000 de décadas atrás, só foi descoberto recentemente que sua implementação otimizada de strcmp() está sutilmente quebrada, mas agora se tornou mais pronunciada após outras mudanças no kernel.
Linus Torvalds lidou com o problema e comentou que "sempre foi quebrado" e, de fato, ao puxar o código m68k strcmp () voltando para os primeiros dias do Linux 2.6 quando inicialmente importado para o Git, a função foi realmente quebrada pelo menos até agora , se nem sempre voltar para o port do Linux/m68k original.
Mas quanto a esta implementação strcmp quebrada sendo quebrada por muitos anos no kernel e passando despercebida, como Torvalds explicou que é sutil porque é quebrada apenas para o caso de estouro e a maioria dos usuários do kernel strcmp () não se importam com não-EUA Ordenações ASCII. Muitos desenvolvedores também se preocupam se strcmp() corresponde às duas strings ou não, mas nem sempre estão preocupados com o valor retornado.
O problema m68k strcmp() só se tornou mais pronunciado agora com o código de desenvolvimento do kernel Linux 6.2, onde a flag do compilador -funsigned-char está sendo definida para lidar melhor com o código com erros.
Linus Torvalds resumiu o problema neste commit foi corrigindo o problema, que também está incorporado abaixo para facilitar a leitura. A correção/solução alternativa está apenas excluindo a implementação otimizada (quebrada) para que ela volte a usar a implementação strcmp() genérica dentro do kernel para aqueles que ainda executam o hardware da série 68000 da Motorola.
A versão do montador m68 escrita à mão de strcmp() sempre foi quebrada: ela retorna a diferença entre o primeiro byte não correspondente feito como uma subtração de 8 bits.
Isso é _quase_ certo, mas está quebrado para o caso de estouro. A função strcmp() deve sim retornar o sinal da diferença entre o primeiro byte que difere, mas a subtração precisa ser feita em um tipo mais amplo que 'char'. Caso contrário, a ordem não é realmente estável.
Isso passou despercebido basicamente para sempre, porque ninguém nunca se importa com ordenações não-US-ASCII no kernel (na verdade, a maioria dos usuários só se preocupa com "correspondência exata ou não"), então estouros realmente não acontecem na prática, mesmo se foi muito muito errado.
Mas esse bug quase imperceptível se torna muito perceptível pela recente mudança para fazer com que 'char' não seja assinado no kernel em todas as arquiteturas (commit 3bc753c06dd0: "kbuild: trate char como sempre não assinado"). Como o código não apenas fez a subtração na largura do tipo errado, ele também usou 'char' para fazer o compilador expandir o resultado de uma diferença de 8 bits para o valor de retorno 'int'.
Portanto, agora, com um caractere sem sinal, essa largura aritmética incorreta nem mesmo foi expandida por sinal e sempre retornou apenas um número inteiro positivo.
Poderíamos restabelecer o antigo código quebrado apenas transformando o 'char' em 'signed char' como foi feito em outros lugares onde as pessoas dependiam da assinatura de 'char', mas desde que toda a função foi quebrada para começar, e nós tiver uma implementação de fallback padrão não quebrada, vamos apenas remover completamente essa função quebrada.
A eliminação da implementação quebrada do m68k strcmp() foi mesclada hoje para o Linux 6.2.
Até a próxima !!
Nenhum comentário:
Postar um comentário