Linux KernelにeBPF周りの複数の脆弱性(CVE-2017-17862, CVE-2017-17863, CVE-2017-17864)
こんにちは。SIOS OSSエバンジェリスト/セキュリティ担当の面 和毅です。
12/24/2017にLinux KernelにeBPF周りの複数の脆弱性情報(CVE-2017-17862, CVE-2017-17863, CVE-2017-17864)が公開されています。今回はこの脆弱性の概要と、各ディストリビューションの対応について簡単にまとめてみます。
修正方法
各ディストリビューションの情報を確認してください。
CVE概要(詳細はCVEのサイトをご確認ください)
- http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-17862
ローカルユーザによるDoSの可能性
Linux Kernel 4.14.8以前のkernel/bpf/verifier.cでは、JITコンパイラによって処理されているにも関わらず到達不能なコードを無視しています。ローカルユーザはこれを悪用してDoSを引き起こす事が出来る可能性があります。
素のカーネルでは、この修正のために、sanitize_dead_code()が導入されています。
+/* The verifier does more data flow analysis than llvm and will not explore + * branches that are dead at run time. Malicious programs can have dead code + * too. Therefore replace all dead at-run-time code with nops. + */ +static void sanitize_dead_code(struct bpf_verifier_env *env) +{ + struct bpf_insn_aux_data *aux_data = env->insn_aux_data; + struct bpf_insn nop = BPF_MOV64_REG(BPF_REG_0, BPF_REG_0); + struct bpf_insn *insn = env->prog->insnsi; + const int insn_cnt = env->prog->len; + int i; + + for (i = 0; i < insn_cnt; i++) { + if (aux_data[i].seen) + continue; + memcpy(insn + i, &nop;, sizeof(nop)); + } +}
- http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-17863
ローカルユーザによるDoS(整数オーバーフロー、または不正なメモリアクセス)の可能性
Linux Kernel 4.9.71までの4.9.x系では、kernel/bpf/verifier.c で BPF stackとポインタの値の関係をチェックしていませんでした。ローカルのユーザはこれを悪用して、DoS(整数オーバーフロー、または不正なメモリアクセス)を引き起こす事が出来る可能性があります。
素のカーネルでは修正はcheck_alu_op()関数に対して
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 2f19c94..b03af36 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1861,10 +1861,28 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) ((BPF_SRC(insn->code) == BPF_X && regs[insn->src_reg].type == CONST_IMM) || BPF_SRC(insn->code) == BPF_K)) { - if (BPF_SRC(insn->code) == BPF_X) + if (BPF_SRC(insn->code) == BPF_X) { + /* check in case the register contains a big + * 64-bit value + */ --省略--
のように施されています。
- http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-17864
ローカルユーザによる機密情報読み出しの可能性
Linux Kernel 4.14.8以前では、kernel/bpf/verifier.c でUNKNOWN_VALUEデータタイプとpointerのデータタイプの states_equal比較演算のところで誤った扱いがあったため、ローカルのユーザはこれを悪用して機密情報を読み出すことが可能です(”pointerリーク”の可能性です)。
この修正は、素のカーネルではkernel/bpf/verifier.cのstatic bool states_equal()に対して
--- --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2722,11 +2722,12 @@ static bool states_equal(struct bpf_veri /* If we didn't map access then again we don't care about the * mismatched range values and it's ok if our old type was - * UNKNOWN and we didn't go to a NOT_INIT'ed reg. + * UNKNOWN and we didn't go to a NOT_INIT'ed or pointer reg. */ if (rold->type == NOT_INIT || (!varlen_map_access && rold->type == UNKNOWN_VALUE && - rcur->type != NOT_INIT)) + rcur->type != NOT_INIT && + !__is_pointer_value(env->allow_ptr_leaks, rcur))) continue; /* Don't care about the reg->id in this case. */
のように施されています。
主なディストリビューションの対応方法
詳細は、各ディストリビューションの提供元にご確認ください
Debian
https://security-tracker.debian.org/tracker/CVE-2017-17862
Red Hat Enterprise Linux/CentOS
Ubuntu
SUSE/openSUSE
対処方法
各ディストリビューションの案内に従い、アップデートを行ってください。全てのRed Hat製品でパッチが行き渡っているかを確認するには、Red Hat Satelliteを使うと管理が便利でしょう。
Red Hat Satelliteを用いた一般的なErattaの適用は、『Red Hat Satellite 6でerrataを適用してみる』を
参考にして下さい。
また、OSの再起動が発生しますので、pacemakerなどOSSのクラスタ製品やLifeKeeperなどの商用のクラスタリング製品を使うとサービス断の時間を最小限にすることが出来ます。
[参考]
bpf: reject out-of-bounds stack pointer calculation
セキュリティ系連載案内
OSSセキュリティ技術の会による日経Linuxでの連載「IoT時代の最新SELinux入門」がITPro上で読めるようになりました。技術の会代表で第一人者である中村さん等による、最新のSELinuxの情報やコマンド類等も更新されているのでお薦めです。
OSSセキュリティ技術の会によるThinkITでの連載「開発者のためのセキュリティ実践講座」がThinkIT上で開始しました。技術の会の中の人間で、最新の代表的なOSSセキュリティ技術を紹介していきます。
OSSセキュリティ技術の会により、ThinkITでLinuxSecuritySummit 2017のレポートが紹介されています。