Libseccomp: BUG: teste 53/55 falhas / erros em aarch64

Criado em 4 mar. 2020  ·  23Comentários  ·  Fonte: seccomp/libseccomp

Parece que temos várias falhas e erros de teste em aarch64 com o branch master atual; HEAD é 38f04da ("testes: adicionar testes para a árvore binária").

FALHAS do teste:

 test mode:  c
 test type:  bpf-valgrind
Test 53-sim-binary_tree%%331-00001 result:   FAILURE 53-sim-binary_tree rc=14
 test mode:  c
 test type:  basic
Test 55-basic-pfc_binary_tree%%001-00001 result:   FAILURE 55-basic-pfc_binary_tree.sh rc=1

ERROS de teste:

 test mode:  c
 test type:  bpf-sim
Test 53-sim-binary_tree%%001-00001 result:   ERROR 53-sim-binary_tree rc=14
...
<every 53-sim-binary_tree test in "c" mode ERRORs in the same manner>
 test mode:  python
 test type:  bpf-sim
Test 53-sim-binary_tree%%001-00001 result:   ERROR 53-sim-binary_tree rc=1
...
<every 53-sim-binary_tree test in "python" mode ERRORs in the same manner>
bug prioritmedium

Comentários muito úteis

Olá @ piso77 , obrigado pelo relatório. Depois que @drakenclimber tiver uma correção, você estaria disposto a testá-la?

Claro, envie um ping quando houver um patch disponível!

Todos 23 comentários

@drakenclimber Não tenho certeza se você tem acesso a um sistema aarch64 (talvez um Raspberry Pi executando uma compilação de 64 bits?), mas vou atribuir este a você por razões óbvias. Se você não tiver acesso a um sistema aarch64, me avise e eu verificarei isso.

EDITAR: desculpe, esse é o código de erro 14, NÃO o erro 16 (CORRIGIDO ABAIXO)

Eu fiz uma pequena pesquisa agora e parece que o teste 53-sim-binary_tree não está gerando nenhuma entrada e está retornando com o código de erro 14 / EFAULT quando executado autônomo.

Eu adicionei alguns instrumentos rápidos (abaixo):

diff --git a/tests/53-sim-binary_tree.c b/tests/53-sim-binary_tree.c
index 2c7890e..c154f67 100644
--- a/tests/53-sim-binary_tree.c
+++ b/tests/53-sim-binary_tree.c
@@ -81,6 +81,7 @@ int main(int argc, char *argv[])
                                              SCMP_A0(SCMP_CMP_EQ, i));
                else
                        rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(i), i, 0);
+               printf("PMD: i=%d, rc=%d\n", i, rc);
                if (rc < 0)
                        goto out;
        }

... que resultou na seguinte saída:

# ./53-sim-binary_tree -p
PMD: i=0, rc=0
PMD: i=1, rc=0
PMD: i=2, rc=0
PMD: i=3, rc=0
...
PMD: i=161, rc=0
PMD: i=162, rc=0
PMD: i=163, rc=-14

Interessante. Meu Raspberry Pi morreu há alguns meses, mas essa parece uma boa desculpa para pedir um novo. A nova versão de 2 GB parece realmente tentadora.

Até que chegue, devo conseguir encontrar uma máquina ARM dentro do Oracle. Vou começar a procurar ...

Parece bom. Ficarei curioso para saber como se sai o novo RPi 4, só tenho um 3B.

De qualquer forma, se você não conseguir encontrar um sistema, me avise.

A tabela syscall de aarch64 é esparsa em vários lugares e, portanto, aarch64_syscall_resolve_num() retorna NULL se o número syscall não puder ser encontrado em aarch64_syscall_table .

Aqui está a lista exata de números de syscall que atualmente não existem em aarch64:

                if (i == 163 || i == 164 || i == 244 || i == 245 ||
                    i == 246 || i == 247 || i == 248 || i == 249 ||
                    i == 250 || i == 251 || i == 252 || i == 253 ||
                    i == 254 || i == 255 || i == 256 || i == 257 ||
                    i == 258 || i == 259 || i >= 295)
                        /* aarch64 doesn't support these syscall numbers.
                         * remove them
                         */
                        continue;

Não tenho certeza da melhor maneira de proceder. Devemos limitar os testes 53 e 55 apenas para x86_64? Eu realmente quero ter certeza de que estamos testando árvores binárias grandes e desequilibradas. Parece que em um caso como este podemos pular esses testes. Ou talvez devêssemos fazer um teste menor e mais simples para essas arquiteturas.

Pensamentos?

Desapontamento. Embora alimentar um número falso de syscall e esperar um resultado válido não seja muito justo;)

Uma possibilidade seria primeiro fazer uma chamada para seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, i) para ver se esse número syscall existe; se não, você simplesmente pula aquele syscall inexistente.

Acho que também é importante notar que este é puramente um problema de teste e não um problema aarch64 geral. No mundo real, apenas números syscall válidos seriam alimentados na API com a expectativa de resultados adequados.

Desapontamento. Embora alimentar um número falso de syscall e esperar um resultado válido não seja muito justo;)

Eu sabia que estava brincando com fogo quando fiz isso :). Este é um recurso complicado de testar porque o comportamento do end seccomp não deve mudar ao usar uma árvore binária. Apenas a maneira como atravessamos o bpf (ou pfc) deve mudar.

Uma possibilidade seria primeiro fazer uma chamada para seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, i) para ver se esse número syscall existe; se não, você simplesmente pula aquele syscall inexistente.

Eu pensei sobre isso, mas isso torna realmente difícil comparar com um arquivo * .pfc pré-preenchido como estamos fazendo no teste 55.

Acho que também é importante notar que este é puramente um problema de teste e não um problema aarch64 geral. No mundo real, apenas números syscall válidos seriam alimentados na API com a expectativa de resultados adequados.

Concordaram. Preciso dar um passo para trás e pensar um pouco sobre isso. Talvez haja uma maneira de usar algumas das ferramentas bpf que você criou para ajudar nos testes.

Eu pensei sobre isso, mas isso torna realmente difícil comparar com um arquivo * .pfc pré-preenchido como estamos fazendo no teste 55.

Talvez a resposta seja que para o teste 55 usamos um subconjunto menor de syscalls (uma dúzia, duas dúzias?) De forma que possamos fazer a resolução do número a partir do nome do syscall para garantir que existam.

Talvez a resposta seja que para o teste 55 usamos um subconjunto menor de syscalls (uma dúzia, duas dúzias?) De forma que possamos fazer a resolução do número a partir do nome do syscall para garantir que existam.

Sim, acho que é provavelmente a melhor e mais segura resposta. Então, obviamente, a tabela syscall de aarch64 não tem buracos até 163. Você sabe como são as outras tabelas de arquitetura?

E temos certeza de que uma árvore binária de 24 ou mais syscalls testa totalmente o código? (Provavelmente mais uma pergunta para mim do que para você.) Meu pressentimento é sim, mas eu gostaria de dar uma olhada e repassar também os macacões.

Sim, acho que é provavelmente a melhor e mais segura resposta. Então, obviamente, a tabela syscall de aarch64 não tem buracos até 163. Você sabe como são as outras tabelas de arquitetura?

Se ao menos tivéssemos uma tabela pré-construída de arquiteturas de escala ... oh, espere, temos! ;)

Exemplo usando aarch64, classificado pelo número da syscall:

# ./src/arch-syscall-dump -a aarch64 | sort -k2 -n

E temos certeza de que uma árvore binária de 24 ou mais syscalls testa totalmente o código? (Provavelmente mais uma pergunta para mim do que para você.) Meu pressentimento é sim, mas eu gostaria de dar uma olhada e repassar também os macacões.

Um teste que não é confiável, independentemente do seu nível de abrangência, não é útil. Eu prefiro ter um teste "bom o suficiente" que seja sempre consistente, em todos os lugares em que for executado, sempre que for executado, que possamos desenvolver posteriormente.

Se ao menos tivéssemos uma tabela pré-construída de arquiteturas de escala ... oh, espere, temos! ;)

Tive a sensação de que havia uma ferramenta para isso. Obrigado ;)

Um teste que não é confiável, independentemente do seu nível de abrangência, não é útil.

Concordaram. Fiquei ganancioso e pensei que poderia criar o home run dos testes. Bem, um teste "bom o suficiente" neste caso deve ser suficiente. Vou trabalhar nisso hoje.

Fiquei ganancioso e pensei que poderia criar o home run dos testes. Bem, um teste "bom o suficiente" neste caso deve ser suficiente. Vou trabalhar nisso hoje.

Ei, não se preocupe, todos nós caímos nessa armadilha de vez em quando. Ainda é uma boa melhoria e temos pelo menos um teste básico; isso poderia ser muito pior :)

FWIW, ele falha no ppc64 também:

nome do lote: 53-sim-binary_tree
modo de teste: c
tipo de teste: bpf-sim
Resultado do teste 53-sim-binary_tree %% 001-00001: ERROR 53-sim-binary_tree rc = 14
Resultado do teste 53-sim-binary_tree %% 002-00001: ERROR 53-sim-binary_tree rc = 14
Resultado do teste 53-sim-binary_tree %% 003-00001: ERROR 53-sim-binary_tree rc = 14
Resultado do teste 53-sim-binary_tree %% 004-00001: ERROR 53-sim-binary_tree rc = 14
Teste 53-sim-binary_tree %% 005-00001 resultado: ERROR 53-sim-binary_tree rc = 14
Teste 53-sim-binary_tree %% 006-00001 resultado: ERROR 53-sim-binary_tree rc = 14
Resultado do teste 53-sim-binary_tree %% 007-00001: ERROR 53-sim-binary_tree rc = 14
Resultado do teste 53-sim-binary_tree %% 008-00001: ERROR 53-sim-binary_tree rc = 14
Resultado do teste 53-sim-binary_tree %% 009-00001: ERROR 53-sim-binary_tree rc = 14
Resultado do teste 53-sim-binary_tree %% 010-00001: ERROR 53-sim-binary_tree rc = 14
...
modo de teste: c
tipo de teste: bpf-valgrind
Teste 53-sim-binary_tree %% 331-00001 resultado: FALHA 53-sim-binary_tree rc = 14

E 55-basic-pfc_binary_tree também:

nome do lote: 55-basic-pfc_binary_tree
modo de teste: c
tipo de teste: básico
Resultado do teste 55-basic-pfc_binary_tree %% 001-00001: FALHA 55-basic-pfc_binary_tree.sh rc = 1

Olá @ piso77 , obrigado pelo relatório. Depois que @drakenclimber tiver uma correção, você estaria disposto a testá-la?

Infelizmente, imagino que pode haver alguns outros ABIs que apresentam falhas semelhantes; é simplesmente que aarch64 é a única ABI não x86 à qual tenho fácil acesso para fins de teste. A correção que discutimos neste tópico deve abordar todas essas falhas (eu acho).

Eu escrevi um script python rápido para encontrar o primeiro buraco em cada arquitetura.

Aqui estão os resultados:

$ ./find-first-hole-in-each-arch.py 
aarch64's first syscall number hole is 163
arm's first syscall number hole is 7
mips64's first syscall number hole is 1
mips64n32's first syscall number hole is 1
mips's first syscall number hole is 1
parisc64's first syscall number hole is 102
ppc64's first syscall number hole is 192
ppc's first syscall number hole is 224
riscv64's first syscall number hole is 38
s390's first syscall number hole is 17
s390x's first syscall number hole is 13
x32's first syscall number hole is 1
x86_64's first syscall number hole is 335

Com base nesses resultados, acho que devemos diminuir os testes 53 e 55 para limitar o syscall número 12. Observe que existem algumas arquiteturas (mips, etc.) que irão falhar independentemente do número que escolhemos.

Olá @ piso77 , obrigado pelo relatório. Depois que @drakenclimber tiver uma correção, você estaria disposto a testá-la?

Claro, envie um ping quando houver um patch disponível!

Observe que existem algumas arquiteturas (mips, etc.) que falharão independentemente do número que escolhermos.

Como você planeja resolver isso?

Observe que existem algumas arquiteturas (mips, etc.) que falharão independentemente do número que escolhermos.

Como você planeja resolver isso?

Eu estava pensando em verificar a arquitetura nativa e, se ela fosse compatível com arm, mips * ou x32, ignoraríamos os testes. Não é bonito, mas não vejo uma maneira fácil de testar a árvore binária nesses sistemas.

Eu estava pensando em verificar a arquitetura nativa e, se ela fosse compatível com arm, mips * ou x32, ignoraríamos os testes. Não é bonito, mas não vejo uma maneira fácil de testar a árvore binária nesses sistemas.

Se vamos ignorar os ABIs com base nisso, podemos também limitá-lo a apenas x86_64. O que é muito ruim. Não tenho certeza se temos precedência com qualquer um dos outros testes, mas estou começando a pensar que a maneira certa de consertar isso é usar uma lista de nomes de syscall e não números. É um pouco mais trabalhoso no teste, mas provavelmente deve evitar isso completamente.

NOTA: as syscalls não precisam ser válidas para aquela ABI em particular, desde que sejam nomes de syscall válidos em nossa tabela syscall interna.

Não tenho certeza se temos precedência com qualquer um dos outros testes

Eu acredito que você está correto. Esta é uma situação especial.

Estou começando a pensar que a maneira certa de consertar isso é usar uma lista de nomes de syscall e não de números. É um pouco mais trabalhoso no teste, mas provavelmente deve evitar isso completamente.

Estou bem com essa escolha. Ainda não tenho certeza de como posso fazer isso funcionar no caso do pfc (teste 55), mas vou tentar!

Isso foi corrigido no PR # 211 e uma correção de acompanhamento que hackeamos juntos (sem PR) via dc2831e8fdcad71d565ba02abf732c8ffd260f66.

Esta página foi útil?
0 / 5 - 0 avaliações