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

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

このコミットは、GoランタイムにおけるPlan 9環境でのAESハッシュ初期化に関する問題を修正するものです。具体的には、Plan 9固有のシステムコールであるruntime·openの呼び出し規約の変更と、ランダムデータ取得メカニズムの調整が含まれています。

コミット

commit 66e346433eaf931ed66d599f100cacad892d001b
Author: Keith Randall <khr@golang.org>
Date:   Tue Mar 12 11:03:16 2013 -0700

    runtime: Fix plan9 aes hash initialization.
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/7593045

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

https://github.com/golang/go/commit/66e346433eaf931ed66d599f100cacad892d001b

元コミット内容

runtime: Fix plan9 aes hash initialization.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/7593045

変更の背景

Go言語のランタイムは、内部的にハッシュマップ(map)の実装などで高速なハッシュ関数を使用しています。x86-64アーキテクチャでは、Intel AES-NI命令セットを活用したaeshashと呼ばれる内部ハッシュ関数が利用されることがあります。このコミットは、特にPlan 9オペレーティングシステム環境において、このaeshash関数の初期化に問題があったことを示唆しています。ハッシュ関数の初期化は、その性能や、場合によっては衝突耐性(暗号学的ハッシュではないが、マップの効率性には影響する)に影響を与えるため、正確に行われる必要があります。

この問題は、Plan 9固有のシステムコールとの連携、特にファイル操作や乱数生成に関連する部分で発生していたと考えられます。Goランタイムは、各OSの特性に合わせてシステムコールをラップし、抽象化されたインターフェースを提供しています。Plan 9環境におけるこれらのシステムコールの呼び出し規約の不一致や、必要なランダムデータの取得方法の不備が、aeshashの不適切な初期化を引き起こしていた可能性があります。

前提知識の解説

  • Goランタイム: Goプログラムの実行を管理する低レベルのコンポーネントです。ガベージコレクション、スケジューリング、システムコールインターフェースなどを担当します。
  • Plan 9: ベル研究所で開発された分散オペレーティングシステムです。Unixとは異なる設計思想を持ち、すべてのリソースをファイルとして扱うという特徴があります。Go言語はPlan 9の影響を強く受けており、Goの初期開発者にはPlan 9の開発者が多く含まれています。
  • AESハッシュ (aeshash): Goランタイム内部で使用されるハッシュ関数の一つで、主にmapのキーのハッシュ計算に利用されます。これは暗号学的なハッシュ関数ではなく、高速なデータ構造のハッシュを目的としています。Intel AES-NI命令セットが利用可能な環境では、ハードウェアアクセラレーションを利用して高速に動作します。
  • システムコール: オペレーティングシステムのカーネルが提供するサービスをプログラムが利用するためのインターフェースです。ファイル操作(open, read, close)、メモリ管理、プロセス管理などが含まれます。OSによってシステムコールの引数や戻り値の規約が異なります。
  • runtime·open: GoランタイムがPlan 9上でファイルを開くために使用する内部関数です。これはPlan 9のopenシステムコールをラップしていると考えられます。
  • runtime·get_random_data: ランタイムがランダムなデータを取得するための内部関数です。ハッシュ関数のシードや、その他のランダム性を必要とする操作に利用される可能性があります。

技術的詳細

このコミットは、主に以下の2つの技術的な変更を含んでいます。

  1. runtime·open関数の呼び出し規約の変更:

    • 変更前: runtime·open(file, mode) のように2つの引数で呼び出されていました。
    • 変更後: runtime·open((int8*)file, mode, 0) のように3つ目の引数として0が追加されました。
    • これは、Plan 9のopenシステムコール、またはそれをラップするGoランタイムの内部関数runtime·openのシグネチャが変更されたことを示唆しています。3つ目の引数はおそらくパーミッション(アクセス権)を示すもので、以前は暗黙的に扱われていたか、デフォルト値が適用されていたものが、明示的に指定されるようになったと考えられます。この変更は、src/pkg/runtime/env_plan9.csrc/pkg/runtime/thread_plan9.c内の複数のruntime·open呼び出しに適用されています。
    • また、src/pkg/runtime/os_plan9.hからruntime·open, runtime·read, runtime·closeの関数宣言が削除されています。これは、これらの関数がもはやこのヘッダファイルで公開されるべきではない、あるいは宣言が別の場所に移されたことを意味します。Goランタイムの内部実装の詳細が変更された結果と考えられます。
  2. runtime·get_random_data関数の追加:

    • src/pkg/runtime/thread_plan9.cruntime·get_random_dataという新しい関数が追加されました。
    • この関数は、byte **rndint32 *rnd_lenという引数を取り、ランダムなデータへのポインタとその長さを設定することを意図しています。
    • 現在の実装では、*rnd = nil;*rnd_len = 0;となっており、これはまだ具体的なランダムデータを提供する実装がされていないか、あるいはこのコミットの時点ではランダムデータが直接この関数を通じて提供されるわけではないことを示しています。しかし、「Fix plan9 aes hash initialization」というコミットメッセージとこの関数の追加は、AESハッシュの初期化に必要なランダム性の供給メカニズムを確立しようとしていることを強く示唆しています。ハッシュ関数の初期シードとしてランダムな値を使用することは一般的であり、これによりハッシュの分布が改善されたり、特定の入力に対する予測可能性が低減されたりします。

これらの変更は、Plan 9環境におけるGoランタイムの安定性と正確性を向上させることを目的としています。特に、aeshashの初期化が正しく行われることで、mapなどのデータ構造のパフォーマンスと信頼性が確保されます。

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

src/pkg/runtime/env_plan9.c

--- a/src/pkg/runtime/env_plan9.c
+++ b/src/pkg/runtime/env_plan9.c
@@ -20,7 +20,7 @@ runtime·getenv(int8 *s)
 	runtime·memmove((void*)file, (void*)"/env/", 5);
 	runtime·memmove((void*)(file+5), (void*)s, len);
 
-	fd = runtime·open(file, OREAD);
+	fd = runtime·open((int8*)file, OREAD, 0);
 	if(fd < 0)
 		return nil;
 	n = runtime·seek(fd, 0, 2);

src/pkg/runtime/os_plan9.h

--- a/src/pkg/runtime/os_plan9.h
+++ b/src/pkg/runtime/os_plan9.h
@@ -3,12 +3,9 @@
 // license that can be found in the LICENSE file.
 
 // Plan 9-specific system calls
-int32	runtime·open(uint8 *file, int32 mode);
 int32	runtime·pread(int32 fd, void *buf, int32 nbytes, int64 offset);
 int32	runtime·pwrite(int32 fd, void *buf, int32 nbytes, int64 offset);
-int32	runtime·read(int32 fd, void *buf, int32 nbytes);
 int64	runtime·seek(int32 fd, int64 offset, int32 whence);
-int32	runtime·close(int32 fd);
 void	runtime·exits(int8* msg);
 intptr	runtime·brk_(void*);
 int32	runtime·sleep(int32 ms);

src/pkg/runtime/thread_plan9.c

--- a/src/pkg/runtime/thread_plan9.c
+++ b/src/pkg/runtime/thread_plan9.c
@@ -48,7 +48,7 @@ getproccount(void)
 	int32 fd, i, n, ncpu;
 	byte buf[2048];
 
-	fd = runtime·open((byte*)"/dev/sysstat", OREAD);
+	fd = runtime·open("/dev/sysstat", OREAD, 0);
 	if(fd < 0)
 		return 1;
 	ncpu = 0;
@@ -72,7 +72,7 @@ getpid(void)
 	int32 fd;
 
 	runtime·memclr(b, sizeof(b));
-	fd = runtime·open((byte*)"#c/pid", 0);
+	fd = runtime·open("#c/pid", 0, 0);
 	if(fd >= 0) {
 		runtime·read(fd, b, sizeof(b));
 		runtime·close(fd);
@@ -91,6 +91,13 @@ runtime·osinit(void)
 	runtime·notify(runtime·sigtramp);
 }
 
+void
+runtime·get_random_data(byte **rnd, int32 *rnd_len)
+{
+	*rnd = nil;
+	*rnd_len = 0;
+}
+
 void
 runtime·goenvs(void)
 {
@@ -195,7 +202,7 @@ runtime·postnote(int32 pid, int8* msg)
 	p--;
 	runtime·memmove((void*)p, (void*)"/note", 5);
 
-	fd = runtime·open(buf, OWRITE);
+	fd = runtime·open((int8*)buf, OWRITE, 0);
 	if(fd < 0)
 		return -1;
 

コアとなるコードの解説

  • src/pkg/runtime/env_plan9.c および src/pkg/runtime/thread_plan9.c における runtime·open の変更:
    • これらのファイルでは、runtime·open関数の呼び出し箇所がすべて修正され、3つ目の引数として0が追加されています。これは、Plan 9のファイルオープンシステムコールが、ファイルパス、モードに加えて、パーミッション(アクセス権)を明示的に指定するようになったことを反映しています。以前の呼び出しでは、このパーミッションが暗黙的に扱われていたか、デフォルト値が適用されていた可能性があります。この変更により、ファイル操作の正確性とセキュリティが向上します。
  • src/pkg/runtime/os_plan9.h からの関数宣言の削除:
    • runtime·open, runtime·read, runtime·closeといった基本的なファイル操作関数の宣言がこのヘッダファイルから削除されました。これは、これらの関数がもはや外部に公開されるAPIとして扱われず、ランタイム内部でのみ使用されるようになったことを示唆しています。これにより、ランタイムの内部構造がよりカプセル化され、外部からの不適切な利用を防ぐことができます。
  • src/pkg/runtime/thread_plan9.c における runtime·get_random_data の追加:
    • この新しい関数は、ランタイムがランダムなデータを取得するためのインターフェースを提供します。現在の実装ではnil0を返していますが、これは将来的にPlan 9環境でAESハッシュの初期化やその他のランダム性を必要とする操作のために、適切なランダムデータを供給するメカニズムがここに実装されることを示唆しています。ハッシュ関数の初期化には、予測不可能なシード値が重要であり、この関数はそのための基盤となります。

これらの変更は、GoランタイムがPlan 9環境でより堅牢かつ正確に動作するための重要なステップであり、特にaeshashの初期化に関する問題を解決することを目的としています。

関連リンク

  • Go言語の公式ドキュメント: https://go.dev/
  • Plan 9 from Bell Labs: https://9p.io/plan9/
  • Goのmap実装に関する議論(aeshashについて言及がある場合があります): Goのソースコードリポジトリや関連する設計ドキュメントを参照。

参考にした情報源リンク