Trusted Solaris 開発ガイド

第 5 章 ラベル

Trusted Solaris 7 は、CMW ラベル、機密ラベルの 2 種類のラベルを使用します。情報ラベル (IL) は Trusted Solaris 7 およびそれ以降のバージョンではサポートしません。Trusted Solaris ソフトウェアは、ADMIN_LOW として稼動している既存リリースのシステムから、通信とファイル上の情報ラベルを再度インタプリタ処理します。ただし、CMW ラベルは、機密ラベルと情報ラベルを 1 つの単位として扱うための構成体にすぎません。すべてのプロセスとオブジェクトには、CMW ラベルがありますが、情報ラベル部は ADMIN_LOW に限定されます。

CMW ラベルの機密ラベル部は、プロセスとオブジェクト内のデータの格付けに対するアクセスの制御と管理をする必須アクセス制御 (MAC) 機構です。CMW ラベルの機密ラベル部は、情報がどのレベルで保護される必要があるかについても示します。プロセスがオブジェクトにアクセスする場合は常に、第 1 章「API とセキュリティポリシーの紹介」に説明されているように、必須アクセスチェックと任意アクセスチェックが実行されます。

情報ラベルがサポートされなくなったことにより、Trusted Solaris 7 では次のような影響が生じます。

この章では、ラベルの初期化、CMW ラベルのラベル部の取得、ラベルの比較など、一般的なラベル操作を実行するプログラミングインタフェースについて説明します。また、プロセスやファイルシステムオブジェクトの CMW ラベルにアクセスするプログラミングインタフェースについても説明します。この章で説明するプログラミングインタフェースのコード例は、第 6 章「ラベルのコード例」で示します。

認可上限は機密ラベルと同じ構成をしていますが、実行する機能は異なります。この類似性のため、この章のインタフェースの中には認可上限をパラメータとして使用できるものもあります。また、一部のインタフェースは認可上限を処理するインタフェースを含みます。しかし、認可上限は異なる機能を持つため、認可上限を管理するインタフェースはすべて、認可上限を使用するコード例と共に、第 7 章「プロセス認可上限」で説明しています。

CMW ラベル

CMW ラベルは、すべてのプロセスとオブジェクトのラベル付けを行う構成体です。CMW ラベルとは、機密ラベルと情報ラベルがプログラム上で 1 つの単位として処理されたり、あるいは個々にアクセスされるように、2 つのラベルを結合したものです。

機密ラベル

機密ラベルには、1 つの ID フィールド、 1 つの階層的な格付け、1 つ以上の非階層的なコンパートメントが 1 セット含まれます。格付けは、階層内でのレベルを表します。一方、コンパートメントは、システム内の情報の範囲区分を表します。コンパートメントは、特定の範囲の情報を知る必要のある人物だけにアクセスを託すためのものです。たとえば、Secret 格付けの人物は、コンパートメントリストに指定された機密情報に対するアクセス権がありますが、それ以外の機密情報に対するアクセス権はありません。機密ラベルの格付けとコンパートメントの両方によってプロセスまたはオブジェクトの機密レベルが決定されます。

機密ラベルの比較とは、プロセス CMW ラベルの機密ラベル部を、対象となる CMW ラベルの機密ラベル部と比較することです。プロセスに対するアクセス権は、プロセスの機密レベルが対象となる CMW の機密レベルより優位かどうかに基づいて、付与または拒否されます。同等と優位の関係は、「ラベルの関係の確認」で説明しています。

CMW ラベルの表示

CMW ラベルは、Trusted Solaris 7 のユーザーインタフェースで、単一の機密ラベルを表します。

CMW ラベルの取得

ラベルは、ワークスペースとほかのプロセスから取得されます。ユーザーは、現在作業中のワークスペースの機密ラベルにおいてのみ、プロセスを開始することができます。

プロセスの CMW ラベル

プロセスがワークスペースから開始されると、プロセスの CMW ラベルはワークスペースの CMW ラベルの機密ラベルの値を継承します。

fork(2) により新しいプロセスが作成されると、新しいプロセスはその呼び出しプロセスの CMW ラベル値を継承します。

新しいプログラムが exec(1) により開始されるとき、exec を実行するプロセスは、新しいプログラムのファイルに対する任意アクセス権と必須アクセス権の両方を必要とします。

setcmwplabel(2) システムコールは、プログラム中からプロセスの CMW ラベルを設定します。このシステムコールは、新しいプロセスを fork または exec により起動したあとで、そのプロセスを呼び出し元のプロセスとは別の CMW ラベルで動作させたいときに使用してください。このとき、特権が必要になる場合があります。詳細は、「特権の必要な操作」を参照してください。

オブジェクト CMW ラベル

プロセスによってオブジェクトが作成されると、オブジェクトはその呼び出し元プロセスの CMW ラベル値を継承します。ラベル表示の設定に応じて、ADMIN_LOW ラベルまたはシステム上で次にもっとも低いラベルがユーザーに表示されます。ラベル表示とは、「プロセスのセキュリティ属性フラグの取得と設定」で説明されている、プロセスのセキュリティ属性フラグです。

特権プロセスがオブジェクトに対し下位書き込みを行うと、システムはオブジェクトの機密ラベルを、プロセスの機密ラベルと同じになるよう変更します。この変更により、より高い機密ラベルでプロセスから書き込まれる情報が、より低い機密ラベルで動作しているほかのプロセスによってアクセスされないように保護します。

setcmwlabel(2) システムコールは、ファイルシステムオブジェクトの CMW ラベルをプログラム中から設定します。

承認を受けたユーザーは、ファイルマネージャを使用して、既存のファイルの CMW ラベルの機密ラベルを変更できます。

特権の必要な操作

プロセスやファイルシステムオブジェクトの CMW ラベルの取得と設定を行うシステムコールは、プロセスやファイルシステムオブジェクトに対する必須アクセス権と任意アクセス権を必要とします。また、アクセスがシステムセキュリティポリシーにより拒否される場合は、特権が必要になります。システムコールの一覧は、「システムコール」を参照してください。

バイナリラベルの変換

呼び出し元のプロセスは、バイナリと ASCII 間でラベルを変換するときに、プロセスの機密ラベルが変換されるラベルより優位でないときは、有効セット内に sys_trans_label 特権を必要とします。この特権は、プロセスの機密ラベルが検査されるラベルより優位でない場合に、ラベルが有効であるかどうかを検査する場合にも必要になります。

プロセスラベルの設定

呼び出し元プロセス自体の機密ラベルを現在とは異なるラベルに変更したいとき、呼び出しプロセスの有効セット内に proc_setsl 特権が必要となります。

機密ラベルの降格と昇格

呼び出し元プロセス自体が所有していないファイルの機密ラベルを降格する場合、呼び出し元プロセスの有効セット内に file_owner 特権が必要となります。

機密ラベルの降格

プロセスは、その有効セット内の file_downgrade_sl 特権を使用して、ファイルシステムオブジェクトの機密ラベルを、オブジェクトの現在の機密ラベルよりも優位でない機密ラベルに設定できます。

機密ラベルの昇格

プロセスは、その有効セット内の file_upgrade_sl 特権を使用して、ファイルシステムオブジェクトの機密ラベルを、オブジェクトの現在の機密ラベルより優位な機密ラベルに設定できます。

ラベルのガイドライン

この節では、アクセス制御の回避や、機密ラベルの変更を行うために、プログラムが、特権を必要とする場合に守るべきガイドラインを示します。

機密ラベル

ほとんどのアプリケーションは、次のどれかの方法で動作するため、アクセス制御を回避するときに特権は使用しません。

アプリケーションがそのプロセスの機密ラベルとは異なる機密ラベルでデータにアクセスし、そのアクセスが拒否される場合、プロセスは特権を必要とします。特権によりアプリケーションは、file_mac_readfile_dac_readfile_mac_writefile_dac_writefile_mac_search、または file_dac_search を使用して必須または任意のアクセス制御の適用を回避したり、proc_setsl を使用して必須アクセスが与えられるようにプロセスの機密ラベルを変更したり、あるいは file_upgrade_slfile_downgrade_sl を使用してデータの機密ラベルを昇格または降格することができます。どのような方法でアクセスするにせよ、アクセスされるデータの格付けに害を及ぼすことがないように、この節に示されたガイドラインを守ってアプリケーションを設計する必要があります。

必須アクセス制御の回避

特権を使用して必須アクセス制限が適用されないようにする場合、アプリケーションは、データを読み取るレベルよりも低い機密ラベルでデータを書き込むことができません。また、プログラムエラーによるデータの降格を行うことがないようにアプリケーションを設計してください。

機密ラベルの昇格または降格

アプリケーションがそれ自体の機密ラベルまたは別のオブジェクトの機密ラベルを変更する場合、次のガイドラインに従ってください。

別の機密ラベルでのプロセスの作成

プロセスの機密ラベルを変更する代わりに、新しいプロセスを fork() により起動し、フォークされた子プロセスの機密ラベルを変更することによって、子プロセスが、親プロセスのデータとは異なるレベルで作業できるようになります。子プロセスは、親プロセスに対して情報を返すか、あるいは別のプロセスに情報を送る必要があります。

変更された機密レベルで子プロセスが返す情報には、必要不可欠な情報だけが含まれるようにします。たとえば、処理が成功したか失敗したかを表示しても、実際のデータは表示しないようにします。特定の情報を渡すことにより、処理に使用されるデータを守り、1 つのレベルのデータが別のレベルのデータと混ざることのないようにします。

データ型、ヘッダーファイル、ライブラリ

この章で説明しているプログラミングインタフェースを使用するには、次のヘッダーファイルが必要です。

#include <tsol/label.h>

この章の例は、次のライブラリを使用してコンパイルしています。

-ltsol

CMW ラベル

データ構造体 bclabel_t は、バイナリの CMW ラベルを示します。インタフェースでは、bclabel_t 型構造のバイナリ CMW ラベルを使用します。

フラグの設定

CMW ラベルフラグの値を定義する setting_flag 型の定義を次に示します。

SETCL_SL - CMW ラベルの機密ラベル部を設定する。

SETCL_ALL - CMW ラベル全体を設定する。

機密ラベル

bslabel_t 型の定義は、バイナリ CMW ラベルの機密ラベル部を示します。インタフェースでは、バイナリの機密ラベルは、bslabel_t 型の変数のパラメータとして受け渡されます。bslabel_t 型の定義は、blevel_t 構造と互換性があります。

バイナリレベル

blevel_t 構造は、機密ラベル、情報ラベル、または認可上限の、格付けとコンパートメントセットのバイナリレベルを示します。インタフェースでは、blevel_t 型構造体のバイナリレベルが受け渡されます。

型の互換性

bclear_t 型または bslabel_t 型の変数は、blevel_t 型のパラメータを受け入れる関数に渡すことができます。

機密ラベルの範囲

brange_t データ構造体は、機密ラベルの範囲を示します。この構造は、最下位ラベルと最上位ラベルを保持します。構造フィールドは、variable.lower_boundvariable.upper_bound として参照されます。

認可範囲

set_id データ構造体は、現在、次の整数値を受け入れます。1 = SYSTEM_ACCREDITATION_RANGE (システム認可範囲); 2 = USER_ACCREDITATION_RANGE (ユーザー認可範囲)

ラベル情報

label_info 構造には、label_encodings ファイル内の項目の長さが指定されます。この構造は、labelinfo(3) によって返されます。

フィールド 

内容 

slabel_len

機密ラベルの最大長 

clabel_len

CMW ラベルの最大長 

clear_len

認可上限ラベルの最大長 

vers_len

バージョン文字列の長さ 

header_len

プリンタバナーの最大長 

protect_as_len

bcltobanner(3) が返すプリンタバナーページの、ヘッダー文字列の最大長

caveats_len

bcltobanner(3) が返すプリンタバナーページの、文字列の最大長

channels_len

プリンタバナーページのチャネル文字列の最大長 

バナーフィールド

banner_field 構造には、ASCII コードに変換されたラベルと文字列が含まれます。このラベルと文字列は、プリンタバナー、トレーラページ、および文書の本文ページの先頭と最後に表示されます。この構造は、bcltobanner(3) によって返されます。最初の 5 つのフィールドは、文字列へのポインタです。次の 5 つのフィールドは、対応する文字列ポインタの指す領域に対して事前に割り当てられたメモリーの長さを示すショート整数 (short integer) です。

フィールド 

内容 

header

バナーページとトレーラページの先頭と最後に表示される文字列 

protect_as

バナーページの protect as セクションに表示される文字列 

caveats

バナーページの caveats セクションに表示される文字列 

channels

handling channels セクションに表示される文字列 

header_len

ヘッダーの文字列に事前に割り当てられたメモリーの長さ 

protect_as_len

protect as セクションの文字列に事前に割り当てられたメモリーの長さ 

ilabel_len

情報ラベルの文字列に事前に割り当てられたメモリーの長さ 

caveats_len

caveats セクションの文字列に事前に割り当てられたメモリーの長さ 

channels_len

channels セクションの文字列に事前に割り当てられたメモリーの長さ 

プログラミングインタフェースの宣言

プロセスとファイルシステムオブジェクトのラベルについて、一般的な操作を行なったりアクセスしたりするときに、次に示すプログラミングインタフェースを使用できます。

システムコール

次のシステムコールは、ファイルまたはプロセスの CMW ラベルの取得と設定を行なったり、ファイルシステムのラベル範囲を取得したりします。


注意 - 注意 -

別のプロセスまたはファイルシステムのオブジェクトにラベルを設定するプロセスはすべて、label_encodings ファイルの定義どおりに有効なラベルを設定しなければなりません。また、この種のプロセスは、正しいバイナリ型のラベルを渡す必要があります。ASCII からバイナリへの変換機能は、変換により正しいバイナリラベルが得られるように、できるかぎりラベルを修正します。しかし、ラベルが有効であるか、bslvalid(3) ルーチンを使用してさらに調べる場合もあります。正しく構築されたバイナリラベルでも、一定のシステムまたはユーザーには無効な場合もあるため、ラベルがシステム認可またはユーザー認可の範囲内であるか、blinset(3) ルーチンを使用して検査してください。


ファイルの CMW ラベル

次のシステムコールは、パス名またはファイル記述子を使用して、ファイルの CMW ラベルの取得と設定を行います。詳細は、setcmwlabel(2)getcmwlabel(2) のマニュアルページを参照してください。

int			setcmwlabel(						const char *path,
 									const bclabel_t *label,
 									const setting_flag_t flag);
 int			getcmwlabel(						const char *path,
 									const bclabel_t *label);

 int			fsetcmwlabel(							const int fd,
 									const bclabel_t *label,
 									const setting_flag_t flag);
 int			fgetcmwlabel(						const int fd,
 									bclabel_t *label);

 int			lsetcmwlabel(						const int fd,
 									const bclabel_t *label,
 									const setting_flag_t flag);
 int			lgetcmwlabel(						const int fd,
 									bclabel_t *label);

プロセスの CMW ラベル

次のシステムコールは、プロセスの CMW ラベルの取得と設定を行います。詳細は、setcmwplabel(2)getcmwplabel(2) のマニュアルページを参照してください。

int			setcmwplabel(							const bclabel_t *label,
 									const setting_flag_t flag);
 int			getcmwplabel(							const bclabel_t *label);

ファイルシステムのラベル範囲

次のシステムコールは、ファイルシステムのラベル範囲を取得します。詳細は、getcmwfsrange(2) のマニュアルページを参照してください。

int			getcmwfsrange(							char *path, brange_t *range);
 int			fgetcmwfsrange(							int fd, brange_t *range);

ライブラリルーチン

次のライブラリルーチンは、ラベルのアクセス、初期化、比較、変換、および検証を行います。また、label_encodings(4) 情報の取得も行います。

CMW ラベルの初期化

次のルーチンは、CMW ラベルを ADMIN_HIGHADMIN_LOW、または NULL に似た定義されていない状態に初期化します。詳細は、blmanifest(3) のマニュアルページを参照してください。

void		bclhigh(				bclabel_t *label);
 void		bcllow(				bclabel_t *label);
 void		bclundef(				bclabel_t *label);

CMW ラベルのラベル部

次のルーチンは、CMW ラベルの機密ラベル部にアクセスします。詳細は、blportion(3) のマニュアルページを参照してください。

void 				getcsl(					bslabel_t *destination_label,
 									const bclabel_t *source_label);
 void				setcsl(					bclabel_t *destination_label,
 									const bslabel_t *source_label);
 bslabel_t				*bcltosl(					bclabel_t *label);

機密ラベルの初期化

次のルーチンは、機密ラベルを ADMIN_HIGHADMIN_LOW、定義されていない状態のいずれかに初期化します。詳細は、blmanifest(3) のマニュアルページを参照してください。

void		bslhigh(				bslabel_t *label);
 void		bsllow(				bslabel_t *label);
 void		bslundef(				bslabel_t *label);

レベルの比較

次のルーチンは、 level1level2 の 2 つのレベルを比較し、両者が同等か、level1 が level2 よりも優位であるか、あるいは level1 が level2 よりも完全に優位であるかを調べます。レベルとは、機密ラベルまたは認可上限内の、格付けおよびコンパートメントのことです。

返される値のうち、0 以外の値は true で、0 は false です。詳細は、 blcompare(3) のマニュアルページを参照してください。

int		blequal(				const blevel_t *level1,
 						const blevel_t *level2);
 int		bldominates(				const blevel_t *level1,
 						const blevel_t *level2);
 int		blstrictdom(				const blevel_t *level1,
 						const blevel_t *level2);
 int 		blinrange(				const blevel_t *level,
 						const brange_t *range);

ラベルタイプ

次のルーチンは、ラベルのタイプを検査し、設定します。ラベルには、定義済みか末定義の CMW ラベル、機密ラベル、情報ラベルがあります。詳細は、bltype(3) のマニュアルページを参照してください

int		bltype(				const void *label
 						const unsigned char type);
 void		setbltype(				void *label
 						const unsigned char type);

レベルの上下限

次のルーチンは、 2 つのレベルを比較し、それら 2 つのレベルの範囲内の、高い方の下限 (blminimum(3)) または低い方の上限 (blmaximum(3)) を示す機密レベルを見つけます。レベルとは、機密ラベルまたは認可上限内の、格付けとコンパートメントのことです(詳細は、blcompare(3) のマニュアルページを参照)。

void		blmaximum(				blevel_t *maximum_label
 						const blevel_t *bounding_label);
 void		blminimum(				blevel_t *minimum_label
 						const blevel_t *bounding_label); 

ラベルエンコーディングファイル

label_encodings ファイルは、システム管理者によって管理される ASCII ファイルで、サイト固有のラベルの定義と制約が記載されています。このファイルは、/etc/security/tsol/label_encodings に保存されます。label_encodings ファイルの詳細は、『Trusted Solaris のラベル管理』と『コンパートメントモードワークステーションのラベル作成: エンコード形式』を参照してください。

次のルーチンは、先頭から順に、最大文字列長の情報、使用中の label_encodings ファイルのバージョン、指定されたバイナリレベルに対する ASCII カラー名などの label_encodings ファイルで指定されている情報を戻します。

int		labelinfo(				struct label_info *info);
int		labelvers(				char **version,
 						const int length);
char		bltocolor(				const blevel_t *label);
 char		bltocolor_t(				const blevel_t *label,
 						const int size,
 						char * color_name); 

有効な機密ラベル

次のルーチンは、指定された機密ラベルがシステムで有効であるか、つまり、システムの label_encodings ファイルで定義されているかを検査します。詳細は、blvalid(3) のマニュアルページを参照してください。

int		bslvalid(				const bslabel_t *senslabel);
  

認可範囲

次のルーチンは、機密ラベルが、システムの label_encodings ファイルで設定されているとおりのシステム認可範囲にあるかを検査します。詳細は、blinset(3) のマニュアルページを参照してください。

int		blinset(				const blevel_t *senslabel,
 						const set_id *id); 

バイナリと ASCII 間の変換

次のルーチンは、バイナリの CMW ラベルまたは機密ラベルを ASCII に変換し、再び元に戻します。文字列からバイナリに変換する場合、flag (フラグ) が NEW_LABELNO_CORRECTION に設定されていれば、文字列は ASCII でも 16 進でも構いません。詳細は、bltos(3)stobl(3) のマニュアルページを参照してください。


注 -

バイナリラベルを ASCII へ変換する、指定された幅に応じて最終的なラベルの長さを変える、Motif ベースのグラフィカルユーザーインタフェース (GUI) で表示用のフォントリストを使用する、などの処理を行う各インタフェースの詳細は、第 15 章「トラステッド X ウィンドウシステム」を参照してください。


int		bcltos(				const bclabel_t *label,
 						char **string,
 						const int length,
 						const int flags);
 int		stobcl(				const char *string,
 						bclabel_t *label,
 						const int flags,
 						int *error);

/* 文字列を変換し、長さを変える */
 char		*sbcltos(				const bclabel_t *label,
 						const int length);

/* プリンタバナーとヘッダーページに含めるために変換する */
 char		*bcltobanner(				const bclabel_t *label,
 						struct banner_fields *fields,
 						const int flags);
int		bsltos(				const bslabel_t *label,
 						char **string,
 						const int length,
 						const int flags);
 int		stobsl(				const char *string,
 						bslabel_t *label,
 						const int flags,
 						int *error);

/* 文字列を変換し、長さを変える */
 char		*sbsltos(				const bslabel_t *label,
 						const int length);

バイナリと 16 進間の変換

次のルーチンは、バイナリの CMW ラベル、機密ラベルを 16 進に変換し、再び元に戻します。btohex(3)hextob(3) のマニュアルページを参照してください。

char		h_alloc(				const unsigned char id);
 void		h_free(				char *hex); 
char		*bcltoh(				const bclabel_t *label);
 char		*bcltoh_r(				const bclabel_t *label,
 						char *hex);
 int		htobcl(				const char *hex,
 						bclabel_t *label);
char		*bsltoh(				const bslabel_t *label);
 char		*bsltoh_r(				const bslabel_t *label,
 						char *hex);
 int		htobsl(				const char *hex,
 						bslabel_t *label);