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

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

このコミットは、Go言語のencoding/gobパッケージがunsafeパッケージへの依存を排除し、より安全になったことをGo 1.4のリリースノートに追記するものです。この変更自体はドキュメントの更新ですが、その背景にはencoding/gobの重要な内部変更があります。

コミット

commit 1abab32c6512ca5c2c3b3855a0f6d108ef2ff3b6
Author: Rob Pike <r@golang.org>
Date:   Mon Jun 30 12:28:20 2014 -0700

    doc/go1.4.txt: encoding/gob is now safe
    
    CC=golang-codereviews
    https://golang.org/cl/103690043
---
 doc/go1.4.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/go1.4.txt b/doc/go1.4.txt
index 09fe387f37..f864857920 100644
--- a/doc/go1.4.txt
+++ b/doc/go1.4.txt
@@ -5,6 +5,7 @@ Please keep the descriptions to a single line, starting with the
 package or cmd/xxx directory name, and ending in a CL number.
 Please keep the list sorted (as in sort.Strings of the lines).
 
+encoding/gob: remove unsafe (CL 102680045)
 runtime/race: freebsd is supported (CL 107270043)
 syscall: Setuid, Setgid are disabled on linux platforms. On linux those syscalls operate on the calling thread, not the whole process. This does not match the semantics of other platforms, nor the expectations of the caller, so the operations have been disabled until issue 1435 is resolved (CL 106170043)
 text/scanner: add IsIdentRune field of Scanner. (CL 108030044)

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

https://github.com/golang/go/commit/1abab32c6512ca5c2c3b3855a0f6d108ef2ff3b6

元コミット内容

このコミットは、Go 1.4のリリースノートを記述するファイルdoc/go1.4.txtに、encoding/gobパッケージがunsafeパッケージの使用を廃止したことを示す一行を追加するものです。具体的には、「encoding/gob: remove unsafe (CL 102680045)」という記述が追加されています。これは、encoding/gobパッケージの内部実装が変更され、より安全になったことを公式にアナウンスするためのドキュメント更新です。

変更の背景

encoding/gobパッケージは、Goのデータ構造をシリアライズ(バイト列に変換)およびデシリアライズ(バイト列からデータ構造に復元)するために設計されています。初期のencoding/gobの実装では、パフォーマンスを最大化するためにGoのunsafeパッケージを内部的に利用していました。unsafeパッケージは、Goの型安全性をバイパスし、低レベルなメモリ操作を可能にする強力な機能を提供します。これにより、データ構造のエンコード/デコード処理を高速化することができました。

しかし、unsafeパッケージの使用にはいくつかの問題点がありました。

  1. セキュリティリスク: unsafeパッケージは、誤用するとメモリ破壊やセキュリティ脆弱性(例:任意コード実行)につながる可能性があります。特に、信頼できないソースからのデータを受け取ってデシリアライズする場合、悪意のあるデータによってunsafeな操作が悪用されるリスクがありました。
  2. サンドボックス環境での制限: unsafeパッケージの使用は、一部のサンドボックス化された実行環境(例:Google App Engineなど)では許可されていませんでした。これは、encoding/gobがそのような環境で利用できないことを意味し、その汎用性を制限していました。
  3. コードの複雑性: unsafeコードは、通常のGoコードよりも理解やデバッグが難しく、メンテナンスコストが高くなる傾向があります。

これらの背景から、Go開発チームはencoding/gobからunsafeパッケージへの依存を排除することを決定しました。このコミット自体は、その変更がGo 1.4で実現されたことをドキュメントに反映するためのものです。実際のunsafe排除の作業は、このコミットが参照しているChange List (CL) 102680045で行われました。

前提知識の解説

encoding/gobパッケージ

encoding/gobは、Go言語の標準ライブラリに含まれるパッケージで、Goのデータ構造をバイトストリームにエンコード(シリアライズ)し、またバイトストリームからデコード(デシリアライズ)する機能を提供します。これは、Goプログラム間でデータを交換したり、ディスクに永続化したりする際に特に有用です。例えば、GoのRPC (Remote Procedure Call) システムでは、gob形式がデータの送受信に利用されています。gobは、データ型情報も一緒にエンコードするため、受信側は送信側と同じ型定義を持っていなくても、データ構造を正しくデコードできます。

unsafeパッケージ

Go言語のunsafeパッケージは、Goの型システムが提供する安全性を意図的にバイパスするための機能を提供します。これにより、ポインタと任意の型の間で変換を行ったり、ポインタ演算を実行したりすることが可能になります。

  • unsafe.Pointer: 任意の型のポインタを保持できる特殊なポインタ型。*intから*float64への変換など、通常では許可されない型変換を可能にします。
  • unsafe.Sizeof: 型のメモリサイズをバイト単位で返します。
  • unsafe.Alignof: 型のアライメント要件をバイト単位で返します。
  • unsafe.Offsetof: 構造体内のフィールドのオフセットをバイト単位で返します。

unsafeパッケージは、ガベージコレクタとの連携や、C言語とのFFI (Foreign Function Interface) など、特定の低レベルな最適化やシステムプログラミングのシナリオで非常に強力なツールとなります。しかし、その名の通り「安全ではない」ため、誤って使用するとメモリ破壊、データ破損、プログラムのクラッシュ、さらにはセキュリティ脆弱性につながる可能性があります。そのため、通常はGoのコードでunsafeパッケージを直接使用することは推奨されません。

シリアライゼーション/デシリアライゼーションの安全性

シリアライゼーションとデシリアライゼーションは、プログラム間でデータを交換したり、データを永続化したりする上で不可欠なプロセスです。しかし、信頼できないソースから受け取ったデータをデシリアライズする際には、重大なセキュリティリスクが伴います。

  • 任意コード実行 (RCE): 悪意のあるシリアライズされたデータが、デシリアライゼーションプロセス中に予期しないコードを実行させる可能性があります。これは、特にデシリアライザがオブジェクトのメソッドを呼び出したり、特定のクラスをインスタンス化したりする際に発生しやすいです。
  • サービス拒否 (DoS): 非常に大きな、または複雑な構造を持つ悪意のあるデータが、デシリアライザに過剰なリソース(CPU、メモリ)を消費させ、アプリケーションをクラッシュさせたり、応答不能にしたりする可能性があります。
  • データ改ざん: 悪意のあるデータが、デシリアライズされたオブジェクトの内部状態を不正に操作し、アプリケーションのロジックを破壊する可能性があります。

unsafeパッケージを内部的に使用するデシリアライザは、これらのリスクをさらに高める可能性があります。なぜなら、unsafeな操作はGoの型システムによる保護を迂回するため、悪意のある入力が直接メモリを操作する経路を提供してしまう可能性があるからです。

サンドボックス環境

サンドボックス環境とは、プログラムの実行を厳しく制限されたセキュリティコンテキスト内で隔離するメカニズムです。これにより、悪意のあるコードやバグのあるコードがシステム全体に損害を与えるのを防ぎます。サンドボックスは、ファイルシステムへのアクセス、ネットワーク通信、システムコール、メモリ操作などを制限することが一般的です。unsafeパッケージのような低レベルなメモリ操作を可能にする機能は、サンドボックスのセキュリティモデルと衝突することが多いため、サンドボックス環境ではunsafeパッケージの使用が禁止されるか、厳しく制限されることがあります。

技術的詳細

このコミットは、Go 1.4のリリースノートにencoding/gobパッケージがunsafeパッケージの使用を廃止したことを明記するためのものです。これは、Go言語の進化における重要なマイルストーンであり、encoding/gobの安全性と汎用性を向上させるための取り組みの一環です。

具体的な技術的変更は、このコミットが参照しているChange List (CL) 102680045で行われました。このCLでは、encoding/gobの内部実装が書き直され、unsafeパッケージに依存しない形でデータ構造のシリアライズとデシリアライズが行われるようになりました。

この変更の主な影響は以下の通りです。

  1. 安全性の向上: unsafeパッケージの排除により、encoding/gobはGoの型システムによる保護を完全に享受できるようになりました。これにより、信頼できないソースからのデータデシリアライズに伴う潜在的なセキュリティリスク(メモリ破壊や任意コード実行など)が大幅に軽減されました。
  2. 汎用性の向上: unsafeパッケージの使用が制限されるサンドボックス環境(例:Google App Engine)でもencoding/gobが利用可能になりました。これにより、gobパッケージの適用範囲が広がり、より多くのGoアプリケーションで安全に利用できるようになりました。
  3. パフォーマンスへの影響: unsafeパッケージを使用しない実装は、直接的なメモリ操作による最適化ができないため、パフォーマンスに影響が出ました。Web検索の結果によると、この変更によりencoding/gobのエンコード/デコード速度は、一般的な使用シナリオで10%から30%程度低下したとされています。しかし、この性能低下は、得られる安全性と汎用性の向上に見合うものと判断されました。
  4. ドキュメントの更新: このコミットは、上記の重要な変更をGo 1.4の公式リリースノートに反映させるためのものです。これにより、ユーザーはGo 1.4でencoding/gobがより安全になったことを認識し、安心して利用できるようになります。

このコミット自体は単なるドキュメントの追加ですが、その背後にあるencoding/gobunsafe排除は、Go言語の設計哲学である「安全性とシンプルさ」を追求する上で重要な一歩でした。パフォーマンスと安全性のトレードオフを考慮し、より堅牢な標準ライブラリを提供するための開発チームの努力が反映されています。

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

このコミットにおけるコアとなるコードの変更箇所は、doc/go1.4.txtファイルへの以下の1行の追加です。

--- a/doc/go1.4.txt
+++ b/doc/go1.4.txt
@@ -5,6 +5,7 @@ Please keep the descriptions to a single line, starting with the
 package or cmd/xxx directory name, and ending in a CL number.
 Please keep the list sorted (as in sort.Strings of the lines).
 
+encoding/gob: remove unsafe (CL 102680045)
 runtime/race: freebsd is supported (CL 107270043)
 syscall: Setuid, Setgid are disabled on linux platforms. On linux those syscalls operate on the calling thread, not the whole process. This does not match the semantics of other platforms, nor the expectations of the caller, so the operations have been disabled until issue 1435 is resolved (CL 106170043)
 text/scanner: add IsIdentRune field of Scanner. (CL 108030044)

コアとなるコードの解説

追加された行「encoding/gob: remove unsafe (CL 102680045)」は、Go 1.4のリリースノートの一部として機能します。この行は、以下の重要な情報を簡潔に伝えています。

  • 対象パッケージ: encoding/gob
  • 変更内容: unsafeパッケージの使用が削除されたこと。これは、encoding/gobがもはや低レベルなメモリ操作に依存せず、Goの型システムによって完全に保護されるようになったことを意味します。
  • 参照CL: CL 102680045。これは、実際にunsafeコードを削除し、encoding/gobの内部実装を書き換えた変更セットの識別子です。このコミット自体はドキュメントの更新ですが、このCLを参照することで、ユーザーや開発者は実際の技術的変更の詳細を追跡できます。

このドキュメントの更新は、Go 1.4のユーザーに対して、encoding/gobがより安全で、より広範な環境(特にサンドボックス化された環境)で利用可能になったことを明確に伝える役割を果たします。また、パフォーマンスのトレードオフがあったとしても、安全性が優先されたというGo開発チームの設計判断を示唆しています。

関連リンク

  • このコミットのChange List (CL): https://golang.org/cl/103690043
  • encoding/gobからunsafeを削除した実際のChange List (CL): https://golang.org/cl/102680045

参考にした情報源リンク

  • Go言語の公式ドキュメント(encoding/gobおよびunsafeパッケージに関する情報)
  • Web検索結果: encoding/gobunsafe排除に関する情報(Go 1.4の変更点、パフォーマンスへの影響など)
    • https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFluYFXTFZFPbp1xaI5qi7NUPmM8zbtvk5KU1HiyrzPfAqs9JXp7lc5x4oKA6-aNicfpQdaS0nbNZhapZf0xSRDgvdfvywb8Ks5B7QZVlk2WkQ=
    • https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFLMEcWff37fswtNE1rrqoaRq0wHRUW-mRjhqPGVG_L2oM04aEa_ROOHtdGwhp6u6428NfkbS41pw7WIbjzLHnTvNcgrmmbaG3oShxTtYFN5LXI