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

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

このコミットは、Go言語のプロファイリングツールであるpprofスクリプトの挙動を修正するものです。具体的には、Webブラウザを起動する際に、カレントディレクトリ内でブラウザの実行ファイルを探すという不適切な挙動を排除します。

コミット

commit 11a40cb34db360661ed75268bd6b33aa221ad537
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date:   Fri Dec 21 20:40:44 2012 +0100

    misc/pprof: don't look for browser in current directory.
    
    Taken from upstream pprof.
    
    Fixes #4564.
    
    R=golang-dev, minux.ma
    CC=golang-dev
    https://golang.org/cl/6952045

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

https://github.com/golang/go/commit/11a40cb34db360661ed75268bd6b33aa221ad537

元コミット内容

misc/pprof: don't look for browser in current directory.

Taken from upstream pprof.

Fixes #4564.

R=golang-dev, minux.ma
CC=golang-dev
https://golang.org/cl/6952045

変更の背景

この変更は、Go言語のプロファイリングツールであるpprofが、プロファイル結果をWebブラウザで表示する際に、ブラウザの実行ファイルをカレントディレクトリ(現在の作業ディレクトリ)で探してしまうという問題に対処するために行われました。

従来のpprofスクリプトでは、Webブラウザを起動する際に、firefoxgoogle-chromeといった一般的なブラウザのパスを探索するリストの中に、カレントディレクトリも含まれていました。これは、悪意のあるスクリプトや予期せぬ実行ファイルがカレントディレクトリに存在する場合、それらが意図せず実行されてしまうセキュリティ上のリスクや、単に予期しないプログラムが起動してしまうというユーザ体験上の問題を引き起こす可能性がありました。

この修正は、より安全で予測可能な挙動を保証するために、カレントディレクトリでのブラウザ検索を停止することを目的としています。コミットメッセージにある「Taken from upstream pprof」は、この修正が元々GoogleのPerl版pprofツールで行われた変更を取り込んだものであることを示唆しています。

前提知識の解説

  • Go言語のpprofツール: pprofは、Goプログラムのパフォーマンスプロファイリングを行うためのツールです。CPU使用率、メモリ割り当て、ゴルーチンスタックトレースなどを収集し、それらを視覚的に分析するためのWebインターフェースを提供します。このWebインターフェースを起動する際に、システムにインストールされているWebブラウザを利用します。
  • Perlスクリプト: 変更が加えられたmisc/pprofファイルはPerlで書かれたスクリプトです。Go言語のツールでありながらPerlスクリプトが使われているのは、初期のGoツール群が既存のUnixツールやスクリプトの慣習に倣って開発されていたためです。
  • system関数 (Perl): Perlのsystem関数は、外部コマンドを実行するために使用されます。引数としてコマンドとその引数を受け取り、そのコマンドを実行します。コマンドが正常に実行された場合、system関数は0を返します。
  • -f演算子 (Perl): Perlのファイルテスト演算子の一つで、-f $file$fileというパスが存在し、かつそれが通常のファイル(ディレクトリやシンボリックリンクではない)である場合に真を返します。

技術的詳細

このコミットの技術的な変更は、misc/pprofスクリプト内のRunWebサブルーチンにあります。このサブルーチンは、プロファイル結果を表示するためのWebブラウザを起動する役割を担っています。

変更前のコードでは、ブラウザの実行ファイルを探索するループ内で、以下の条件分岐がありました。

if (-f $b) {
  if (system($b, $fname) == 0) {
    return;
  }
}

ここで$bはブラウザの実行ファイルパス候補(例: /usr/bin/firefox, firefoxなど)を表します。if (-f $b)という条件は、「もし$bで指定されたパスが通常のファイルとして存在すれば」というチェックを行っていました。

このチェックの問題点は、$bが単なる実行ファイル名(例: firefox)である場合、Perlのsystem関数が内部的にPATH環境変数を利用して実行ファイルを探す前に、if (-f $b)がカレントディレクトリでfirefoxという名前のファイルを探してしまう点にありました。もしカレントディレクトリにfirefoxという名前の実行ファイルが存在した場合、たとえそれが正規のブラウザでなくても、この条件が真となり、そのファイルがsystem関数によって実行される可能性がありました。

今回の修正では、このif (-f $b)の条件を削除しました。

if (system($b, $fname) == 0) {
  return;
}

これにより、system($b, $fname)が直接呼び出されるようになります。system関数は、引数として与えられたコマンド名($b)を、システムのPATH環境変数に基づいて探索し、最初に見つかった実行可能ファイルを起動します。この挙動は、カレントディレクトリを明示的にPATHに含めていない限り、通常はカレントディレクトリを優先的に検索することはありません。これにより、意図しない実行ファイルの起動を防ぎ、より安全なブラウザ起動メカニズムが実現されます。

この変更は、pprofがブラウザを起動する際のセキュリティと堅牢性を向上させるための重要な修正です。

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

--- a/misc/pprof
+++ b/misc/pprof
@@ -726,10 +726,8 @@ sub RunWeb {
     "firefox",
   );
   foreach my $b (@alt) {
-    if (-f $b) {
-      if (system($b, $fname) == 0) {
-        return;
-      }\n+    if (system($b, $fname) == 0) {\n+      return;\n     }\n   }\n \n

コアとなるコードの解説

変更はmisc/pprofファイルのRunWebサブルーチン内で行われています。

  • 変更前:

    foreach my $b (@alt) {
      if (-f $b) { # ここでファイルが存在するかをチェック
        if (system($b, $fname) == 0) {
          return;
        }
      }
    }
    

    このコードでは、@altリスト(ブラウザの実行ファイルパス候補の配列)の各要素$bについて、まず-f $bでそのパスが通常のファイルとして存在するかどうかを確認していました。このチェックが、カレントディレクトリに同名のファイルが存在する場合に問題を引き起こす可能性がありました。

  • 変更後:

    foreach my $b (@alt) {
      if (system($b, $fname) == 0) { # 直接 system 関数を呼び出す
        return;
      }
    }
    

    変更後では、if (-f $b)の条件が削除され、直接system($b, $fname)が呼び出されるようになりました。これにより、Perlのsystem関数がシステムのPATH環境変数に基づいてブラウザの実行ファイルを探索する標準的な挙動に依存するようになります。これにより、カレントディレクトリに存在する予期しない実行ファイルが誤って起動されるリスクがなくなります。

関連リンク

参考にした情報源リンク

特になし。