Linux Kernelの脆弱性(CVE-2018-1000200)


こちらのサイトはoss.sios.com/securityの引越し先が整理される前の仮の場所になります。



05/01/2018にLinux Kernelの脆弱性情報(CVE-2018-1000200)が公開されています。今回はこの脆弱性の概要と、各ディストリビューションの対応について簡単にまとめてみます。


こちらのサイトはoss.sios.comの引越し先が整理される前の仮の場所になります。

こんにちは。SIOS OSSエバンジェリスト/セキュリティ担当の面 和毅です。

05/01/2018にLinux Kernelの脆弱性情報(CVE-2018-1000200)が公開されています。今回はこの脆弱性の概要と、各ディストリビューションの対応について簡単にまとめてみます。



Priority

Moderate

修正方法

各ディストリビューションの情報を確認してください。

CVE概要(詳細はCVEのサイトをご確認ください)

  • http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1000200
    • ローカルユーザによるDoSの可能性

    • 重要度 – Moderate

    • 4.14-4.16のLinux Kernelで、out of memory(oom)で大きな範囲のメモリをmlockして使用しているプロセスをkillする際に、NULLポインタ非参照が発生することによりDoSが発生する可能性があります。

      4.17-rc5での修正は以下のようになります。

      diff --git a/mm/mmap.c b/mm/mmap.c
      index 9d5968d..d683656 100644
      --- a/mm/mmap.c
      +++ b/mm/mmap.c
      @@ -3024,6 +3024,32 @@ void exit_mmap(struct mm_struct *mm)
       	/* mm's last user has gone, and its about to be pulled down */
       	mmu_notifier_release(mm);
       
      +	if (unlikely(mm_is_oom_victim(mm))) {
      +		/*
      +		 * Manually reap the mm to free as much memory as possible.
      +		 * Then, as the oom reaper does, set MMF_OOM_SKIP to disregard
      +		 * this mm from further consideration.  Taking mm->mmap_sem for
      +		 * write after setting MMF_OOM_SKIP will guarantee that the oom
      +		 * reaper will not run on this mm again after mmap_sem is
      +		 * dropped.
      +		 *
      +		 * Nothing can be holding mm->mmap_sem here and the above call
      +		 * to mmu_notifier_release(mm) ensures mmu notifier callbacks in
      +		 * __oom_reap_task_mm() will not block.
      +		 *
      +		 * This needs to be done before calling munlock_vma_pages_all(),
      +		 * which clears VM_LOCKED, otherwise the oom reaper cannot
      +		 * reliably test it.
      +		 */
      +		mutex_lock(&oom_lock);
      +		__oom_reap_task_mm(mm);
      +		mutex_unlock(&oom_lock);
      +
      +		set_bit(MMF_OOM_SKIP, &mm->flags);
      +		down_write(&mm->mmap_sem);
      +		up_write(&mm->mmap_sem);
      +	}
      +
       	if (mm->locked_vm) {
       		vma = mm->mmap;
       		while (vma) {
      @@ -3045,24 +3071,6 @@ void exit_mmap(struct mm_struct *mm)
       	/* update_hiwater_rss(mm) here? but nobody should be looking */
       	/* Use -1 here to ensure all VMAs in the mm are unmapped */
       	unmap_vmas(&tlb, vma, 0, -1);
      -
      -	if (unlikely(mm_is_oom_victim(mm))) {
      -		/*
      -		 * Wait for oom_reap_task() to stop working on this
      -		 * mm. Because MMF_OOM_SKIP is already set before
      -		 * calling down_read(), oom_reap_task() will not run
      -		 * on this "mm" post up_write().
      -		 *
      -		 * mm_is_oom_victim() cannot be set from under us
      -		 * either because victim->mm is already set to NULL
      -		 * under task_lock before calling mmput and oom_mm is
      -		 * set not NULL by the OOM killer only if victim->mm
      -		 * is found not NULL while holding the task_lock.
      -		 */
      -		set_bit(MMF_OOM_SKIP, &mm->flags);
      -		down_write(&mm->mmap_sem);
      -		up_write(&mm->mmap_sem);
      -	}
       	free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING);
       	tlb_finish_mmu(&tlb, 0, -1);
       
      diff --git a/mm/oom_kill.c b/mm/oom_kill.c
      index ff992fa..8ba6cb8 100644
      --- a/mm/oom_kill.c
      +++ b/mm/oom_kill.c
      @@ -469,7 +469,6 @@ bool process_shares_mm(struct task_struct *p, struct mm_struct *mm)
       	return false;
       }
       
      -
       #ifdef CONFIG_MMU
       /*
        * OOM Reaper kernel thread which tries to reap the memory used by the OOM
      @@ -480,16 +479,54 @@ static DECLARE_WAIT_QUEUE_HEAD(oom_reaper_wait);
       static struct task_struct *oom_reaper_list;
       static DEFINE_SPINLOCK(oom_reaper_lock);
       
      -static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm)
      +void __oom_reap_task_mm(struct mm_struct *mm)
       {
      -	struct mmu_gather tlb;
       	struct vm_area_struct *vma;
      +
      +	/*
      +	 * Tell all users of get_user/copy_from_user etc... that the content
      +	 * is no longer stable. No barriers really needed because unmapping
      +	 * should imply barriers already and the reader would hit a page fault
      +	 * if it stumbled over a reaped memory.
      +	 */
      +	set_bit(MMF_UNSTABLE, &mm->flags);
      +
      +	for (vma = mm->mmap ; vma; vma = vma->vm_next) {
      +		if (!can_madv_dontneed_vma(vma))
      +			continue;
      +
      +		/*
      +		 * Only anonymous pages have a good chance to be dropped
      +		 * without additional steps which we cannot afford as we
      +		 * are OOM already.
      +		 *
      +		 * We do not even care about fs backed pages because all
      +		 * which are reclaimable have already been reclaimed and
      +		 * we do not want to block exit_mmap by keeping mm ref
      +		 * count elevated without a good reason.
      +		 */
      +		if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) {
      +			const unsigned long start = vma->vm_start;
      +			const unsigned long end = vma->vm_end;
      +			struct mmu_gather tlb;
      +
      +			tlb_gather_mmu(&tlb, mm, start, end);
      +			mmu_notifier_invalidate_range_start(mm, start, end);
      +			unmap_page_range(&tlb, vma, start, end, NULL);
      +			mmu_notifier_invalidate_range_end(mm, start, end);
      +			tlb_finish_mmu(&tlb, start, end);
      +		}
      +	}
      +}
      +
      +static bool oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm)
      +{
       	bool ret = true;
       
       	/*
       	 * We have to make sure to not race with the victim exit path
       	 * and cause premature new oom victim selection:
      -	 * __oom_reap_task_mm		exit_mm
      +	 * oom_reap_task_mm		exit_mm
       	 *   mmget_not_zero
       	 *				  mmput
       	 *				    atomic_dec_and_test
      @@ -534,39 +571,8 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm)
       
       	trace_start_task_reaping(tsk->pid);
       
      -	/*
      -	 * Tell all users of get_user/copy_from_user etc... that the content
      -	 * is no longer stable. No barriers really needed because unmapping
      -	 * should imply barriers already and the reader would hit a page fault
      -	 * if it stumbled over a reaped memory.
      -	 */
      -	set_bit(MMF_UNSTABLE, &mm->flags);
      -
      -	for (vma = mm->mmap ; vma; vma = vma->vm_next) {
      -		if (!can_madv_dontneed_vma(vma))
      -			continue;
      +	__oom_reap_task_mm(mm);
       
      -		/*
      -		 * Only anonymous pages have a good chance to be dropped
      -		 * without additional steps which we cannot afford as we
      -		 * are OOM already.
      -		 *
      -		 * We do not even care about fs backed pages because all
      -		 * which are reclaimable have already been reclaimed and
      -		 * we do not want to block exit_mmap by keeping mm ref
      -		 * count elevated without a good reason.
      -		 */
      -		if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) {
      -			const unsigned long start = vma->vm_start;
      -			const unsigned long end = vma->vm_end;
      -
      -			tlb_gather_mmu(&tlb, mm, start, end);
      -			mmu_notifier_invalidate_range_start(mm, start, end);
      -			unmap_page_range(&tlb, vma, start, end, NULL);
      -			mmu_notifier_invalidate_range_end(mm, start, end);
      -			tlb_finish_mmu(&tlb, start, end);
      -		}
      -	}
       	pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
       			task_pid_nr(tsk), tsk->comm,
       			K(get_mm_counter(mm, MM_ANONPAGES)),
      @@ -587,14 +593,13 @@ static void oom_reap_task(struct task_struct *tsk)
       	struct mm_struct *mm = tsk->signal->oom_mm;
       
       	/* Retry the down_read_trylock(mmap_sem) a few times */
      -	while (attempts++ < MAX_OOM_REAP_RETRIES && !__oom_reap_task_mm(tsk, mm))
      +	while (attempts++ < MAX_OOM_REAP_RETRIES && !oom_reap_task_mm(tsk, mm))
       		schedule_timeout_idle(HZ/10);
       
       	if (attempts <= MAX_OOM_REAP_RETRIES ||
       	    test_bit(MMF_OOM_SKIP, &mm->flags))
       		goto done;
       
      -
       	pr_info("oom_reaper: unable to reap pid:%d (%s)\n",
       		task_pid_nr(tsk), tsk->comm);
       	debug_show_all_locks();
      

主なディストリビューションの対応方法

詳細は、各ディストリビューションの提供元にご確認ください


対処方法

各ディストリビューションの案内に従い、アップデートを行ってください。全てのRed Hat製品でパッチが行き渡っているかを確認するには、Red Hat SatelliteやKatello、Spacewalk等を使うと管理が便利でしょう。

また、OSの再起動が発生しますので、peacemakerなどOSSのクラスタ製品を使うとサービス断の時間を最小限にすることが出来ます。

[参考]

http://seclists.org/oss-sec/2018/q2/67

セキュリティ系連載案内

OpenPGP, S/MIMEに関する各メールクライアントの脆弱性(EFAIL: CVE-2017-17688, CVE-2017-17689)


こちらのサイトはoss.sios.com/securityの引越し先が整理される前の仮の場所になります。



05/14/2018に”EFAIL”というend-to-endでのメール暗号化に関する一連の脆弱性情報( CVE-2017-17688: OpenPGP CFB gadget attacks , CVE-2017-17689: S/MIME CBC gadget attacks )が出ています。今回はこの脆弱性の概要と、各ディストリビューションの対応について簡単にまとめてみます。

5/15更新:Apple Mailでの例(Youtube)をリンクに加えました。メールクライアントは数が多いので一次情報源を確認してください。

5/15更新:元になった論文(PDF)を加えました。メールクライアントへのリンクとしてCERTを追加しました。


こんにちは。SIOS OSSエバンジェリスト/セキュリティ担当の面 和毅です。

05/14/2018に”EFAIL”というend-to-endでのメール暗号化に関する一連の脆弱性情報( CVE-2017-17688: OpenPGP CFB gadget attacks , CVE-2017-17689: S/MIME CBC gadget attacks )が出ています。今回はこの脆弱性の概要と、各ディストリビューションの対応について簡単にまとめてみます。

暗号化を用いる全てのメールクライアントに関わってくる脆弱性のため、情報は流動的です。情報は逐次更新します。



脆弱性概要

EFAILはOpenPGPやS/MIMEによりend-to-endで暗号化されたemailから平文が洩れるという脆弱性になります。

EFAILは外部から読み込まれた画像やスタイル等のHTMLメールのアクティブコンテンツを悪用して、要求されたURLを通じて平文を流出させます。攻撃者はまず、ネットワークトラフィックを盗聴したり、暗号化されたメールをサーバやクライアント等を侵害してアクセスする必要があります。

攻撃者は暗号化されたメールを特定の方法で変更し、変更した暗号化されたメールを攻撃対象に送信します。攻撃対象のメールクライアントは、メールを復号化して外部のコンテンツをロードし、平文を攻撃者に流出させます。

攻撃方法

この攻撃方法には2種類あります。

Direct Exfiltration(直接攻撃)

Direct Exfiltration(直接攻撃)では、Apple Mail, iOS Mail, Mozilla Thunderbirdの脆弱性を悪用して、暗号化されたメールの平文を直接抽出します。これらの脆弱性は、それぞれのメールクライアントに存在します。攻撃の詳しい方法は一次情報源(https://efail.de)に手順が載っています。

The CBC/CFB Gadget Attack(CBC/CFBガジェット攻撃)

CBC/CFBガジェット攻撃は、OpenPGPとS/MIMEの仕様の脆弱性を乱用してプレーンテキストを流出させるものになります。こちらも、S/MIMEでの攻撃の詳細な説明が一次情報源(https://efail.de)に手順が載っています。


関連するCVE

  • CVE-2017-17688: OpenPGP CFB gadget attacks

  • CVE-2017-17689: S/MIME CBC gadget attacks

対象となるメールクライアント

多くのメールクライアントが対象になっています。詳しくは一次情報源を確認してください。

こちら(https://www.kb.cert.org/vuls/id/122919)の方がメール一覧が見やすいです。

各ディストリビューションの情報を確認してください。



対処方法

各ディストリビューションの案内に従い、アップデートを行ってください。全てのRed Hat製品でパッチが行き渡っているかを確認するには、Red Hat Satelliteを使うと管理が便利でしょう。

[参考]

https://efail.de

セキュリティ系連載案内