次のページ 前のページ 目次へ

2. 背景知識

2.1 Linux とオープンソースソフトウェア

1984 年に Richard Stallman 率いる Free Software Foundation (FSF) は GNU プロジェクトを開始した.このプロジェクトはフリーな版の UNIX OS を作ろ うとするものである.Stallman は「フリー」という言葉によって,自由に 使い,読み,変更し,再配布できるソフトウェアを表そうとした. 1991 年に Linux Torvalds は OS のカーネルの開発を始めた.Linus は これを「Linux」と名付けた[Torvalds 1999]. このカーネルは FSF のツール群や他の品々と組み合わせることができ,自由 に配布可能で,しかも非常に役立つ OS だった. この論文ではカーネル本体を「Linux カーネル」と呼び,組み合わせて作られ た全体のものを「Linux」と呼ぶことにする(この組み合せでなく,GNU/Linux という言葉が使われる場合も多い).

色々な組織によって,利用可能な品々が色々な形で組み合わせられている. それぞれの組み合わせを「ディストリビューション」と呼び,ディストリビューション を開発している組織を「ディストリビュータ」と呼ぶ. 有名なディストリビューションには RedHat, Mandrake, SuSE, Caldera, Corel, Debian 等がある. この論文は特定のディストリビューションに依存しない.この論文で仮定する のは,カーネルのバージョンが 2.2 以降であることと,C ライブラリが glic 2.1 以降であることである.この仮定は,現在の主要な Linux ディストリビューション に対しては基本的に有効である.

このような「フリーソフトウェア」への注目が高まるとともに, フリーソフトウェアを定義し,説明する必要性が高まってきた.広く用いられて いる用語は「オープンソースソフトウェア」であり,その定義は [OSI 1999] で詳しく述べられている. Eric Raymond [1997, 1998] はフリーソフトウェアの開発プロセスを考察した 文章をいくつか書き,大きな影響を与えた.

Linux は UNIX のソースコードを使っていないが,Linux のインタフェースは 意図的に UNIX に似せてある. したがって,UNIX の教訓は Linux にも当てはまり,それはセキュリティにつ いても言える. この論文に書かれている情報の多くは,実際にはどのような UNIX 的 OS にも当 てはまるが,Linux の利用者が Linux の機能を生かせるようにするため, Linux 固有の情報も意図的に加えている. この論文は扱う対象を絞るため,意図的に Linux だけに焦点を当てている. 全ての UNIX 的 OS を扱うと移植性の問題や他の OS の機能の問題が関わって くるが,そうなるとこの論文が大きくなりすぎてしまうからである.

Linux は UNIX に似せて作られたものなので,UNIX のセキュリティ機構を備えている. その機構に含まれるのは,各プロセスに対するユーザ ID と グループ ID (uid と gid), ファイルシステムの読み取り/書き込み/実行の(ユーザ/グループ/全体に対する) パーミッション,System V のプロセス間通信(IPC),ソケットベース の IPC(ネットワーク通信を含む)等である. UNIX システムに関する一般的な知識については Thompson [1974] や Bach [1986] を参照すること.これらの文献では基本的なセキュリティ機構についても述べ られている. 第 3 章では,Linux で重要なセキュリティ機構を概説する.

2.2 セキュリティの基本原則

セキュリティに関して馴染んでおくべき一般的な原則は数多くある. [Pfleeger 1997] 等のコンピュータセキュリティに関する教科書を読むこと.

Saltzer [1974] および Saltzer と Schroeder [1975] は,安全な 防御システムの設計の原則として以下の項目を挙げている.これらの項目は現 在でもなお有効である:

2.3 安全にすべきプログラムの種類

安全にする必要があるプログラム(この論文での定義に基づく)は多岐に渡る. 以下では一般的な種類をいくつか述べる:

この論文ではこれらいくつかの種類の問題を一つの集合にまとめる. このアプローチの欠点は,ここで指摘された問題の一部は必ずしも全ての種類 の問題には当てはまらないことである. 特に setuid/setgid したプログラムには多くの驚くような問題があるため, この論文で述べるガイドラインのいくつかは setuid/setgid したプログラム にしか当てはまらない. しかし綺麗に分類することは難しい.なぜなら,プログラムによっては複数の 領域にまたがることがあるからである(例えば,CGI スクリプトは setuid/setgid されることもあるし,同様の効果が得られるように設定される こともある). 全ての種類の問題をまとめて捉えることの利点は,あるプログラムに間違った 分類を当てはめることなしに全ての問題を検討できることである. 以下に述べるように,原則の多くは安全にする必要がある全てのプログラムに 適用できる.

この論文の大部分では, C で書いたプログラムに対する暗黙の偏向がある. ただし C++, Perl, Python, Ada95, Java といった他のプログラムについても, 多少記述している. その理由は,Linux 上で安全なプログラムを実装するためのもっとも一般的な 言語が C だからであり(ただし CGI スクリプトは除く.この分野では Perl が よく使われる),他の多くの言語の実装も C ライブラリを呼び出すからである. ただし,これは C が安全なプログラムを書く目的に「最も適した」言語であ ると言っているわけではない. また,この論文で説明した原則のほとんどは使用するプログラミング言語に関 係なく適用できる.

2.4 神経質なのは良いことである

安全なプログラムを書く上で最も難しいのは,このようなプログラムを書く際 には普段とは違った心構えが必要となる点である.短く言えば「神経質な心構え」 が必要となる. その理由は,間違い(欠陥,バグとも呼ばれる)がもたらす影響が大きく異なる からである.

普通の安全でないプログラムには多くのエラーがある. こういったエラーは望ましいものではないが,普通は稀で滅多に起こらない条 件によるので,ユーザがバグに出会っても,その後はバグを避けながらツール を使えるだろう.

安全なプログラムでは状況は逆になる. 一部のユーザは稀で滅多に起こらない条件を故意に探し出して起こし,認めら れていない権限をその攻撃によって得ようとする. したがって,安全にすべきプログラムを書く際には,神経質なのは良いことで ある.

2.5 設計と実装のガイドラインに関する情報源

いくつかの文献で安全なプログラムの書き方(あるいは換言すると,既存の プログラムが持つセキュリティ上の問題を見つけ出す方法)が説明されており, この論文でも述べるガイドラインの基本的な内容が強調されている.

AUSCERT はプログラミングのチェックリスト [AUSCERT 1996] を公開している. これは Garfinkel と Spafford による文献の 22 章の一部の,安全な SUID とネットワークプログラムの書き方に関する議論を元にしている [Garfinkel 1996]. Matt Bishop [1996, 1997] はこの分野における非常に重要な論文の作成と発表を行っている. Galvin [1998a] は安全なプログラムを開発するための単純なプロセスとチェックリストを述べ ている.Galvin は後に Galvin [1998b] でこのチェックリストを新しくしている. Sitaker [1999] は「Linux security audit(Linux セキュリティ監査)」チームが調べるべき 項目の一覧を発表している. Shostack [1999] はセキュリティが重要視されるコードのための チェックリストを独自に定義している. Secure Unix Programming FAQ からも役立つ知識が得られるだろう [Al-Herbish 1999]. 役立つ情報は Ranum [1998] からもいくつか得られる. 勧められていることの中には注意して扱わなければならないものもある. 例えば Anonymous [不明] は,通常 access(3) に伴って起こる危険な競合状態に触れないで access(3) の使用を推奨している. Wood [1985] はいくつかの有益なアドバイスを 「Security for Programmers」の章で述べている.ただし,この内容的は古く なっている. Bellovin [1994]FreeBSD [1999] にも役立つガイドラインが含まれている.

多くの文献で,ウェブとのインタフェースとなる CGI (Common Gateway Interface) を用いたプログラムのためのセキュリティに関するガイドラインが与えられて いる. このような文献としては Gundavaram [unknown], Kim [1996], Gundavaram [unknown], Kim [1996], Phillips [1995], Stein [1999], Webber [1999] が挙げられる.

この論文は,非常に役立つと筆者が考えたガイドラインのをまとめたも のである.したがって,全ての可能性を網羅したガイドラインではない. この論文の構成は筆者独自のものであり(各リストはそれぞれ独自の異なる 構成を持つ),Linux 専用のガイドライン(例: ケーパビリティや fsuid 値等) も筆者独自のものである. 前述の参考文献も全て読むことを強くお勧めする.

ここで「どうして単に他の文献を紹介するだけでなく自分で独自の文書を書い たのか?」という疑問を持たれるかもしれない. それに対する答えは以下である:

2.6 この論文における表記方法

システムのマニュアルページは「名称(番号)」の形式で参照する. ここで番号はマニュアルのセクション番号である. C と C++ は文字 '\0' (ASCII の 0) を特別扱いするので,この論文ではこの 値を NIL と書くことにする. 「どこも指さない」ことを意味するポインタ値は NULL と呼ぶ. 多くの環境で C コンパイラは整数値 0 を値 NULL に変換するが,C 言語の 標準規格には,実際に全てのビットが 0 である値として NULL を実装するこ とを求める規則はない.


次のページ 前のページ 目次へ