<!doctype linuxdoctr system>

<!-- This is a sample comment.
     Originally titled "How to Write Secure Programs for Linux", then
     "Design and Implementation Guidelines for Secure Linux Applications".

     You can get the latest version of this document from:
     http://www.dwheeler.com/

     This file is in SGML using the linuxdoc DTD.
     To process this, get sgmltools at www.sgmltools.org.
     To just check, use:
          sgmlcheck how*.sgml.
     To produce plaintext, use:
          sgml2txt how*.sgml.
     To print (using Latex and Postscript):
        sgml2latex \-\-output=ps how*.sgml; lpr how*.ps
     To do it all at once:
        sgmlcheck how*.sgml && sgml2latex \-\-output=ps how*.sgml && lpr how*.ps
-->

<!--
fujiwara: 論文スタイルで書いているので「である」調にしてみました．
-->

<article>
<title>Secure Programming for Linux HOWTO
<author>David A. Wheeler, <tt>dwheeler@dwheeler.com</tt>
<date>version 1.23, 5 January 2000 
<trans>The Linux JF Project
<tdate>version 1.23j, 3 Feburary 2000
<abstract>
<!--O
This paper provides a set of design and implementation
guidelines for writing secure programs for Linux systems.
Such programs include application programs used as viewers of remote data,
CGI scripts, network servers, and setuid/setgid programs.
-->
この論文は，安全なプログラムを Linux システム用に書くための設計と
実装のガイドラインを集めたものである．対象となるプログラムには，
リモートデータのビューアとして使われるプログラム，CGI スクリプト，
ネットワークサーバ，setuid/setgid して使用するプログラム等がある．
</abstract>

<toc>

<!-- Begin the document -->

<!--O
<sect>Introduction
-->
<sect>序文

<p>
<!--O
This paper describes a set of design and implementation guidelines for
writing secure programs on Linux systems.
For purposes of this paper, a ``secure program'' is a program
that sits on a security boundary, taking input from a source that does
not have the same access rights as the program.
Such programs include application programs used as viewers of remote data,
CGI scripts, network servers, and setuid/setgid programs.
This paper does not address modifying the Linux kernel itself,
although many of the principles discussed here do apply.
These guidelines were developed as a survey of
``lessons learned'' from various sources on how to create such programs
(along with additional observations by the author),
reorganized into a set of larger principles.
-->
この論文は，安全なプログラムを Linux システム用に書くための設計と実装
のガイドラインを集めたものである．
この論文の目的である「安全なプログラム」とは，安全な位置とそうでない位置
との境界上に置かれ，自分とは同等の権限を持っていないソースからの入力を
扱うプログラムのことである．
これに該当するプログラムには，リモートデータのビューアとして使われる
プログラム，CGI スクリプト，ネットワークサーバ，setuid/setgid して使用
するプログラム等がある．
本論文で説明する原則の多くは Linux カーネルにも当てはまるが，この論文
ではカーネルそのものの修正には触れない．
この論文で述べるガイドラインは，安全なプログラムを作る方法に関するさま
ざまな情報から「学んだ教訓」のまとめとして作成され(筆者が加えた意見も
ある)，より大きな原則として整理し直されている．
<p>
<!--O
This paper does not cover assurance measures, software engineering
processes, and quality assurance approaches,
which are important but widely discussed elsewhere.
Such measures include testing, peer review,
configuration management, and formal methods.
Documents specifically identifying sets of development
assurance measures for security issues include
the Common Criteria [CC 1999]
and the
System Security Engineering Capability Maturity Model [SSE-CMM 1999].
More general sets of software engineering methods or processes
are defined in documents such as the
Software Engineering Institute's Capability Maturity Model for Software
(SE-CMM), ISO 9000 (along with ISO 9001 and ISO 9001-3), and ISO 12207.
-->
<!-- ??? Ideally have references for these. -->
<!--
fujiwara: この辺りは用語がぐちゃぐちゃです(^_^; 定訳があれば教えてください．
-->
この論文は保証基準，ソフトウェアエンジニアリングの工程，品質
保証のアプローチは扱わない．これらは重要な問題であるが，他の場所で広く
議論されている．このような基準にはテスト，ピアレビュー，構成管理，
形式的手法が含まれる．特にセキュリティに関する開発保証基準を扱った
ものとしては，Common Criteria [CC 1999],
System Security Engineering Capability Maturity Model [SSE-CMM 1999]
がある．より一般的なソフトウェアエンジニアリング手法やプロセスは
Software Engineering Institute's Capability Maturity Model for Software
(SE-CMM), ISO 9000 (および ISO 9001, ISO 9001-3), ISO 12207
等の文書で定義されている．
<p>
<!--nakano ほんとはあらゆる &lsqb; &rsqb; にすべき? -->
<!--O
This paper does not discuss how to configure a system (or network)
to be secure in a given environment. This is clearly necessary for
secure use of a given program,
but a great many other documents discuss secure configurations.
Information on configuring a Linux system to be secure is available in a
wide variety of documents including
Fenzi [1999], Seifried [1999], and Wreski [1998].
-->
この論文は，与えられた環境でシステム(あるいはネットワーク)が安全となる
ように設定する方法については議論しない．既存のプログラムを安全に使う方
法が重要なことは明らかだが，安全な設定については非常に多くの文書で
議論されている．Linux システムの安全な設定に関する情報は
Fenzi [1999], Seifried [1999], Wreski [1998] を含む多岐に渡る文献から
入手できる．
<p>
<!--O
This paper assumes that the reader understands computer
security issues in general, the general security model of Unix-like systems,
and the C programming language.
This paper does include some information about the Linux programming model
for security.
-->
この論文では，読者はセキュリティに関する一般的な知識，UNIX 的 OS の
セキュリティモデル，C 言語の知識を持っているものとする．また，
セキュリティに対する Linux のプログラミングモデルに関する知識も多少扱っ
ている．
<p>
<!--O
This paper has been intentionally formatted so that it can be easily
added to the Linux Documentation Project (LDP) at
<url url="http://www.linuxdoc.org">.
You can find the master copy of this document at
<url url="http://www.dwheeler.com">.
-->
この論文の書式は，
Linux Documentation Project (LDP, <url url="http://www.linuxdoc.org">) 
に容易に加えられるように意図して整形してある．この論文のオリジナルは 
<url url="http://www.dwheeler.com"> から入手できる．
<p>
<!--O
This document is (C) 1999 David A. Wheeler and is covered by the
GNU General Public License (GPL); see the last section for more information.
-->
この論文は David A. Wheeler の著作物であり((C) 1999 David A. Wheeler)，
GNU General Public License (GPL) により保護される．詳しくは最後の節を
参照すること．
<p>
<!--O
This paper first discusses the background of Linux and security.
The next section describes the general Linux security model,
giving an overview of the security attributes and operations of
processes, filesystem objects, and so on.
This is followed by the meat of this paper, a set of design and implementation
guidelines for developing applications on Linux systems.
This is broken into validating all input, avoiding buffer overflows,
structuring program internals and approach,
carefully calling out to other resources,
judiciously sending information back, and finally information on
special topics (such as how to acquire random numbers).
The paper ends with conclusions and references.
-->
この論文では，まず Linux とセキュリティに関する背景的な知識を議論する．
次の節では Linux の一般的なセキュリティモデルの解説として，プロセス，
ファイルシステムオブジェクト等のセキュリティに関する属性と操作の概要を
説明する．その次に本論文の主題である，Linux システム上でアプリケーション
を開発する際の設計と実装のガイドラインを述べる．この説明は，
全ての入力の検証，バッファオーバーフローの回避，
プログラムの内部および入口の構成，
外部リソースの慎重な呼び出し，
情報の慎重な返送，そして特殊な話題に関する情報(乱数の取得方法など)に分
けられる．
そして最後に結論と参考文献を述べて論文の結びとする．

</sect>
<!--O
<sect>Background
-->
<sect>背景知識
<!--O
<sect1>Linux and Open Source Software
-->
<sect1>Linux とオープンソースソフトウェア
<p>
<!--O
In 1984 Richard Stallman's Free Software Foundation (FSF) began the GNU
project, a project to create a free version of the Unix operating system.
By free, Stallman meant software that could be freely
used, read, modified, and redistributed.
The FSF successfully built many useful components but was having
trouble developing the operating system kernel [FSF 1998].
In 1991 Linus Torvalds began developing an operating system kernel, which
he named ``Linux'' [Torvalds 1999].
This kernel could be combined with the FSF material and other components
producing a freely-modifiable and very useful operating system.
This paper will term the kernel itself the ``Linux kernel'' and
an entire combination as ``Linux'' (many use the term GNU/Linux instead
for this combination).
-->
1984 年に Richard Stallman 率いる Free Software Foundation (FSF) は GNU 
プロジェクトを開始した．このプロジェクトはフリーな版の UNIX OS を作ろ
うとするものである．Stallman は「フリー」という言葉によって，自由に
使い，読み，変更し，再配布できるソフトウェアを表そうとした．
1991 年に Linus Torvalds は OS のカーネルの開発を始めた．Linus は
これを「Linux」と名付けた[Torvalds 1999]．
このカーネルは FSF のツール群や他の品々と組み合わせることができ，自由
に配布可能で，しかも非常に役立つ OS だった．
この論文ではカーネル本体を「Linux カーネル」と呼び，組み合わせて作られ
た全体のものを「Linux」と呼ぶことにする(この組み合せでなく，GNU/Linux
という言葉が使われる場合も多い)．
<p>
<!--O
Different organizations have combined the available components differently.
Each combination is called a ``distribution,'' and the organizations that
develop distributions are called ``distributors.''
Common distributions include Red Hat, Mandrake, SuSE, Caldera, Corel,
and Debian.
This paper is not specific to any distribution; it does presume Linux
kernel version 2.2 or greater and the C library glibc 2.1 or greater,
which are valid assumptions for essentially all current major
Linux distributions.
-->
色々な組織によって，利用可能な品々が色々な形で組み合わせられている．
それぞれの組み合わせを「ディストリビューション」と呼び，ディストリビューション
を開発している組織を「ディストリビュータ」と呼ぶ．
有名なディストリビューションには RedHat, Mandrake, SuSE,
Caldera, Corel, Debian 等がある．
この論文は特定のディストリビューションに依存しない．この論文で仮定する
のは，カーネルのバージョンが 2.2 以降であることと，C ライブラリが glic
2.1 以降であることである．この仮定は，現在の主要な Linux ディストリビューション
に対しては基本的に有効である．
<p>
<!--O
Increased interest in such ``free software'' has made it increasingly necessary
to define and explain it.
A widely used term is ``open source software,'' which further defined in
[OSI 1999].
Eric Raymond [1997, 1998] wrote several seminal articles examining
its development process.
-->
このような「フリーソフトウェア」への注目が高まるとともに，
フリーソフトウェアを定義し，説明する必要性が高まってきた．広く用いられて
いる用語は「オープンソースソフトウェア」であり，その定義は
[OSI 1999] で詳しく述べられている．
Eric Raymond [1997, 1998] はフリーソフトウェアの開発プロセスを考察した
文章をいくつか書き，大きな影響を与えた．
<p>
<!--O
Linux is not derived from Unix source code, but its interfaces are
intentionally Unix-like.
Therefore, Unix lessons learned apply to Linux, including information
on security.
Much of the information in this paper actually applies to any Unix-like
system, but Linux-specific information has been intentionally added to
enable those using Linux to take advantage of its capabilities.
This paper intentionally focuses on Linux systems to narrow its scope;
including all Unix-like systems would require an analysis
of porting issues and other systems' capabilities, which would have greatly 
increased the size of this document.
-->
Linux は UNIX のソースコードを使っていないが，Linux のインタフェースは
意図的に UNIX に似せてある．
したがって，UNIX の教訓は Linux にも当てはまり，それはセキュリティにつ
いても言える．
この論文に書かれている情報の多くは，実際にはどのような UNIX 的 OS にも当
てはまるが，Linux の利用者が Linux の機能を生かせるようにするため，
Linux 固有の情報も意図的に加えている．
この論文は扱う対象を絞るため，意図的に Linux だけに焦点を当てている．
全ての UNIX 的 OS を扱うと移植性の問題や他の OS の機能の問題が関わって
くるが，そうなるとこの論文が大きくなりすぎてしまうからである．
<p>
<!--O
Since Linux is intentionally Unix-like, it has Unix security mechanisms.
These include user and group ids (uids and gids) for each process,
a filesystem with read, write, and execute permissions (for user, group, and
other), System V inter-process communication (IPC), socket-based IPC
(including network communication), and so on.
See Thompson [1974] and Bach [1986]
for general information on Unix systems, including their basic
security mechanisms.
Section 3 summarizes key Linux security mechanisms.
-->
<!-- ???: This is cheating; switch eventually to a real cross-reference -->
Linux は UNIX に似せて作られたものなので，UNIX のセキュリティ機構を備えている．
その機構に含まれるのは，各プロセスに対するユーザ ID と グループ ID (uid と gid)，
ファイルシステムの読み取り/書き込み/実行の(ユーザ/グループ/全体に対する)
パーミッション，System V のプロセス間通信(IPC)，ソケットベース
の IPC(ネットワーク通信を含む)等である．
UNIX システムに関する一般的な知識については Thompson [1974] や Bach [1986]
を参照すること．これらの文献では基本的なセキュリティ機構についても述べ
られている．
第 3 章では，Linux で重要なセキュリティ機構を概説する．

<!--O
<sect1>Security Principles
-->
<sect1>セキュリティの基本原則
<p>
<!--O
There are many general security principles which you should be
familiar with; consult a general text on computer security such as
[Pfleeger 1997].
-->
セキュリティに関して馴染んでおくべき一般的な原則は数多くある．
[Pfleeger 1997] 等のコンピュータセキュリティに関する教科書を読むこと．
<p>
<!--O
Saltzer [1974] and Saltzer and Schroeder [1975]
list the following principles of the design of secure
protection systems, which are still valid:
-->
Saltzer [1974] および Saltzer と Schroeder [1975] は，安全な
防御システムの設計の原則として以下の項目を挙げている．これらの項目は現
在でもなお有効である:
<itemize>
<!--O
<item><it>Least privilege</it>.
-->
<item><it>権限をできるだけ小さくすること</it>．
<!--O
Each user and program should operate using the fewest privileges possible.
That way, damage from attack is minimized.
-->
それぞれのユーザとプログラムは，できる限り小さい権限を使って動作すべき
である．そうすれば，攻撃を受けたときの被害を最小限に抑えることができる．
<!--O
<item><it>Economy of mechanism</it>.
-->
<item><it>機構が経済的であること</it>．
<!--O
The protection system's design should be small, simple, and straightforward.
-->
防御システムは小さく，単純に，素直に設計すべきである．
<!--O
<item><it>Open design</it>.
-->
<item><it>オープンな設計であること</it>．
<!--O
The protection mechanism must not depend on the attacker ignorance.
Instead, the mechanism should be public, depending on the secrecy of
relatively few (and easily changeable) items like passwords.
This makes extensive public scrutiny possible.
Bruce Schneier argues that smart engineers should ``demand
open source code for anything related to security,''
as well as ensuring that it receives widespread review and that
any identified problems are fixed &lsqb;Schneier 1999&rsqb;.
-->
防御機構は「攻撃者が機構の仕組みを知らないこと」をあてにしてはならない．
逆に防御機構そのものの内容は公開されているべきで，機構の安全性は
パスワード等，比較的少数の
(しかも容易に変更可能な)要素に依存すべきである．そうすれば，数多くの
第三者の検証を受けることが可能となる．
Bruce Schneier は，賢い技術者は「セキュリティに関することは全て
オープンソースコードに頼るべき」であると指摘している．彼はまた，
オープンソースコードは多くの人に検閲されることや見つかった問題は全て
解決されることを確かめている&lsqb;Schneier 1999&rsqb;．
<!--O
<item><it>Complete mediation</it>.
-->
<item><it>完全に仲介を行うこと</it>．
<!--O
Every access attempt must be checked; position the mechanism
so it cannot be subverted.
For example, in a client-server model, generally the server must do all
access checking because users can build or modify their own clients.
-->
考え得るアクセス方法は全てチェックしなければならない．チェック機構は
回避できないように配置すること．
例えば，クライアント-サーバモデルにおいては，一般的にはサーバは全ての
アクセスをチェックしなければならない．なぜなら，ユーザは改造等により
独自のクライアントを作ることができるからである．
<!--O
<item><it>Permission-based</it>.
-->
<item><it>禁止を基本の態度とすること</it>．
<!--O
The default should be denial of service.
-->
デフォルトの動作ではサービスを拒否すべきである．
<!--O
<item><it>Separation of privilege</it>.
-->
<item><it>権限を分離すること</it>．
<!--O
Ideally, access to objects should depend on more than one condition, so
that defeating one protection system won't enable complete access.
-->
理想的には，オブジェクトへのアクセスは複数の条件に基づいて行うべきであ
る．そうすれば，一つの防御機構が破られても完全なアクセスを許すことはな
い．
<!--O
<item><it>Least common mechanism</it>.
-->
<item><it>共通して持つ機構を最小限にすること</it>．
<!--O
Shared objects provide potentially dangerous channels for information
flow, so physically or logically separate them.
-->
共有されているオブジェクトは情報流出の経路となる危険性を持っている．
したがって，オブジェクトは物理的にも論理的にも分割すべきである．
<!--O
<item><it>Easy to use</it>.
-->
<item><it>使いやすいこと</it>．
<!--O
If a mechanism is easy to use it is unlikely to be avoided.
-->
使いやすい機構はユーザに避けられにくい．
</itemize>

<!--O
<sect1>Types of Secure Programs
-->
<sect1>安全にすべきプログラムの種類
<p>
<!--O
Many different types of programs may need to be secure programs
(as the term is defined in this paper).
Some common types are:
-->
安全にする必要があるプログラム(この論文での定義に基づく)は多岐に渡る．
以下では一般的な種類をいくつか述べる:
<itemize>
<!--O
<item>Application programs used as viewers of remote data.
Programs used as viewers (such as word processors or file format viewers)
are often asked to view data sent remotely by an untrusted user
(this request may be automatically invoked by a web browser).
Clearly, the untrusted
user's input should not be allowed to cause the application
to run arbitrary programs.
It's usually unwise to support initialization macros (run when the data
is displayed); if you must, then you must create a secure sandbox
(a complex and error-prone task).
Be careful of issues such as buffer overflow, discussed later, which might
allow an untrusted user to force the viewer to run an arbitrary program.
-->
<item>リモートのデータのビューアとして使われるアプリケーション
プログラム．ビューアとして使われるプログラム(ワードプロセッサや
何らかのフォーマットのファイルのビューア)は，リモートの信頼できない
ユーザから送られたデータを表示するように求められることがしばしばある
(この要求はウェブブラウザが自動的に行うこともある)．
明らかなことだが，信頼できないユーザからの入力に対して
アプリケーションから任意のプログラムを実行させることは許可すべきでない．
初期化マクロ(データを表示する時に実行される)に対応することも普通は賢明
とは言えない．初期化マクロに対応しなければならない場合は，安全な砂箱
(sandbox) (複雑かつエラー対処の作業を行う)を用意しなければならない．
&lsqb;
訳注:
砂箱とは，ペットが排泄するときに使う砂を入れた箱のこと．しつけの悪い
ペットに粗相をされても外には影響が出ないように，しつけの悪いプログラム
が悪さをしても影響が出ないという意味．
&rsqb;
<!--
fujiwara: …でいいのか?
-->
<!--nakano: Java で良く聞きますね. sandbox のままでいいかもしれません.
http://java.sun.com/products/jdk/1.2/ja/docs/ja/guide/security/spec/security-spec.doc1.html
などを参照. -->
<!--
fujiwara: 訳注のところは土屋@富士通研さんのコメントをそのまま頂きまし
た．多謝．
-->
バッファオーバーフローのような問題(後述)には注意すること．
バッファオーバーフローが起きると，信頼できないユーザが
ビューア経由で任意のプログラムを実行できてしまうことがある．
<!--nakano: 意訳しすぎ?-->
<!--O
<item>Application programs used by the administrator (root).
Such programs shouldn't trust information that can be controlled
by non-administrators.
-->
<item>システム管理者(root)が使うアプリケーションプログラム．
この種のプログラムは，システム管理者でないユーザが変更できる情報を信用
すべきでない．
<!--O
<item>Local servers (also called daemons).
-->
<item>ローカルのサーバ(デーモンとも呼ばれる)．
<!--O
<item>Network-accessible servers (sometimes called network daemons).
-->
<item>ネットワーク利用が可能なサーバ(ネットワークデーモンと呼ばれるこ
ともある)．
<!--O
<item>CGI scripts.
These are a special case of network-accessible servers, but they're
so common they deserve their own category.
Such programs are invoked indirectly via a web server, which filters out
some attacks but nevertheless leaves many attacks that must be withstood.
-->
<item>CGI スクリプト．
CGI スクリプトはネットワーク利用が可能なサーバの特殊なケースであるが，
非常に一般的なので独自に分類にしている．
CGI スクリプトはウェブサーバ経由で間接的に呼び出される．ウェブサーバは
一部の攻撃を排除するが，それでもなお CGI スクリプト側で対処しなければ
ならない攻撃もたくさん残っている．
<!--O
<item>setuid/setgid programs.
These programs are invoked by a local user and, when executed, are
immediately granted the privileges of the program's owner and/or
owner's group.
In many ways these are the hardest programs to secure, because so many
of their inputs are under the control of the untrusted user and some
of those inputs are not obvious.
-->
<item>setuid/setgid されるプログラム．
このようなプログラムはローカルのユーザに起動され，起動した直後に
プログラムの所有者や所有グループの権限を得る．
色々な理由により，setuid/setgid されるプログラムは安全にするのが非常に
困難なプログラムである．なぜなら，入力の大部分が信頼できないユーザの
制御の下にあり，そういった入力の一部は明らかでないからである．
</itemize>
<p>
<!--O
This paper merges the issues of these different types of program into
a single set.
The disadvantage of this approach is that some of the issues identified
here don't apply to all types of program.
In particular, setuid/setgid programs have many surprising inputs and several
of the guidelines here only apply to them.
However, things are not so clear-cut, because 
a particular program may cut across these boundaries (e.g., a CGI script
may be setuid or setgid, or be configured in a way that has the same effect).
The advantage of considering all of these program types together is that we can
consider all issues without trying to apply an inappropriate category
to a program.
As will be seen, many of the principles apply to all programs that
need to be secured.
-->
この論文ではこれらいくつかの種類の問題を一つの集合にまとめる．
このアプローチの欠点は，ここで指摘された問題の一部は必ずしも全ての種類
の問題には当てはまらないことである．
特に setuid/setgid したプログラムには多くの驚くような問題があるため，
この論文で述べるガイドラインのいくつかは setuid/setgid したプログラム
にしか当てはまらない．
しかし綺麗に分類することは難しい．なぜなら，プログラムによっては複数の
領域にまたがることがあるからである(例えば，CGI スクリプトは
setuid/setgid されることもあるし，同様の効果が得られるように設定される
こともある)．
全ての種類の問題をまとめて捉えることの利点は，あるプログラムに間違った
分類を当てはめることなしに全ての問題を検討できることである．
以下に述べるように，原則の多くは安全にする必要がある全てのプログラムに
適用できる．
<p>
<!--O
There is a slight bias in much of this paper towards programs written in
C, with some notes on other languages such as C++, Perl, Python, Ada95, and
Java.
This is because C is the most common language for
implementing secure programs on Linux
(other than CGI scripts, which tend to use Perl),
and most other languages' implementations call the C library.
This is not to imply that C is somehow the ``best'' language for this purpose,
and most of the principles described here apply regardless of the
programming language used.
-->
この論文の大部分では， C で書いたプログラムに対する暗黙の偏向がある．
ただし C++, Perl, Python, Ada95, Java といった他のプログラムについても，
多少記述している．
その理由は，Linux 上で安全なプログラムを実装するためのもっとも一般的な
言語が C だからであり(ただし CGI スクリプトは除く．この分野では Perl が
よく使われる)，他の多くの言語の実装も C ライブラリを呼び出すからである．
ただし，これは C が安全なプログラムを書く目的に「最も適した」言語であ
ると言っているわけではない．
また，この論文で説明した原則のほとんどは使用するプログラミング言語に関
係なく適用できる．

<!--O
<sect1>Paranoia is a Virtue
-->
<sect1>神経質なのは良いことである
<p>
<!--O
The primary difficulty in writing secure programs is that
writing them requires a different mindset, in short, a paranoid mindset.
The reason is that the impact of errors (also called defects or bugs)
can be profoundly different.
-->
安全なプログラムを書く上で最も難しいのは，このようなプログラムを書く際
には普段とは違った心構えが必要となる点である．短く言えば「神経質な心構え」
が必要となる．
その理由は，間違い(欠陥，バグとも呼ばれる)がもたらす影響が大きく異なる
からである．
<!--nakano: paranoia は「偏執症」というのが述語ですが,
かえってわかりにくいかな -->
<p>
<!--O
Normal non-secure programs have many errors.
While these errors are undesirable, these errors usually 
involve rare or unlikely situations, and if a user should stumble upon
one they will try to avoid using the tool that way in the future.
-->
普通の安全でないプログラムには多くのエラーがある．
こういったエラーは望ましいものではないが，普通は稀で滅多に起こらない条
件によるので，ユーザがバグに出会っても，その後はバグを避けながらツール
を使えるだろう．
<p>
<!--O
In secure programs, the situation is reversed.
Certain users will intentionally search out and cause rare or unlikely
situations, in the hope that such attacks will give them unwarranted privileges.
As a result, when writing secure programs, paranoia is a virtue.
-->
安全なプログラムでは状況は逆になる．
一部のユーザは稀で滅多に起こらない条件を故意に探し出して起こし，認めら
れていない権限をその攻撃によって得ようとする．
したがって，安全にすべきプログラムを書く際には，神経質なのは良いことで
ある．
</sect1>

<!--O
<sect1>Sources of Design and Implementation Guidelines
-->
<sect1>設計と実装のガイドラインに関する情報源
<p>
<!--O
Several documents help describe how to write
secure programs (or, alternatively, how to find security problems in
existing programs), and were the basis for the guidelines highlighted
in the rest of this paper.
-->
いくつかの文献で安全なプログラムの書き方(あるいは換言すると，既存の
プログラムが持つセキュリティ上の問題を見つけ出す方法)が説明されており，
この論文でも述べるガイドラインの基本的な内容が強調されている．
<p>
<#unless output=html>
<!--O
For general-purpose servers and setuid/setgid programs, there are a number
of valuable documents (though some are difficult to find without
having a reference to them).
-->
一般目的のサーバおよび setuid/setgid されたプログラムについては，重要
な文献がたくさんある(ただし，その一部はどこかで引用されていなければ
探すのが困難である)．
<!--O
AUSCERT has released a programming checklist [AUSCERT 1996],
based in part on chapter 22 of Garfinkel and Spafford's book discussing how
to write secure SUID and network programs
[Garfinkel 1996].
-->
AUSCERT はプログラミングのためのチェックリストを出している[AUSCERT 1996]．
これは Garfinkel と Spafford による文献の 22 章の一部の，安全な SUID
とネットワークプログラムの書き方に関する議論を元にしている[Garfinkel 1996]．
<!--O
Matt Bishop [1996, 1997]
has developed several extremely valuable papers and presentations
on the topic.
-->
Matt Bishop [1996, 1997] はこの分野における非常に重要な論文の作成と発
表を行っている．
<!--O
Galvin [1998a] described a simple process and checklist
for developing secure programs; he later updated the checklist
in Galvin [1998b].
-->
Galvin [1998a] は安全なプログラムを開発するための単純なプロセスと
チェックリストを述べている．Galvin は後に Galvin [1998b] でこの
チェックリストを新しくしている．
<!--O
Sitaker [1999]
presents a list of issues for the ``Linux security audit'' team to search for.
-->
Sitaker [1999]
は「Linux security audit(Linux セキュリティ監査)」チームが調べるべき
項目の一覧を発表している．
<!--O
Shostack [1999]
defines another checklist for reviewing security-sensitive code.
-->
Shostack [1999] はセキュリティが重要視されるコードのための
チェックリストを独自に定義している．
<!--O
The <it>Secure Unix Programming FAQ</it> also has some useful suggestions
[Al-Herbish 1999].
-->
<it>Secure Unix Programming FAQ</it> からも役立つ知識が得られるだろう
[Al-Herbish 1999]．
<!--O
Some useful information is also available from
Ranum [1998].
-->
役立つ情報は Ranum [1998] からもいくつか得られる．
<!--O
Some recommendations must be taken with caution, for example,
Anonymous [unknown]
recommends the use of access(3) without noting the dangerous race conditions
that usually accompany it.
-->
<!--
fujiwara: anonymous って訳出してよかったかな? 確か Anonymous を名乗っ
ている人がいた気がするんだけど…．
-->
勧められていることの中には注意して扱わなければならないものもある．
例えば，access(3) に通常存在する危険な
競合状態に触れずに access(3) の使用を推奨している [不明] ような人もいる．
<!--O
Wood [1985] has some useful but dated advice
in its ``Security for Programmers'' chapter.
-->
Wood [1985] はいくつかの有益なアドバイスを
「Security for Programmers」の章で述べている．ただし，この内容的は古く
なっている．
<!--O
Bellovin [1994]
and
FreeBSD [1999]
also include useful guidelines.
-->
Bellovin [1994]
と
FreeBSD [1999]
にも役立つガイドラインが含まれている．
<p>
<!--O
There are many documents giving security guidelines for
programs using
the Common Gateway Interface (CGI) to interface with the web.
These include Gundavaram [unknown], Kim [1996], Phillips [1995], Stein [1999],
and Webber [1999].
-->
多くの文献で，ウェブとのインタフェースとなる CGI (Common Gateway Interface) 
を用いたプログラムのためのセキュリティに関するガイドラインが与えられて
いる．
このような文献としては Gundavaram [unknown], Kim [1996], 
Phillips [1995], Stein [1999], Webber [1999] が挙げられる．
</#unless>
<#if output=html>
<!--O
AUSCERT has released a programming checklist
<htmlurl url="ftp://ftp.auscert.org.au/pub/auscert/papers/secure_programming_checklist"
         name="[AUSCERT 1996]">,
based in part on chapter 22 of Garfinkel and Spafford's book discussing how
to write secure SUID and network programs
<htmlurl url="http://www.oreilly.com/catalog/puis"
         name="[Garfinkel 1996]">.
-->
AUSCERT はプログラミングのチェックリスト
<htmlurl url="ftp://ftp.auscert.org.au/pub/auscert/papers/secure_programming_checklist" name="[AUSCERT 1996]">
を公開している．
これは Garfinkel と Spafford による文献の 22 章の一部の，安全な SUID
とネットワークプログラムの書き方に関する議論を元にしている
<htmlurl url="http://www.oreilly.com/catalog/puis" name="[Garfinkel 1996]">．
<!--O
Matt
<htmlurl url="http://olympus.cs.ucdavis.edu/~bishop/secprog.html"
         name="Bishop [1996, 1997]">
has developed several extremely valuable papers and presentations
on the topic.
-->
Matt 
<htmlurl url="http://olympus.cs.ucdavis.edu/~bishop/secprog.html" name="Bishop [1996, 1997]">
はこの分野における非常に重要な論文の作成と発表を行っている．
<!--O
<htmlurl url="http://www.sunworld.com/swol-04-1998/swol-04-security.html"
         name="Galvin [1998a]"> described a simple process and checklist
for developing secure programs; he later updated the checklist in
<htmlurl url="http://www.sunworld.com/sunworldonline/swol-08-1998/swol-08-security.html"
         name="Galvin [1998b]">.
-->
<htmlurl url="http://www.sunworld.com/swol-04-1998/swol-04-security.html" name="Galvin [1998a]">
は安全なプログラムを開発するための単純なプロセスとチェックリストを述べ
ている．Galvin は後に
<htmlurl url="http://www.sunworld.com/sunworldonline/swol-08-1998/swol-08-security.html" name="Galvin [1998b]">
でこのチェックリストを新しくしている．
<!--O
<htmlurl url="http://www.pobox.com/~kragen/security-holes.html"
         name="Sitaker [1999]">
presents a list of issues for the ``Linux security audit'' team to search for.
-->
<htmlurl url="http://www.pobox.com/~kragen/security-holes.html" name="Sitaker [1999]">
は「Linux security audit(Linux セキュリティ監査)」チームが調べるべき
項目の一覧を発表している．
<!--O
<htmlurl url="http://www.homeport.org/~adam/review.html"
         name="Shostack [1999]">
defines another checklist for reviewing security-sensitive code.
-->
<htmlurl url="http://www.homeport.org/~adam/review.html" name="Shostack [1999]">
はセキュリティが重要視されるコードのための
チェックリストを独自に定義している．
<!--O
The <it>Secure Unix Programming FAQ</it> also has some useful suggestions
<htmlurl url="http://www.whitefang.com/sup/"
         name="[Al-Herbish 1999]">.
-->
<it>Secure Unix Programming FAQ</it> からも役立つ知識が得られるだろう
<htmlurl url="http://www.whitefang.com/sup/" name="[Al-Herbish 1999]">．
<!--O
Some useful information is also available from
<htmlurl url="http://www.clark.net/pub/mjr/pubs/pdf/"
         name="Ranum [1998]">.
-->
役立つ情報は
<htmlurl url="http://www.clark.net/pub/mjr/pubs/pdf/" name="Ranum [1998]">
からもいくつか得られる．
<!--O
Some recommendations must be taken with caution, for example,
<htmlurl url="http://www.homeport.org/~adam/setuid.7.html"
         name="Anonymous [unknown]">
recommends the use of access(3) without noting the dangerous race conditions
that usually accompany it.
-->
勧められていることの中には注意して扱わなければならないものもある．
例えば
<htmlurl url="http://www.homeport.org/~adam/setuid.7.html" name="Anonymous [不明]">
は，通常 access(3) に伴って起こる危険な競合状態に触れないで access(3)
の使用を推奨している．
<!--O
Wood [1985] has some useful but dated advice
in its ``Security for Programmers'' chapter.
-->
Wood [1985] はいくつかの有益なアドバイスを
「Security for Programmers」の章で述べている．ただし，この内容的は古く
なっている．
<!--O
<htmlurl url="http://www.research.att.com/~smb/talks"
         name="Bellovin [1994]">
and
<htmlurl url="http://www.freebsd.org/security/security.html"
         name="FreeBSD [1999]">
also include useful guidelines.
-->
<htmlurl url="http://www.research.att.com/~smb/talks" name="Bellovin [1994]">
と
<htmlurl url="http://www.freebsd.org/security/security.html" name="FreeBSD [1999]">
にも役立つガイドラインが含まれている．
<p>
<!--O
There are many documents giving security guidelines for
programs using
the Common Gateway Interface (CGI) to interface with the web.
-->
多くの文献で，ウェブとのインタフェースとなる CGI (Common Gateway Interface) 
を用いたプログラムのためのセキュリティに関するガイドラインが与えられて
いる．
<!--O
These include
<htmlurl url="http://language.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html"
         name="Gundavaram [unknown]">,
<htmlurl url="http://www.eekim.com/pubs/cgibook"
         name="Kim [1996]">,
<htmlurl url="http://www.go2net.com/people/paulp/cgi-security/safe-cgi.txt"
         name="Phillips [1995]">,
<htmlurl url="http://www.w3.org/Security/Faq/www-security-faq.html"
         name="Stein [1999]">,
and
<htmlurl url="http://www.webbertech.com/tips/web-security.html"
         name="Webber [1999]">.
-->
このような文献としては Gundavaram [unknown], Kim [1996], 
<htmlurl url="http://language.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html"
         name="Gundavaram [unknown]">,
<htmlurl url="http://www.eekim.com/pubs/cgibook"
         name="Kim [1996]">,
<htmlurl url="http://www.go2net.com/people/paulp/cgi-security/safe-cgi.txt"
         name="Phillips [1995]">,
<htmlurl url="http://www.w3.org/Security/Faq/www-security-faq.html"
         name="Stein [1999]">,
<htmlurl url="http://www.webbertech.com/tips/web-security.html"
         name="Webber [1999]">
が挙げられる．
</#if>
<!--nakano: ううむ、ほんとは ref & cite でまとめると sgml 的にはいいんでしょうが... -->
<p>
<!--O
This paper is a summary of what I believe are the most
useful guidelines; it is not a complete list of all possible guidelines.
The organization presented here is my own (every list has its own, different
structure), and the Linux-unique guidelines (e.g., on capabilities and
the fsuid value) are also my own.
Reading all of the referenced documents listed above as well
is highly recommended.
-->
この論文は，非常に役立つと筆者が考えたガイドラインのをまとめたも
のである．したがって，全ての可能性を網羅したガイドラインではない．
この論文の構成は筆者独自のものであり(各リストはそれぞれ独自の異なる
構成を持つ)，Linux 専用のガイドライン(例: ケーパビリティや fsuid 値等)
も筆者独自のものである．
前述の参考文献も全て読むことを強くお勧めする．
<p>
<!--O
One question that could be asked is ``why did you write your own document
instead of just referring to other documents?''
There are several answers:
-->
ここで「どうして単に他の文献を紹介するだけでなく自分で独自の文書を書い
たのか?」という疑問を持たれるかもしれない．
それに対する答えは以下である:
<itemize>
<!--O
<item>Much of this information was scattered about; placing 
the critical information in one organized document
makes it easier to use.
-->
<item>これらの情報の多くが分散している．重要な情報をひとつのまとまった
文書にしておけば使いやすい．
<!--O
<item>Some of this information is not written for the programmer, but
is written for an administrator or user.
-->
<item>これらの一部の情報はプログラマ向けでなく，システム管理者やユーザ
向けに書かれている．
<!--O
<item>Some information isn't relevant to Linux.
For example, many checklists warn against setuid shell scripts; since
Linux doesn't permit them in the normal case,
there's no need to warn against them.
-->
<item>一部の情報は Linux に関係しない．
例えば，多くのチェックリストは setuid されたシェルスクリプトに対する
警告を行っているが，Linux はこのようなシェルスクリプトを通常は許可して
いないので，改めて警告する必要がない．
<!--O
<item>Much of the available information emphasizes portable constructs
(constructs that work on all Unix-like systems).
It's often best to avoid Linux-unique abilities for portability's sake,
but somethimes the Linux-unique abilities can really aid security.
Even if non-Linux portability is desired, you may want to support
Linux-unique abilities on Linux.
-->
<item>入手できる情報の多くは，可搬性の高い構成を強く意識している(全て
の UNIX 的 OS で利用できるように作られている)．
可搬性を考えると Linux 固有の技術を避けることは正しいが，Linux 固有の
技術を使えば実際にセキュリティの向上に役立つ場合もある．
Linux 以外の OS への可搬性が本来望ましい場合であっても，Linux 上では
Linux 固有の機能を使いたいこともあるだろう．
<!--O
<item>This approach isn't unique.
Other operating systems, such as FreeBSD,
have a security programming guide specific to their operating system.
-->
<item>Linux に特化するアプローチは珍しいものではない．
他の OS (FreeBSD 等)でも，独自のセキュリティ関連の
プログラミングガイドがある．
</itemize>
</sect1>
<!--O
<sect1>Document Conventions
-->
<sect1>この論文における表記方法
<p>
<!--O
System manual pages are referenced in the format <it>name(number)</it>,
where <it>number</it> is the section number of the manual.
C and C++ treat the character '\0' (ASCII 0) specially, and this value
is referred to as NIL in this paper.
The pointer value that means ``does not point anywhere'' is called NULL;
C compilers will convert the integer 0 to the value NULL in most circumstances,
but note that nothing in the C standard requires that NULL actually
be implemented by a series of all-zero bits.
-->
システムのマニュアルページは「<it>名称(番号)</it>」の形式で参照する．
ここで<it>番号</it>はマニュアルのセクション番号である．
C と C++ は文字 '\0' (ASCII の 0) を特別扱いするので，この論文ではこの
値を NIL と書くことにする．
「どこも指さない」ことを意味するポインタ値は NULL と呼ぶ．
多くの環境で C コンパイラは整数値 0 を値 NULL に変換するが，C 言語の
標準規格には，実際に全てのビットが 0 である値として NULL を実装するこ
とを求める規則はない．
</sect1>
</sect>

<!--O
<sect>Summary of Linux Security Features
-->
<sect>Linux のセキュリティ機能の概要
<p>
<!--O
Before discussing guidelines on how to use Linux security features,
it's useful to know what those features are from a programmer's viewpoint.
This section briefly describes those features; if you already know what
those features are, please feel free to skip this section.
-->
Linux のセキュリティ機能の使い方のガイドラインを説明する前に，
プログラマの観点からこれらの機能について知っておくと役に立つと思われる．
この節では Linux のセキュリティ機能を簡単に説明する．これらの機能につ
いて既に理解しているなら，次の節に進んでも構わない．
<p>
<!--O
Many programming guides skim briefly over the security-relevant portions
of Linux and skip important information.
In particular, they often discuss ``how to use'' something in general terms
but gloss over the security attributes that affect their use.
Conversely, there's a great deal of detailed information in
the manual pages about individual functions, but the manual pages
sometimes obscure the forest with the trees.
This section tries to bridge that gap; it gives an overview of
the security mechanisms in Linux that are likely to be used
by a programmer.
This section has more depth than the typical programming guides, focusing
specifically on security-related matters, and points to references
where you can get more details.
Unix programmers will be in familiar territory, but there are several
Linux extensions and specifics that may surprise them.
This section will try to point out those differences.
-->
多くのプログラミングガイドは，Linux のセキュリティ関連の部分を切り詰め，
重要な情報を飛ばしている．特にこのようなガイドでは，何かの「使い方」の
一般的な内容は説明しているが，その使い方に影響を与えるセキュリティ属性
については体裁しか整えていないことが多い．その逆に，マニュアルページ
には個々の関数についての詳しい情報が載っているが，マニュアルページでは
往々にして森の中に木が埋もれてしまうことになる．
この節ではこのギャップの橋渡しを試みる．つまり，プログラマが使うと思わ
れる Linux のセキュリティ機構の概要を説明する．
この節では Linux のセキュリティ関連事項に特に注目して，普通の
プログラミングガイドよりも深い話題を扱い，そしてさらに詳しい情報が得ら
れるように参考文献を紹介する．
UNIX のプログラマには馴染みがある分野だと思われるが，Linux における
拡張や Linux 固有の事情があるので驚くこともあるかもしれない．
この節ではこのような相違点もできるだけ述べることにする．
<p>
<!--O
First, the basics.
Linux is fundamentally divided into two parts: the Linux kernel (along with
its kernel modules) and ``user space'' in which various programs execute
on top of the kernel.
When users log in, their usernames are mapped to integers marking their
``UID'' (for ``user id'') and the ``GID''s (for ``group id'') that they
are a member of.
UID 0 is a special privileged user (role) traditionally called ``root,'' who can
overrule most security checks and is used to administrate the system.
Processes are the only ``subjects'' in terms of security (that is, only
processes are active objects).
Processes can access various data objects, in particular filesystem
objects (FSOs), System V Interprocess Communication (IPC) objects, and
network ports.
The next few sections detail this.
-->
まずは基礎を説明する．
Linux は基本的に 2 つの部分に分けられる．すなわち Linux カーネル
(カーネルモジュールを含む)と「ユーザ空間」である．ユーザ空間は
カーネルの上にあり、様々なプログラムがここで動作する．
ユーザがログインすると，そのユーザ名はそのユーザが所属する
「UID(user id の意味)」と「GID(group id の意味)」を表す整数値に割り当てられる．
UID 0 は特殊な権限(役割)を持つユーザで，伝統的に「root」と呼ばれる．
このユーザはほとんどのセキュリティチェックを越えることができ，
システム管理のために用いられる．
プロセスはセキュリティの点から見ると唯一の「主体」である(つまり，
プロセスだけがアクティブなオブジェクトである)．
プロセスは様々なデータオブジェクト，特にファイルシステムオブジェクト
(FSO, filesystem object)，System V プロセス間通信(IPC)オブジェクト，
ネットワークオブジェクトにアクセスできる．
次以降の節ではこれらを詳しく説明する．
<!--O
<sect1>Processes
-->
<sect1>プロセス
<p>
<!--O
In Linux, user-level activities are implemented by running processes.
Many systems support separate ``threads''; in Linux, different
threads may be implemented by using multiple processes (the Linux kernel
then performs optimizations to get thread-level speeds).
-->
Linux では，ユーザレベルの動作はプロセスの実行として実装されている．
多くのシステムは分離された「スレッド」をサポートしている．Linux では，
複数のスレッドが複数のプロセスを用いて実装されていることもある(この場
合，Linux カーネルはスレッドレベルの速度を得るための最適化を実行する)．
<!--O
<sect2>Process Attributes
-->
<sect2>プロセスの属性
<p>
<!--O
Every process has a set of security-relevant attributes, including the
following:
-->
全てのプロセスはセキュリティ関連の属性の集合を持っている．これを以下に
挙げる:
<itemize>
<!--O
<item>RUID, RGID - real UID and GID
of the user on whose behalf the process is running
-->
<item>RUID, RGID - 実 UID および実 GID．
これはプロセスを実行したユーザである．
<!--O
<item>EUID, EGID - effective UID and GID
used for privilege checks (except for the filesystem)
-->
<item>EUID, EGID - 実効 UID と実効 GID．
権限チェックのためのユーザ(ファイルシステムの権限チェックは除く)．
<!--O
<item>FSUID, FSGID - UID and GID used for filesystem access checks;
this is usually equal to the EUID and EGID respectively.
This is a Linux-unique attribute.
-->
<item>FSUID, FSGID - ファイルシステムのアクセスチェックに使われる UID
と GID．普通は FSUID と EUID は同じであり，FSGID と EGID は同じである．
これは Linux 固有の属性である．
<!--O
<item>SUID, SGID - Saved UID and GID;
used to support switching permissions ``on and off'' as discussed below.
-->
<item>SUID, SGID - 保存 UID と保存 GID．
パーミッションの「オン/オフ」の切替えをサポートするために使われる．
詳しくは後述する．
<!--O
<item>groups - a list of groups (GIDs) in which this user has membership.
-->
<item>groups - ユーザが所属しているグループ(GID)のリスト．
<!--O
<item>umask - a set of bits determining the default access control settings
when a new filesystem object is created; see umask(2).
-->
<item>umask - 新しいファイルシステムオブジェクトを作る際のデフォルトの
アクセス制御の設定を決めるビットの集合．umask(2) を参照すること．
<!--O
<item>scheduling parameters - each process has a scheduling policy, and those
with the default policy SCHED_OTHER have the additional parameters
nice, priority, and counter.  See sched_setscheduler(2) for more information.
-->
<item>スケジューリング用パラメータ - 各プロセスはスケジューリングの
ポリシーを持っており，デフォルトのポリシーが SCHED_OTHER になっている
プロセスは nice 値，優先度(priority)，カウンタを持っている．詳しくは
sched_setscheduler(2) を参照すること．
<!--<it> するんじゃなかったっけ? -->
<!--O
<item>capabilities - POSIX capability information; there are actually three
sets of capabilities on a process: the effective, inheritable, and permitted
capabilities.  See below for more information on POSIX capabilities.
-->
<item>ケーパビリティ - POSIX のケーパビリティ情報．実際にはプロセスに
は 3 組のケーパビリティがある．すなわち実効ケーパビリティ，
継承可能ケーパビリティ，許可ケーパビリティである．
<!--
fujiwara: ケーパビリティ関連の訳語はあやしい．
-->
POSIX ケーパビリティに関する詳しい情報は後述する．
<!--O
<item>limits - per-process resource limits (see below).
-->
<item>limit 値 - プロセスごとのリソースの制限(後述)．
<!--O
<item>filesystem root - the process' idea of where the root filesystem
begins; see chroot(2).
-->
<item>ファイルシステムのルート - プロセスがルートファイルシステムと考
えている場所．chroot(2) を参照．
</itemize>
<p>
<!--O
If you really need to know exactly what attributes are associated
with each process, examine the Linux source code, in particular
include/linux/sched.h's definition of task_struct.
-->
どの属性がそれぞれのプロセスに関連しているのかを正確に知る必要が本当に
あれば，Linux のソースコードを調べること．特に include/linux/sched.h
での task_struct を調べるとよい．
</sect2>
<!--O
<sect2>POSIX Capabilities
-->
<sect2>POSIX ケーパビリティ
<p>
<!--O
Linux version 2.2 added internal support for ``POSIX Capabilities.''
POSIX capabilities supports some splitting of the privileges
typically held by root into a larger set of more specific privileges.
POSIX capabilities are defined
by a draft IEEE standard; they're not unique to Linux but they're not
universally supported by other Unix-like systems either.
When Linux documentation (including this one)
says ``requires root privilege'', in nearly all cases it
really means ``requires a capability'' as documented in the capability
documentation.
If you need to know the specific capability required, look it up in the
capability documentation.
-->
Linux バージョン 2.2 で「POSIX ケーパビリティ」の内部サポートが追加さ
れた．POSIX ケーパビリティは，通常は root が持っている権限を，よ
り細かい多数の権限に分割するといった機能に対応する．
POSIX ケーパビリティは IEEE 標準のドラフトで定義されている．したがって，
これは Linux 固有の機能ではないが，他の UNIX 的システムではあまり
サポートされていない．
Linux の文献(この論文も含む)に「root の権限を必要とする」と書かれてい
るほとんど全ての場合は，実際には「ケーパビリティを必要とする」という意
味である．これはケーパビリティに関する文書に書かれている．
必要としている特定のケーパビリティについて知る必要があれば，
ケーパビリティに関する文書で調べること．
<p>
<!--O
The eventual intent is to permit capabilities to be attached to files
in the filesystem; as of this writing, however, this is not yet supported.
There is support for transferring capabilities, but this is disabled
by default.
Linux version 2.2.11 added a feature that makes capabilities
more directly useful, called the ``capability bounding set.''
The capability bounding set is a list of capabilities
that are allowed to be held by any process on the system (otherwise,
only the special init process can hold it).
If a capability does not appear in the bounding set, it may not be
exercised by any process, no matter how privileged. 
This feature can be used to, for example, disable kernel module loading.
A sample tool that takes advantage of this is LCAP at
<url url="http://pweb.netcom.com/~spoon/lcap/">.
-->
最終的には，ファイルシステム内のファイルにケーパビリティを割り当て
可能にすることが目指されているが，この論文の執筆時点では，その機能にはまだ
対応していない．
ケーパビリティの転送機能には対応しているが，この機能はデフォルトで無効
にされている．
Linux のバージョン 2.2.11 には，ケーパビリティをより直接的に使いやすく
する機能が追加された．この機能は
「ケーパビリティ限界集合(capability bounding set)」と呼ばれる．
ケーパビリティ限界集合は，システム上の全てのプロセスが持つことが許され
ているケーパビリティのリストである(許されていないケーパビリティは，
特殊な init プロセスだけが持てる)．
ケーパビリティが限界リストに載っていない場合は，特権を持っているかどう
かに関係なく，どんなプロセスもそのケーパビリティを使用できない．
この機能は例えば，カーネルモジュールの読み込みを無効にするときに使われ
る．
この機能を生かしたツールの例としては，LCAP
(<url url="http://pweb.netcom.com/~spoon/lcap/">)
が挙げられる．
<p>
<!--O
More information about POSIX capabilities is available at
<url url="ftp://linux.kernel.org/pub/linux/libs/security/linux-privs">.
-->
POSIX ケーパビリティに関する詳しい情報は
<url url="ftp://linux.kernel.org/pub/linux/libs/security/linux-privs">
で入手できる．
</sect2>
<!--O
<sect2>Process Creation and Manipulation
-->
<sect2>プロセスの生成と操作
<p>
<!--O
Processes may be created using fork(2), the non-recommended vfork(2),
or the Linux-unique clone(2); all of these system calls duplicate the existing
process, creating two processes out of it.
A process can execute a different program by calling execve(2),
or various front-ends to it (for example, see exec(3), system(3), and popen(3)).
-->
プロセスの生成には， fork(2), 使用が勧められない vfork(2)，そして Linux 固有の
clone(2) が使える．これらのシステムコール全ては，既にある
プロセスを複製し，2 つのプロセスを作成する．
プロセスは execve(2) とその各種フロントエンド(例えば exec(3),
system(3), and popen(3) を参照)を呼び出すことによって別のプログラムを
実行できる．
<p>
<!--O
When a program is executed, and its file has its setuid or setgid bit set,
the process' EUID or EGID (respectively) is set to the file's.
Note that under Linux this does not occur with ordinary scripts such
as shell scripts, because there are a number of security dangers when
trying to do this with scripts (some other Unix-like systems do support
setuid shell scripts).
As a special case, Perl includes a special setup to support setuid Perl scripts.
-->
プログラムが実行された時にそのファイルの setuid ビットか setgid ビット
が立っていると，そのプロセスの EUID (setuid の場合)または EGID (setgid
の場合)がファイルの値に設定される．
Linux では，シェルスクリプト等の普通のスクリプトではこのような操作は行
われない点に注意すること．この操作をスクリプトに対して行うのは
セキュリティ的な危険が多くあるからである(他の UNIX 的 OS には setuid
したシェルスクリプトに対応しているものもある)．
例外的に，Perl では setuid した Perl スクリプトに対応した設定を行える．
<p>
<!--O
In some cases a process can affect the various UID and GID values; see
setuid(2), seteuid(2), setreuid(2), setfsuid(2).
In particular the SUID attribute is there to permit trusted programs
to temporarily switch UIDs.
If the RUID is changed, or the EUID is set to a value not equal to the RUID,
the SUID is set to the new EUID.
Unprivileged users can set their EUID from their SUID,
the RUID to the EUID, and the EUID to the RUID.
-->
場合によっては，プロセスはさまざまな UID 値や GID 値に影響を及ぼすこと
ができる．setuid(2), seteuid(2), setreuid(2), setfsuid(2) を参照すること．
特に SUID 属性は，信頼したプログラムが一時的に UID を切替えることを許す．
RUID が変更された場合，または EUID に RUID と異なる値が設定された場合
には，SUID には新しい EUID が設定される．
特権を持たないユーザは，自分の SUID から自分の EUID を，
RUID から EUID を，EUID から RUID を設定できる．
<p>
<!--O
The FSUID process attribute is intended to permit programs like the NFS server
to limit themselves to only the filesystem rights of some given UID
without giving that UID permission to send signals to the process.
Whenever the EUID is changed, the FSUID is changed to the new
EUID value; the FSUID value can be set separately using setfsuid(2), a
Linux-unique call.
Note that non-root callers can only set FSUID to the current
RUID, EUID, SEUID, or current FSUID values.
-->
FSUID プロセス属性は，NFS サーバ等のプログラムに対し，
ある UID の権限をファイルシステム関係のものに限って許可するためのものである。
その UID 権限でプロセスにシグナルを送ることはできなくする。
EUID が変更されると，FSUID は必ず新しい値に変更される．つまり，
FSUID 値 は setfsuid(2) (Linux 固有のシステムコール)を使わなくても変わ
る場合がある．
root 以外からの呼び出しでは，FSUID には現在の RUID 値, EUID 値, SEUID 値,
あるいは現在の FSUID 値しか設定できない．
</sect2>
</sect1>
<!--O
<sect1>Filesystem
-->
<sect1>ファイルシステム
<p>
<!--O
Filesystem objects (FSOs) may be ordinary files, directories,
symbolic links, named pipes (FIFOs),
sockets, character special (device) files, or block special (device) files
(this list is shown in the find(1) command).
Filesystem objects are collected on filesystems, which can be
mounted and unmounted on directories in the filesystem;
filesystems may have slightly different sets of access control attributes
and access controls can be affected by options selected at mount time.
-->
ファイルシステムオブジェクト(FSO)は通常ファイル，ディレクトリ，
シンボリックリンク，名前付きパイプ(FIFO)，ソケット，
キャラクタ特殊(デバイス)ファイル，ブロック特殊(デバイス)ファイルのいず
れでもよい(このリストは find(1) コマンドで表示される)．
ファイルシステムオブジェクトはファイルシステム上に集められる．
ファイルシステムは親となるファイルシステム上のディレクトリに
マウント/アンマウントできる．
ファイルシステムはファイルと少し異なるアクセス制御属性を持ち，
アクセス制御はマウント時に選択したオプションの影響を受ける．
<!--O
<sect2>Filesystem Object Attributes
-->
<sect2>ファイルシステムオブジェクトの属性
<p>
<!--O
Currently ext2 is the most popular filesystem on Linux systems; it supports
the following attributes on each filesystem object:
-->
現在 ext2 は Linux システムで最もよく使われているファイルシステムであ
る．ext2 ファイルシステムは各ファイルシステムオブジェクトに対して
以下の属性をサポートしている:
<itemize>
<!--O
<item>owning UID and GID - identifies the ``owner'' of the filesystem
object.  Only the owner or root can change the access control attributes
unless otherwise noted.
-->
<item>所有 UID と GID - これはファイルシステムオブジェクトの「所有者」
を特定する．特に補足しない限り，アクセス制御属性を変更できるのは
所有者と root だけである．
<!--O
<item>read, write, execute bits for each of user (owner), group, and other.
For ordinary files, read, write, and execute have their typical meanings.
In directories, the ``read'' permission is necessary to display a directory's
contents, while the ``execute'' permission is sometimes called ``search''
permission and is necessary to actually enter the directory to use its contents.
In a directory ``write'' permission on a directory permits
adding, removing, and renaming files in that directory; if you only want
to permit adding, set the sticky bit noted below.
Note that the permission values of symbolic links are never used; it's only
the values of their containing directories and the linked-to file that matter.
-->
<item>ユーザ(所有者)，グループ，その他のユーザに対する読み取り，
書き込み，実行ビット．
通常ファイルの場合は，読み取り，書き込み，実行は言葉通りの意味を持つ．
ディレクトリの場合，「読み取り」パーミッションはディレクトリの内容を
表示するために必要であるが，これに対して「実行」パーミッションは「検索」
パーミッションと呼ばれることもあり，実際にそのディレクトリに入って
その内容を使うために必要となる．
ディレクトリの場合，「書き込み」パーミッションはそのディレクトリ内での
ファイルの追加，削除，ファイル名変更を許可する．ファイルの追加だけを許
可したければ後述の sticky ビットを設定すること．
シンボリックリンクのパーミッション値は全く使われない点に注意すること．
つまり，関係があるのはシンボリックリンクが置かれているディレクトリと
リンク先のファイルのパーミッション値だけである．
<!--O
<item>``sticky'' bit - when set on a directory, unlinks (removes) are limited to
root, the file owner, or the directory owner.
This is a very common Unix extension, though not quite universal.
The sticky bit has no affect on ordinary files and ordinary users can
turn on this bit.
Old versions of Unix called this the ``save program text'' bit and used this
to indicate executable files that should stay in memory; Linux's virtual
memory management makes this use irrelevant.
-->
<item>``sticky'' ビット - sticky ビットがディレクトリに設定されると，
unlink(削除)を行えるユーザは root, ファイルの所有者，
ディレクトリの所有者だけに制限される．
これは UNIX で非常に一般的に使われている拡張機能であり，
一般ユーザもこのビットを設定できる．
古いバージョンの UNIX ではこれを「プログラムテキスト保存」ビットを呼ん
でおり，(スワップアウトしないで)メモリ上だけで実行すべき実行ファイルを
示すために使っていたが，Linux の仮想メモリ管理機能により，このやり方は
時代遅れになった．
<!--O
<item>setuid, setgid - when set on an executable file,
executing the file will set the process' effective UID or effective GID
to the value of the file's owning UID or GID (respectively).
All Unix-like systems support this.
When setgid is set on a directory, files created in the directory will
have their GID automatically reset to that of the directory's GID.
When setgid is set on a file that does not have any execute privileges,
this indicates a file that is subject to mandatory locking
during access (if the filesystem is mounted to support mandatory locking);
this overload of meaning surprises many and not universal across Unix-like
systems.
-->
<item>setuid, setgid - 実行ファイルに設定すると，
このファイルを実行したプロセスの実効 UID と実効 GID は
(それぞれ)ファイルの所有者の UID と GID となる．
全ての UNIX 的 OS はこの機能をサポートしている．
setgid がディレクトリに設定されると，そのディレクトリ内で作成された
ファイルの GID は自動的にディレクトリの GID に再設定される．
どの実行権も持たないファイルに setgid を設定すると，そのファイルが
アクセスされている間は強制的にロックがかかるようになる(ただし，
マウントしているファイルシステムが強制ロックをサポートしている場合)．
この機構の負荷は驚くほど高く，UNIX 的 OS で広く使われているわけではな
い．
<!--O
<item>timestamps - access and modification times are stored for each
filesystem object.  However, the owner is allowed to set these values
arbitrarily (see touch(1)), so be careful about trusting this information.
All Unix-like systems support this.
-->
<item>タイムスタンプ - アクセス時刻と修正時刻は全てのファイルシステム
オブジェクトについて保存される．ただし，所有者はこの時刻を自由に設定す
ることができるので(touch(1)を参照)，この情報を信頼するにあたっては注意
すること．
全ての UNIX 的 OS はこの機能をサポートしている．
<!--O
<item>immutable bit - no changes to the filesystem object are allowed;
only root can set or clear this bit.
This is only supported by ext2 and is not portable across all Unix
systems (or even all Linux filesystems).
-->
<item>不変ビット(immutable bit) - ファイルシステムオブジェクトに対する
一切の変更を禁止できる．このビットの設定と解除を行えるのは root だけで
ある．
この機能をサポートしているのは ext2 ファイルシステムだけであり，全ての
UNIX システムで(あるいは全ての Linux 用ファイルシステムでさえ)広く使え
るわけではない．
<!--
fujiwara: immutable bit の定訳って何でしたっけ?
-->
<!--O
<item>append-only bit - only appending to the filesystem object are allowed;
only root can set or clear this bit.
This is only supported by ext2 and is not portable across all Unix
systems (or even all Linux filesystems).
-->
<item>追加限定ビット - ファイルシステムオブジェクトに追加のみが許可
される．このビットの設定と解除を行えるのは root だけである．
この機能をサポートしているのは ext2 ファイルシステムだけであり，全ての
UNIX システムで(あるいは全ての Linux 用ファイルシステムでさえ)広く使え
るわけではない．
</itemize>
<p>
<!--O
Many of these values can be influenced at mount time, so that, for example,
certain bits can be treated as though they had a certain value (regardless
of their values on the media).
See mount(1) for more information about this.
Some filesystems don't support some of these access control values; again,
see mount(1) for how these filesystems are handled.
-->
以上の値の多くはマウント時に影響を受ける．つまり，例えば，
(メディア上に保持している値に関係なく)あるビットがある特定の値を持って
いるかのように扱われることがある．
詳しい情報については mount(1) を参照すること．
ファイルシステムによっては，一部のアクセス制御値をサポートしていないこ
とがある．繰り返しになるがこのようなファイルシステムの扱いについては
mount(1)を参照すること．
<!--nakano: 普通は mount(8) じゃないかなあ -->
<p>
<!--O
There is ongoing work to add access control lists (ACLs) and
POSIX capability values to the filesystem,
but these do not exist in stock Linux 2.2.
-->
アクセス制御リスト(ACL, access control list)と POSIX ケーパビリティ値
をファイルシステムに追加する作業が現在行われているが，この機能は
普通 の Linux 2.2 には入っていない．
</sect2>
<!--O
<sect2>Creation Time Initial Values
-->
<sect2>作成時の初期値
<p>
<!--nakano:###-->
<!--O
At creation time, the following rules apply.
When a filesystem object (FSO) is created (e.g. via creat(2)),
the FSO's UID is set
to the process' FSUID. The FSO GID is usually set to the process' FSGID, though
if the containing directory's setgid bit is set or the filesystem's
``GRPID'' flag is set, the FSO GID is set to the
GID of the containing directory.
This special case supports ``project'' directories: to make a ``project''
directory, create a special group for the project,
create a directory for the project owned by that group, then make the
directory setgid: files placed there
are automatically owned by the project.
Similarly, if a new subdirectory is created inside a directory with the
setgid bit set (and the filesystem GRPID isn't set), the new subdirectory
will also have its setgid bit set (so that project subdirectories will
``do the right thing.''); in all other cases the setgid is clear for a new file.
FSO basic access control values (read, write, execute) are computed from
(requested values &amp; &tilde; umask of process).
New files always start with a clear sticky bit and clear setuid bit.
-->
ファイルシステムオブジェクトの生成時には以下の規則が適用される．
ファイルシステムオブジェクト(FSO)が(例えば creat(2) を使って)生成され
たとき，その FSO の UID には，FSO を生成したプロセスの FSUID が設定さ
れる．普通は FSO の GID には，FSO を生成したプロセスの FSGID が設定
されるが，FSO が作られるディレクトリの setgid ビットが設定されている
場合や，ファイルシステムの「GRPID」フラグが設定されている場合には，
FSO の GID にはこのディレクトリの GID が設定される．
この特殊なケースを使うと「プロジェクト」ディレクトリに対応できる．
つまり，「プロジェクト」用のディレクトリを作り，そのプロジェクトのため
の専用のグループを作り，そのグループが所有するプロジェクトのための
ディレクトリを作ってから，そのディレクトリに setgid を設定する．
すると，このディレクトリに作成されたファイルは自動的にプロジェクトのも
のとなる．
同様に，setgid ビットが設定されている(そしてファイルシステムの GRPID
が設定されていない)ディレクトリ内に新しくサブディレクトリを作ると，
そのサブディレクトリの setgid ビットも設定される(したがって，
プロジェクトのサブディレクトリも「正しく」動作する)．それ以外の場合に
は全て，新しいファイルの setgid ビットはクリアされる．
FSO の基本的なアクセス制御値(読み取り，書き込み，実行)は
(要求された値 &amp; &tilde; プロセスの umask 値)によって求められる．
新しいファイルが作られたときは，sticky ビットと setuid ビットは
必ずクリアされた状態になっている．
</sect2>
<!--O
<sect2>Changing Access Control Attributes
-->
<sect2>アクセス制御属性の変更
<p>
<!--O
You can set most of these values with chmod(2) or chmod(1), but see also
chown(1), chgrp(1), and chattr(1).
-->
アクセス制御属性のほとんどは chmod(2) や chmod(1) で設定できる．ただし，
chown(1), chgrp(1), chattr(1) も参照すること．
<p>
<!--O
Note that in Linux, only root can change the owner of a given file.
Some Unix-like systems allow ordinary users to change ownership, but this
causes complications.  For example, if you're trying to limit disk usage,
allowing such operations would allow users to claim that large files
actually belonged to some other ``victim.''
-->
Linux では，あるファイルの所有者を変更できるのは root だけである点に注
意すること．一部の UNIX 的 OS には一般ユーザが所有権を変更できるものが
あるが，これは扱いが面倒になる．例えばディスクの使用量を制限しようとし
た場合，一般ユーザに所有権の変更を許していると，大きなファイルは
誰か別の「被害者」のもののようにできてしまう．
</sect2>
<!--O
<sect2>Using Access Control Attributes
-->
<sect2>アクセス制御情報の利用
<p>
<!--O
Under Linux and most Unix-like systems, reading and writing
attribute values are only checked when the file is opened; they
are not re-checked on every read or write.
A large number of calls use these attributes, since the filesystem is
so central to Linux.
This includes open(2), creat(2), link(2), unlink(2), rename(2),
mknod(2), symlink(2), and socket(2).
-->
Linux およびほとんどの UNIX 的 OS では，属性値の読み書きはファイルを
オープンしたときにしかチェックされない．つまり，一度ファイルをオープン
した後は読み書きするたびの再チェックは行われない．
これらの属性値をしているシステムコールは非常にたくさんある．なぜなら，
ファイルシステムは Linux の中心にとても近い部分にあるからである．
このようなシステムコールには open(2), creat(2), link(2), unlink(2),
rename(2), mknod(2), symlink(2), socket(2) 等がある．
</sect2>
<!--O
<sect2>Filesystem Hierarchy
-->
<sect2>ファイルシステムの階層
<p>
<!--O
Over the years conventions have been built on ``what files to place where'';
please follow them and use them when placing information in the hierarchy.
A summary of this information is in hier(5).
More information is available on the
Filesystem Hierarchy Standard (FHS), which is an update to the previous
Linux Filesystem Structure standard (FSSTND); see
<url url="http://www.pathname.com/fhs">
-->
長年の伝統により「どのファイルをどこに置くか」という約束ごとができている．
情報をファイル階層内に配置するときには，この決まりに従うこと．
この決まりには hier(5) にまとめられている．
さらに詳しい情報は Filesystem Hierarchy Standard (FHS) として入手できる．
この規約は，以前に存在した Linux Filesystem Structure standard (FSSTND) 
を改めたものである．詳しくは <url url="http://www.pathname.com/fhs">
を参照すること．
</sect2>
</sect1>
<sect1>System V IPC
<p>
<!--O
Linux supports System V IPC objects, that is,
System V message queues, semaphore sets, and shared memory segments. 
Each such object has the following attributes:
-->
Linux は System V IPC オブジェクト，すなわち，System V のメッセージ
キュー，セマフォセット，共有メモリセグメントに対応している．
これらのオブジェクトはそれぞれ以下の属性を持っている:
<itemize>
<!--O
<item>read and write permissions for each of creator, creator group, and
others.
-->
<item>作成者，作成者のグループ，その他のユーザに対する読み書きの
パーミッション．
<!--O
<item>creator UID and GID - UID and GID of the creator of the object.
-->
<item>作成者の UID と GID - オブジェクトの作成者の UID と GID．
<!--O
<item>owning UID and GID - UID and GID of the owner of the
object (initially equal to the creator UID).
-->
<item>所有者の UID と GID - オブジェクトの所有者の UID と GID
(初期状態では作成者の UID, GID と同じ)．
</itemize>
<p>
<!--O
When accessing such objects, the rules are as follows:
-->
このようなオブジェクトにアクセス際に適用される規則は以下の通りである:
<itemize>
<!--O
<item>if the process has root privileges, the access is granted.
-->
<item>プロセスが root 権限を持っていればアクセスは許可される．
<!--O
<item>if the process' EUID is the owner or creator UID of the object,
then the appropriate creator permission bit is
checked to see if access is granted.
-->
<item>もし，プロセスの EUID がオブジェクトの所有者か作成者の UID なら
ば，該当する作成者のパーミッションビットがチェックされ，アクセスを
許可するかどうかが確認される．
<!--O
<item>if the process' EGID is the owner or creator GID of the object,
or one of the process' groups is the owning or creating GID of the object,
then the appropriate creator group permission bit is checked for access.
-->
<item>プロセスの EGID がオブジェクトの所有者か作成者の GID であるか，
あるいはプロセスのグループのどれかがオブジェクトの所有者か作成者の GID
ならば，該当する作成者のグループパーミッションビットがアクセスに
際してチェックされる．
<!--O
<item>otherwise, the appropriate ``other'' permission bit is checked
for access.
-->
<item>上記のいずれでもない場合は，該当する「その他のユーザ」の
パーミッションビットがアクセスに際してチェックされる．
</itemize>
<p>
<!--O
Note that root, or a process with the EUID of either the owner or creator,
can set the owning UID and owning GID and/or remove the object.
More information is available in ipc(5).
-->
root が実行したプロセスまたは所有者か作成者の EUID を持つプロセスは，
所有者 UID と所有者 GID を設定したり，オブジェクトを削除できる．
詳しい説明が ipc(5) にある．
</sect1>

<!--O
<sect1>Sockets and Network Connections
-->
<sect1>ソケットとネットワーク接続
<p>
<!--O
Sockets are used for communication, particularly over a network.
Socket(2) creates an endpoint for communication and returns a descriptor;
see socket(2) for more information and cross-references to
other relevant information.
Note that binding to TCP and UDP local
port numbers less than 1024 requires root privilege in Linux
(binding to a remote port number less than 1024 requires no special privilege).
-->
ソケットは通信，特にネットワーク通信で用いられる．
socket(2) は通信用の端点(endpoint)を作成し，デスクリプタを返す．
詳しくは socket(2) や，その他の関連情報を参照すること．
Linux では，TCP と UDP を 1024 番未満のローカルポートに割り当てるには
root 権限が必要な点に注意すること(1024 番未満のリモートポートに割り当
てる場合には特別な権限は必要ない)．
</sect1>

<!--O
<sect1>Quotas and Limits
-->
<sect1>quota とリソース制限
<p>
<!--O
Linux has mechanisms to support filesystem quotas and process resource limits.
Be careful with terminology here, because they both have ``hard'' and
``soft'' limits but the terms mean slightly different things.
-->
Linux にはファイルシステムの quota とプロセスのリソース制限を行うため
の機構がある．
ここでは用語に注意すること．というのも，quota とリソース制限には
「ハードな」制限と「ソフトな」制限があるが，これらの用語は少し違う
意味を持つからである．
<p>
<!--O
You can define storage (filesystem) quota limits on each mountpoint
for the number of blocks of storage and/or the number of unique files
(inodes) that can be used by a given user or a given group.
A ``hard'' quota limit is a never-to-exceed limit, while a
``soft'' quota can be temporarily exceeded.
See quota(1), quotactl(2), and quotaon(8).
-->
記憶装置(ファイルシステム)の quota 制限を各マウントポイントごとに定義
できる．定義は，指定されたユーザかグループが使用できる
記憶装置のブロック数か，ユニークなファイル数(inode の数)について行う．
「ハード」な quota 制限は決して超えることができない制限であるが，
「ソフト」な quota 制限は一時的に超過することが許される．
詳しくは quota(1), quotactl(2), quotaon(8) を参照すること．
<p>
<!--O
The rlimit mechanism supports a large number of process quotas, such as
file size, number of child processes, number of open files, and so on.
There is a ``soft'' limit (also called the current limit) and a
``hard limit'' (also called the upper limit).
The soft limit cannot be exceeded at any time, but through calls it can
be raised up to the value of the hard limit.
See getrlimit(), setrlimit(), and getrusage().
-->
rlimit 機構は，プロセスに対する非常に多くの種類の quota に対応している．
例えばファイルサイズ，子プロセスの数，オープンできるファイルの数などで
ある．
制限には「ソフトな」制限(現在の制限(current limit)とも呼ばれる)と「ハード」
な制限(上限(upper limit)とも呼ばれる)がある．
ソフトな制限を超えることはどんな場合も許されないが，ソフトな制限値は
システムコールを使ってハードな上限値まで上げることができる．
詳しくは getrlimit(), setrlimit(), getrusage() を参照すること．
</sect1>

<!--O
<sect1>Audit
-->
<sect1>監査
<p>
<!--O
Currently the most common ``audit'' mechanism is syslogd(8).
You might also want to look at wtmp(5), utmp(5), lastlog(8), and acct(2).
Some server programs (such as the Apache web server)
also have their own audit trail mechanisms.
-->
現在もっとも一般的な「監査」機構は syslogd(8) である．
wtmp(5), utmp(5), lastlog(8), acct(2) も見ると良いだろう．
サーバプログラムによっては(例えば WWW サーバの Apache 等)は，独自の
監査機構も備えている．
</sect1>

<sect1>PAM
<p>
<!--O
When authenticating, most Linux systems use Pluggable Authentication
Modules (PAM).  This permits configuration of authentication
(e.g., use of passwords, smart cards, etc.).
PAM will be discussed more fully later in this document.
-->
認証を行う際，ほとんどの Linux システムでは PAM
(Pluggable Authentication Modules, 差し替え可能な認証モジュール)
が用いられる．PAM を用いると認証の設定を行うことができる(例えば
パスワードの使用，スマートカードの使用など)．
PAM については，この論文の後の方で詳しく説明する．
</sect1>
</sect>

<!--O
<sect>Validate All Input
-->
<sect>全ての入力を検証する
<p>
<!--O
Some inputs are from untrustable users, so those inputs must be validated
(filtered) before being used.
You should determine what is legal and reject anything that does
not match that definition.
Do not do the reverse (identify what is illegal and reject those cases),
because you are likely to forget to handle an important case.
Limit the maximum character length (and minimum length if appropriate),
and be sure to not lose control when such lengths are exceeded
(see the buffer overflow section below for more about this).
-->
入力によっては信頼できないユーザから行われることがあり，こういった場合
には入力を使用する前に検証(フィルタリング)する必要がある．
何が正しいかを決めておき，その定義に合わないものは全て排除すべきである．
その逆(何が正しくないかを決めておき，それに当てはまるものを排除する)を
行ってはならない．なぜなら，重要なケースを処理し忘れるかもしれないから
である．
文字列の最大の長さ(必要なら最小の長さ)を制限しておき，その長さを超えた
ときにも制御を失わないようにすること(この問題についての詳しい説明は，
「バッファオーバーフロー」の節を参照すること)．
<p>
<!--O
For strings, identify the legal characters or legal patterns
(e.g., as a regular expression) and reject anything not matching that form.
There are special problems when strings contain control characters
(especially linefeed or NIL) or shell metacharacters; it is often
best to ``escape'' such metacharacters immediately when the input is received so
that such characters are not accidentally sent.
CERT goes further and recommends escaping all characters
that aren't in a list of characters not needing escaping [CERT 1998, CMU 1998].
see the section on ``limit call-outs to valid values'', below, for more
information.
-->
文字列の場合は，正しい文字やパターンを(例えば正規表現として)決めておき，
それに当てはまらないものを全て排除すること．
文字列が制御文字(特に改行文字や NIL 文字)やシェルのメタ文字を含むとき
には特別な問題が起きる．したがって，このようなメタ文字は入力された時点
ですぐに「エスケープ」し，間違って送られてしまわないようにするとよい
だろう．
CERT はこれをさらに進めて，エスケープする必要がない文字のリストに含ま
れていない全ての文字をエスケープすることを推奨している[CERT 1998, CMU 1998]．
詳しくは「呼び出しの際に正しい値だけを使う」の節を参照すること．
<p>
<!--O
Limit all numbers to the minimum (often zero) and maximum allowed values.
Filenames should be checked; usually you will want to not include ``..''
(higher directory) as a legal value.
In filenames it's best to prohibit any change in directory, e.g., by not
including ``/'' in the set of legal characters.
A full email address checker is actually quite complicated, because there
are legacy formats that greatly complicate validation if you need
to support all of them; see mailaddr(7) and IETF RFC 822 [RFC 822]
for more information if such checking is necessary.
-->
全ての数値について，許可する最小値(0 のことが多い)と最大値を決める．
ファイル名はチェックすべきだ．普通は「..」(上位ディレクトリ)は正しい値と
は認めないとよいだろう．
ファイル名では，ディレクトリの変更は全て禁止するとよいだろう．例えば，
「/」を正しい文字の集合に含めないなどの方法がある．
電子メールアドレスを完全にチェックしようとすると非常に面倒である．なぜ
なら，全てのアドレスに対応しようとしても，検証が非常に面倒な古い形式の
アドレスが存在するからである．このようなチェックが必要であれば，
mailaddr(7) と IETF RFC 822 [RFC 822] に詳しい情報がある．
<p>
<!--O
These tests should usually be centralized in one place so that the
validity tests can be easily examined for correctness later.
-->
これらの検査は普通，一ヶ所で集中して行うべきである．
なぜなら，後で正当性の検査自体の正確さの確認を行うことが容易になるから
である．
<p>
<!--O
Make sure that your validity test is actually correct; this is particularly
a problem when checking input that will be used by another program
(such as a filename, email address, or URL).
Often these tests are have subtle errors, producing the so-called
``deputy problem'' (where the checking program
makes different assumptions than the program that actually uses the data).
-->
正当性の検証するコードを自分で作った場合は，それが実際に正しく動作する
ことを確かめること．このことは，
別のプログラムが使う入力(ファイル名や電子メールアドレス，URL 等)を
チェックする場合には特に重要である．
このようなテストには気づきにくい間違いがあることが多く，いわゆる
「代理人問題」(チェック用のプログラムの前提が，実際にデータを使う
プログラムの前提と異なる問題)を起こすことがある．
<p>
<!--O
The following subsections discuss different kinds of inputs to a program;
note that input includes process state such as environment variables,
umask values, and so on.
Not all inputs are under the control of an untrusted user, so you need
only worry about those inputs that are.
-->
以下の節では，プログラムへ与える様々な種類の入力について説明する．
この入力には環境変数や umask 値など，プロセスが持っている状態も含む点
に注意すること．
必ずしも全ての入力を信頼できないユーザが行うわけではないので，注意する
必要があるのは信頼できないユーザからの入力だけでよい．

<!--O
<sect1>Command line
-->
<sect1>コマンドライン
<p>
<!--O
Many programs use the command line as an input interface, accepting
input by being passed arguments.
A setuid/setgid program has a command line interface provided to it by
an untrusted user, so it must defend itself.
Users have great control over the command line (through calls such
as the execve(3) call).
Therefore, setuid/setgid programs must validate the command line inputs and
must not trust the name of the program reported by command line argument zero
(the user can set it to any value including NULL).
-->
多くのプログラムはコマンドラインを入力のインタフェースとして用い，引数
として渡すことにより入力を受け取る．
setuid/setgid されたプログラムは信頼できないユーザからコマンドライン
入力を受け取ることがあるので，自分自身で防御しなければならない．
また，ユーザはコマンドラインをかなり自由に扱うことができる(execve(3)
等のシステムコールを用いる)．
したがって，setuid/setgid されるプログラムはコマンドライン入力を検証し
なければならないし，コマンドライン引数 0 が示すプログラム名を信用して
はならない(ユーザはプログラム名に NULL を含めた自由な値を設定できる)．

<!--O
<sect1>Environment Variables
-->
<sect1>環境変数
<p>
<!--O
By default, environment variables are inherited from a process' parent.
However, when a program executes another one it can set the environment
variables to arbitrary values.
This is dangerous to setuid/setgid programs, because their invoker can
control their environment variables, sending them on.
Since they are usually inherited, this also applies transitively.
-->
デフォルトでは環境変数は親プロセスから引き継がれる．
しかし，あるプログラムが他のプログラムを実行する際には，環境変数を任意
の値に設定することができる．
これは setuid/setgid されるプログラムにとって危険である．なぜなら，このよ
うなプログラムを呼び出す元のプログラムは環境変数を制御して送り付けるこ
とができるからである．
環境変数は普通は引き継がれるので，この危険性も引き継がれていく．
<p>
<!--O
Environment variables are stored in a format that allows multiple values
with the same field (e.g., two SHELL values).
While typical command shells prohibit doing this, a cracker can create such a
situation; some programs may test one value but use a different one
in this case.
Even worse, many libraries and programs are controlled by environment
variables in ways that are obscure, subtle, or even undocumented.
For example, the IFS variable is used by the <it>sh</it> and <it>bash</it>
shell to determine which characters separate command line arguments.
Since the shell is invoked by several low-level calls, setting IFS to
unusual values can subvert apparently-safe calls.
-->
環境変数は，同じフィールドに複数の値を持てる形式で保存される(例えば 
SHELL 変数を 2 つ持てる)．
普通のコマンドシェルではこのような設定は禁止されているが，クラッカーは
このような状況を作ることができる．つまりプログラムは 1 つの値しかチェッ
クしないが，実際には別の値が使われることもある．
さらに悪いことに，多くのライブラリやプログラムは環境変数で制御されてい
るが，制御方法があいまいだったり，分かりにくかったり，そもそも文書化さ
れていないことさえある．
例えば，<it>sh</it> と <it>bash</it> は IFS 変数を使ってコマンドライン
引数を区切る文字を決める．
シェルはいくつかの低レベルシステムコールを使って呼び出されるので，
IFS に普通でない値を設定することにより，安全そうに見えるシステムコール
を破壊することができる．
<p>
<!--O
For secure setuid/setgid programs, the short list of environment variables
needed as input (if any) should be carefully extracted.
Then the entire environment should be erased by setting the global variable
<it>environ</it>
to NULL, followed by resetting a small set of necessary environment
variables to safe values (<it>not</it> values from the user).
These values usually include PATH (the list of directories to search for
programs, which should <it>not</it> include
the current directory), IFS (to its default of `` \t\n''), and TZ (timezone).
-->
setuid/setgid されたプログラムを安全にするには，まず(もし存在するなら)
入力として必要な環境変数の短いリストを注意深く取り出す．
次に，大域変数 <it>environ</it> に NULL を設定することにより環境変数
全てを消去し，その後に必要な環境変数の小さい集合に安全な値を再設定する
(ユーザが指定した値は<it>含めない</it>)．
このような値としては PATH(プログラムを探す対象のディレクトリのリスト．
カレントディレクトリを含めては<it>ならない</it>),
IFS(デフォルトの `` \t\n'' を設定すること), TZ(タイムゾーン)等がある．

<!--O
<sect1>File Descriptors
-->
<sect1>ファイルデスクリプタ
<p>
<!--O
A program is passed a set of ``open file descriptors,'' that is,
pre-opened files.
A setuid/setgid program must deal with the fact that the user gets to
select what files are open and to what (within their permission limits).
A setuid/setgid program must not assume that opening a new file will always
open into a fixed file descriptor id.
It must also not assume that standard input, standard output, and standard
error refer to a terminal or are even open.
-->
プログラムには「オープンしたファイルデスクリプタ」の集合が渡される．
これは予めオープンされているファイルである．
setuid/setgid されたプログラムは，オープンするファイルをユーザが
(パーミッションの制限内で)選べるという事実に対処できなければならない．
setuid/setgid されたプログラムは，新しいファイルをオープンしたときに常
に決まったファイルデスクリプタ ID でオープンされると仮定してはならない．
標準入力，標準出力，標準エラー出力が端末であることや，あるいはオープン
されていることすら仮定してはならない．

<!--O
<sect1>File Contents
-->
<sect1>ファイルの内容
<p>
<!--O
If a program takes directions from a given file, it must not give it
special trust unless only a trusted user can control its contents.
This means that an untrusted user must not be able to modify the file,
its directory, or any of its parent directories.
Otherwise, the file must be treated as suspect.
-->
あるプログラムが指定されたファイルから指示を受ける場合は，信頼している
ユーザしかファイルの内容を制御できない場合を除き，そのファイルを特別に
信頼してはならない．
つまり，信頼できないユーザはそのファイルやディレクトリ，そしてファイル
の全ての親ディレクトリを編集できてはならない．
そうでない場合には，このファイルは信頼できないものとして扱わなければな
らない．

<!--O
<sect1>CGI Inputs
-->
<sect1>CGI の入力
<p>
<!--O
CGI inputs are internally a specified set of environment variables and
standard input.
These values must be validated.
-->
CGI の入力は，内部的には設定された環境変数の集合と標準入力である．
これらの値は検証しなければならない．
<p>
<!--O
One additional complication is that many CGI inputs are provided in
so-called ``URL-encoded'' format, that is, some values are written in the
format %HH where HH is the hexadecimal code for that byte.
You or your CGI library must handle these inputs correctly by
URL-decoding the input and then checking
if the resulting byte value is acceptable.
You must correctly handle all values, including problematic
values such as %00 (NIL) and %0A (newline).
Don't decode inputs more than once, or input such as ``%2500''
will be mishandled (the %25 would be translated to ``%'', and the resulting
``%00'' would be erroneously translated to the NIL character).
-->
その他の難しい点としては，CGI への入力の多くがいわゆる「URL エンコード」
，つまり一部の値が %HH の形で書かれている形式で与えられる点がある．
ここで HH はそのバイト値を表す 16 進コードである．
CGI ライブラリは，入力を URL デコードして，さらにデコードによって得ら
れたバイト値が適切かどうかをチェックすることにより，入力を正しく処理し
なければならない．
%00 (NIL) や %0A (改行) のように問題がある値を含め，全ての値を正しく扱
えなければならない．
入力を複数回デコードしてはならない．そうでないと，「%2500」のような値
の処理を誤ってしまう(まず %25 が「%」に変換され，その結果得られた「%00」
が間違って展開されて NIL 文字になってしまう)．
<p>
<!--O
CGI scripts are commonly attacked by including special characters in their
inputs; see the comments above.
-->
CGI スクリプトは入力に特殊文字を含める攻撃をよく受ける．
これについては上記のコメントを参照すること．
<p>
<!--O
Some HTML forms include client-side checking to prevent some illegal values.
This checking can be helpful for the user but is useless for security, because
attackers can send such ``illegal'' values directly to the web server.
As noted below (in the section on trusting only trustworthy channels),
servers must perform all of their own input checking.
-->
一部の HTML form は，不正な値をある程度取り除くためにクライアント側で
のチェックを行う．
このチェックやユーザの手助けにはなるが，セキュリティの役には立たない．
なぜなら，攻撃者はこういった「不正な」値を直接ウェブサーバに送ることが
できるからである．
(「信頼できる経路しか信頼しない」の節で)後述するように，サーバは自分の
全ての入力についてテストを実行しなければならない．

<!--O
<sect1>Other Inputs
-->
<sect1>他の入力
<p>
<!--O
Programs must ensure that all inputs are controlled; this is particularly
difficult for setuid/setgid programs because they have so many such inputs.
Other inputs programs must consider include
the current directory,
signals, memory maps (mmaps), System V IPC, and the umask (which determines
the default permissions of newly-created files).
Consider explicitly changing directories (using chdir(2)) to an appropriately
fully named directory at program startup.
-->
プログラムは必ず全ての入力を制御できていなければならない．これは
setuid/setgid されたプログラムでは特に難しい．なぜなら，そのような入力
が非常にたくさんあるからである．
プログラムが考慮しなければならない他の入力としては，カレントディレクトリ，
シグナル，メモリマップ(mmap)，System V IPC, umask (新しく生成される
ファイルのデフォルトのパーミッションを決める)等がある．
プログラムの起動時に，適切かつ完全に指定されたディレクトリに(chdir(2) 
を用いて)明示的に移動することも考慮すること．

<!--O
<sect1>Limit Valid Input Time and Load Level
-->
<sect1>有効な入力時間と負荷レベルの制限
<p>
<!--O
Place timeouts and load level limits, especially on incoming network data.
Otherwise, an attacker might be able to easily cause a denial of service
by constantly requesting the service.
-->
タイムアウトと負荷レベルの制限は行うこと．特にネットワークからの入力
データに対してはこの制限を行うこと．
さもないと，攻撃者はサービスの要求を送り続けることにより，簡単に
サービス妨害攻撃を行えてしまう．

</sect>

<!--O
<sect>Avoid Buffer Overflow
-->
<sect>バッファオーバーフローの回避
<p>
<!--O
An extremely common security flaw is the ``buffer overflow.''
Technically, a buffer overflow is a problem with the program's internal
implementation, but it's such a common and serious problem that
I've placed this information in its own chapter.
To give you an idea of how important this subject is,
at the CERT, 9 of 13 advisories in 1998 and at least half of
the 1999 advisories involved buffer overflows.
An informal survey on Bugtraq found that approximately 2/3 of the
respondants felt that buffer overflows were the leading cause of
security vulnerability (the remaining respondants identified
``misconfiguration'' as the leading cause) [Cowan 1999].
-->
非常に一般的なセキュリティ的欠陥に「バッファオーバーフロー」がある．
技術的には，バッファオーバーフローはプログラムの内部的実装の問題だが，
バッファオーバーフローは一般的かつ重大な問題なので，この問題の説明に
章をひとつ割くことにする．
この問題がどれだけ重要かというと，CERT による勧告の 1998 年 9, 13 号，
そして 1999 年の勧告の少なくとも半分がバッファオーバーフロー
に関係している．
Bugtraq における非公式の調査によると，
セキュリティの弱点の一番多い原因はバッファオーバーフローであると回答者
の約 2/3 が感じている(残りの回答者は「設定ミス」であるとしている)
[Cowan 1999]．
<p>
<!--O
A buffer overflow occurs when you write a set of values
(usually a string of characters) into a fixed length buffer
and keep writing past its end.
These can occur when reading input from the user into a buffer,
but they can also occur during other kinds of processing in a program.
-->
バッファオーバフローが起こるのは，値の集合(普通は文字列)を固定長の
バッファに書き込む際にバッファの終端を超えて書き込み続けたときである．
バッファオーバーフローはユーザからの入力をバッファに読み込む時に起こる
可能性があるが，他の種類の処理をプログラム中で行っている最中にも起こる
可能性がある．
<p>
<!--O
If a secure program permits a buffer overflow, it can usually be
exploited by an adversary.
If the buffer is a local C variable, the overflow can be used to
force the function to run code of an attackers' choosing
(see [Aleph1 1996] for more details).
A buffer in the heap isn't much better; attackers can use this to
control variables in the program.
-->
安全であるべきプログラムでバッファオーバーフローを許すと，普通は
攻撃者が悪用できてしまう．
バッファが C 言語のローカル変数ならば，オーバーフローを利用して
攻撃者の好きなコードを実行する関数を呼ばせることができる
(詳しくは [Aleph1 1996] を参照すること)．
バッファがヒープ中にあればまだましであるが，攻撃者はこれを利用して
プログラム中の変数を制御することができる．
<p>
<!--O
Some programming languages are essentially immune to this problem, either
because they automatically resize arrays (e.g., Perl), or because they normally
detect and prevent buffer overflows (e.g., Ada95).
However, the C language provides absolutely no protection against
such problems, and C++ can be easily used in ways to cause this problem too.
-->
プログラミング言語によっては，本質的にこの問題の影響を受けない．
その理由としては，言語が自動的に配列のサイズを変える場合(例: Perl)や，
普通はバッファオーバーフローを検出して防ぐ場合(例: Ada95)がある．
しかし，C はバッファオーバーフローを防ぐ手段を全く持たないし，C++ も
この問題を起こすような使い方が簡単にできてしまう．
<!--O
<sect1>Dangers in C/C++
-->
<sect1>C/C++ における危険
<p>
<!--O
C users must avoid using dangerous functions that do not check bounds
unless they've ensured the bounds will never get exceeded.
Functions to avoid in most cases include
the functions strcpy(3), strcat(3), sprintf(3), and gets(3).
These should be replaced with functions such as strncpy(3), strncat(3),
snprintf(3), and fgets(3) respectively, but see the discussion below.
The function strlen(3) should be avoided unless you can ensure that there
will be a terminating NIL character to find.
Other dangerous functions that may permit buffer overruns (depending on their
use) include
fscanf(3), scanf(3), vsprintf(3), realpath(3), getopt(3), getpass(3),
streadd(3), strecpy(3), and strtrns(3).
-->
C を使う場合は，境界を絶対に超えないことが確実な場合を除き，
境界をチェックしない危険な関数の使用を避けるべきである．
多くの場合に避けるべき関数としては，
strcpy(3), strcat(3), sprintf(3), gets(3) 等がある．
これらの関数はそれぞれ strncpy(3), strncat(3),
snprintf(3), fgets(3) で置き換えるべきであるが，詳しくは後で説明する．
関数 strlen(3) は，文字列の終端の NIL 文字が見つかることが確かで
ない限りは利用を避けるべきである．
この他に(使い方によっては)バッファオーバーフローを許すかもしれない関数
としては，fscanf(3), scanf(3), vsprintf(3), realpath(3), getopt(3),
getpass(3), streadd(3), strecpy(3), strtrns(3) がある．
</sect1>
<!--O
<sect1>Library Solutions in C/C++
-->
<sect1>ライブラリを用いた解決方法(C/C++)
<p>
<!--O
One solution in C/C++ is to use library functions that do not have
buffer overflow problems.
-->
C/C++ における解決方法の一つは，バッファオーバーフローの問題を持たない
ライブラリ関数を使うことである．
<p>
<!--O
The ``standard'' solution to prevent buffer overflow in C
is to use the standard C library calls that defend against these
problems.
This approach depends heavily on the standard library functions
strncpy(3) and strncat(3).
If you choose this approach, beware: these calls have somewhat surprising
semantics and are hard to use correctly.
The function strncpy(3) does not NIL-terminate the destination string
if the source string length is at least equal to the destination's, so
be sure to set the last character of the destination string to NIL after
calling strncpy(3).
Both strncpy(3) and strncat(3) requires that you pass
the amount of space left available, a computation
that is easy to get wrong (and getting it wrong could permit a
buffer overflow attack).
Neither provide a simple mechanism to determine if an overflow has occurred.
Finally, strncpy(3) has a performance penalty compared to the strcpy(3)
it replaces, because strncpy(3) zero-fills the remainder of the destination.
-->
C でバッファオーバーフローを起こさないための「標準的」な解決方法は，
このような問題を受けない C ライブラリの標準関数を使うことである．
このアプローチでは，標準ライブラリ関数の strncpy(3) と strncat(3) に
深く頼ることになる．このアプローチを使う場合は注意すること: これらの
関数のセマンティクスは少し変わっていて，正しく使うことが難しい．
関数 strncpy(3) は，コピー元の文字列の長さがコピー先の長さ以上の場合，
コピー先の文字列を NIL で終端しない．したがって，strncpy(3) を呼び出し
た後は，コピー先の文字列の最後の文字に必ず NIL を設定すること．
strncpy(3) と strncat(3) のいずれでも，利用可能な容量の残りを渡してや
らなければならないが，この計算は間違いやすい(そして，この計算を間違う
とバッファオーバーフロー攻撃を許すことになる)．
どちらの関数も，バッファオーバーフローが起きたかどうかを調べる簡単な
仕組みを持っていない．
最後に，strncpy(3) は置き換えの対象である strcpy(3) よりも性能的には不
利である．その理由は，strncpy(3) はコピー先の残りの領域を 0 で埋めるか
らである．
<p>
<!--O
An alternative, being employed by OpenBSD, is the
strlcpy(3) and strlcat(3) functions by Miller and de Raadt [Miller 1999].
This is a minimalist approach that provides C string
copying and concatenation with a different (and less error-prone) interface.
Source and documentation of these functions
are available under a BSD-style license at
<url url="ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3">.
-->
別の方法として(これは OpenBSD よりもらってきた方法である)，
Miller と de Raadt が開発した strlcpy(3) と strlcat(3) がある[Miller 1999]．
これは最小化アプローチであり，，文字列のコピーと連結を標準の関数群と異
なる(そして間違いが起こりにくい)インタフェースで C 言語に提供する．
これらの関数のソースコードと文書は，
<url url="ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3">
からBSD 形式のライセンスに基づいて入手できる．
<p>
<!--O
Another alternative is to dynamically reallocate all strings instead of using
fixed-size buffers.
This general approach is recommended by the GNU programming guidelines.
One toolset for C that dynamically reallocates strings automatically
is the ``libmib allocated string functions'' by
Forrest J. Cavalier III, available at
<url url="http://www.mibsoftware.com/libmib/astring">.
The source code is open source; the documentation is not but it is
freely available.
-->
さらに別の方法としては，固定長のバッファを用いず，全ての文字列を動的に
割り当て直す方法がある．
この汎用的な方法は，GNU プログラミングガイドラインが推奨している．
C 言語で文字列の動的な再割り当てを自動的に行うためのツールセットの一つ
として，Forrest J. Cavalier III による「libmib allocated string functions」
がある．これは
<url url="http://www.mibsoftware.com/libmib/astring">
から入手できる．
このソースコードはオープンソースである．文書はオープンソースではないが，
自由に入手できる．
<p>
<!--O
There are other libraries that may help.
For example, the glib library is widely available on open source platforms
(the GTK+ toolkit uses glib, and glib can be used separately without GTK+).
At this time I do not have an analysis showing definitively that the
glib library functions protect against buffer overflow, but this seems likely.
Hopefully a later edition of this document will confirm which glib functions
can be used to avoid buffer overflow issues.
-->
役に立つかもしれないライブラリは他にもある．
例えば，glib ライブラリはオープンソースのプラットフォームで広く利用可
能である(GTK+ ツールキットは glib を用いているが，glib は GTK+ とは別
に利用可能である)．
今回は glib を解析して，glib のライブラリ関数がバッファオーバーフロー
を起こさないことを明らかにすることはできなかったが，これは正しいようで
ある．
本論文の後の版では，どの glib 関数を使えばバッファオーバーフローの問題
を避けられるかを確かめられると考えている．
</sect1>
<!--O
<sect1>Compilation Solutions in C/C++
-->
<sect1>コンパイルを行う解決方法(C/C++)
<p>
<!--O
A completely different approach is to use compilation methods that perform
bounds-checking (see [Sitaker 1999] for a list).
In my opinion, such tools are very useful in having multiple layers of
defense, but it's not wise to use this technique as your sole defense.
There are at least two reasons for this.
First of all, most such tools only provide partial defense against
buffer overflows (and the ``complete'' defenses are generally
12-30 times slower); C and C++ were simply not designed to protect
against buffer overflow.
Second of all, for open source programs you cannot be certain what tools
will be used to compile the program; using the default ``normal'' compiler
for a given system might suddenly open security flaws.
-->
全く別のアプローチとして，境界チェックを行うコンパイル方法を用いること
ができる(方法の一覧については [Sitaker 1999] を参照)．
筆者の意見では，こういったツールは防御を何重にもする場合には非常に役立
つが，この技術を単独の防御手段として用いるのは賢明とは言えない．
この理由は少なくとも 2 つある．
まず最初の理由は，こういったツールのほとんどは一部の
バッファオーバーフローしか防げない(「完全」に防ごうとすると，一般に
速度が 12-30 倍遅くなる)．
これは単に，C や C++ はバッファオーバーフローを防ぐようには設計されて
いないからである．
次の理由としては，オープンソースのプログラムでは，プログラムのコンパイ
ルする際に使われるツールがはっきりしない．したがって，あるシステムの
デフォルトの「普通」のコンパイラを使ったとたんにセキュリティの欠陥が生
じることになる．
<p>
<!--O
One of the more useful tools is ``StackGuard,'' which works by inserting
a ``guard'' value (called a ``canary'')
in front of the return address; if a buffer overflow
overwrites the return address, the canary's value (hopefully) changes
and the system detects this before using it.
This is quite valuable, but note that this does not protect against
buffer overflows overwriting other values (which they may still be able
to use to attack a system).
There is work to extend StackGuard to be able to add canaries to other
data items, called ``PointGuard.''
PointGuard will automatically protect certain values (e.g., function
pointers and longjump buffers).
However, protecting other variable types using PointGuard
requires specific programmer intervention (the programmer
has to identify which data values must be protected with canaries).
This can be valuable, but it's easy to accidentally omit
protection for a data value you didn't think needed protection -
but needs it anyway.
More information on StackGuard, PointGuard, and other alternatives
is in Cowan [1999].
-->
より便利なツールのひとつに「StackGuard」がある．このツールは「防御」の
ための値(「canary(カナリア)」と呼ばれる)を復帰アドレスの前に挿入する．
もしバッファオーバーフローによって復帰アドレスが書き換えられると，
この canary 値が(多分)変化し，システムはそのアドレスを使う前に
バッファオーバーフローを検出できる．
このツールは非常に重要だが，他の値を書き換えるようなバッファオーバーフロー
は防げない点に注意すること．
StackGuard を拡張して他のデータ要素にも canary 値を追加できるツールが
ある．これは「PointGuard」と呼ばれている．
PointGuard は特定の値(例えば関数へのポインタや longjump バッファ等)を
自動的に保護する．
しかし，PointGuard を使って他の型の変数を守るためには，プログラマが
特定の仲介作業を行う必要がある(プログラマは，canary 値を使って
守るべきデータを指定しなければならない)．
このツールは重要だが，保護はいらないと考えていたが実は保護が必要な
データの保護を間違って省略してしまいやすい．
StackGuard, PointGuard やこれらの代わりとなるツールに関する詳しい情報
ついては，Cowan [1999] を参照すること．
<p>
<!--O
As a related issue, you could modify the Linux kernel so that
the stack segment is not executable; such a patch to Linux does exist
(see Solar Designer's patch, which includes this, at
<url url="http://www.openwall.com/linux/">
However, as of this writing this is not built into the Linux kernel.
Part of the rationale is that this is less protection than it seems;
attackers can simply force the system to call other ``interesting'' locations
already in the program (e.g., in its library, the heap,
or static data segments).
Also, sometimes Linux does require executable code in the stack,
e.g., to implement signals and to implement GCC ``trampolines.''
Solar Designer's patch does handle these cases, but this does
complicate the patch.
Personally, I'd like to see this merged into the main Linux
distribution, since it does make attacks somewhat more difficult and
it defends against a range of existing attacks.
However, I agree with Linus Torvalds and others
that this does not add the amount of protection it would appear to and
can be circumvented with relative ease.
You can read Linus Torvalds' explanation for not including this support at
<url url="http://lwn.net/980806/a/linus-noexec.html">.
-->
関連事項として，Linux カーネルを修正してスタックセグメントを実行可能で
なくすることもできる．このようなパッチは実際に存在する(
Solar Designer のパッチにこの機能が含まれている．
パッチは <url url="http://www.openwall.com/linux/"> から入手できる)．
しかし，この論文を書いている時点では，このパッチは Linux カーネルには
取り込まれていない．その根拠のひとつは，このパッチは見ためほど
防御効果がないことである．つまり，攻撃者は単に
既にプログラムに入っている他の「面白い」場所(例えば，ライブラリ内，ヒー
プ内，静的データセグメント等)をシステムに呼ばせることができるのである．
また，Linux はスタック内に実行可能なコードを必要とすることもある．
例えば，シグナルの実装や，GCC の「トランポリン」を実装する時である．
&lsqb;訳注: 「トランポリン」とは，入れ子になった関数に入るために実行時
に生成されるコードのことです&rsqb;
<!--
fujiwara: GCC ``trampolines'' って何を指しているんでしょう?
-->
<!-- cz:
gcc でいうトランポリンは "Trampolines: Code set up at run time to enter a nested function." だそうです。http://www.bekkoame.ne.jp/~bero/gnudocj/gcc/gcc_19.htm#SEC207 より
-->
Solar Designer のパッチはこれらのケースにも対処できるが，そのために
パッチが複雑になっている．
個人的にはこのパッチが本家の Linux 配布に組み込まれることを希望してい
る．なぜなら，このパッチにより攻撃がいくらか困難になるし，ある範囲の
既存の攻撃を防ぐことができるからである．
しかし，このパッチは見ためほど防御を強化しないことと，比較的容易に出し
抜ける点については筆者は Linus Torvalds たちと同意見である．
この機能を含めないことに関する Linus Torvalds の説明は
<url url="http://lwn.net/980806/a/linus-noexec.html">
で読むことができる．
<p>
<!--O
In short, it's better to work first on developing a correct program
that defends itself against buffer overflows.
Then, after you've done this, by all means use techniques and tools
like StackGuard as an additional safety net.
If you've worked hard to eliminate buffer overflows in the code itself,
then StackGuard is likely to be more effective because there will be
fewer ``chinks in the armor'' that StackGuard will be called on to protect.
-->
要約すると，まずはバッファオーバーフローによる攻撃を受けない正しい
プログラムを開発する方がよいということである．
そして，それを行った上で，StackGuard 等の技術やツールを追加の安全ネット
として使うとよい．
コード自身からバッファオーバーフローを無くすように努力すれば，
StackGuard もさらに効果的に使えるだろう．なぜなら，
防御のために StackGuard を呼び出すこととなる「鎧の隙間」が少なくなるか
らである．
</sect1>
<!--O
<sect1>Other Languages
-->
<sect1>他の言語の使用
<p>
<!--O
The problem of buffer overflows is an argument for using
many other programming languages
such as Perl, Python, and Ada95, which protect against buffer overflows.
Using those other languages does not eliminate all problems, of course;
in particular see the discussion under ``limit call-outs to valid values''
regarding the NIL character.
There is also the problem of ensuring that those other languages'
infrastructure (e.g., run-time library) is available and secured.
Still, you should certainly consider using other programming languages
when developing secure programs to protect against buffer overflows.
-->
バッファオーバーフローの問題は，バッファオーバーフローに対して安全な
Perl, Python, Ada95 といった他の言語でも問題となる．
もちろん，こういった言語を使ったからといって全ての問題がなくなるわけで
はない．特に「呼び出しの際に正しい値だけを使う」で述べられている NIL 
文字に関する説明を参照すること．
また，他の言語のインフラ(例えば実行時ライブラリ等)が利用可能かつ安全で
あることを保証することの問題もある．
ただしそれでも，バッファオーバーフローが起こらない安全なプログラムを
開発する際には，他の言語の使用を確かに検討すべきである．
</sect1>
</sect>

<!--O
<sect>Structure Program Internals and Approach
-->
<sect>プログラムの内部と入口の構造化
<p>

<!--O
<sect1>Secure the Interface
-->
<sect1>インタフェースを安全にする
<p>
<!--O
Interfaces should be minimal (simple as possible), narrow
(provide only the functions needed), and non-bypassable.
Trust should be minimized.
Applications and data viewers may be used to
display files developed externally, so in general don't allow them
to accept programs (including auto-executing
macros) unless you're willing to do the
extensive work necessary to create a secure sandbox.
-->
インタフェースはできるだけ小さく(できる限り単純に)，狭く(必要な機能し
か提供せず)，迂回できないようにすべきである．
信頼はできるだけしないようにすべきである．
アプリケーションやデータのビューアは外部で作られたファイルの表示に使わ
れることがあるので，安全な「砂箱」を作るだけの大量の作業をするつもりが
ないのであれば，普通はプログラム(自動実行マクロを含む)の実行を許可して
はならない．
</sect1>

<!--O
<sect1>Minimize Permissions
-->
<sect1>与える権限をできるだけ小さくする
<p>
<!--O
As noted earlier, it is an important general
principle that programs have the minimal amount of permission
necessary to do its job.
That way, if the program is broken, its damage is limited.
The most extreme example is to simply not write a secure program at all -
if this can be done, it usually should be.
-->
先に述べたように，プログラムに持たせるのは作業に必要最小限の権限だけに
すべきであるという重要な一般原則がある．
こうしておけば，プログラムが壊れても被害は抑えられる．
もっとも極端な例は，安全にしなければならないようなプログラムを単に書か
ないことである．それで済むのであれば，ぜひそうすべきである．
<p>
<!--O
In Linux, the primary determiner of a process' permission is the set of
id's associated with it:
each process has a real, effective, filesystem,
and saved id for both the user and group.
Manipulating these values is critical to keeping permissions minimized.
-->
Linux では，プロセスのパーミッションを決める主要な要素は，プロセスが持っ
ている ID である:
各プロセスはユーザとグループの両方について実 ID, 実効 ID,
ファイルシステム ID, 保存 ID を持っている．
これらの値をうまく処理することは，パーミッションを最小限に保つ上で非常
に重要である．
<p>
<!--O
Permissions should be minimized along several different views:
-->
パーミッションは，以下で述べる複数の観点から最小化すべきである:
<itemize>
<!--O
<item>Minimize the highest permission granted.
Avoid giving a program root privileges if possible.
Don't make a program <it>setuid root</it> if it only needs access
to a single file; consider creating a special group, make the file owned
by the group, and then make the program <it>setgid</it> to that group.
Similarly, try to make a program <it>setgid</it> instead of <it>setuid</it>,
since group membership grants fewer rights (in particular, it does not
grant the right to change file permissions).
If a program must constantly switch between user permissions to access files
(e.g., an NFS server),
consider setting only the Linux-unique value
``file system uid'' (fsuid) since this will limit
file accesses without causing race conditions and without permitting
users to send signals to the process.
-->
<item>与える最高のパーミッションをできるだけ小さくすること．
プログラムには，root 権限は可能ならば与えない．
あるファイルにアクセスする必要があるだけならば，プログラムに
<it>setuid root</it> してはならない．この場合は専用のグループを作り，
問題のファイルをそのグループに入れ，そしてプログラムをそのグループに
<it>setgid</it> することを考慮すべきである．
このように，プログラムは <it>setuid</it> でなく <it>setgid</it> するよ
うに試みること．なぜなら，グループに所属する方が得られる権限が小さいか
らである(特に，グループに所属しただけではファイルのパーミッションを変
更する権限は得られない)．
もし，ファイルにアクセスするためにプログラムのユーザパーミッションが常
に切り替わっている場合(例えば NFS サーバ等)は，Linux 固有の値である
「ファイルシステム UID」(FSUID)だけの設定を考えること．なぜなら，
FSUID を使えば，競合状態を起こさずに，しかもユーザからプロセスにシグナ
ルを送らせないでファイルアクセスを制限できるからである．
<p>
<!--O
If you <it>must</it> give a program root privileges,
consider using the POSIX capability features available in Linux 2.2 and
greater to minimize them immediately on program startup.
By calling cap_set_proc(3) or the Linux-specific capsetp(3) 
routines immediately after starting, you can permanently
reduce the abilities of your program to just those abilities it actually needs.
Note that not all Unix-like systems implement POSIX capabilities.
For more information on Linux's implementation of POSIX capabilities, see
<url url="http://linux.kernel.org/pub/linux/libs/security/linux-privs">.
-->
プログラムに root 権限を<it>与えなければならない</it>場合は，Linux 2.2 
以降で利用可能な POSIX のケーパビリティ機能を使い，プログラムを起動し
てすぐに権限をできるだけ小さくすることも考慮すること．
cap_set_proc(3) や Linux 固有の capsetp(3) を関数を起動直後に用いるこ
とによって，それ以降はプログラムの権限を本当に必要な権限だけに減らすこ
とができる．
必ずしも全ての UNIX 的 OS には POSIX ケーパビリティが実装されていない
点に注意すること．
Linux における POSIX ケーパビリティの実装に関する詳しい情報については，
<url url="http://linux.kernel.org/pub/linux/libs/security/linux-privs">
を参照すること．
<!--O
<item>Minimize the time the permission is active.
Use setuid(2), seteuid(2), and related functions to ensure that the program
only has these permissions active when necessary.
-->
<item>パーミッションが有効な時間をできるだけ短くすること．
必ず，setuid(2), seteuid(2) やこの関係の関数を用いて，プログラムの
パーミッションが必要な時だけに有効となるようにすること．
<!--O
<item>Minimize the time the permission can become active.
As soon as possible, permanently give up permissions.
Since Linux implements ``saved'' IDs, the simplest approach is to set
the other id's twice to an untrusted id.
In setuid/setgid programs, you should usually set
the effective gid and uid
to the real ones, in particular right after a fork(2),
unless there's a good reason not to.
Note that you have to change the gid first when dropping from root to another
privilege or it won't work!
-->
<item>パーミッションが有効になり得る時間をできるだけ短くすること．
できる限り早く，パーミッションを完全に放棄すること．
Linux は「保存」ID を持っているので，最も簡単なアプローチは
他のユーザの ID を二度信頼できない ID に設定することである．
setuid/setgid されたプログラムでは，そうしない理由があるのでなければ
普通は実効 GID と実効 UID に実際の ID を指定すること．特に fork(2) の
直後はこれを守ること．
root 権限を捨てて他のユーザの権限に切替えるときはまず GID を変更しなけ
ればならない点に注意すること．そうしなければ動作しない!
<!--O
<item>Minimize the number of modules needing and granted the permission.
If only a few modules are granted the permission, then it's much
easier to determine if they're secure.
One way to do so follows the previous point; have a single module use the
privilege and then drop it, so that other modules called later cannot misuse
the privilege.
Another approach is to have separate commands; one command is a complex
tool that can do a vast number of tasks for a privileged user (e.g., root),
while the other tool is setuid but is a small, simple tool that
only permits a small command subset
(which, if the input is acceptable, is then passed to the first tool).
This is especially helpful for GUI-based systems; have the GUI portion
run as a normal user, and then pass those requests on to another module
that has the special privileges.
-->
<item>パーミッションを持つ必要があるモジュールの数をできるだけ少なくす
ること．パーミッションを持っているモジュールの数が少なければ，その
モジュールが安全かどうかを調べることがずっと容易になる．
これを実現する方法の一つは，前の項目に従うことである．つまり，
ある一つのモジュールが権限を使った後にそれを捨てれば，後で呼び出された
他のモジュールがその権限を濫用することは不可能である．
別の方法としては，コマンドを分けるやり方がある．つまり，
ある特権ユーザ(root 等)のために色々な種類の作業が行える単独のコマンド
と，setuid されているけれど小さく，単純であり
限られた一部のコマンドだけを許す(入力が正しければ作業コマンドを最初の
プログラムに渡す)ツールを用意するのである．
これは GUI ベースのシステムでは特に有効である．つまり，GUI 部分は
一般ユーザで動作させ，GUI 部分からのリクエストを特殊権限を持った別の
モジュールに渡すのである．
<!--O
<item>Minimize the resources available.
You can set file and directory permissions so that only a small number
of them can be written by the program.
This is commonly done for game high scores, where
games are usually setgid <it>games</it>,
the score files are owned by the group <it>games</it>,
and the programs are owned by someone else (say root).
Thus, breaking into a game allows the perpetrator to change high scores but
won't allow him to change a game's executable or configuration file.
-->
<item>利用可能なリソースをできるだけ少なくする．
ファイルやディレクトリのパーミッションは，プログラムを使って書き換えら
れるのが少数のユーザだけになるように設定すべきである．
これはゲームのハイスコアなどでよく使われる方法である．つまり，
ゲームは普通は <it>games</it> グループに setgid にされていて，
スコアファイルはグループ <it>games</it> が所有しているが，
ゲームのプログラムは誰か別のユーザ(root など)が所有している．
こうしていれば，ゲームのシステムを破った犯人はハイスコアを変更できるが，
ゲームの実行ファイルや設定ファイルを変更することはできない．
<p>
<!--O
Consider creating separate user or group accounts for different functions, so
breaking into one system will not automatically allow damage to others.
-->
異なる機能には異なるユーザやグループを用意することを検討すること．
そうすれば，あるシステムを破っても，そのまま続けて他のシステムに被害を
与えることはできない．
<p>
<!--O
You can use the chroot(2) command so that the
program has only a limited number of files available to it.
This requires carefully setting up a directory (called the ``chroot jail'').
A program with root permission can still break out (using calls like mknod(2)
to modify system memory), but otherwise such a jail can
significantly improve a program's security.
-->
chroot(2) コマンドを使えば，プログラムが限られた数のファイルしか利用で
きないようにできる．
これを行うにはディレクトリを注意深く設定する必要がある(いわゆる
「chroot の牢獄(chroot jail)」)．
root 権限を持ったプログラムはそれでもシステム破りを行えるが
(mknod(2) 等のシステムコールでシステムメモリを変更する)，それ以外の場
合はこのような「牢獄」を使うことでプログラムのセキュリティが大幅に向上
する．
</itemize>
<p>
<!--O
Some operating systems have the concept of multiple
layers of trust in a single process, e.g., Multics' rings.
Standard Unix and Linux don't have a way of separating multiple levels of trust
by function inside a single process
like this; a call to the kernel increases permission,
but otherwise a given process has a single level of trust.
Linux and other Unix-like systems can sometimes
simulate this ability by forking a process into
multiple processes, each of which has different permissions.
To do this, set up a secure communication channel
(usually unnamed pipes are used), then fork into different processes
and drop as many permissions as possible.
Then use a simple protocol to allow the less trusted processes
to request actions from more trusted processes, and ensure that the more
trusted processes only support a limited set of requests.
-->
OS によっては，ひとつのプロセス内に信頼処理を行う層を複数個持っている
ものがある．例えば，Multics のリング機構などである．
標準の UNIX や Linux は，単独のプロセス内で関数を使ってこのように
信頼処理のレベルを複数個に分割する方法を持っていない．カーネルに対する
システムコールでパーミッションを向上させることはできるが，一つのプロセス
は一つの信頼レベルしか持てない．
Linux や他の UNIX 的 OS では，ひとつのプロセスを複数個のプロセスに
fork させることよってこの機能を疑似的に実現できることもある．
これを行うには安全な通信経路を設定し(普通は名前なしパイプが使われる)，
それから複数のプロセスへの fork を行い，そしてできる限り多くの
パーミッションを捨てる．
それから，単純なプロトコルを用いて信頼度の高いプロセスから信頼度の低い
プロセスに動作を要求できるようにし，信頼度の高いプロセスは
限られた要求にしか対応しないことを確実に行う．
<p>
<!--O
This is one area where technologies like Java 2 and Fluke have an advantage.
For example,
Java 2 can specify fine-grained permissions such as the permission to
only open a specific file.
However, general-purpose operating systems do not typically
have such abilities.
-->
これは Java 2 や Fluke のような技術が優位性を持っている分野のひとつで
ある．
Java 2 では，細かく分けられたパーミッションが指定できる(例: 特定のファ
イルだけをオープンできるパーミッション)．
しかし，普通は汎用の OS はこのような機能は持っていない．
<p>
<!--O
Each Linux process has two Linux-unique state values called
filesystem user id (fsuid) and filesystem group id (fsgid).
These values are used when checking for filesystem permissions.
Programs with root privileges should consider
changing just fsuid and fsgid before accessing files on behalf of
a normal user.
The reason is that setting a process' euid allows the corresponding
user to send a signal to that process, while just setting fsuid does not.
The disadvantage is that these calls are not portable to other POSIX systems.
-->
Linux の各プロセスは Linux 固有の状態値を 2 つ持っている．つまり，
ファイルシステムユーザ ID (FSUID) とファイルシステムグループ ID(FSGID)
である．
これらの値はファイルシステムのパーミッションをチェックするときに使われる．
root 権限を持つプログラムは，ID を一般ユーザのもの切り替えてファイルシステムを
アクセスするのではなく，単に FSUID と FSGID を変えるだけという方法も検
討すべきである．
その理由は，プロセスの実行 UID を設定すると，その UID に対応するユーザ
はそのプロセスにシグナルを送れるが，FSUID を変更しただけならばシグナル
を送れないからである．
この方法の利点は，このシステムコールは他の POSIX システムには移植でき
ない点である．
</sect1>

<!--O
<sect1>Use Safe Defaults
-->
<sect1>デフォルトは安全な設定にする
<p>
<!--O
On installation the program should deny all accesses until the user
has had a chance to configure it.
Installed files and directories
should certainly not be world writable, and in
in fact it's best to make them unreadable by all but the trusted user.
If there's a configuration language, the default should be to deny access
until the user specifically grants it.
-->
インストール時は，ユーザに設定の機会を与えるまでは，プログラムは全ての
アクセスを拒否すべきである．
インストールされたファイルやディレクトリは世界中から書き込める状態であっ
てはならない．また実際には，信頼するユーザ以外には読めなくしておくとよ
いだろう．
設定を記述するところがあれば，デフォルトの設定はユーザが特別に許可して
いなければアクセスを拒否する設定にしてあるべきである．
</sect1>

<!--O
<sect1>Fail Open
-->
<sect1>フェールオープン
<p>
<!--O
A secure program should always ``fail open,'' that is,
it should be designed so that if the program does fail, the program
will deny all access (this is also called ``failing safe'').
If there seems to be some sort of bad behavior (malformed input,
reaching a ``can't get here'' state, and so on), then the program
should immediately deny service.
Don't try to ``figure out what the user wanted'': just deny the service.
Sometimes this can decrease reliability or usability
(from a user's perspective), but it increases security.
-->
安全なプログラムは常に「フェールオープン」であるべきである．
つまり，プログラムが何か失敗すると，プログラムは全てのアクセスを拒否す
るように設計されているべきである(「フェールセーフ」とも呼ばれる)．
もし何らかのおかしな動き(不正な入力，「なるはずのない状態に」なること
等)があるようならば，プログラムは即座にサービスを停止すべきである．
「ユーザの求めていることを調べ」ようとはせず，即座にサービスを禁止すること．
このようなやり方は(ユーザから見た場合の)信頼性や便利さを損ねることがあ
るが，セキュリティは向上する．
</sect1>

<!--O
<sect1>Avoid Race Conditions
-->
<sect1>競合状態の回避
<p>
<!--O
Secure programs must determine if a request should be granted, and if
so, act on that request.
There must be no way for an untrusted user to change anything used in
this determination before the program acts on it.
-->
安全にすべきプログラムで，受け取ったリクエストを認めるべきかどうかを決
めなければならず，もし認めるべきであればリクエストを実行しなければなら
ない．
プログラムがリクエストを実行する前の意思決定には，信頼できないユーザが
何らかの影響を及ぼす手段があってはならない．
<p>
<!--O
This issue repeatedly comes up in the filesystem.
Programs should generally avoid using access(2) to determine
if a request should be granted, followed later by open(2), because users
may be able to move files around between these calls.
A secure program should instead set its effective id or filesystem id,
then make the open call directly.
It's possible to use access(2) securely, but only when a user cannot affect
the file or any directory along its path from the filesystem root.
-->
この問題はファイルシステムでは繰り返し起きる．
プログラムでは一般的に，リクエストを認めるかどうかを決めるために
access(2) を用い，その後で open(2) を使うのは避けるべきである．
なぜなら，2 つのシステムコールが呼ばれる合間にユーザがファイルを移動
させることができるからである．
安全なプログラムでは，この方法ではなく，実効 ID かファイルシステム ID
を設定し，それから直接 open システムコールを呼び出すべきである．
access(2) を安全に使うことも可能ではあるが，それはユーザがファイルおよ
びファイルシステムのルートからのパス上にあるどのディレクトリにも影響を
及ぼせない時だけである．
</sect1>

<!--O
<sect1>Trust Only Trustworthy Channels
-->
<sect1>信頼できる通信経路しか信頼しない
<p>
<!--O
In general, do not trust results from untrustworthy channels.
-->
一般的には，信頼できない通信経路から得た結果を信頼してはならない．
<p>
<!--O
In most computer networks (and certainly for the Internet at large),
no unauthenticated transmission is trustworthy.
For example,
on the Internet arbitrary packets can be forged, including header values,
so don't use their values as your primary criteria for security decisions
unless you can authenticate them.
In some cases you can assert that a packet claiming to come from the
``inside'' actually does, since the local firewall would prevent such
spoofs from outside, but broken firewalls, alternative paths, and
mobile code make even this assumption suspect.
In a similar vein, do not assume that low port numbers (less than 1024)
are trustworthy; in most networks such requests can be forged or
the platform can be made to permit use of low-numbered ports.
-->
ほとんどのコンピュータネットワーク(もちろん一般のインターネットの場合
も)認証されていない送信データはまったく信頼に値しない．
例えばインターネット上ではヘッダ値を含めて任意のパケットを偽造できるの
で，パケットの認証を行える場合を除いて，これらの値をセキュリティ的な
判断を下すための主な基準にしてはならない．
場合によっては，「内部ネットワーク」から来たと主張しているパケットが
実際にそうであると断言できることもあるが(ローカルのファイアウォールが
外部からのなりすましを防ぐ場合など)，ファイウォールが破られたり，別の
経路があったり，携帯機器を持ち込まれた場合にはこのような仮定も疑わしく
なってしまう．
同様の話で，低位のポート番号(1024 未満)が信用できると仮定してはならない．
ほとんどのネットワークではこのようなリクエストは偽造できるし，低位の
ポート番号が使えるようなプラットフォームを作ることもできるからである．
<p>
<!--O
If you're implementing a standard and inherently insecure protocol
(e.g., ftp and rlogin), provide safe defaults and document clearly
the assumptions.
-->
標準であるが本質的に安全でないプロトコル(例: ftp や rlogin)を実装しよ
うとしている場合は，安全なデフォルト設定を用意し，前述のような仮定を
明文化しておくこと．
<p>
<!--O
The Domain Name Server (DNS) is widely used on the Internet to maintain
mappings between the names of computers and their IP (numeric) addresses.
The technique called ``reverse DNS'' eliminates some simple
spoofing attacks, and is useful for determining a host's name.
However, this technique is not trustworthy for authentication
decisions.
The problem is that, in the end, a DNS request will be sent eventually
to some remote system that may be controlled by an attacker.
Therefore, treat DNS results as an input that needs
validation and don't trust it for serious access control.
-->
ドメインネームシステム(DNS)はコンピュータの名前と IP(数値)アドレスを
結びつけるためにインターネット上で広く使われている．
「DNS 逆引き」と呼ばれる技術を使えば，一部の単純ななりすまし攻撃を防ぐ
ことができ，ホストの名前を調べるときにも役立つ．
しかし，この技術を信頼して認証の決定に使うことはできない．
この問題は結局，DNS のリクエストは最終的には攻撃者が制御しているかもし
れないどこかのリモートシステムに送られるという点である．
したがって，DNS の参照結果を入力として扱う際には，検証を行う必要がある
し，結果を信用して重要なアクセス制御に用いてはならない．
<p>
<!--O
If asking for a password, try to set up trusted path (e.g.,
require pressing an unforgeable key
before login, or display unforgeable pattern such as flashing LEDs).
When handling a password, encrypt it between trusted endpoints.
-->
パスワードを求める場合は，信頼できる経路をできるだけ用意すること(例え
ば，ログインの前に偽造できないキーを押させたり，LED の点滅のような偽造
できないパターンの表示を行うことが必要である)．
パスワードを扱うときには，パスワードの暗号化を接続の信頼できる端点で行
うこと．
<p>
<!--O
Arbitrary email (including the ``from'' value of addresses)
can be forged as well.
Using digital signatures is a method to thwart many such attacks.
A more easily thwarted approach is to require emailing back and forth
with special randomly-created values, but for low-value transactions
such as signing onto a public mailing list this is usually acceptable.
-->
また，どんな電子メール(「From 行」のアドレスを含む)でも偽造することが
可能である．
電子署名の利用は，このような攻撃の多くを阻止する手段となる．
もっと簡単な防御手段は，ランダムに生成した特殊な値をつけた電子メールを
やりとりすることである．公開メーリングリストの登録などの重要性の低いや
りとりでは，普通はこの程度で十分である．
<p>
<!--O
If you need a trustworthy channel over an untrusted network,
you need some sort of cryptologic
service (at the very least, a cryptologically safe hash);
see the section below on cryptographic algorithms and protocols.
-->
信頼できないネットワーク上に信頼できる通信経路を用意することが必要がな
らば，何らかの種類の暗号サービス(最低限のところでは，暗号的に安全な
ハッシュ)が必要である．詳しくは「暗号のアルゴリズムとプロトコル」の節
を参照すること．
<p>
<!--O
Note that in any client/server model, including CGI, that the server
must assume that the client can modify any value.
For example, so-called ``hidden fields'' and cookie values can be
changed by the client before being received by CGI programs.
These cannot be trusted unless they are signed in a way the client
cannot forge and the server checks the signature.
-->
クライアント/サーバモデル(CGI を含む)はどんな形のものであれ，サーバは
クライアントはどんな値でも変更できることを想定していなければならない．
例えば，いわゆる「隠しフィールド」やクッキーの値も，CGI プログラムが受
け取る前にクライアント側で変更できる．
クライアントが偽造を行えず，サーバがチェックできるような形で署名がなさ
れているのでなければ，このような値を信用することはできない．
<p>
<!--O
The routines getlogin(3) and ttyname(3) return information that can be
controlled by a local user, so don't trust them for security purposes.
-->
関数 getlogin(3) や ttyname(3) は，ローカルのユーザが制御できる情報を
返すので，セキュリティ上の目的でこれらの情報を信用してはならない．
</sect1>

<!--O
<sect1>Use Internal Consistency-Checking Code
-->
<sect1>内部的な整合性をチェックするようなコードを書く
<p>
<!--O
The program should check to ensure that its call arguments and basic state
assumptions are valid.
In C, macros such as assert(3) may be helpful in doing so.
-->
プログラムは，関数呼び出しの引数と基本状態の仮定が正しいことを保証する
ためのチェックを行わなくてはならない．
C 言語では，assert(3) のようなマクロがチェックに役立つ．

<!--O
<sect1>Self-limit Resources
-->
<sect1>自分自身でリソースを制限する
<p>
<!--O
In network daemons, shed or limit excessive loads.
Set limit values (using setrlimit(2)) to limit the resources that will be used.
At the least, use setrlimit(2) to disable creation of ``core'' files.
Normally Linux will create a core file that saves all program memory if the
program fails abnormally, but such a file might include passwords or
other sensitive data.
-->
ネットワークデーモンの場合は，高すぎる負荷は切り捨てるか制限すること．
limit 値を設定し(setrlimit(2) を使用)，使われるリソースを制限すること．
少なくとも，「core」ファイルの生成は setrlimit(2) で起こらないように設
定すること．プログラムが異常終了したときに Linux が生成する core ファイル
には通常は全てのプログラムメモリが保存されるが，このようなファイルには
パスワードやその他の問題があるデータが入るかもしれないからである．
</sect>

<!--O
<sect>Carefully Call Out to Other Resources
-->
<sect>他のリソースの呼び出しの際には注意する
<p>

<!--O
<sect1>Limit Call-outs to Valid Values
-->
<sect1>呼び出しの際に正しい値だけを使う
<p>
<!--O
Ensure that any call out to another program only permits valid
and expected values for every parameter.
This is more difficult than it sounds, because there are many
library calls or commands call lower-level routines in potentially
surprising ways.
For example, several system calls, such as popen(3) and system(3),
are implemented by calling the command shell, meaning that they will
be affected by shell metacharacters.
Similarly, execlp(3) and execvp(3) may cause the shell to be called.
Many guidelines suggest avoiding popen(3), system(3), execlp(3), and execvp(3)
entirely and use execve(3) directly in C when trying to spawn
a process [Galvin 1998b].
In a similar manner the Perl and shell backtick (`) also call a command shell.
-->
他のプログラムの呼び出しは，全ての引数が正しくかつ期待されている値であ
る場合に限って許すこと．
これは見た感じよりも難しいことである．なぜなら，おかしな方法で低レベル
関数を呼び出しているかもしれないライブラリ関数やコマンドがたくさん存在
するからである．
例えば，popen(3) や system(3) などのシステムコールはコマンドシェルを呼
び出す方法で実装されているので，シェルのメタ文字の影響を受けてしまう．
同様に，execlp(3) と execvp(3) はシェルを呼び出すことがある．
多くのガイドラインでは，popen(3), system(3), execlp(3), execvp(3) の使
用は絶対に避け，C でプロセスを立ち上げる時には直接 execve(3) を使うこ
とを勧めている[Galvin 1998b]．
同じように，Perl やシェルのバッククォート記号(`)もコマンドシェルを呼び
出す．
<p>
<!--O
One of the nastiest examples of this problem are shell metacharacters.
The standard Linux command shell interprets a number of characters specially.
If these characters are sent to the shell, then their special interpretation
will be used unless escaped; this fact can be used to break programs.
According to the WWW Security FAQ [Stein 1999, Q37], these metacharacters are:
-->
この問題で一番悪質な例は，シェルのメタ文字である．
Linux の標準のコマンドシェルは多くの文字を特別扱いする．
このような文字がシェルに送られた場合，その文字をエスケープしていなけれ
ば特殊な処理が行われる．この動作を利用してプログラムを破ることが可能で
ある．
WWW Security FAQ [Stein 1999, Q37] によると，このようなメタ文字は以下
の通りである:
<verb>
&amp; ; ` ' \ " | * ? ~ < > ^ ( ) [ ] { } $ \n \r
</verb>
<p>
<!--O
Forgetting one of these characters can be disastrous, for example,
many programs omit backslash as a metacharacter [rfp 1999].
As discussed in the section on validating input, a recommended approach
is to immediately escape at least all of these characters when they are input.
-->
これらの文字のどれかを忘れていると悲惨なことになる可能性がある．例えば，
多くのプログラムはバックスラッシュをメタ文字として省略する[rfp 1999]．
「全ての入力を検証する」の章で説明したように，望ましいアプローチは，
少なくともこれらの文字が入力に現われたら即座にエスケープすることである．
<p>
<!--O
A related problem is that the NIL character (character 0) can have
surprising effects.
Most C and C++ functions assume
that this character marks the end of a string, but string-handling routines
in other languages (such as Perl and Ada95) can handle strings containing NIL.
Since many libraries and kernel calls use the C convention, the result
is that what is checked is not what is actually used [rfp 1999].
-->
これに関連する問題として，NIL 文字(文字 `0')が困った影響をもたらす可能
性がある．
C/C++ のほとんどの関数は，NIL 文字は文字列の終わりを表すものとしている
が，他の言語(Perl や Ada95 等)では NIL 文字を含む文字列を扱うことがで
きる．
多くの関数やシステムコールは C の慣習に従っているので，チェックしたも
のが実際に使われるものと異なってしまうことになる[rfp 1999]．
<p>
<!--O
When calling another program or referring to a file
always specify its full path (e.g, /usr/bin/sort).
For program calls,
this will eliminate possible errors in calling the ``wrong'' command,
even if the PATH value is incorrectly set.
For other file referents, this reduces problems from ``bad'' starting
directories.
-->
他のプログラムを呼び出すときやファイルを参照するときには，必ず絶対パス
で(/usr/bin/sort)指定すること．
プログラムを呼び出す場合にこのような指定を行うと，PATH 変数が正しく設
定されていなくても「間違った」コマンドを呼ぶことがなくなる．
他のファイルを参照する場合にも，開始ディレクトリを「間違う」問題を減ら
すことができる．
</sect1>

<!--O
<sect1>Check All System Call Returns
-->
<sect1>システムコールの戻り値は全てチェックする
<p>
<!--O
Every system call that can return an error condition must have that
error condition checked.
One reason is that nearly all system calls require limited system resources,
and users can often affect resources in a variety of ways.
Setuid/setgid programs can have limits set on them through calls such as
setrlimit(3) and nice(2).
External users of server programs and CGI scripts
may be able to cause resource exhaustion simply by making a large number
of simultaneous requests.
If the error cannot be handled gracefully, then fail open as discussed earlier.
-->
エラー状態を返せるシステムコールを呼び出す場合には必ず，エラー状態を
チェックしなければならない．
その理由のひとつは，ほとんど全てのシステムコールはシステムのリソースを
制限する必要があるが，ユーザはいろいろな方法でリソースに影響を与えられ
ることである．
setuid/setgid されたプログラムには，setrlimit(3) や nice(2) といったシ
ステムコールを使って制限を設定するとよい．
サーバプログラムや CGI スクリプトを外部から使うユーザは，大量の
リクエストを同時に送るだけでシステムのリソースを食い潰すことができるか
もしれない．
エラーを無難に処理できないのであれば，先に説明したフェールオープンな対
応を行うこと．
</sect1>
</sect>

<!--O
<sect>Send Information Back Judiciously
-->
<sect>相手に返す情報は注意深く選ぶ
<p>

<!--O
<sect1>Minimize Feedback
-->
<sect1>返す情報をできるだけ少なくする
<p>
<!--O
Avoid giving much information to untrusted users; simply succeed or fail,
and if it fails just say it failed and minimize information on why it failed.
Save the detailed information for audit trail logs.
For example:
-->
信頼できないユーザには情報を与えすぎてはならない．単に成功または失敗を
返し，失敗の場合も単に失敗した事実と失敗した理由に関する最小限の情報を
返すだけにすること．
詳しい情報は監査するためのログとして保存する．
以下に例を示す:
<itemize>
<item>
<!--O
If your program requires some sort of user authentication
(e.g., you're writing a network service or login program),
give the user as little information as possible before they authenticate.
In particular, avoid giving away the version number of your program
before authentication.
Otherwise,
if a particular version of your program is found to have a vulnerability,
then users who don't upgrade from that version advertise to attackers that
they are vulnerable.
-->
プログラムが何らかのユーザ認証を必要とする場合(ネットワークサービスや
ログインプログラム等を書いている場合)，認証の前にユーザに与える情報は
できる限り少なくすること．
特に，認証の前にプログラムのバージョン番号を教えることは避けなければな
らない．
プログラムのバージョンを教えてしまい，しかもそれが弱点を持っているバー
ジョンであることを明らかになった場合，そのバージョンからアップグレード
していないユーザは弱点を持っていることを攻撃者に宣伝しているようなもの
である．
<item>
<!--O
If your program accepts a password, don't echo it back;
this creates another way passwords can be seen.
-->
パスワードを受け付けるプログラムの場合，パスワードをエコーバックしては
ならない．パスワードをエコーバックすると，パスワードを覗ける抜け道を作っ
てしまうことになる．
</itemize>

<!-- takei: fucky close tag </sect1> -->

<!--O
<sect1>Handle Full/Unresponsive Output
-->
<sect1>出力先が詰まっている場合や応答しない場合への対処
<p>
<!--O
It may be possible for a user to clog or make unresponsive a secure
program's output channel back to that user.
For example, a web browser could be intentionally halted or have its
TCP/IP channel response slowed.
The secure program should handle such cases, in particular it should release
locks quickly (preferably before replying) so that this will not create
an opportunity for a Denial-of-Service attack.
Always place timeouts on outgoing network-oriented write requests.
-->
ユーザは，安全にすべきプログラムがユーザに情報を返す出力経路を詰まらせ
たり，応答しなくさせることができる．
例えば，故意にウェブブラウザを停止させたり，TCP/IP 経路の反応を遅くで
きる．
安全にすべきプログラムは，こういった場合にも対処できなければならない．
特に，サービス妨害攻撃の余地を与えないために，(できれば応答を返す前に)
素早くロック状態から抜け出せるべきである．
ネットワーク向けの書き出しリクエストには，必ずタイムアウトを設定すべき
である．
</sect1>
</sect>

<!--O
<sect>Special Topics
-->
<sect>特殊な話題
<!--O
<sect1>Locking
-->
<sect1>ロッキング
<p>
<!--O
There are often situations in which a program must ensure that it has
exclusive rights to something.
On POSIX systems this is traditionally done by creating
a file to indicate a lock, because this is portable to many systems.
-->
何かを行う権利をプログラムに対して排他的に保証しなければならない状況は
よく起こる．
POSIX システムの慣習では，これはロック状態を示すファイルを作ることによっ
て行われる．なぜなら，この方法は多くのシステムに移植できるからである．
<p>
<!--O
However, there are several traps to avoid.
First, a program with root privileges can open a file, even if it
sets the O_EXCL mode (which normally fails if the file already exists).
If that can happen, don't use open(2), use link(2) to create the file.
If you just want to be sure that your server doesn't execute more than once
on a given machine, consider creating a lockfile as
/var/log/NAME.pid with the pid as its contents.
This has the disadvantage of hanging around if the program prematurely halts,
but it's common practice and is easily handled by other system tools.
-->
しかし，避けなければならない罠もいくつかある．
まず，root 権限を持つプログラムは，O_EXCL モードでオープンされている
ファイル(普通は既にファイルがあれば失敗する)であってもオープンできる．
こうなる可能性がある場合には，open(2) ではなく link(2) を使ってファイ
ルを作成すること．
一つのマシンで同時に複数の同じサーバを動作させたくないだけであれば，
/var/log/NAME.pid というロックファイルを作り，その中に pid を書き込む
方法も検討すること．
この方法には，
プログラムが途中で止まるとロックファイルが残ってしまうという欠点もある
が，よく使われる方法であり，他のシステムツールでも簡単に扱うことができ
る．
<p>
<!--O
Second, if the lock file may be on an NFS-mounted filesystem, then you have
the problem that NFS doesn't completely support normal file semantics.
The manual for <it>open(2)</it> explains how to handle things in this case
(which also handles the case of root programs):
-->
次に，ロックファイルが NFS マウントしたファイルシステム上に置かれる可
能性がある場合には，NFS は通常のファイルに対する操作を完全にはサポート
していないという問題が起こる．<it>open(2)</it> のマニュアルには，
このようなケースに対処する方法が書かれている(root のプログラムの問題の
扱い方も説明されている):
<p>
<quote>
<!--O
... programs which rely on [the O_CREAT and O_EXCL flags of open(2)]
for performing locking tasks will contain a race condition. The solution
for performing atomic file locking using a lockfile is to create
a unique file on the same filesystem (e.g., incorporating
hostname and pid), use link(2) to make a link to
the lockfile and use stat(2) on the unique file to
check if its link count has increased to 2. Do
not use the return value of the link(2) call.
-->
</quote>
…ロック処理を行う際に [open(2) の O_CREAT フラグと O_EXCL フラグ]
に頼っているプログラムは，競合状態になる可能性がある．
ロックファイルを使って atomic な(不可分な)ファイルのロックを行う方法で
は，同じファイルシステム上にユニークなファイル(例えばホスト名と pid を
組み合わせたもの)を作ることである．これを行うには，link(2) を使って
ロックファイルへのリンクを作り，stat(2) を使ってそのリンクカウントが 2
に増えたかどうかを調べること．
link(2) システムコールの戻り値を使ってはならない．

<!--O
<sect1>Passwords
-->
<sect1>パスワード
<p>
<!--O
Where possible, don't write code to handle passwords.
In particular, if the application is local,
try to depend on the normal login authentication by a user.
If the application is a CGI script, depend on the web server to provide
the protection.
If the application is over a network, avoid sending the password as cleartext
(where possible) since it can
be easily captured by network sniffers and reused later.
For networks, consider at least using digest passwords (which are
vulnerable to active attack threats but protect against passive
network sniffers).
-->
可能であれば，パスワードを処理するコードは書かないほうがよい．
特に，アプリケーションがローカルで使うものであれば，ユーザによる通常の
ログイン認証に頼るようにすること．
アプリケーションが CGI スクリプトならば，防御はウェブサーバに任せると
よい．
ネットワーク上で動作するアプリケーションの場合は，パスワードを平文で送
るのは(できるなら)避けるべきである．なぜなら，平文でネットワークを流れ
たパスワードはネットワーク盗聴ツールで簡単に拾えるため，後で使われるお
それがあるからである．
ネットワークの場合には少なくともダイジェストパスワードの使用を検討する
こと(これは能動的な攻撃には弱いが，受動的なネットワーク盗聴は防ぐこと
ができる)．
<p>
<!--O
If your application must handle passwords, overwrite them
immediately after use so they have minimal exposure.
In Java, don't use the type String to store a password because Strings are
immutable (they will not be overwritten until garbage-collected and
reused, possibly a far time in the future).
Instead, in Java use char[] to store a password, so it can be
immediately overwritten.
-->
作成するアプリケーションでパスワードを扱う場合には，パスワードが明らか
になるのをできるだけ避けるため，使用後にはすぐパスワードを書き潰すこと．
Java の場合は，パスワードの保持に String 型を使ってはならない．なぜな
ら，String 型の内容は変化しないからである(ガベージコレクションが行われ
て再利用されるまでは書き潰されることはなく，そうなるのもおそらくずっと
時間が経ってからである)．
パスワードの保持には String 型ではなく char[] 型を用いること．そうすれ
ば，すぐに書き潰すことができる．
<p>
<!--O
If your application permits users to set their passwords, check
the passwords and permit only ``good'' passwords
(e.g., not in a dictionary, having certain minimal length, etc.).
You may want to look at information such as
<url url="http://consult.cern.ch/writeup/security/security_3.html">
on how to choose a good password.
-->
ユーザがパスワードを設定できるアプリケーションの場合は，パスワードを
確認し，「良い」パスワードだけを受け付けること(例: 辞書にない言葉であっ
たり，ある程度の長さがある等)．
良いパスワードの選び方については
<url url="http://consult.cern.ch/writeup/security/security_3.html">
等の情報も調べるとよいだろう．

<!--O
<sect1>Random Numbers
-->
<sect1>乱数
<p>
<!--O
The Linux kernel (since 1.3.30) includes a random number generator.
The random number generator  gathers  environmental  noise
from  device  drivers  and  other  sources into an entropy pool.
When accessed as /dev/random, random bytes are only returned
within the estimated number of bits of noise in the entropy pool
(when the entropy pool is empty, the call blocks until additional
environmental noise is gathered).
When accessed as /dev/urandom, as many bytes as are requested are
returned even when the entropy pool is exhausted.
If you are using the random values for cryptographic purposes (e.g.,
to generate a key), use /dev/random.
More information is available in the system documentation random(4).
-->
Linux カーネル(1.3.30 以降)には乱数生成器が入っている．
乱数生成器は，環境ノイズをデバイスドライバなどの入力源から集めて
エントロピープールに入れる．
/dev/random がアクセスされると，エントロピープール内の乱雑さの度合を
推定したビット数に限られた範囲でランダムなバイト列が返される
(エントロピープールが空の時は，この呼び出しは新しく環境ノイズが集まる
まではブロックされる)．
/dev/urandom としてアクセスされた場合は，たとえエントロピープールが空
であっても，要求された数だけのバイト列が返される．
暗号に使うため(例: 鍵の生成)にランダムな値を使うのであれば，
/dev/random を使うこと．
さらに詳しい情報については，マニュアルの random(4) を参照すること．

<!--O
<sect1>Cryptographic Algorithms and Protocols
-->
<sect1>暗号のアルゴリズムとプロトコル
<p>
<!--O
Often cryptographic algorithms and protocols are necessary to keep
a system secure, particularly when communicating through an untrusted
network such as the Internet.
Where possible, use session encryption to foil session hijacking and
to hide authentication information, as well as to support privacy.
-->
暗号のアルゴリズムとプロトコルはシステムの安全を確保するために必要なこ
とが多い．特に，インターネットのように信頼できないネットワークを通じて
通信する時はそうである．
可能であれば，セッションのハイジャックを防ぎ，認証情報を隠し，さらに
プライバシーを守るために通信セッションの暗号化を行うべきである．
<p>
<!--O
Cryptographic
algorithms and protocols are difficult to get right, so do not create
your own.
Instead, use existing standard-conforming protocols
such as SSL, SSH, IPSec, GnuPG/PGP, and Kerberos.
Use only encryption algorithms that have been openly published and withstood
years of attack (examples include triple DES, which is also not
encumbered by patents).
In particular, do not create your own encryption algorithms unless you are
an expert in cryptology and know what you're doing;
creating such algorithms is a task for experts only.
-->
暗号のアルゴリズムとプロトコルを正しく作るのは困難なので，自分では作ら
ない方がよい．
その代わりに，SSL, SSH, IPSec, GnuPG/PGP, Kerberos といった既存の標準
準拠のプロトコルを使うとよい．
オープンに公開されていて，長年の攻撃にも耐えた暗号アルゴリズム(これに
は triple DES も含まれる．このアルゴリズムにも特許の制限は付いていない)
だけを使うこと．
特に，暗号の専門家であり何をやっているのかがわかるのでなければ，
自分独自の暗号アルゴリズムを作るべきではない．こういったアルゴリズムを
作るのは専門家だけがすべき作業である．

<sect1>Java
<p>
<!--O
Some security-relevant programs on Linux may be implemented
using the Java language and/or the Java Virtual Machine (JVM).
Developing secure programs on Java is discussed in detail in
material such as Gong [1999].
The following are a few key points extracted from Gong [1999]:
-->
Linux の一部のセキュリティ関連プログラムは Java 言語や Java 仮想マシン
(Java Virtual Machine, JVM)を使って作られている．
Java を使った安全なプログラムの開発については，Gong [1999] などが実例
を挙げて詳しく説明している．
以下に，重要な点をいくつか Gong [1999] から引用する:
<itemize>
<!--O
<item>Do not use public fields or variables; declare them as private and
provide accessors to them so you can limit their accessibility.
-->
<item>pulic なフィールドや変数を使わない．フィールドや変数は private 
で宣言してアクセス側に提供すること．そうすればアクセスに制限をかけるこ
とができる．
<!--O
<item>Make methods private unless these is a good reason to do otherwise.
-->
<item>private にしない十分な理由がなければ，メソッドは private にする．
<!--O
<item>Avoid using static field variables. Such variables are attached to the
class (not class instances), and classes can be located by any other class.
As a result, static field variables can be found by any other class, making
them much more difficult to secure.
-->
<item>static なフィールド変数を使わない．このような変数は(クラスの
インスタンスではなく)クラスに割り当てられるが，クラスは他の全ての
クラスから見つけることができる．その結果，static なフィールド変数は他
のクラスに見つけられるので，安全にするのがずっと難しくなる．
<!--O
<item>Never return a mutable object to potentially malicious code
(since the code may decide to change it).
-->
<item>mutable なオブジェクトは，悪意を持っているかもしれないコードに返
してはならない(そのコードが変更されるかもしれないから)．
</itemize>
</sect1>

<sect1>PAM
<p>
<!--O
Most Linux distributions include PAM (Pluggable Authentication Modules),
a flexible mechanism for authenticating users.
This includes Red Hat Linux, Caldera, Debian as of version 2.2;
note that FreeBSD also supports PAM as of version 3.1.
By using PAM, your program can be independent of the
authentication scheme (passwords, SmartCards, etc.).
Basically, your program calls PAM, which at run-time determines
which ``authentication modules'' are required by checking the configuration
set by the local system administrator.
If you're writing a program that requires authentication (e.g., entering
a password), you should include support for PAM.
You can find out more about the Linux-PAM project at
<url url="http://www.kernel.org/pub/linux/libs/pam/index.html">.
-->
ほとんどの Linux ディストリビューションには PAM
(Pluggable Authentication Modules)という柔軟なユーザ認証機構が入ってい
る．バージョン 2.2 の時点では，PAM は RedHat Linux, Caldera, Debian に
入っている．バージョン 3.1 の時点で FreeBSD も PAM をサポートしている．
PAM を用いると，作成するプログラムを認証方法(パスワード，SmartCard 等)
と独立にできる．
基本的には，プログラムが PAM を呼ぶと，PAM はローカルのシステム管理者
が用意した設定の組を調べ，どの「認証モジュール」が必要かを実行時に決定
する．
認証(パスワードの入力など)を必要とするプログラムを作成する場合には，
PAM に対応させるべきである．
Linux-PAM プロジェクトに関する情報は 
<url url="http://www.kernel.org/pub/linux/libs/pam/index.html"> 
で見つけられる．
</sect1>

<!--O
<sect1>Miscellaneous
-->
<sect1>その他の話題
<p>
<!--O
Have your program check at least some of its assumptions before it uses them
(e.g., at the beginning of the program).
For example, if you depend on the ``sticky'' bit being set on a given
directory, test it; such tests take little time and could prevent
a serious problem.
If you worry about the execution time of some tests on each call, at least
perform the test at installation time.
-->
プログラムの動作に何らかの前提がある場合，少なくともチェックできるもの
は実際に使う前に(例えばプログラムの最初で)プログラムでチェックすること．
例えば，指定されたディレクトリに ``sticky'' ビットが設定されていること
にプログラムが依存しているならば，それを確かめること．このような確認は
ほとんど時間はかからないが，重大な問題を回避できる．
呼び出す度に確認すると実行時間が不安なテストについては，少なくとも
インストール時にテストすること．
<p>
<!--O
Write audit logs for program startup, session startup, and
for suspicious activity.
Possible information of value includes date, time, uid, euid, gid, egid,
terminal information, process id, and command line values.
You may find the function syslog(3) helpful for implementing audit logs.
-->
プログラムの起動時，セッションの開始時，動作が疑わしい時には，監査ログ
を出力すること．
考えられる情報としては，日付，時刻，UID, EUID, GID, EGID, 端末に関する
情報，プロセス ID, コマンドラインの値などがある．
監査ログを実装する際には，syslog(3) 関数が役立つだろう．
<p>
<!--O
Have installation scripts install a program as safely as possible.
By default, install all files as owned by root or some other
system user and make them unwriteable by others;
this prevents non-root users from installing viruses.
Allow non-root installation where possible as well, so that users without
root permission and administrators who do not fully trust the
installer to still use the program.
-->
インストール用スクリプトには，できる限り安全にプログラムのインストール
を行わせること．
デフォルトでは，全てのファイルは root または別のシステムユーザの所有に
しておき，他のユーザからは書き込めないようにしておくこと．
これにより，root 以外のユーザによるウィルスのインストールを防ぐことが
できる．
可能な場所については root 以外のユーザによるインストールも許すこと．
そうすれば，root 権限を持たないユーザや，インストーラを完全には信用し
ていない管理者でもそのプログラムを使用できる．
<p>
<!--O
If possible, don't create setuid or setgid root programs;
make the user log in as root instead.
-->
可能であれば，root に setuid/setgid したプログラムは作成しないこと．
その代わりに，ユーザに root としてログインさせればよい．
<p>
<!--O
Sign your code. That way, others can check to see if what's available
was what was sent.
-->
コードに署名しておくこと．そうすれば，入手したものと用意されたものが同
じかどうかを確かめることができる．
<p>
<!--O
Consider statically linking secure programs.
This counters attacks on the dynamic link library mechanism
by making sure that the secure programs don't use it.
-->
安全にする必要があるプログラムは，静的にリンクすることも検討するとよい．
そうすれば動的リンクのライブラリは使われないので，動的リンク機構を狙っ
た攻撃を防ぐことができる．
<p>
<!--O
When reading over code, consider all the cases where a match is not made.
For example, if there is a switch statement, what happens when none of the
cases match?
If there is an ``if'' statement, what happens when the condition is false?
-->
コードを読む時には，どの条件も一致しない場合も含めて全て考慮すること．
例えば switch 文がある場合にどの case にも一致しないとどうなるだろうか? 
``if'' 文がある場合には，条件が偽ならどうなるだろうか?
<p>
<!--O
Ensure the program works with compile-time and run-time
checks turned on, and leave them on where practical.
Perl programs should turn on the warning flag (-w), which warns of
potentially dangerous or obsolete statements, and possibly the
taint flag (-T), which prevents the direct use of untrusted inputs without
performing some sort of filtering.
Security-relevant programs should compile cleanly with
all warnings turned on.
For C or C++ compilations using gcc, use at least
the following as compilation flags (which turn on a host of warning messages)
and try to eliminate all warnings:
-->
プログラムを動作させる時はコンパイル時のチェックと実行時のチェック
は必ず有効にし，実用的に動くならばチェックオプションはそのままにしてお
くこと．
Perl のプログラムでは警告フラグ(-w)を有効にしておくべきである．このフ
ラグを有効にしていると，危険性がある文や古い仕様の文に対して警告を出
してもらえる．
また，たぶん taint フラグ(-T)も有効にしておくべきだろう．
このフラグを有効にしていると，信頼できない入力を何らかの処理に通さずに
直接使用することができなくなる．
セキュリティ関連のプログラムは，全ての警告オプションを有効にした状態で
も警告メッセージが出ないようにコンパイルできるようにすべきである．
gcc を使って C や C++ をコンパイルする時は，少なくとも以下のコンパイル
フラグを使用し(ほとんどの警告メッセージが有効になる)，できれば全ての
警告を出ないようにすること:
<verb>
gcc -Wall -Wpointer-arith -Wstrict-prototypes
</verb>
</sect1>
</sect>
<!-- maybe someday add Logging discussion -->

<!--O
<sect>Conclusions
-->
<sect>結論
<p>
<!--o
Designing and implementing a truly secure program
is actually a difficult task on Linux.
The difficulty is that a truly secure program must respond
appropriately to all possible inputs and environments
controlled by a potentially hostile user.
This is not a problem unique to Linux; 
other general-purpose operating systems (such as Unix and Windows NT)
present developers with similar challenges.
Developers of secure programs must deeply understand their platform,
seek and use guidelines (such as these), and then use assurance
processes (such as peer review) to reduce their programs' vulnerabilities.
-->
本当に安全なプログラムの設計と実装を Linux 上で行うことは本当に難しい
作業である．
この難しさは，本当に安全なプログラムは敵になる可能性があるユーザが操作
できる全ての入力と環境に対して適切に応答できなければならない点にある．
これは Linux 固有の問題ではなく，他の汎用の OS (UNIX や WindowsNT 等)
でも開発者達は同様の試みを行っている．
安全でなければならないプログラム開発者は，プラットフォームを深く理解し，
(本論文のような)ガイドラインをよく読んで利用し，(ピアレビューなどの)
保証のための工程を実施することによりプログラムの弱点を減らさなければな
らない．
</sect>


<!--O
<sect>References
-->
<sect>参考文献
<p>
<!--O
<it>Note that there is a heavy
emphasis on technical articles available on the web, since this is where
most of this kind of technical information is available.
</it>
-->
<it>ウェブで入手可能な技術記事を特に強調している点に注意すること．
なぜなら，この種の技術情報のほとんどはウェブを使って入手できるからであ
る．</it>

[Al-Herbish 1999]
Al-Herbish, Thamer.
1999.
<it>Secure Unix Programming FAQ</it>.
<url url="http://www.whitefang.com/sup">.

[Aleph1 1996] 
Aleph1.
November 8, 1996.
``Smashing The Stack For Fun And Profit.''
<it>Phrack Magazine</it>.
Issue 49, Article 14.
<url url="http://www.phrack.com">

[Anonymous unknown]
<it>SETUID(7)</it>
<url url="http://www.homeport.org/~adam/setuid.7.html">.
<!-- Claimed to be from Dan Farmer's COPS, but COPS does not include it. -->

&lsqb;AUSCERT 1996&rsqb;
Australian Computer Emergency Response Team (AUSCERT) and O'Reilly.
May 23, 1996 (rev 3C).
<it>A Lab Engineers Check List for Writing Secure Unix Code</it>.
<url url="ftp://ftp.auscert.org.au/pub/auscert/papers/secure_programming_checklist">

[Bach 1986]
Bach, Maurice J.
1986.
<it>The Design of the Unix Operating System</it>.
Englewood Cliffs, NJ: Prentice-Hall, Inc.
ISBN 0-13-201799-7 025.

[Bellovin 1994]
Bellovin, Steven M.
December 1994.
<it>Shifting the Odds -- Writing (More) Secure Software</it>.
Murray Hill, NJ: AT&amp;T Research.
<url url="http://www.research.att.com/~smb/talks">

[Bishop 1996]
Bishop, Matt.
May 1996.
``UNIX Security: Security in Programming.''
<it>SANS '96</it>. Washington DC (May 1996).
<url url="http://olympus.cs.ucdavis.edu/~bishop/secprog.html">

[Bishop 1997]
Bishop, Matt.
October 1997.
``Writing Safe Privileged Programs.''
<it>Network Security 1997</it>
New Orleans, LA.
<url url="http://olympus.cs.ucdavis.edu/~bishop/secprog.html">

[CC 1999]
<it>The Common Criteria for Information Technology Security Evaluation
(CC)</it>.
August 1999.
Version 2.1.
Technically identical to International Standard ISO/IEC 15408:1999.
<url url="http://csrc.nist.gov/cc/ccv20/ccv2list.htm">


[CERT 1998]
Computer Emergency Response Team (CERT) Coordination Center (CERT/CC).
February 13, 1998.
<it>Sanitizing User-Supplied Data in CGI Scripts</it>.
CERT Advisory CA-97.25.CGI_metachar.
<url url="http://www.cert.org/advisories/CA-97.25.CGI_metachar.html">.

[CMU 1998]
Carnegie Mellon University (CMU).
February 13, 1998
Version 1.4.
``How To Remove Meta-characters From User-Supplied Data In CGI Scripts.''
<url url="ftp://ftp.cert.org/pub/tech_tips/cgi_metacharacters">.

[Cowan 1999]
Cowan, Crispin, Perry Wagle, Calton Pu, Steve Beattie, and
Jonathan Walpole.
``Buffer Overflows: Attacks and Defenses for the Vulnerability
of the Decade.''
Proceedings of DARPA Information Survivability Conference and Expo (DISCEX),
<url url="http://schafercorp-ballston.com/discex">
To appear at SANS 2000,
<url url="http://www.sans.org/newlook/events/sans2000.htm">.
For a copy, see
<url url="http://immunix.org/documentation.html">.

[Fenzi 1999]
Fenzi, Kevin, and Dave Wrenski.
April 25, 1999.
<it>Linux Security HOWTO</it>.
Version 1.0.2.
<url url="http://www.linuxdoc.org/HOWTO/Security-HOWTO.html">

[FreeBSD 1999]
FreeBSD, Inc.
1999.
``Secure Programming Guidelines.''
<it>FreeBSD Security Information</it>.
<url url="http://www.freebsd.org/security/security.html">

[FSF 1998]
Free Software Foundation.
December 17, 1999.
<it>Overview of the GNU Project</it>.
<url url="http://www.gnu.ai.mit.edu/gnu/gnu-history.html">

[Galvin 1998a]
Galvin, Peter.
April 1998.
``Designing Secure Software''.
<it>Sunworld</it>.
<url url="http://www.sunworld.com/swol-04-1998/swol-04-security.html">.

[Galvin 1998b]
Galvin, Peter.
August 1998.
``The Unix Secure Programming FAQ''.
<it>Sunworld</it>.
<url url="http://www.sunworld.com/sunworldonline/swol-08-1998/swol-08-security.html">

&lsqb;Garfinkel 1996&rsqb;
Garfinkel, Simson and Gene Spafford.
April 1996.
<it>Practical UNIX &amp; Internet Security, 2nd Edition</it>.
ISBN 1-56592-148-8.
Sebastopol, CA: O'Reilly &amp; Associates, Inc. 
<url url="http://www.oreilly.com/catalog/puis">

[Gong 1999]
Gong, Li.
June 1999.
<it>Inside Java 2 Platform Security</it>.
Reading, MA: Addison Wesley Longman, Inc.
ISBN 0-201-31000-7.

[Gundavaram Unknown]
Gundavaram, Shishir, and Tom Christiansen.
Date Unknown.
<it>Perl CGI Programming FAQ</it>.
<url url="http://language.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html">

[Kim 1996]
Kim, Eugene Eric.
1996.
<it>CGI Developer's Guide</it>.
SAMS.net Publishing.
ISBN: 1-57521-087-8
<url url="http://www.eekim.com/pubs/cgibook">

[Miller 1999]
Miller, Todd C. and Theo de Raadt.
``strlcpy and strlcat -- Consistent, Safe, String Copy and Concatenation''
<it>Proceedings of Usenix '99</it>.
<url url="http://www.usenix.org/events/usenix99/millert.html"> and
<url url="http://www.usenix.org/events/usenix99/full_papers/millert/PACKING_LIST">

[OSI 1999].
Open Source Initiative.
1999.
<it>The Open Source Definition</it>.
<url url="http://www.opensource.org/osd.html">.

[Pfleeger 1997]
Pfleeger, Charles P.
1997.
<it>Security in Computing.</it>
Upper Saddle River, NJ: Prentice-Hall PTR.
ISBN 0-13-337486-6.

[Phillips 1995]
Phillips, Paul.
September 3, 1995.
<it>Safe CGI Programming</it>.
<url url="http://www.go2net.com/people/paulp/cgi-security/safe-cgi.txt">

[Raymond 1997]
Raymond, Eric.
1997.
<it>The Cathedral and the Bazaar</it>.
<url url="http://www.tuxedo.org/~esr/writings/cathedral-bazaar">

[Raymond 1998]
Raymond, Eric.
April 1998.
<it>Homesteading the Noosphere</it>.
<url url="http://www.tuxedo.org/~esr/writings/homesteading/homesteading.html">

[Ranum 1998]
Ranum, Marcus J.
1998.
<it>Security-critical coding for programmers -
a C and UNIX-centric full-day tutorial</it>.
<url url="http://www.clark.net/pub/mjr/pubs/pdf/">.

[RFC 822]
August 13, 1982
<it>Standard for the Format of ARPA Internet Text Messages</it>.
IETF RFC 822.
<url url="http://www.ietf.org/rfc/rfc0822.txt">.

[rfp 1999].
rain.forest.puppy.
``Perl CGI problems.''
<it>Phrack Magazine</it>.
Issue 55, Article 07.
<url url="http://www.phrack.com">.

[Saltzer 1974]
Saltzer, J.
July 1974.
``Protection and the Control of Information Sharing in MULTICS.''
<it>Communications of the ACM</it>.
v17 n7.
pp. 388-402.

[Saltzer 1975]
Saltzer, J., and M. Schroeder.
September 1975.
``The Protection of Information in Computing Systems.''
<it>Proceedings of the IEEE</it>.
v63 n9.
pp. 1278-1308.
Summarized in [Pfleeger 1997, 286].

[Schneier 1999]
Schneier, Bruce.
September 15, 1999.
``Open Source and Security.''
<it>Crypto-Gram</it>.
Counterpane Internet Security, Inc.
<url url="http://www.counterpane.com/crypto-gram-9909.html">

[Seifried 1999]
Seifried, Kurt.
October 9, 1999.
<it>Linux Administrator's Security Guide</it>.
<url url="http://www.securityportal.com/lasg">.

&lsqb;Shostack 1999&rsqb;
Shostack, Adam.
June 1, 1999.
<it>Security Code Review Guidelines</it>.
<url url="http://www.homeport.org/~adam/review.html">.

&lsqb;Sitaker 1999&rsqb;
Sitaker, Kragen.
Feb 26, 1999.
<it>How to Find Security Holes</it>
<url url="http://www.pobox.com/~kragen/security-holes.html"> and
<url url="http://www.dnaco.net/~kragen/security-holes.html">

[SSE-CMM 1999]
SSE-CMM Project.
April 1999.
<it>System Security Engineering Capability Maturity Model (SSE CMM)
Model Description Document</it>.
Version 2.0.
<url url="http://www.sse-cmm.org">

[Stein 1999].
Stein, Lincoln D.
September 13, 1999.
<it>The World Wide Web Security FAQ</it>.
Version 2.0.1
<url url="http://www.w3.org/Security/Faq/www-security-faq.html">

[Thompson 1974]
Thompson, K. and D.M. Richie.
July 1974.
``The UNIX Time-Sharing System.''
<it>Communications of the ACM</it>
Vol. 17, No. 7.
pp. 365-375.
<!-- Revised and reprinted in Ritchie 1978a; see Bach 1986 -->

[Torvalds 1999]
Torvalds, Linus.
February 1999.
``The Story of the Linux Kernel.''
<it>Open Sources: Voices from the Open Source Revolution</it>.
Edited by Chris Dibona, Mark Stone, and Sam Ockman.
O'Reilly and Associates.
ISBN 1565925823.
<url url="http://www.oreilly.com/catalog/opensources/book/linus.html">

[Webber 1999]
Webber Technical Services.
February 26, 1999.
<it>Writing Secure Web Applications</it>.
<url url="http://www.webbertech.com/tips/web-security.html">.

[Wood 1985]
Wood, Patrick H. and Stephen G. Kochan.
1985.
<it>Unix System Security</it>.
Indianapolis, Indiana: Hayden Books.
ISBN 0-8104-6267-2.

[Wreski 1998]
Wreski, Dave.
August 22, 1998.
<it>Linux Security Administrator's Guide</it>.
Version 0.98.
<url url="http://www.nic.com/~dave/SecurityAdminGuide/index.html">

</sect>
<!--O
<sect>Document License
-->
<sect>文書のライセンス
<P>
<!--O
This document is Copyright (C) 1999 David A. Wheeler and is covered by the
GNU General Public License (GPL).
You may redistribute it freely.
Interpret the document's source text
as the ``program'' and adhere to the following terms:
-->
この文書は 1999 David A. Wheeler の著作物であり(Copyright (C) 1999 David A. Wheeler)，
GNU General Public License (GPL) によって保護されている．
再配布は自由に行って構わない．
文書のソーステキストを「プログラム」と解釈して，以下の条件に従うこと．
<tscreen><verb>
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
</verb></tscreen>
</sect>

<sect>日本語訳について
<p>
日本語訳は Linux Japanese FAQ Project が行いました．
翻訳に関するご意見は JF プロジェクト
&lt;JF@linux.or.jp&gt;
宛に連絡してください．

改訂履歴を以下に示します．

<descrip>
<tag>v1.23j, 3 Feburary 2000</tag>
翻訳:
藤原輝嘉 &lt;fujiwara@linux.or.jp&gt;

校正/技術チェック:
<itemize>
<item>荒木靖宏 &lt;yasu@debian.or.jp&gt;
<item>土屋哲 &lt;satoshi@flab.fujitsu.co.jp&gt;
<item>中野武雄 &lt;nakano@apm.seikei.ac.jp&gt;
<item>早川仁 &lt;uv9h-hykw@asahi-net.or.jp&gt;
<item>武井伸光 &lt;takei@cc.kochi-u.ac.jp&gt;
</itemize>
</descrip>
</sect>

</article>
