[インデックス 16264] ファイルの概要
このコミットは、src/pkg/runtime/cgo/gcc_arm.S
ファイルに対する変更です。具体的には、ARMアーキテクチャ向けのCGO(C言語との相互運用)ランタイムビルドにおける問題を修正しています。
コミット
commit 988236ba86c8cb7ceb027cd2eaf091b4363f20e2
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Fri May 3 17:15:43 2013 +0800
runtime/cgo: fix build for ARM
TBR=iant
CC=golang-dev
https://golang.org/cl/9048048
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/988236ba86c8cb7ceb027cd2eaf091b4363f20e2
元コミット内容
runtime/cgo: fix build for ARM
変更の背景
このコミットは、Go言語のランタイムにおけるCGO(C言語との相互運用)機能がARMアーキテクチャでビルドされる際に発生していた問題を修正するために行われました。具体的には、アセンブリコード内でELFセクションを定義する際の構文が、ARMアーキテクチャのGNUアセンブラ(as
)の特定のバージョンで正しく解釈されないことが原因でした。
ELF(Executable and Linkable Format)ファイルにおいて、.note.GNU-stack
セクションは、スタックの実行可能性に関する情報をリンカに伝えるために使用されます。非実行可能なスタックは、バッファオーバーフロー攻撃など、スタックに悪意のあるコードを注入して実行しようとする攻撃を防ぐための重要なセキュリティ対策です。このセクションは通常、progbits
タイプとして宣言されます。
問題は、GNUアセンブラにおいてセクションタイプを指定する際に、一般的な構文である@progbits
が、ARMアーキテクチャでは@
がコメントの開始文字として解釈されてしまうことにありました。これにより、セクションタイプが正しく認識されず、ビルドエラーや予期せぬ動作を引き起こす可能性がありました。このコミットは、ARM環境でのビルドを成功させるために、この構文の差異を吸収することを目的としています。
前提知識の解説
ELF (Executable and Linkable Format)
ELFは、Unix系オペレーティングシステム(Linuxを含む)で広く使用されている、実行可能ファイル、オブジェクトコード、共有ライブラリ、コアダンプなどの標準ファイル形式です。柔軟性が高く、ARMのような様々なアーキテクチャに対応しています。
.note.GNU-stack
セクション
ELFファイル内の特別なセクションで、GNUツール(GNUアセンブラ as
やGNUリンカ ld
など)によって、スタックの実行可能性に関する情報を伝達するために使用されます。このセクションが存在し、適切にマークされている場合(例えば、実行可能フラグなし)、リンカに対してスタックが実行可能であってはならないことを指示します。これは、セキュリティ上の脆弱性(例:バッファオーバーフローによるコード実行)を防ぐための重要なセキュリティ機能です。
progbits
ELFファイルにおけるセクションタイプ(SHT_PROGBITS
)の一つです。これは、セクションが「プログラムのビット」またはプログラムの一部を形成する実際のデータを含んでいることを意味します。これには、実行可能コード、初期化されたデータ、およびプログラムによって明示的に定義されたその他の情報が含まれます。.note.GNU-stack
の文脈では、このセクションはプログラム自体の実行可能コードを含んでいませんが、リンカのためのメタデータを含んでいるため、通常progbits
タイプとして扱われます。
ARMアセンブリ
ARMアーキテクチャ向けに書かれたアセンブリ言語コードを指します。ARMは、RISC(Reduced Instruction Set Computer)アーキテクチャのファミリーであり、モバイルデバイス、組み込みシステム、そして近年ではサーバーやデスクトップでも広く使用されています。ARMアセンブリでは、.section
のようなディレクティブを使用して、出力オブジェクトファイル内のセクションを定義します。
@progbits
と %progbits
これらは、GNUアセンブラ(as
)を使用してアセンブリ言語でセクションタイプを指定する方法です。
@progbits
: 一般的に、.section
ディレクティブでセクションタイプを指定するために使用される構文です。%progbits
: ARMのような一部のターゲットでは、@
文字がコメントの開始として解釈される可能性があるため、代わりに%
文字がセクションタイプを指定するために使用されます。したがって、ARMアセンブリでは、.section .note.GNU-stack,\"\",%progbits
のように記述することで、.note.GNU-stack
セクションをprogbits
タイプとして宣言し、それがデータ(リンカのためのメタデータであっても)を含み、実行可能ではないことを示します。
このコミットは、ARM環境におけるGNUアセンブラの挙動の違いに対応するために、@progbits
を%progbits
に変更しています。
技術的詳細
このコミットの技術的な核心は、GNUアセンブラ(as
)が異なるアーキテクチャ(特にARM)でセクション属性をどのように解釈するかの違いにあります。
ELFファイルでは、.section
ディレクティブを使用して新しいセクションを定義し、その属性を指定します。一般的な構文は以下のようになります。
.section name, "flags", @type
ここで、type
はセクションの目的を示すもので、progbits
は「プログラムのデータ」を意味します。
しかし、ARMアーキテクチャ向けのGNUアセンブラでは、@
記号がコメントの開始文字として扱われる場合があります。このため、.section .note.GNU-stack,"",@progbits
という記述は、@progbits
の部分がコメントとして無視され、セクションタイプが正しく設定されないという問題が発生していました。
この問題を解決するため、ARMアセンブラではセクションタイプを指定する際に%
記号を使用する慣習があります。つまり、%progbits
と記述することで、progbits
がセクションタイプとして正しく認識されるようになります。
このコミットは、src/pkg/runtime/cgo/gcc_arm.S
ファイル内の.note.GNU-stack
セクションの定義を、@progbits
から%progbits
に変更することで、ARM環境でのビルドが正しく行われるように修正しています。これにより、生成されるELFファイルが意図した通りに.note.GNU-stack
セクションを持ち、スタックの非実行可能性がリンカに正しく伝達されるようになります。これは、セキュリティとビルドの安定性の両面で重要な修正です。
コアとなるコードの変更箇所
--- a/src/pkg/runtime/cgo/gcc_arm.S
+++ b/src/pkg/runtime/cgo/gcc_arm.S
@@ -35,5 +35,5 @@ EXT(__stack_chk_fail_local):
b 1b
#ifdef __ELF__
-.section .note.GNU-stack,"",@progbits
+.section .note.GNU-stack,"",%progbits
#endif
コアとなるコードの解説
変更された行は、src/pkg/runtime/cgo/gcc_arm.S
ファイル内の以下の部分です。
#ifdef __ELF__
.section .note.GNU-stack,"",@progbits
#endif
このコードは、__ELF__
が定義されている場合(つまり、ELF形式のバイナリを生成する場合)に、.note.GNU-stack
という名前のセクションを定義しています。このセクションは、スタックの実行可能性に関する情報をリンカに伝えるためのものです。
元のコードでは、セクションタイプとして@progbits
が指定されていました。しかし、前述の通り、ARMアーキテクチャのGNUアセンブラでは@
がコメント文字として解釈されるため、この指定が正しく機能しませんでした。
修正後のコードは以下のようになります。
#ifdef __ELF__
.section .note.GNU-stack,"",%progbits
#endif
@progbits
が%progbits
に変更されています。この変更により、ARMアーキテクチャのGNUアセンブラは%progbits
を正しくセクションタイプとして認識し、.note.GNU-stack
セクションが意図した通りにELFファイルに組み込まれるようになります。これにより、GoランタイムのCGO機能がARM環境で正しくビルドされ、セキュリティ上の要件も満たされるようになります。
関連リンク
参考にした情報源リンク
- ELF (Executable and Linkable Format) - bottomupcs.com
- What is the purpose of .note.GNU-stack? - stackoverflow.com
- What is the meaning of .note.GNU-stack? - ycombinator.com
- What is the purpose of .note.GNU-stack? - stackoverflow.com
- Non-executable stack - redhat.com
- What is the purpose of .note.GNU-stack? - stackoverflow.com
- ELF Section Types - oracle.com
- GNU Assembler Directives - sourceware.org
- ELF Section Types - linux-foundation.org
- ELF Section Types - tortall.net
- ELF Section Types - tortall.net
- ARM Assembly Language - gnu.org
- GNU Assembler Directives - huihoo.com