
Análise e mitigação da vulnerabilidade Copy Fail (CVE-2026-31431) do kernel Linux, que explora a mutação do cache de páginas via AF_ALG/splice, com verificador de PoC, regras de detecção do auditd e verificação de atualização do kernel.
Este projeto é um miniprojeto que analisa o princípio de funcionamento da vulnerabilidade Copy Fail (CVE-2026-31431) do Linux Kernel e compara o estado antes e depois do patch usando o checker não destrutivo do repositório PoC público.
Não executa exploits reais de modificação de binário setuid ou de /etc/passwd; o foco está na verificação segura da vulnerabilidade com base em um testfile temporário e na análise sob a perspectiva de detecção/mitigação.
O objetivo deste projeto não é simplesmente executar um exploit, mas entender a combinação de estruturas internas que originam a vulnerabilidade do kernel Linux e documentar como identificá-la e respondê-la do ponto de vista operacional.
O escopo do trabalho é o seguinte:
취약점 원리 분석
↓
PoC 코드 구조 분석
↓
비파괴 checker 기반 실습
↓
패치 전후 비교
↓
탐지/완화 방안 정리
Nesta prática, apenas o vulnerable.c do repositório copy-fail-c foi executado.
| Item | Antes do patch | Depois do patch |
|---|---|---|
| OS | Ubuntu 24.04.2 LTS | Ubuntu 24.04.4 LTS |
| Kernel | 6.8.0-53-generic | 6.8.0-134-generic |
| Conta | usuário comum client | usuário comum client |
| checker | vulnerable | vulnerable |
| Método de teste | verificação não destrutiva com base em testfile temporário | re-execução do mesmo checker |
Informações do kernel antes do patch:
Linux ubuntu-server 6.8.0-53-generic #55-Ubuntu SMP PREEMPT_DYNAMIC Fri Jan 17 15:37:52 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Informações do kernel depois do patch:
Linux ubuntu-server 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 26 18:43:11 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Resumo das alterações dos pacotes do kernel:
- linux-image-6.8.0-53-generic 6.8.0-53.55
- linux-image-generic 6.8.0-53.55+1
+ linux-image-6.8.0-134-generic 6.8.0-134.134
+ linux-image-generic 6.8.0-134.134
+ linux-generic 6.8.0-134.134
+ linux-headers-generic 6.8.0-134.134
Copy Fail é uma vulnerabilidade em que o page cache de arquivos somente leitura pode ser usado como alvo de escrita indevida, quando o caminho de processamento AEAD do AF_ALG do kernel Linux se combina com o comportamento zero-copy do splice().
Os componentes centrais são os seguintes:
| Elemento | Função |
|---|---|
| Linux page cache | Mecanismo do kernel que armazena o conteúdo de arquivos em disco na RAM |
splice() | Chamada de sistema zero-copy que encadeia dados por referência dentro do kernel, sem copiá-los para o espaço do usuário |
AF_ALG | Interface que permite usar a crypto API do kernel Linux como um socket no espaço do usuário |
| Processamento AEAD in-place | Otimização que processa o buffer de entrada e o de saída no mesmo buffer, sem separá-los |
authencesn | Template de crypto no qual ocorre uma escrita scratch de 4 bytes durante o processamento AEAD |
O fluxo central da vulnerabilidade é o seguinte:
읽기 가능한 파일
↓
Linux page cache에 올라감
↓
splice()로 AF_ALG crypto 경로에 page cache reference 전달
↓
AEAD in-place 처리로 입력과 출력 scatterlist가 엮임
↓
authencesn 처리 중 4바이트 scratch write 발생
↓
별도 출력 버퍼가 아니라 page cache에 쓰기 발생
↓
page cache mutation 발생
Ou seja, splice() entrega a referência do page cache, o processamento AEAD in-place entrelaça entrada e saída no mesmo caminho, e authencesn é o que efetivamente realiza a escrita de 4 bytes.
A estrutura do repositório usado na prática é a seguinte:
copy-fail-c/
├── exploit.c
├── exploit-passwd.c
├── vulnerable.c
├── payload.c
├── utils.c
├── utils.h
├── Makefile
└── nolibc/
| Arquivo | Função | Uso nesta prática |
|---|---|---|
utils.c, utils.h | Implementação da primitive de mutation do page cache baseada em AF_ALG/splice | Usado na análise e execução do vulnerable |
vulnerable.c | Ferramenta de verificação não destrutiva da vulnerabilidade baseada em testfile temporário | Executado |
exploit.c | Variante de modificação do page cache de binário setuid root | Não executado |
exploit-passwd.c | Variante de modificação do page cache de /etc/passwd | Não executado |
payload.c | Payload executado com privilégios root | Não executado |
Makefile | Automação de build | Apenas o target vulnerable é usado |
nolibc/ | Código substituto de libc leve para construir pequenos payloads ELF estáticos | Apenas análise |
utils.cO núcleo de utils.c é a primitive de mutation do page cache da família patch_chunk(). Essa função conecta o page cache do arquivo alvo ao caminho de processamento de crypto usando AF_ALG e splice(), e verifica se, em kernels vulneráveis, parte do page cache é sobrescrita durante o processamento AEAD.
vulnerable.cvulnerable.c não toca em arquivos reais do sistema. Ele cria um testfile temporário no diretório atual e verifica se o page cache desse arquivo é modificado.
Neste projeto, apenas esse arquivo foi executado.
Antes de realizar a atualização do kernel, foram registrados o OS, o kernel e o estado dos pacotes.
mkdir -p ~/copyfail-mini/{before,after,logs}
cd ~/copyfail-mini
uname -a | tee before/uname.txt
cat /etc/os-release | tee before/os-release.txt
dpkg -l | grep -E 'linux-image|linux-headers|linux-generic|linux-virtual' | tee before/kernel-package.txt
git clone https://github.com/jihwan77/copy-fail-c.git
cd copy-fail-c
make clean
make vulnerable
Nesta prática, os binários de exploit não foram compilados junto com o make padrão; apenas o target vulnerable foi usado.
./vulnerable > ../before/vulnerable-output.txt 2>&1
echo $? >> ../before/vulnerable-output.txt
cat ../before/vulnerable-output.txt
Resultado da execução antes do patch:

Análise:
exit code 100
→ page cache mutation 확인
→ 패치 전 커널에서 Copy Fail primitive 동작 확인
Após salvar os resultados antes do patch, foi realizada a atualização dos pacotes do Ubuntu.
sudo apt update
sudo apt full-upgrade -y
sudo reboot
Após a reinicialização, o kernel foi alterado da seguinte forma:
Before: 6.8.0-53-generic
After : 6.8.0-134-generic
cd ~/copyfail-mini/copy-fail-c
make clean
make vulnerable
./vulnerable > ../after/vulnerable-output.txt 2>&1
echo "exit_code=$?" >> ../after/vulnerable-output.txt
cat ../after/vulnerable-output.txt
Resultado da execução depois do patch:

Comparação de resultados:
| Item | Antes do patch | Depois do patch |
|---|---|---|
| Kernel | 6.8.0-53-generic | 6.8.0-134-generic |
| Resultado do checker | VULNERABLE | authencesn template not registered |
| Exit Code | 100 | 2 |
| Mutação do page cache | Confirmada | o checker não avançou até a etapa de mutation |
| Interpretação | A primitive do Copy Fail funcionou | Falha ao entrar no caminho AEAD/authencesn exigido pelo PoC |
O exit_code=2 após o patch não significa simplesmente "não vulnerável". Precisamente, é o seguinte:
AF_ALG의 authencesn(hmac(sha256),cbc(aes)) template이 등록되어 있지 않아,
checker가 취약 여부를 직접 판정하지 못한 상태
Investigações adicionais revelaram que, após a atualização do Ubuntu, o carregamento do módulo algif_aead estava bloqueado.
lsmod | grep -E 'af_alg|algif_aead'
Resultado:
af_alg 32768 0
O módulo algif_aead não estava carregado.
sudo modprobe algif_aead
Resultado:
modprobe: ERROR: ../libkmod/libkmod-module.c:1084 command_do() Error running install command '/bin/false' for module algif_aead: retcode 1
modprobe: ERROR: could not insert 'algif_aead': Invalid argument
Verificação da configuração de bloqueio:
grep -R "algif_aead" /etc/modprobe.d /lib/modprobe.d 2>/dev/null
Resultado:
/etc/modprobe.d/disable-algif_aead.conf:# Disable algif_aead module due to CVE-2026-31431 (AKA copy.fail)
/etc/modprobe.d/disable-algif_aead.conf:install algif_aead /bin/false
Portanto, é correto interpretar o resultado após o patch da seguinte forma:
Ubuntu 보안 업데이트 이후 커널이 6.8.0-134-generic으로 변경되었고,
kmod 기반 algif_aead 모듈 차단 완화가 적용되었습니다.
그 결과 copy-fail-c의 vulnerable checker는
PoC가 요구하는 authencesn(hmac(sha256),cbc(aes)) AF_ALG template에 bind하지 못했고,
page cache mutation 단계까지 진행되지 않았습니다.
Ou seja, o que esta prática confirmou não é apenas o "efeito do patch no código do kernel", mas o estado em que, após a atualização de segurança do Ubuntu, a atualização do kernel e a mitigação via bloqueio do módulo algif_aead foram aplicadas, de modo que o mesmo caminho do PoC não prossegue.
Como o Copy Fail pode modificar o page cache sem alterar diretamente o arquivo em disco, a detecção baseada apenas em hash de arquivos tem limitações. Por isso, a detecção baseada no comportamento de syscalls é importante.
Nesta prática, os seguintes syscalls foram observados usando auditd:
sudo auditctl -a always,exit -F arch=b64 -S socket -F a0=38 -k copyfail_afalg
sudo auditctl -a always,exit -F arch=b64 -S bind -k copyfail_bind
sudo auditctl -a always,exit -F arch=b64 -S splice -k copyfail_splice
sudo auditctl -a always,exit -F arch=b64 -S sendmsg -k copyfail_sendmsg
socket(AF_ALG)Nos logs, foi confirmado que o processo vulnerable criou um socket AF_ALG.
comm=vulnerable
syscall=socket
success=yes
a0=alg
key=copyfail_afalg
bind()No ambiente após o patch/mitigação, o processo vulnerable tentou fazer bind ao template authencesn, mas falhou.
comm=vulnerable
syscall=bind
success=no
exit=ENOENT(No such file or directory)
saddr_fam=alg
key=copyfail_bind
Isso significa que, no ambiente pós-patch, o PoC chegou a criar o socket AF_ALG, mas falhou na etapa de bind ao template authencesn(hmac(sha256),cbc(aes)).
splice() / sendmsg()Após o patch, como a etapa de bind() falhou, o checker não conseguiu avançar até as etapas de splice() e sendmsg(). Portanto, o fluxo de execução do vulnerable não foi observado de forma relevante nos logs desses syscalls.
Em ambientes de produção, ao observar vulnerabilidades da classe Copy Fail, é possível ver a seguinte combinação de comportamentos:
| Alvo de detecção | Significado |
|---|---|
socket(AF_ALG, ...) | Tentativa de uso da crypto API do kernel |
bind() com authencesn | Tentativa de uso do template de crypto AEAD/authencesn |
splice() | Transferência da referência do page cache do arquivo para o caminho interno do kernel |
sendmsg() / recvmsg() | Execução de requisição de crypto via AF_ALG |
| Execução de binário setuid | Possibilidade de cashout via escalonamento de privilégios |
Nesta prática, o evento socket(AF_ALG) e a falha de bind() foram confirmados via auditd.
A medida mais básica é aplicar as atualizações de segurança da distribuição.
sudo apt update
sudo apt full-upgrade -y
sudo reboot
Nesta prática, após a atualização, o ambiente foi alterado para Ubuntu 24.04.4 / kernel 6.8.0-134-generic.
algif_aeadApós a atualização do Ubuntu, a seguinte configuração foi confirmada:
/etc/modprobe.d/disable-algif_aead.conf
install algif_aead /bin/false
Essa configuração bloqueia o carregamento do módulo algif_aead, impedindo a entrada no caminho AF_ALG AEAD exigido pelo PoC.
Como não é comum aplicações de servidor típicas usarem AF_ALG diretamente, chamadas a socket(AF_ALG) podem ser usadas como ponto de detecção.
Os resultados desta prática podem ser resumidos da seguinte forma:
패치 전:
Ubuntu 24.04.2 / kernel 6.8.0-53-generic
vulnerable checker exit code 100
page cache mutation 확인
→ Copy Fail primitive 동작 확인
패치 후:
Ubuntu 24.04.4 / kernel 6.8.0-134-generic
vulnerable checker exit code 2
authencesn template bind 실패
algif_aead 모듈 차단 설정 확인
→ 동일 PoC 경로가 page cache mutation 단계까지 진행되지 않음
Portanto, a conclusão deste projeto é a seguinte:
No kernel anterior ao patch, a primitive de mutation do page cache do Copy Fail realmente funcionou.
Em seguida, ao aplicar a atualização de segurança do Ubuntu, o kernel foi alterado para6.8.0-134-generice foi aplicada uma configuração de bloqueio do móduloalgif_aead, aparentemente baseada emkmod.
Como resultado, o checker não conseguiu fazer bind ao template AF_ALGauthencesn(hmac(sha256),cbc(aes))exigido pelo PoC e, portanto, não avançou até a etapa de mutation do page cache.
Ou seja, com base nos resultados desta prática, não se pode afirmar que "o patch no código do kernel bloqueou diretamente a mutation do page cache", mas o que se pode afirmar com certeza a partir dos logs e resultados até o momento é que após a atualização de segurança do Ubuntu, a mitigação via bloqueio do módulo algif_aead foi aplicada, bloqueando o caminho do PoC.
Ubuntu Security Notice - USN-8226-1: atualização do kmod
https://ubuntu.com/security/notices/USN-8226-1
Ubuntu Blog - Correções disponíveis para o CVE-2026-31431 Copy Fail
https://ubuntu.com/blog/copy-fail-vulnerability-fixes-available
Repositório PoC copy-fail-c
https://github.com/jihwan77/copy-fail-c
O essencial confirmado neste projeto é o seguinte:
1. Copy Fail은 AF_ALG, splice(), AEAD in-place, authencesn, page cache가 결합된 커널 취약점이다.
2. 패치 전 Ubuntu 24.04.2 / kernel 6.8.0-53 환경에서 비파괴 checker가 page cache mutation을 확인했다.
3. 패치 후 Ubuntu 24.04.4 / kernel 6.8.0-134 환경에서는 authencesn bind 단계에서 실패했다.
4. 추가 확인 결과 algif_aead 모듈 로드가 /bin/false 설정으로 차단되어 있었다.
5. auditd를 통해 socket(AF_ALG) 및 bind 실패 이벤트를 관찰할 수 있었다.
6. 운영 대응은 커널/보안 패키지 업데이트, algif_aead 제한, AF_ALG syscall 모니터링, setuid 바이너리 점검으로 정리할 수 있다.