Red Hat Enterprise Linux 7 互換OS向け CVE-2016-0728 対応手順(手抜き)

Red Hat 社のパッチを待てない子のための、CVE-2016-0728 対応手抜き手順。
※たぶんこの手順だと、正式な RPM が公開されたら、問題なく差し替わるはず。
※というか遅くとも一週間でパッチ出るはずだし、逆にもうしないほうがいいと思う。

■ビルド環境の準備
$ vi ~/.rpmmacros
※今回はマルチスレッドでビルドしても大丈夫なので %_smp_mflags はコメントアウトしておく。

%_topdir	%(echo $HOME)/rpmbuild
#%_smp_mflags	-j1
%__arch_install_post	/usr/lib/rpm/check-rpaths	/usr/lib/rpm/check-buildroot
%_tmpfilesdir	/usr/lib/tmpfiles.d

■Kernel の SourceRPM を取得してくる
$ mkdir -p ~/rpmbuild/SRPMS/
$ cd ~/rpmbuild/SRPMS/
$ yumdownloader –source kernel-`uname -r`

■SRPM の展開
$ rpm -ivh kernel-3.10.0-327.4.4.el7.src.rpm

■SOURCES ディレクトリに、[CVE-2016-0728] のパッチを配備
$ cd ~/rpmbuild/SOURCES/
$ vi fix-keyring-ref-leak.patch
※此処の表示をコピペしたらエラーします。↑のリンクをお持ち帰りください。

This fixes CVE-2016-0728.

If a thread is asked to join as a session keyring the keyring that's already
set as its session, we leak a keyring reference.

This can be tested with the following program:

	#include <stddef.h>
	#include <stdio.h>
	#include <sys/types.h>
	#include <keyutils.h>

	int main(int argc, const char *argv[])
	{
		int i = 0;
		key_serial_t serial;

		serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING,
				"leaked-keyring");
		if (serial < 0) {
			perror("keyctl");
			return -1;
		}

		if (keyctl(KEYCTL_SETPERM, serial,
			   KEY_POS_ALL | KEY_USR_ALL) < 0) {
			perror("keyctl");
			return -1;
		}

		for (i = 0; i < 100; i++) {
			serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING,
					"leaked-keyring");
			if (serial < 0) {
				perror("keyctl");
				return -1;
			}
		}

		return 0;
	}

If, after the program has run, there something like the following line in
/proc/keys:

3f3d898f I--Q---   100 perm 3f3f0000     0     0 keyring   leaked-keyring: empty

with a usage count of 100 * the number of times the program has been run,
then the kernel is malfunctioning.  If leaked-keyring has zero usages or
has been garbage collected, then the problem is fixed.

Reported-by: Yevgeny Pats <yevgeny@perception-point.io>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Don Zickus <dzickus@redhat.com>
Acked-by: Prarit Bhargava <prarit@redhat.com>
Acked-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: James Morris <james.l.morris@oracle.com>
---
  security/keys/process_keys.c | 1 +
  1 file changed, 1 insertion(+), 0 deletion(-)

diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index a3f85d2..e6d50172 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -794,6 +794,7 @@ long join_session_keyring(const char *name)
 		ret = PTR_ERR(keyring);
 		goto error2;
 	} else if (keyring == new->session_keyring) {
+		key_put(keyring);
 		ret = 0;
 		goto error2;
 	}

■SPEC にパッチを埋め込む
$ cd ~/rpmbuild/SPECS/
$ cp -piav kernel.spec kernel.spec.org
$ vi kernel.spec
※変更点いくつかあるので、Diffを載せてます。
※pkgrelease のバージョンを書き換えたいのですが、その変数がいろいろ使われてたり
 SOURCES ディレクトリにある linux-3.10.0-327.4.4.el7.tar.xz を指定するポインタにも
 なっているため、あえてそのままです。

--- kernel.spec.org     2016-01-05 23:47:17.000000000 +0900
+++ kernel.spec 2016-01-24 00:19:57.267724500 +0900
@@ -285,7 +285,7 @@ Group: System Environment/Kernel
 License: GPLv2
 URL: http://www.kernel.org/
 Version: %{rpmversion}
-Release: %{pkg_release}
+Release: %{pkg_release}.tsc
 # DO NOT CHANGE THE 'ExclusiveArch' LINE TO TEMPORARILY EXCLUDE AN ARCHITECTURE BUILD.
 # SET %%nobuildarches (ABOVE) INSTEAD
 ExclusiveArch: noarch i686 x86_64 ppc ppc64 ppc64le s390 s390x
@@ -392,6 +392,7 @@ Patch1006: cpufreq.patch
 Patch1007: addmissing.patch
 Patch1008: undorhirqstat.patch
 Patch1009: otherfixes.patch
+Patch2000: fix-keyring-ref-leak.patch

 BuildRoot: %{_tmppath}/kernel-%{KVRA}-root

@@ -710,6 +711,7 @@ ApplyOptionalPatch cpufreq.patch
 ApplyOptionalPatch addmissing.patch
 ApplyOptionalPatch undorhirqstat.patch
 ApplyOptionalPatch otherfixes.patch
+ApplyOptionalPatch fix-keyring-ref-leak.patch

 # Any further pre-build tree manipulations happen here.

@@ -1555,6 +1557,9 @@ fi
 %kernel_variant_files %{with_kdump} kdump

 %changelog
+* Wed Jan 20 2016 Makoto Satou <makopi sgv417 jp> - 3.10.0-327.4.4.el7.tsc
+- Fix keyring ref leak in join_session_keyring() (CVE-2016-0728)
+
 * Tue Jan 05 2016 Johnny Hughes <johnny@centos.org> - 3.10.0-327.4.4.el7
 - Roll in i686 Mods

■SourceRPM の作成
$ cd ~/rpmbuild/SPECS/
$ rpmbuild -bs –define ‘dist .el7.tsc’ kernel.spec
  →ここで「–define」で 「dist .el7.tsc」と入れることで、
   本当は .el7.tsc という文字列が、RPM に刻まれます。
   ただ、CentOS 7 (RHEL 7) の kernel.spec では、–define で dist 指定しても
   ハードコートされているため反映されません。
   そのため、kernel.spec 内の Release 部に、.tsc をハードコートをしてます。

   別に入れなくてもいいんですが、自前ビルドしたものがどれなのか明示的に分かる様に
   あえて入れております。
   SPECファイルのChangelog や define などで .tsc とつけてるのが、自分のサインです。

■Pre-Build の実行
$ rpmbuild -bp –define ‘dist .el7.tsc’ kernel.spec
  → error: Failed build dependencies が出た場合、
   それらをインストールしなければ、ビルドできません。
   また、【exit 0】で終了しない場合、何かがおかしいです。
    ・Patch Fileの内容
    ・SPEC の記述内容
   これらを確認。

■RPM のビルド
$ rpmbuild –rebuild –define ‘dist .el7.tsc’ ~/rpmbuild/SRPMS/kernel-3.10.0-327.4.4.el7.tsc.src.rpm
→ここで「–define」で(ry)

■ビルドした Kernel のインストール
$ su –
# cd ~admin/rpmbuild/RPMS/x86_64/
# yum localupdate ./*3.10.0-327.4.4.el7.tsc*

■念のため試験
<アップデート前>

$ uname -r
3.10.0-327.4.4.el7.x86_64

[admin@centos7 CVE-2016-0728]$ cat /proc/keys
0766e11e I--Q---     6 perm 3f030000  1000  1000 keyring   _ses: 1
183db236 I--Q---    11 perm 3f030000  1000  1000 keyring   _ses: 1
29602763 I--Q---     1 perm 1f3f0000  1000 65534 keyring   _uid_ses.1000: 1
32b1f11a I--Q---   100 perm 3f3f0000  1000  1000 keyring   leaked-keyring: empty
36734ec8 I--Q---     4 perm 1f3f0000  1000 65534 keyring   _uid.1000: empty

 →漏れ漏れ・д・

<アップデート後>

$ uname -r
3.10.0-327.4.4.el7.tsc.x86_64

$ cat /proc/keys
0701ea1e I--Q---     6 perm 3f030000  1000  1000 keyring   _ses: 1
13f0b966 I--Q---     4 perm 1f3f0000  1000 65534 keyring   _uid.1000: empty
30e6d5ee I--Q---    11 perm 3f030000  1000  1000 keyring   _ses: 1
3f4d1a84 I--Q---     1 perm 1f3f0000  1000 65534 keyring   _uid_ses.1000: 1

 →せふせふ・w・b

カテゴリー: めも パーマリンク

1 Response to Red Hat Enterprise Linux 7 互換OS向け CVE-2016-0728 対応手順(手抜き)

  1. ピンバック: 20160126 はれ | まこぴかっと

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です