Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 10350] ファイルの概要

このコミットは、Go言語のビルドシステムにおけるSELinux (Security-Enhanced Linux) の検出ロジックを修正するものです。具体的には、Fedora 16でSELinuxのファイルシステムが従来の/selinuxではなく/sys/fs/selinuxにマウントされるようになった変更に対応し、make.bashスクリプトが両方のパスを適切にチェックするように改善されています。これにより、Fedora 16環境下でGoのビルドがSELinuxのallow_execstack設定によって中断される問題を解決します。

コミット

  • コミットハッシュ: 90c5070000d1db22409dd5b97b3a3bb777021b03
  • 作者: Bobby Powers bobbypowers@gmail.com
  • コミット日時: 2011年11月11日 16:41:37 -0500
  • 変更ファイル: src/make.bash (1ファイル)
  • 変更行数: 18行追加, 13行削除

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/90c5070000d1db22409dd5b97b3a3bb777021b03

元コミット内容

build: fix check for selinux's allow_execstack on Fedora 16

Fedora 16 mounts selinux at /sys/fs/selinux, instead of the
traditional /selinux.  Check both locations for the selinux
filesystem in make.bash

Fixes #2448.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5373077

変更の背景

この変更は、Go言語のビルドプロセスがSELinuxが有効なシステム、特にFedora 16で問題なく動作するようにするために行われました。

Go言語のコンパイラやランタイムは、実行時にスタックの実行を許可する(execstack)必要があります。これは、Goのコンパイラが生成するコードが、一部の最適化やランタイムの動作のために、実行可能なスタック領域を必要とするためです。SELinuxは、セキュリティを強化するために、デフォルトでスタックの実行を制限するポリシーを持つことがあります。

Goのビルドスクリプトであるmake.bashは、SELinuxが有効なシステムでallow_execstackが有効になっているかどうかをチェックし、もし無効であれば警告を表示するロジックを含んでいました。しかし、Fedora 16ではSELinuxのファイルシステムのマウントポイントが従来の/selinuxから/sys/fs/selinuxに変更されました。この変更により、make.bashスクリプトがSELinuxのステータスを正しく検出できなくなり、結果としてGoのビルドが不必要に警告を発したり、場合によっては失敗したりする可能性がありました。

この問題は、GoのIssueトラッカーでIssue #2448として報告されており、このコミットはその問題を解決するために作成されました。

前提知識の解説

SELinux (Security-Enhanced Linux)

SELinuxは、Linuxカーネルに組み込まれた強制アクセス制御 (MAC: Mandatory Access Control) セキュリティメカニズムです。従来の任意アクセス制御 (DAC: Discretionary Access Control) とは異なり、システム管理者が定義したセキュリティポリシーに基づいて、プロセスやユーザーがファイル、デバイス、その他のリソースにアクセスする方法を厳密に制限します。これにより、たとえroot権限を持つプロセスが侵害されたとしても、その被害を最小限に抑えることができます。

SELinuxは、ファイルやプロセスに「コンテキスト」と呼ばれるセキュリティラベルを付与し、ポリシーに基づいてこれらのコンテキスト間の相互作用を制御します。

allow_execstack

allow_execstackは、SELinuxのブーリアン(真偽値)設定の一つです。このブーリアンがon(有効)に設定されている場合、プログラムがスタック領域を実行可能にすることを許可します。多くの現代的なシステムでは、セキュリティ上の理由から、スタック領域は実行不可(NXビット、DEPなど)に設定されています。これは、バッファオーバーフロー攻撃などによって悪意のあるコードがスタックに注入され、実行されるのを防ぐためです。

しかし、一部のアプリケーションやコンパイラ(Go言語を含む)は、動的に生成されたコードや特定の最適化のために、実行可能なスタックを必要とすることがあります。allow_execstackoffの場合、そのようなプログラムは正しく動作しないか、起動すらできない可能性があります。

setsebool コマンド

setseboolコマンドは、SELinuxのブーリアン設定を変更するために使用されます。例えば、setsebool -P allow_execstack 1というコマンドは、allow_execstackブーリアンを永続的にon(1)に設定します。-Pオプションは、変更を永続化し、システム再起動後も設定が保持されるようにします。

Go言語のビルドプロセスと make.bash

Go言語のソースコードからコンパイラや標準ライブラリをビルドする際には、通常、src/make.bash(Unix系システムの場合)またはsrc/make.bat(Windowsの場合)スクリプトが使用されます。これらのスクリプトは、Goのツールチェインをブートストラップし、必要なバイナリをコンパイルし、テストを実行する役割を担っています。

make.bashスクリプトは、ビルド環境の様々な側面をチェックし、潜在的な問題をユーザーに警告するロジックを含んでいます。SELinuxのallow_execstackのチェックもその一部です。

SELinuxのマウントポイントの変更 (/selinux から /sys/fs/selinux)

Linuxシステムでは、SELinuxのステータスや設定を管理するためのファイルシステムが特定のパスにマウントされます。伝統的に、これは/selinuxにマウントされていました。しかし、Linuxカーネルの進化とファイルシステム階層標準 (FHS: Filesystem Hierarchy Standard) の改善に伴い、一部のディストリビューション(Fedora 16など)では、SELinuxのファイルシステムが/sys/fs/selinuxにマウントされるようになりました。これは、/sysがカーネルやデバイスに関する情報を提供する仮想ファイルシステムのマウントポイントとしてより適切であるという考えに基づいています。

この変更は、SELinuxのステータスやブーリアン設定をプログラム的にチェックするスクリプトに影響を与えます。スクリプトが古いパスのみをチェックしている場合、新しいマウントポイントではSELinuxが有効であっても検出できなくなります。

技術的詳細

このコミットの技術的な核心は、make.bashスクリプトがSELinuxのファイルシステムを検出するロジックを強化した点にあります。

変更前は、スクリプトはSELinuxの存在を/selinuxディレクトリの有無によってのみ判断していました。

if [ -d /selinux -a -f /selinux/booleans/allow_execstack -a -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then
    # ... 既存のチェックロジック ...
fi

このロジックは、Fedora 16のようにSELinuxが/sys/fs/selinuxにマウントされているシステムでは機能しませんでした。

コミット後の変更では、SELinuxのファイルシステムがマウントされている可能性のある複数のパス(/selinux/sys/fs/selinux)をループで順にチェックするように改善されました。

for se_mount in /selinux /sys/fs/selinux
do
    if [ -d $se_mount -a -f $se_mount/booleans/allow_execstack -a -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then
        # ... 既存のチェックロジック ...
    fi
done

この変更により、スクリプトはまず/selinuxをチェックし、もしSELinuxがそこにマウントされていなければ、次に/sys/fs/selinuxをチェックします。これにより、異なるLinuxディストリビューションやバージョンにおけるSELinuxのマウントポイントの差異を吸収し、より堅牢な検出メカニズムを提供します。

ループ内で、以下の条件が満たされる場合にのみ、allow_execstackのチェックと警告メッセージの表示が行われます。

  1. $se_mountで指定されたディレクトリが存在する (-d $se_mount)。
  2. $se_mount/booleans/allow_execstackファイルが存在する (-f $se_mount/booleans/allow_execstack)。
  3. /usr/sbin/selinuxenabled実行ファイルが存在し、かつ実行可能である (-x /usr/sbin/selinuxenabled)。
  4. /usr/sbin/selinuxenabledコマンドが成功する(SELinuxが有効であることを示す)。

これらの条件がすべて満たされた上で、allow_execstackブーリアンの値が1 1(有効)でない場合に、Goのビルドに必要な設定が不足している旨の警告が表示されます。

コアとなるコードの変更箇所

--- a/src/make.bash
+++ b/src/make.bash
@@ -50,21 +50,26 @@ chmod +x "$GOBIN"/gomake
 # TODO(brainman): delete this after 01/01/2012.
 rm -f "$GOBIN"/gotest	# remove old bash version of gotest on Windows
 
-if [ -d /selinux -a -f /selinux/booleans/allow_execstack -a -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then
-\tif ! cat /selinux/booleans/allow_execstack | grep -c '^1 1$' >> /dev/null ; then
-\t\techo "WARNING: the default SELinux policy on, at least, Fedora 12 breaks "
-\t\techo "Go. You can enable the features that Go needs via the following "
-\t\techo "command (as root):"\n-\t\techo "  # setsebool -P allow_execstack 1"
-\t\techo
-\t\techo "Note that this affects your system globally! "
-\t\techo
-\t\techo "The build will continue in five seconds in case we "
-\t\techo "misdiagnosed the issue..."
+# on Fedora 16 the selinux filesystem is mounted at /sys/fs/selinux,
+# so loop through the possible selinux mount points
+for se_mount in /selinux /sys/fs/selinux
+do
+\tif [ -d $se_mount -a -f $se_mount/booleans/allow_execstack -a -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then
+\t\tif ! cat $se_mount/booleans/allow_execstack | grep -c '^1 1$' >> /dev/null ; then
+\t\t\techo "WARNING: the default SELinux policy on, at least, Fedora 12 breaks "
+\t\t\techo "Go. You can enable the features that Go needs via the following "
+\t\t\techo "command (as root):"\n+\t\t\techo "  # setsebool -P allow_execstack 1"
+\t\t\techo
+\t\t\techo "Note that this affects your system globally! "
+\t\t\techo
+\t\t\techo "The build will continue in five seconds in case we "
+\t\t\techo "misdiagnosed the issue..."
 \n-\t\tsleep 5
+\t\t\tsleep 5
+\t\tfi
 \tfi
-fi
+done
 \n
 (\n \tcd "$GOROOT"/src/pkg;

コアとなるコードの解説

変更の中心は、SELinuxのチェックを行うif文がforループで囲まれた点です。

  1. for se_mount in /selinux /sys/fs/selinux:

    • この行は、se_mountという変数に、SELinuxのファイルシステムがマウントされている可能性のある2つのパス(/selinux/sys/fs/selinux)を順に代入しながらループを実行することを意味します。
    • これにより、スクリプトはまず従来のパスを試し、次にFedora 16などで採用されている新しいパスを試すことができます。
  2. if [ -d $se_mount -a -f $se_mount/booleans/allow_execstack -a -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then:

    • このif文は、ループの各イテレーションで、現在の$se_mountパスが有効なSELinuxマウントポイントであるかどうかをチェックします。
    • -d $se_mount: $se_mountがディレクトリとして存在するかどうかをチェックします。
    • -a -f $se_mount/booleans/allow_execstack: $se_mount/booleans/allow_execstackファイルが存在するかどうかをチェックします。このファイルはallow_execstackブーリアンの現在の状態を格納しています。
    • -a -x /usr/sbin/selinuxenabled: /usr/sbin/selinuxenabledコマンドが存在し、実行可能であるかをチェックします。このコマンドはSELinuxが有効かどうかを判断するために使用されます。
    • && /usr/sbin/selinuxenabled: 上記のファイルシステムチェックが成功した場合に、実際にselinuxenabledコマンドを実行し、その終了ステータスが成功(SELinuxが有効)であるかをチェックします。
    • これらの条件がすべて真である場合、内側のifブロックが実行されます。
  3. 内側のifブロックのインデントとsleepの修正:

    • ループの導入に伴い、既存の警告ロジック全体がforループと内側のif文のスコープ内に適切にインデントされました。
    • sleep 5の行も、内側のif文のスコープ内に適切に移動し、インデントが修正されています。

この変更により、make.bashはSELinuxのマウントポイントの差異を透過的に処理できるようになり、Goのビルドプロセスがより多くのLinux環境で安定して動作するようになりました。

関連リンク

参考にした情報源リンク

  • SELinux Project: https://selinuxproject.org/page/Main_Page (一般的なSELinux情報)
  • Fedora Project Documentation (Fedora 16リリースノートなど): https://fedoraproject.org/wiki/Documentation (Fedora 16におけるSELinuxパス変更の確認)
  • setsebool man page: (Linuxシステム上でman setseboolで参照可能)
  • make.bashの役割に関するGoのドキュメント: (Goの公式ドキュメントやソースコード内のコメント)

(注:上記「参考にした情報源リンク」は、実際のWeb検索で得られる可能性のある情報源の例です。この解説の生成においては、提供されたコミット情報と一般的な知識に基づいて記述されています。)