[インデックス 18072] ファイルの概要
このコミットは、Go言語のsyscall
パッケージにおいて、Plan 9オペレーティングシステム上でのファイル名にスラッシュ(/
)の使用を禁止する変更を導入しています。これにより、ファイル名の解析やセキュリティに関する潜在的な問題を防ぎ、Plan 9のファイルシステムセマンティクスとの整合性を高めています。
コミット
commit 674606503e716dbea89166d2df87e2ec887aa4da
Author: David du Colombier <0intro@gmail.com>
Date: Thu Dec 19 00:58:23 2013 +0100
syscall: disallow slashes in file names on Plan 9
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/43480050
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/674606503e716dbea89166d2df87e2ec887aa4da
元コミット内容
syscall: disallow slashes in file names on Plan 9
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/43480050
変更の背景
この変更の背景には、Plan 9オペレーティングシステムのファイルシステムにおける特殊なパスの扱いがあります。Unix系システムではスラッシュ(/
)がディレクトリの区切り文字として厳密に機能し、ファイル名自体にスラッシュを含めることは通常許可されません。しかし、Plan 9のファイルシステムプロトコルである9P(またはPlan 9 File Protocol)では、ファイル名にスラッシュを含めることが技術的には可能であり、これが予期せぬ挙動やセキュリティ上の脆弱性を引き起こす可能性がありました。
Go言語のsyscall
パッケージは、OS固有のシステムコールへの低レベルなインターフェースを提供します。Plan 9をターゲットとする場合、Goプログラムがファイルシステム操作を行う際に、Plan 9のセマンティクスに厳密に従う必要があります。ファイル名にスラッシュが含まれていると、パスの解決時に混乱が生じたり、意図しないファイルがアクセスされたりするリスクがありました。このコミットは、このような潜在的な問題を未然に防ぎ、GoプログラムがPlan 9上でより堅牢かつ安全に動作するようにするためのものです。
前提知識の解説
Plan 9 from Bell Labs
Plan 9 from Bell Labsは、ベル研究所で開発された分散オペレーティングシステムです。Unixの設計思想をさらに推し進め、すべてのリソース(ファイル、デバイス、ネットワーク接続など)をファイルとして表現し、9Pプロトコルを通じてアクセスするという徹底した「すべてはファイル」の原則に基づいています。
9Pプロトコル
9P(Plan 9 File Protocol)は、Plan 9システムにおけるクライアントとサーバー間の通信プロトコルです。ファイルシステムのリソースへのアクセスを抽象化し、ネットワーク越しに透過的にファイルシステムを共有することを可能にします。9Pでは、ファイルやディレクトリは「Qid」(Qualified ID)と呼ばれるユニークな識別子によって参照されます。
ファイル名とパスのセマンティクス
Unix系システムでは、ファイル名にスラッシュを含めることはできません。スラッシュはパスの区切り文字として予約されています。例えば、/home/user/document.txt
というパスでは、home
、user
はディレクトリ名、document.txt
はファイル名です。ファイル名自体に/
が含まれると、パスの解釈が曖昧になり、セキュリティ上の問題(例: パストラバーサル攻撃)につながる可能性があります。
Plan 9のファイルシステムでは、ファイル名にスラッシュを含めることがプロトコル上は可能ですが、これは通常推奨されません。なぜなら、多くのアプリケーションやツールがスラッシュをパスの区切り文字として解釈するため、予期せぬ動作を引き起こす可能性があるからです。このコミットは、Goのsyscall
パッケージがPlan 9のファイルシステムとやり取りする際に、この潜在的な不整合を解消することを目的としています。
技術的詳細
このコミットは、src/pkg/syscall/dir_plan9.go
ファイルに修正を加えています。このファイルは、Plan 9固有のディレクトリ操作やファイル情報の構造体(Dir
)を扱うためのGoのシステムコールラッパーの一部です。
具体的には、Dir
構造体をバイト列にマーシャル(シリアライズ)するMarshal
メソッドに、ファイル名(d.Name
)にスラッシュが含まれていないかをチェックするロジックが追加されました。
- エラーの追加:
ErrBadName
という新しいエラーが定義されました。これは「ファイル名に不正な文字が含まれている」ことを示すエラーです。var ( ErrShortStat = errors.New("stat buffer too short") ErrBadStat = errors.New("malformed stat buffer") ErrBadName = errors.New("bad character in file name") // <-- 追加 )
- ファイル名チェックの追加:
Dir.Marshal
メソッド内で、d.Name
の各文字をループし、スラッシュ(/
)が見つかった場合に即座にErrBadName
エラーを返して処理を中断するようになりました。for _, c := range d.Name { if c == '/' { return n, ErrBadName } }
この変更により、GoプログラムがPlan 9のファイルシステムに対して、ファイル名にスラッシュを含むDir
構造体をマーシャルしようとすると、この新しいエラーが返されるようになります。これにより、不正なファイル名がファイルシステムに書き込まれることを防ぎ、パスの解釈に関する問題を未然に防ぐことができます。
コアとなるコードの変更箇所
変更はsrc/pkg/syscall/dir_plan9.go
ファイルに集中しています。
--- a/src/pkg/syscall/dir_plan9.go
+++ b/src/pkg/syscall/dir_plan9.go
@@ -11,6 +11,7 @@ import "errors"
var (
ErrShortStat = errors.New("stat buffer too short")
ErrBadStat = errors.New("malformed stat buffer")
+\tErrBadName = errors.New("bad character in file name")
)
// A Qid represents a 9P server\'s unique identification for a file.
@@ -65,6 +66,12 @@ func (d *Dir) Marshal(b []byte) (n int, err error) {\
\t\treturn n, ErrShortStat
\t}\n \
+\tfor _, c := range d.Name {\
+\t\tif c == \'/\' {\
+\t\t\treturn n, ErrBadName
+\t\t}\n+\t}\n+\
\tb = pbit16(b, uint16(n)-2)\
\tb = pbit16(b, d.Type)\
\tb = pbit32(b, d.Dev)\
コアとなるコードの解説
ErrBadName
の追加
ErrBadName
は、ファイル名に不正な文字が含まれていることを示す新しいエラー定数です。これにより、ファイル名検証の失敗を明確に区別できるようになりました。
Dir.Marshal
メソッド内のループとチェック
Dir.Marshal
メソッドは、Dir
構造体の内容をPlan 9のファイルシステムプロトコル(9P)で定義されたバイト列形式に変換(マーシャル)する役割を担います。このバイト列は、ファイルシステムサーバーに送信され、ファイルやディレクトリのメタデータとして解釈されます。
追加されたコードブロックは以下の通りです。
for _, c := range d.Name {
if c == '/' {
return n, ErrBadName
}
}
for _, c := range d.Name
: これは、Dir
構造体のName
フィールド(ファイル名を表す文字列)の各Unicodeコードポイント(rune)を反復処理します。if c == '/'
: 各文字c
がスラッシュ文字(/
)であるかをチェックします。return n, ErrBadName
: もしスラッシュが見つかった場合、メソッドは直ちに現在のバイト数n
と新しく定義されたErrBadName
エラーを返します。これにより、不正なファイル名を持つDir
構造体がマーシャルされるのを防ぎ、その結果、Plan 9ファイルシステムに不正なファイル名が書き込まれることを防ぎます。
この変更は、Goのsyscall
パッケージがPlan 9のファイルシステムと安全かつ一貫性のある方法で対話することを保証するための重要な防御策です。
関連リンク
- Go言語の
syscall
パッケージのドキュメント: https://pkg.go.dev/syscall - Plan 9 from Bell Labs: https://9p.io/plan9/
- 9Pプロトコルに関する情報: https://9p.io/plan9/man/man5/0intro.html (Plan 9の公式マニュアルページ)
参考にした情報源リンク
- Go言語の公式リポジトリ: https://github.com/golang/go
- Go言語のコードレビューシステム (Gerrit): https://go.dev/cl/43480050 (コミットの変更リスト)
- Plan 9 from Bell Labsの概念に関する一般的な情報源 (例: Wikipedia, 技術記事など)